Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split helix_core::find_root and helix_loader::find_local_config_dirs #3929

Merged
merged 2 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 36 additions & 4 deletions helix-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,42 @@ pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option<usize> {
/// * Git repository 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<std::path::PathBuf> {
helix_loader::find_root_impl(root, root_markers)
.first()
.cloned()
pub fn find_root(root: Option<&str>, root_markers: &[String]) -> std::path::PathBuf {
let current_dir = std::env::current_dir().expect("unable to determine current directory");

let root = match root {
Some(root) => {
let root = std::path::Path::new(root);
if root.is_absolute() {
root.to_path_buf()
} else {
current_dir.join(root)
}
}
None => current_dir.clone(),
};

let mut top_marker = None;
for ancestor in root.ancestors() {
if root_markers
.iter()
.any(|marker| ancestor.join(marker).exists())
{
top_marker = Some(ancestor);
}

if ancestor.join(".git").is_dir() {
// Top marker is repo root if not root marker was detected yet
if top_marker.is_none() {
top_marker = Some(ancestor);
}
// Don't go higher than repo if we're in one
break;
}
}

// Return the found top marker or the current_dir as fallback
top_marker.map_or(current_dir, |a| a.to_path_buf())
}

pub use ropey::{str_utils, Rope, RopeBuilder, RopeSlice};
Expand Down
26 changes: 5 additions & 21 deletions helix-loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn config_dir() -> PathBuf {
}

pub fn local_config_dirs() -> Vec<PathBuf> {
let directories = find_root_impl(None, &[".helix".to_string()])
let directories = find_local_config_dirs()
.into_iter()
.map(|path| path.join(".helix"))
.collect();
Expand Down Expand Up @@ -90,32 +90,16 @@ pub fn log_file() -> PathBuf {
cache_dir().join("helix.log")
}

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

let root = match root {
Some(root) => {
let root = std::path::Path::new(root);
if root.is_absolute() {
root.to_path_buf()
} else {
current_dir.join(root)
}
}
None => current_dir,
};

for ancestor in root.ancestors() {
// don't go higher than repo
for ancestor in current_dir.ancestors() {
if ancestor.join(".git").is_dir() {
// Use workspace if detected from marker
directories.push(ancestor.to_path_buf());
// Don't go higher than repo if we're in one
break;
} else if root_markers
.iter()
.any(|marker| ancestor.join(marker).exists())
{
} else if ancestor.join(".helix").is_dir() {
directories.push(ancestor.to_path_buf());
}
}
Expand Down
11 changes: 3 additions & 8 deletions helix-lsp/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct Client {
pub(crate) capabilities: OnceCell<lsp::ServerCapabilities>,
offset_encoding: OffsetEncoding,
config: Option<Value>,
root_path: Option<std::path::PathBuf>,
root_path: std::path::PathBuf,
root_uri: Option<lsp::Url>,
workspace_folders: Vec<lsp::WorkspaceFolder>,
req_timeout: u64,
Expand Down Expand Up @@ -74,9 +74,7 @@ impl Client {

let root_path = find_root(None, root_markers);

let root_uri = root_path
.clone()
.and_then(|root| lsp::Url::from_file_path(root).ok());
let root_uri = lsp::Url::from_file_path(root_path.clone()).ok();

// TODO: support multiple workspace folders
let workspace_folders = root_uri
Expand Down Expand Up @@ -281,10 +279,7 @@ impl Client {
workspace_folders: Some(self.workspace_folders.clone()),
// root_path is obsolete, but some clients like pyright still use it so we specify both.
// clients will prefer _uri if possible
root_path: self
.root_path
.clone()
.and_then(|path| path.to_str().map(|path| path.to_owned())),
root_path: self.root_path.to_str().map(|path| path.to_owned()),
root_uri: self.root_uri.clone(),
initialization_options: self.config.clone(),
capabilities: lsp::ClientCapabilities {
Expand Down
5 changes: 3 additions & 2 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2223,8 +2223,9 @@ fn append_mode(cx: &mut Context) {
}

fn file_picker(cx: &mut Context) {
// We don't specify language markers, root will be the root of the current git repo
let root = find_root(None, &[]).unwrap_or_else(|| PathBuf::from("./"));
// We don't specify language markers, root will be the root of the current
// git repo or the current dir if we're not in a repo
let root = find_root(None, &[]);
let picker = ui::file_picker(root, &cx.editor.config());
cx.push_layer(Box::new(overlayed(picker)));
}
Expand Down