@@ -354,12 +354,12 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
354
354
Ok ( picker)
355
355
}
356
356
357
- fn directory_content ( path : & Path , editor : & Editor ) -> Result < Vec < ( PathBuf , bool ) > , std:: io:: Error > {
357
+ fn directory_content ( root : & Path , editor : & Editor ) -> Result < Vec < ( PathBuf , bool ) > , std:: io:: Error > {
358
358
use ignore:: WalkBuilder ;
359
359
360
360
let config = editor. config ( ) ;
361
361
362
- let mut walk_builder = WalkBuilder :: new ( path ) ;
362
+ let mut walk_builder = WalkBuilder :: new ( root ) ;
363
363
364
364
let mut content: Vec < ( PathBuf , bool ) > = walk_builder
365
365
. hidden ( config. file_explorer . hidden )
@@ -377,27 +377,41 @@ fn directory_content(path: &Path, editor: &Editor) -> Result<Vec<(PathBuf, bool)
377
377
. filter_map ( |entry| {
378
378
entry
379
379
. map ( |entry| {
380
- (
381
- entry. path ( ) . to_path_buf ( ) ,
382
- entry
383
- . file_type ( )
384
- . is_some_and ( |file_type| file_type. is_dir ( ) ) ,
385
- )
380
+ let is_dir = entry
381
+ . file_type ( )
382
+ . is_some_and ( |file_type| file_type. is_dir ( ) ) ;
383
+ let mut path = entry. path ( ) . to_path_buf ( ) ;
384
+ if is_dir && path != root && config. file_explorer . flatten_dirs {
385
+ while let Some ( single_child_directory) = get_child_if_single_dir ( & path) {
386
+ path = single_child_directory;
387
+ }
388
+ }
389
+ ( path, is_dir)
386
390
} )
387
391
. ok ( )
388
- . filter ( |entry| entry. 0 != path )
392
+ . filter ( |entry| entry. 0 != root )
389
393
} )
390
394
. collect ( ) ;
391
395
392
396
content. sort_by ( |( path1, is_dir1) , ( path2, is_dir2) | ( !is_dir1, path1) . cmp ( & ( !is_dir2, path2) ) ) ;
393
397
394
- if path . parent ( ) . is_some ( ) {
395
- content. insert ( 0 , ( path . join ( ".." ) , true ) ) ;
398
+ if root . parent ( ) . is_some ( ) {
399
+ content. insert ( 0 , ( root . join ( ".." ) , true ) ) ;
396
400
}
397
401
398
402
Ok ( content)
399
403
}
400
404
405
+ fn get_child_if_single_dir ( path : & Path ) -> Option < PathBuf > {
406
+ let mut entries = path. read_dir ( ) . ok ( ) ?;
407
+ let entry = entries. next ( ) ?. ok ( ) ?;
408
+ if entries. next ( ) . is_none ( ) && entry. file_type ( ) . is_ok_and ( |file_type| file_type. is_dir ( ) ) {
409
+ Some ( entry. path ( ) )
410
+ } else {
411
+ None
412
+ }
413
+ }
414
+
401
415
pub mod completers {
402
416
use super :: Utf8PathBuf ;
403
417
use crate :: ui:: prompt:: Completion ;
@@ -770,3 +784,27 @@ pub mod completers {
770
784
completions
771
785
}
772
786
}
787
+
788
+ #[ cfg( test) ]
789
+ mod tests {
790
+ use std:: fs:: { create_dir, File } ;
791
+
792
+ use super :: * ;
793
+
794
+ #[ test]
795
+ fn test_get_child_if_single_dir ( ) {
796
+ let root = tempfile:: tempdir ( ) . unwrap ( ) ;
797
+
798
+ assert_eq ! ( get_child_if_single_dir( root. path( ) ) , None ) ;
799
+
800
+ let dir = root. path ( ) . join ( "dir1" ) ;
801
+ create_dir ( & dir) . unwrap ( ) ;
802
+
803
+ assert_eq ! ( get_child_if_single_dir( root. path( ) ) , Some ( dir) ) ;
804
+
805
+ let file = root. path ( ) . join ( "file" ) ;
806
+ File :: create ( file) . unwrap ( ) ;
807
+
808
+ assert_eq ! ( get_child_if_single_dir( root. path( ) ) , None ) ;
809
+ }
810
+ }
0 commit comments