mirror of
https://github.com/ilyakooo0/helix.git
synced 2024-12-01 03:15:33 +03:00
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
This commit is contained in:
parent
7983c71752
commit
c2cc2037b5
@ -118,6 +118,7 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi
|
|||||||
.hidden(config.file_picker.hidden)
|
.hidden(config.file_picker.hidden)
|
||||||
.parents(config.file_picker.parents)
|
.parents(config.file_picker.parents)
|
||||||
.ignore(config.file_picker.ignore)
|
.ignore(config.file_picker.ignore)
|
||||||
|
.follow_links(config.file_picker.follow_symlinks)
|
||||||
.git_ignore(config.file_picker.git_ignore)
|
.git_ignore(config.file_picker.git_ignore)
|
||||||
.git_global(config.file_picker.git_global)
|
.git_global(config.file_picker.git_global)
|
||||||
.git_exclude(config.file_picker.git_exclude)
|
.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()?;
|
let entry = entry.ok()?;
|
||||||
|
|
||||||
// This is faster than entry.path().is_dir() since it uses cached fs::Metadata fetched by ignore/walkdir
|
// 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 {
|
if is_dir {
|
||||||
// Will give a false positive if metadata cannot be read (eg. permission error)
|
// 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
|
// 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()
|
path.strip_prefix(&root).unwrap_or(path).to_string_lossy()
|
||||||
},
|
},
|
||||||
move |cx, path: &PathBuf, action| {
|
move |cx, path: &PathBuf, action| {
|
||||||
cx.editor
|
if let Err(e) = cx.editor.open(path.into(), action) {
|
||||||
.open(path.into(), action)
|
let err = if let Some(err) = e.source() {
|
||||||
.expect("editor.open failed");
|
format!("{}", err)
|
||||||
|
} else {
|
||||||
|
format!("unable to open \"{}\"", path.display())
|
||||||
|
};
|
||||||
|
cx.editor.set_error(err);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|_editor, path| Some((path.clone(), None)),
|
|_editor, path| Some((path.clone(), None)),
|
||||||
)
|
)
|
||||||
@ -281,8 +286,8 @@ pub mod completers {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filename(_editor: &Editor, input: &str) -> Vec<Completion> {
|
pub fn filename(editor: &Editor, input: &str) -> Vec<Completion> {
|
||||||
filename_impl(input, |entry| {
|
filename_impl(editor, input, |entry| {
|
||||||
let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
|
let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
|
||||||
|
|
||||||
if is_dir {
|
if is_dir {
|
||||||
@ -314,8 +319,8 @@ pub mod completers {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn directory(_editor: &Editor, input: &str) -> Vec<Completion> {
|
pub fn directory(editor: &Editor, input: &str) -> Vec<Completion> {
|
||||||
filename_impl(input, |entry| {
|
filename_impl(editor, input, |entry| {
|
||||||
let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
|
let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
|
||||||
|
|
||||||
if 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.
|
// 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
|
where
|
||||||
F: Fn(&ignore::DirEntry) -> FileMatch,
|
F: Fn(&ignore::DirEntry) -> FileMatch,
|
||||||
{
|
{
|
||||||
@ -370,6 +375,7 @@ pub mod completers {
|
|||||||
|
|
||||||
let mut files: Vec<_> = WalkBuilder::new(&dir)
|
let mut files: Vec<_> = WalkBuilder::new(&dir)
|
||||||
.hidden(false)
|
.hidden(false)
|
||||||
|
.follow_links(editor.config().file_picker.follow_symlinks)
|
||||||
.max_depth(Some(1))
|
.max_depth(Some(1))
|
||||||
.build()
|
.build()
|
||||||
.filter_map(|file| {
|
.filter_map(|file| {
|
||||||
|
@ -71,6 +71,9 @@ pub struct FilePickerConfig {
|
|||||||
/// Enables ignoring hidden files.
|
/// Enables ignoring hidden files.
|
||||||
/// Whether to hide hidden files in file picker and global search results. Defaults to true.
|
/// Whether to hide hidden files in file picker and global search results. Defaults to true.
|
||||||
pub hidden: bool,
|
pub hidden: bool,
|
||||||
|
/// Enables following symlinks.
|
||||||
|
/// Whether to follow symbolic links in file picker and file or directory completions. Defaults to true.
|
||||||
|
pub follow_symlinks: bool,
|
||||||
/// Enables reading ignore files from parent directories. Defaults to true.
|
/// Enables reading ignore files from parent directories. Defaults to true.
|
||||||
pub parents: bool,
|
pub parents: bool,
|
||||||
/// Enables reading `.ignore` files.
|
/// Enables reading `.ignore` files.
|
||||||
@ -94,6 +97,7 @@ impl Default for FilePickerConfig {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
follow_symlinks: true,
|
||||||
parents: true,
|
parents: true,
|
||||||
ignore: true,
|
ignore: true,
|
||||||
git_ignore: true,
|
git_ignore: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user