ソースを参照

Add --group-directories-first option

Closes #27.
Ben S 11 年 前
コミット
ff1f6d0087
2 ファイル変更16 行追加3 行削除
  1. 8 3
      src/file.rs
  2. 8 0
      src/options.rs

+ 8 - 3
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<U: Users>(&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(&current_dir().unwrap_or(Path::new(".")).join(&self.path),
-                                    self.stat.kind == io::FileType::Directory),
+                                    self.is_directory()),
             None    => GREY.paint("--").to_string(),
         };
 

+ 8 - 0
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()));
+        }
     }
 }