diff options
author | Roland Kovacs | 2022-06-15 04:17:17 +0000 |
---|---|---|
committer | GitHub | 2022-06-15 04:17:17 +0000 |
commit | c2cc2037b548a39d374b11c6919e10b1a7115cfb (patch) | |
tree | f585adf59993e0c21a63fb13e48432db991e3563 /helix-term/src/ui | |
parent | 7983c71752e2443266ecc65581f3a980696cc294 (diff) |
Better handling of symlinks (#2718)
- Add file-picker.follow-symlinks configuration option (default is true), this
also controls if filename and directory completers follow symlinks.
- Update FilePicker to set editor error if opening a file fails, instead of
panicing.
Fix #1548
Fix #2246
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r-- | helix-term/src/ui/mod.rs | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 6dea2192..23d0dca0 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -118,6 +118,7 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi .hidden(config.file_picker.hidden) .parents(config.file_picker.parents) .ignore(config.file_picker.ignore) + .follow_links(config.file_picker.follow_symlinks) .git_ignore(config.file_picker.git_ignore) .git_global(config.file_picker.git_global) .git_exclude(config.file_picker.git_exclude) @@ -146,14 +147,13 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi let entry = entry.ok()?; // This is faster than entry.path().is_dir() since it uses cached fs::Metadata fetched by ignore/walkdir - let is_dir = entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false); - + let is_dir = entry.file_type().map_or(false, |ft| ft.is_dir()); if is_dir { // Will give a false positive if metadata cannot be read (eg. permission error) - return None; + None + } else { + Some(entry.into_path()) } - - Some(entry.into_path()) }); // Cap the number of files if we aren't in a git project, preventing @@ -175,9 +175,14 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi path.strip_prefix(&root).unwrap_or(path).to_string_lossy() }, move |cx, path: &PathBuf, action| { - cx.editor - .open(path.into(), action) - .expect("editor.open failed"); + if let Err(e) = cx.editor.open(path.into(), action) { + let err = if let Some(err) = e.source() { + format!("{}", err) + } else { + format!("unable to open \"{}\"", path.display()) + }; + cx.editor.set_error(err); + } }, |_editor, path| Some((path.clone(), None)), ) @@ -281,8 +286,8 @@ pub mod completers { .collect() } - pub fn filename(_editor: &Editor, input: &str) -> Vec<Completion> { - filename_impl(input, |entry| { + pub fn filename(editor: &Editor, input: &str) -> Vec<Completion> { + filename_impl(editor, input, |entry| { let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); if is_dir { @@ -314,8 +319,8 @@ pub mod completers { .collect() } - pub fn directory(_editor: &Editor, input: &str) -> Vec<Completion> { - filename_impl(input, |entry| { + pub fn directory(editor: &Editor, input: &str) -> Vec<Completion> { + filename_impl(editor, input, |entry| { let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); if is_dir { @@ -338,7 +343,7 @@ pub mod completers { } // TODO: we could return an iter/lazy thing so it can fetch as many as it needs. - fn filename_impl<F>(input: &str, filter_fn: F) -> Vec<Completion> + fn filename_impl<F>(editor: &Editor, input: &str, filter_fn: F) -> Vec<Completion> where F: Fn(&ignore::DirEntry) -> FileMatch, { @@ -370,6 +375,7 @@ pub mod completers { let mut files: Vec<_> = WalkBuilder::new(&dir) .hidden(false) + .follow_links(editor.config().file_picker.follow_symlinks) .max_depth(Some(1)) .build() .filter_map(|file| { |