@@ -377,12 +377,12 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
377
377
Ok ( picker)
378
378
}
379
379
380
- fn directory_content ( path : & Path , editor : & Editor ) -> Result < Vec < ( PathBuf , bool ) > , std:: io:: Error > {
380
+ fn directory_content ( root : & Path , editor : & Editor ) -> Result < Vec < ( PathBuf , bool ) > , std:: io:: Error > {
381
381
use ignore:: WalkBuilder ;
382
382
383
383
let config = editor. config ( ) ;
384
384
385
- let mut walk_builder = WalkBuilder :: new ( path ) ;
385
+ let mut walk_builder = WalkBuilder :: new ( root ) ;
386
386
387
387
let mut content: Vec < ( PathBuf , bool ) > = walk_builder
388
388
. hidden ( config. file_explorer . hidden )
@@ -400,27 +400,41 @@ fn directory_content(path: &Path, editor: &Editor) -> Result<Vec<(PathBuf, bool)
400
400
. filter_map ( |entry| {
401
401
entry
402
402
. map ( |entry| {
403
- (
404
- entry. path ( ) . to_path_buf ( ) ,
405
- entry
406
- . file_type ( )
407
- . is_some_and ( |file_type| file_type. is_dir ( ) ) ,
408
- )
403
+ let is_dir = entry
404
+ . file_type ( )
405
+ . is_some_and ( |file_type| file_type. is_dir ( ) ) ;
406
+ let mut path = entry. path ( ) . to_path_buf ( ) ;
407
+ if is_dir && path != root && config. file_explorer . flatten_dirs {
408
+ while let Some ( single_child_directory) = get_child_if_single_dir ( & path) {
409
+ path = single_child_directory;
410
+ }
411
+ }
412
+ ( path, is_dir)
409
413
} )
410
414
. ok ( )
411
- . filter ( |entry| entry. 0 != path )
415
+ . filter ( |entry| entry. 0 != root )
412
416
} )
413
417
. collect ( ) ;
414
418
415
419
content. sort_by ( |( path1, is_dir1) , ( path2, is_dir2) | ( !is_dir1, path1) . cmp ( & ( !is_dir2, path2) ) ) ;
416
420
417
- if path . parent ( ) . is_some ( ) {
418
- content. insert ( 0 , ( path . join ( ".." ) , true ) ) ;
421
+ if root . parent ( ) . is_some ( ) {
422
+ content. insert ( 0 , ( root . join ( ".." ) , true ) ) ;
419
423
}
420
424
421
425
Ok ( content)
422
426
}
423
427
428
+ fn get_child_if_single_dir ( path : & Path ) -> Option < PathBuf > {
429
+ let mut entries = path. read_dir ( ) . ok ( ) ?;
430
+ let entry = entries. next ( ) ?. ok ( ) ?;
431
+ if entries. next ( ) . is_none ( ) && entry. file_type ( ) . is_ok_and ( |file_type| file_type. is_dir ( ) ) {
432
+ Some ( entry. path ( ) )
433
+ } else {
434
+ None
435
+ }
436
+ }
437
+
424
438
pub mod completers {
425
439
use super :: Utf8PathBuf ;
426
440
use crate :: ui:: prompt:: Completion ;
@@ -793,3 +807,27 @@ pub mod completers {
793
807
completions
794
808
}
795
809
}
810
+
811
+ #[ cfg( test) ]
812
+ mod tests {
813
+ use std:: fs:: { create_dir, File } ;
814
+
815
+ use super :: * ;
816
+
817
+ #[ test]
818
+ fn test_get_child_if_single_dir ( ) {
819
+ let root = tempfile:: tempdir ( ) . unwrap ( ) ;
820
+
821
+ assert_eq ! ( get_child_if_single_dir( root. path( ) ) , None ) ;
822
+
823
+ let dir = root. path ( ) . join ( "dir1" ) ;
824
+ create_dir ( & dir) . unwrap ( ) ;
825
+
826
+ assert_eq ! ( get_child_if_single_dir( root. path( ) ) , Some ( dir) ) ;
827
+
828
+ let file = root. path ( ) . join ( "file" ) ;
829
+ File :: create ( file) . unwrap ( ) ;
830
+
831
+ assert_eq ! ( get_child_if_single_dir( root. path( ) ) , None ) ;
832
+ }
833
+ }
0 commit comments