Skip to content

Commit 6f55461

Browse files
committed
Split helix_core::find_root and helix_loader::find_local_config_dirs
The documentation of find_root described the following priority for detecting a project root: - Top-most folder containing a root marker in current git repository - Git repository root if no marker detected - Top-most folder containing a root marker if not git repository detected - Current working directory as fallback The commit contained in #1249 extracted and changed the implementation of find_root in find_root_impl, actually reversing its result order (since that is the order that made sense for the local configuration merge, from innermost to outermost ancestors). Since the two uses of find_root_impl have different requirements (and it's not a matter of reversing the order of results since, e.g., the top repository dir should be used by find_root only if there's not marker in other dirs), this PR splits the two implementations in two different specialized functions. In doing so, find_root_impl is removed and the implementation is moved back in find_root, moving it closer to the documented behaviour thus making it easier to verify it's actually correct
1 parent 5ea7855 commit 6f55461

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

helix-core/src/lib.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,41 @@ pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option<usize> {
4747
/// * Top-most folder containing a root marker if not git repository detected
4848
/// * Current working directory as fallback
4949
pub fn find_root(root: Option<&str>, root_markers: &[String]) -> Option<std::path::PathBuf> {
50-
helix_loader::find_root_impl(root, root_markers)
51-
.first()
52-
.cloned()
50+
let current_dir = std::env::current_dir().expect("unable to determine current directory");
51+
52+
let root = match root {
53+
Some(root) => {
54+
let root = std::path::Path::new(root);
55+
if root.is_absolute() {
56+
root.to_path_buf()
57+
} else {
58+
current_dir.join(root)
59+
}
60+
}
61+
None => current_dir.clone(),
62+
};
63+
64+
let mut top_marker = None;
65+
for ancestor in root.ancestors() {
66+
if root_markers
67+
.iter()
68+
.any(|marker| ancestor.join(marker).exists())
69+
{
70+
top_marker = Some(ancestor);
71+
}
72+
73+
if ancestor.join(".git").is_dir() {
74+
// Top marker is repo root if not root marker was detected yet
75+
if top_marker.is_none() {
76+
top_marker = Some(ancestor);
77+
}
78+
// Don't go higher than repo if we're in one
79+
break;
80+
}
81+
}
82+
83+
// Return the found top marker or the current_dir as fallback
84+
top_marker.map(|a| a.to_path_buf()).or(Some(current_dir))
5385
}
5486

5587
pub use ropey::{str_utils, Rope, RopeBuilder, RopeSlice};

helix-loader/src/lib.rs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub fn config_dir() -> PathBuf {
5959
}
6060

6161
pub fn local_config_dirs() -> Vec<PathBuf> {
62-
let directories = find_root_impl(None, &[".helix".to_string()])
62+
let directories = find_local_config_dirs()
6363
.into_iter()
6464
.map(|path| path.join(".helix"))
6565
.collect();
@@ -90,32 +90,16 @@ pub fn log_file() -> PathBuf {
9090
cache_dir().join("helix.log")
9191
}
9292

93-
pub fn find_root_impl(root: Option<&str>, root_markers: &[String]) -> Vec<PathBuf> {
93+
pub fn find_local_config_dirs() -> Vec<PathBuf> {
9494
let current_dir = std::env::current_dir().expect("unable to determine current directory");
9595
let mut directories = Vec::new();
9696

97-
let root = match root {
98-
Some(root) => {
99-
let root = std::path::Path::new(root);
100-
if root.is_absolute() {
101-
root.to_path_buf()
102-
} else {
103-
current_dir.join(root)
104-
}
105-
}
106-
None => current_dir,
107-
};
108-
109-
for ancestor in root.ancestors() {
110-
// don't go higher than repo
97+
for ancestor in current_dir.ancestors() {
98+
// Don't go higher than repo if we're in one
11199
if ancestor.join(".git").is_dir() {
112-
// Use workspace if detected from marker
113100
directories.push(ancestor.to_path_buf());
114101
break;
115-
} else if root_markers
116-
.iter()
117-
.any(|marker| ancestor.join(marker).exists())
118-
{
102+
} else if ancestor.join(".helix").is_dir() {
119103
directories.push(ancestor.to_path_buf());
120104
}
121105
}

0 commit comments

Comments
 (0)