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

Better handling of symlinks #2718

Merged
merged 1 commit into from
Jun 15, 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
32 changes: 19 additions & 13 deletions helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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)),
)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
{
Expand Down Expand Up @@ -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| {
Expand Down
4 changes: 4 additions & 0 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ pub struct FilePickerConfig {
/// Enables ignoring hidden files.
/// Whether to hide hidden files in file picker and global search results. Defaults to true.
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.
pub parents: bool,
/// Enables reading `.ignore` files.
Expand All @@ -94,6 +97,7 @@ impl Default for FilePickerConfig {
fn default() -> Self {
Self {
hidden: true,
follow_symlinks: true,
parents: true,
ignore: true,
git_ignore: true,
Expand Down