Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/ui/mod.rs')
-rw-r--r--helix-term/src/ui/mod.rs60
1 files changed, 49 insertions, 11 deletions
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index 5a4db046..58b6fc00 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -354,12 +354,12 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
Ok(picker)
}
-fn directory_content(path: &Path, editor: &Editor) -> Result<Vec<(PathBuf, bool)>, std::io::Error> {
+fn directory_content(root: &Path, editor: &Editor) -> Result<Vec<(PathBuf, bool)>, std::io::Error> {
use ignore::WalkBuilder;
let config = editor.config();
- let mut walk_builder = WalkBuilder::new(path);
+ let mut walk_builder = WalkBuilder::new(root);
let mut content: Vec<(PathBuf, bool)> = walk_builder
.hidden(config.file_explorer.hidden)
@@ -377,27 +377,41 @@ fn directory_content(path: &Path, editor: &Editor) -> Result<Vec<(PathBuf, bool)
.filter_map(|entry| {
entry
.map(|entry| {
- (
- entry.path().to_path_buf(),
- entry
- .file_type()
- .is_some_and(|file_type| file_type.is_dir()),
- )
+ let is_dir = entry
+ .file_type()
+ .is_some_and(|file_type| file_type.is_dir());
+ let mut path = entry.path().to_path_buf();
+ if is_dir && path != root && config.file_explorer.flatten_dirs {
+ while let Some(single_child_directory) = get_child_if_single_dir(&path) {
+ path = single_child_directory;
+ }
+ }
+ (path, is_dir)
})
.ok()
- .filter(|entry| entry.0 != path)
+ .filter(|entry| entry.0 != root)
})
.collect();
content.sort_by(|(path1, is_dir1), (path2, is_dir2)| (!is_dir1, path1).cmp(&(!is_dir2, path2)));
- if path.parent().is_some() {
- content.insert(0, (path.join(".."), true));
+ if root.parent().is_some() {
+ content.insert(0, (root.join(".."), true));
}
Ok(content)
}
+fn get_child_if_single_dir(path: &Path) -> Option<PathBuf> {
+ let mut entries = path.read_dir().ok()?;
+ let entry = entries.next()?.ok()?;
+ if entries.next().is_none() && entry.file_type().is_ok_and(|file_type| file_type.is_dir()) {
+ Some(entry.path())
+ } else {
+ None
+ }
+}
+
pub mod completers {
use super::Utf8PathBuf;
use crate::ui::prompt::Completion;
@@ -770,3 +784,27 @@ pub mod completers {
completions
}
}
+
+#[cfg(test)]
+mod tests {
+ use std::fs::{create_dir, File};
+
+ use super::*;
+
+ #[test]
+ fn test_get_child_if_single_dir() {
+ let root = tempfile::tempdir().unwrap();
+
+ assert_eq!(get_child_if_single_dir(root.path()), None);
+
+ let dir = root.path().join("dir1");
+ create_dir(&dir).unwrap();
+
+ assert_eq!(get_child_if_single_dir(root.path()), Some(dir));
+
+ let file = root.path().join("file");
+ File::create(file).unwrap();
+
+ assert_eq!(get_child_if_single_dir(root.path()), None);
+ }
+}