From ff1f6d0087f6475474c77031ded85be9e35cebfa Mon Sep 17 00:00:00 2001 From: Ben S Date: Thu, 26 Feb 2015 14:05:26 +0000 Subject: [PATCH] Add --group-directories-first option Closes #27. --- src/file.rs | 11 ++++++++--- src/options.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/file.rs b/src/file.rs index 3dc50df..efc4797 100644 --- a/src/file.rs +++ b/src/file.rs @@ -91,6 +91,11 @@ impl<'a> File<'a> { name.ends_with("~") || (name.starts_with("#") && name.ends_with("#")) } + /// Whether this file is a directory or not. + pub fn is_directory(&self) -> bool { + self.stat.kind == io::FileType::Directory + } + /// Get the data for a column, formatted as a coloured string. pub fn display(&self, column: &Column, users_cache: &mut U, locale: &UserLocale) -> Cell { match *column { @@ -300,7 +305,7 @@ impl<'a> File<'a> { /// any information from it, so by emitting "-" instead, the table is less /// cluttered with numbers. fn file_size(&self, size_format: SizeFormat, locale: &locale::Numeric) -> Cell { - if self.stat.kind == io::FileType::Directory { + if self.is_directory() { Cell { text: GREY.paint("-").to_string(), length: 1 } } else { @@ -363,7 +368,7 @@ impl<'a> File<'a> { /// Marker indicating that the file contains extended attributes /// - /// Returns “@” or “ ” depending on wheter the file contains an extented + /// Returns “@” or “ ” depending on wheter the file contains an extented /// attribute or not. Also returns “ ” in case the attributes cannot be read /// for some reason. fn attribute_marker(&self) -> ANSIString { @@ -447,7 +452,7 @@ impl<'a> File<'a> { fn git_status(&self) -> Cell { let status = match self.dir { Some(d) => d.git_status(¤t_dir().unwrap_or(Path::new(".")).join(&self.path), - self.stat.kind == io::FileType::Directory), + self.is_directory()), None => GREY.paint("--").to_string(), }; diff --git a/src/options.rs b/src/options.rs index 6a6c068..40a7b4b 100644 --- a/src/options.rs +++ b/src/options.rs @@ -28,6 +28,7 @@ pub struct Options { #[derive(PartialEq, Debug, Copy)] pub struct FileFilter { + list_dirs_first: bool, reverse: bool, show_invisibles: bool, sort_field: SortField, @@ -51,6 +52,7 @@ impl Options { opts.optflag("B", "bytes", "list file sizes in bytes, without prefixes"); opts.optflag("d", "list-dirs", "list directories as regular files"); opts.optflag("g", "group", "show group as well as user"); + opts.optflag("", "group-directories-first", "list directories before other files"); opts.optflag("h", "header", "show a header row at the top"); opts.optflag("H", "links", "show number of hard links"); opts.optflag("i", "inode", "show each file's inode number"); @@ -87,6 +89,7 @@ impl Options { }; let filter = FileFilter { + list_dirs_first: matches.opt_present("group-directories-first"), reverse: matches.opt_present("reverse"), show_invisibles: matches.opt_present("all"), sort_field: sort_field, @@ -139,6 +142,11 @@ impl FileFilter { if self.reverse { files.reverse(); } + + if self.list_dirs_first { + // This relies on the fact that sort_by is stable. + files.sort_by(|a, b| b.is_directory().cmp(&a.is_directory())); + } } }