From 8a019b423f5d51bcfc107da9cb50aa90eacff19d Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Fri, 31 Dec 2021 09:06:54 +0100 Subject: Detect workspace root using language markers (#1370) * Detect workspace root using language markers * Avoid allocating root_markers * Update helix-core/src/lib.rs Co-authored-by: Blaž Hrastnik * Update helix-core/src/lib.rs Co-authored-by: Kirawi <67773714+kirawi@users.noreply.github.com> Co-authored-by: Blaž Hrastnik Co-authored-by: Kirawi <67773714+kirawi@users.noreply.github.com>--- helix-core/src/lib.rs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'helix-core/src') diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 1c78e7c0..7fd23b97 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -39,8 +39,14 @@ pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option { line.chars().position(|ch| !ch.is_whitespace()) } -/// Find `.git` root. -pub fn find_root(root: Option<&str>) -> Option { +/// Find project root. +/// +/// Order of detection: +/// * Top-most folder containing a root marker in current git repository +/// * Git repostory root if no marker detected +/// * Top-most folder containing a root marker if not git repository detected +/// * Current working directory as fallback +pub fn find_root(root: Option<&str>, root_markers: &[String]) -> Option { let current_dir = std::env::current_dir().expect("unable to determine current directory"); let root = match root { @@ -52,16 +58,30 @@ pub fn find_root(root: Option<&str>) -> Option { current_dir.join(root) } } - None => current_dir, + None => current_dir.clone(), }; + let mut top_marker = None; for ancestor in root.ancestors() { - // TODO: also use defined roots if git isn't found + for marker in root_markers { + if ancestor.join(marker).exists() { + top_marker = Some(ancestor); + break; + } + } + // don't go higher than repo if ancestor.join(".git").is_dir() { - return Some(ancestor.to_path_buf()); + // Use workspace if detected from marker + return Some(top_marker.unwrap_or(ancestor).to_path_buf()); } } - None + + // In absence of git repo, use workspace if detected + if top_marker.is_some() { + top_marker.map(|a| a.to_path_buf()) + } else { + Some(current_dir) + } } pub fn runtime_dir() -> std::path::PathBuf { -- cgit v1.2.3-70-g09d2