Sfoglia il codice sorgente

Add sort option

And move options struct into its own module
Ben S 11 anni fa
parent
commit
cb1b8bc2d7
3 ha cambiato i file con 57 aggiunte e 16 eliminazioni
  1. 13 13
      exa.rs
  2. 3 3
      file.rs
  3. 41 0
      options.rs

+ 13 - 13
exa.rs

@@ -8,16 +8,14 @@ use std::io::fs;
 
 use file::File;
 use column::defaultColumns;
+use options::{Options, SortField, Name};
 
 pub mod colours;
 pub mod column;
 pub mod format;
 pub mod file;
 pub mod unix;
-
-struct Options {
-    showInvisibles: bool,
-}
+pub mod options;
 
 fn main() {
     let args: Vec<StrBuf> = os::args().iter()
@@ -25,7 +23,8 @@ fn main() {
         .collect();
 
     let opts = ~[
-        getopts::optflag("a", "all", "show dot-files")
+        getopts::optflag("a", "all", "show dot-files"),
+        getopts::optopt("s", "sort", "field to sort by", "WORD"),
     ];
 
     let matches = match getopts::getopts(args.tail(), opts) {
@@ -34,7 +33,8 @@ fn main() {
     };
 
     let opts = Options {
-        showInvisibles: matches.opt_present("all")
+        showInvisibles: matches.opt_present("all"),
+        sortField: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(Name),
     };
 
     let strs = if matches.free.is_empty() {
@@ -49,18 +49,18 @@ fn main() {
     }
 }
 
-fn list(opts: Options, path: Path) {
-    let mut files = match fs::readdir(&path) {
-        Ok(files) => files,
+fn list(options: Options, path: Path) {
+    let paths = match fs::readdir(&path) {
+        Ok(paths) => paths,
         Err(e) => fail!("readdir: {}", e),
     };
-    files.sort_by(|a, b| a.filename_str().cmp(&b.filename_str()));
 
-    let columns = defaultColumns();
+    let mut files = paths.iter().map(|path| File::from_path(path)).collect();
+    options.sort(&mut files);
 
+    let columns = defaultColumns();
     let table: Vec<Vec<StrBuf>> = files.iter()
-        .map(|p| File::from_path(p))
-        .filter(|f| !f.is_dotfile() || opts.showInvisibles )
+        .filter(|&f| options.show(f))
         .map(|f| columns.iter().map(|c| f.display(c)).collect())
         .collect();
 

+ 3 - 3
file.rs

@@ -10,9 +10,9 @@ use unix::{get_user_name, get_group_name};
 // only to determine what kind of file it is, so carry the `stat`
 // result around with the file for safe keeping.
 pub struct File<'a> {
-    name: &'a str,
-    path: &'a Path,
-    stat: io::FileStat,
+    pub name: &'a str,
+    pub path: &'a Path,
+    pub stat: io::FileStat,
 }
 
 impl<'a> File<'a> {

+ 41 - 0
options.rs

@@ -0,0 +1,41 @@
+use file::File;
+
+pub enum SortField {
+    Name, Size
+}
+
+pub struct Options {
+    pub showInvisibles: bool,
+    pub sortField: SortField,
+}
+
+impl SortField {
+    pub fn from_word(word: StrBuf) -> SortField {
+        match word.as_slice() {
+            "name" => Name,
+            "size" => Size,
+            _ => fail!("Invalid sorting order"),
+        }
+    }
+
+    fn sort(&self, files: &mut Vec<File>) {
+        match *self {
+            Name => files.sort_by(|a, b| a.name.cmp(&b.name)),
+            Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)),
+        }
+    }
+}
+
+impl Options {
+    pub fn sort(&self, files: &mut Vec<File>) {
+        self.sortField.sort(files);
+    }
+
+    pub fn show(&self, f: &File) -> bool {
+        if self.showInvisibles {
+            true
+        } else {
+            !f.name.starts_with(".")
+        }
+    }
+}