diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index d5cf3aaed..c1c6cfab4 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -140,6 +140,7 @@ pub mod options { pub static HIDE: &str = "hide"; pub static IGNORE: &str = "ignore"; pub static CONTEXT: &str = "context"; + pub static GROUP_DIRECTORIES_FIRST: &str = "group-directories-first"; } const DEFAULT_TERM_WIDTH: u16 = 80; @@ -330,6 +331,7 @@ pub struct Config { time_style: TimeStyle, context: bool, selinux_supported: bool, + group_directories_first: bool, } // Fields that can be removed or added to the long format @@ -780,6 +782,7 @@ impl Config { false } }, + group_directories_first: options.is_present(options::GROUP_DIRECTORIES_FIRST), }) } } @@ -1397,6 +1400,12 @@ pub fn uu_app<'a>() -> Command<'a> { .long(options::CONTEXT) .help(CONTEXT_HELP_TEXT), ) + .arg( + Arg::new(options::GROUP_DIRECTORIES_FIRST) + .long(options::GROUP_DIRECTORIES_FIRST) + .help("group directories before files; can be augmented with \ + a --sort option, but any use of --sort=none (-U) disables grouping"), + ) // Positional arguments .arg( Arg::new(options::PATHS) @@ -1635,6 +1644,28 @@ fn sort_entries(entries: &mut [PathData], config: &Config, out: &mut BufWriter { + // If it metadata cannot be determined, treat as a file. + get_metadata(p.p_buf.as_path(), true).map_or_else(|_| false, |m| m.is_dir()) + } + Some(Some(m)) => m.is_dir(), + } + }); + } } fn is_hidden(file_path: &DirEntry) -> bool {