Przeglądaj źródła

Change the way columns are created

You can now have different columns per directory. So now, the Git column only appears when there's a Git repository in the current directory.
Ben S 11 lat temu
rodzic
commit
b0cdd17b97
3 zmienionych plików z 60 dodań i 36 usunięć
  1. 3 3
      src/main.rs
  2. 50 28
      src/options.rs
  3. 7 5
      src/output.rs

+ 3 - 3
src/main.rs

@@ -56,7 +56,7 @@ fn exa(options: &Options) {
     let mut first = files.is_empty();
 
     if !files.is_empty() {
-        options.view(files);
+        options.view(None, files);
     }
 
     for dir_name in dirs.iter() {
@@ -68,7 +68,7 @@ fn exa(options: &Options) {
         }
 
         match Dir::readdir(Path::new(dir_name.clone())) {
-            Ok(dir) => {
+            Ok(ref dir) => {
                 let unsorted_files = dir.files();
                 let files: Vec<File> = options.transform_files(unsorted_files);
 
@@ -76,7 +76,7 @@ fn exa(options: &Options) {
                     println!("{}:", dir_name);
                 }
 
-                options.view(files);
+                options.view(Some(dir), files);
             }
             Err(e) => {
                 println!("{}: {}", dir_name, e);

+ 50 - 28
src/options.rs

@@ -1,6 +1,7 @@
 extern crate getopts;
 extern crate natord;
 
+use dir::Dir;
 use file::File;
 use column::{Column, SizeFormat};
 use column::Column::*;
@@ -78,8 +79,8 @@ impl Options {
     }
 
     /// Display the files using this Option's View.
-    pub fn view(&self, files: Vec<File>) {
-        self.view.view(files)
+    pub fn view(&self, dir: Option<&Dir>, files: Vec<File>) {
+        self.view.view(dir, files)
     }
 
     /// Transform the files (sorting, reversing, filtering) before listing them.
@@ -187,7 +188,7 @@ fn view(matches: &getopts::Matches) -> Result<View, Misfire> {
             Err(Misfire::Useless("oneline", true, "long"))
         }
         else {
-            Ok(View::Details(try!(columns(matches)), matches.opt_present("header")))
+            Ok(View::Details(try!(Columns::new(matches)), matches.opt_present("header")))
         }
     }
     else if matches.opt_present("binary") {
@@ -237,40 +238,62 @@ fn file_size(matches: &getopts::Matches) -> Result<SizeFormat, Misfire> {
     }
 }
 
-/// Turns the Getopts results object into a list of columns for the columns
-/// view, depending on the passed-in command-line arguments.
-fn columns(matches: &getopts::Matches) -> Result<Vec<Column>, Misfire> {
-    let mut columns = vec![];
+#[derive(PartialEq, Copy, Debug)]
+pub struct Columns {
+    size_format: SizeFormat,
+    inode: bool,
+    links: bool,
+    blocks: bool,
+    group: bool,
+}
 
-    if matches.opt_present("inode") {
-        columns.push(Inode);
+impl Columns {
+    pub fn new(matches: &getopts::Matches) -> Result<Columns, Misfire> {
+        Ok(Columns {
+            size_format: try!(file_size(matches)),
+            inode:  matches.opt_present("inode"),
+            links:  matches.opt_present("links"),
+            blocks: matches.opt_present("blocks"),
+            group:  matches.opt_present("group"),
+        })
     }
 
-    columns.push(Permissions);
+    pub fn for_dir(&self, dir: Option<&Dir>) -> Vec<Column> {
+        let mut columns = vec![];
 
-    if matches.opt_present("links") {
-        columns.push(HardLinks);
-    }
+        if self.inode {
+            columns.push(Inode);
+        }
 
-    // Fail early here if two file size flags are given
-    columns.push(FileSize(try!(file_size(matches))));
+        columns.push(Permissions);
 
-    if matches.opt_present("blocks") {
-        columns.push(Blocks);
-    }
+        if self.links {
+            columns.push(HardLinks);
+        }
 
-    columns.push(User);
+        columns.push(FileSize(self.size_format));
 
-    if matches.opt_present("group") {
-        columns.push(Group);
-    }
+        if self.blocks {
+            columns.push(Blocks);
+        }
 
-    if cfg!(feature="git") {
-        columns.push(GitStatus);
-    }
+        columns.push(User);
+
+        if self.group {
+            columns.push(Group);
+        }
+
+        if cfg!(feature="git") {
+            if let Some(d) = dir {
+                if d.has_git_repo() {
+                    columns.push(GitStatus);
+                }
+            }
+        }
 
-    columns.push(FileName);
-    Ok(columns)
+        columns.push(FileName);
+        columns
+    }
 }
 
 #[cfg(test)]
@@ -373,5 +396,4 @@ mod test {
         let opts = Options::getopts(&[ "--blocks".to_string() ]);
         assert_eq!(opts.unwrap_err(), Misfire::Useless("blocks", false, "long"))
     }
-
 }

+ 7 - 5
src/output.rs

@@ -3,23 +3,25 @@ use std::iter::{AdditiveIterator, repeat};
 
 use column::{Column, Cell};
 use column::Alignment::Left;
+use dir::Dir;
 use file::File;
+use options::Columns;
 use users::OSUsers;
 
 use ansi_term::Style::Plain;
 
-#[derive(PartialEq, Debug)]
+#[derive(PartialEq, Copy, Debug)]
 pub enum View {
-    Details(Vec<Column>, bool),
+    Details(Columns, bool),
     Lines,
     Grid(bool, usize),
 }
 
 impl View {
-    pub fn view(&self, files: Vec<File>) {
+    pub fn view(&self, dir: Option<&Dir>, files: Vec<File>) {
         match *self {
             View::Grid(across, width)       => grid_view(across, width, files),
-            View::Details(ref cols, header) => details_view(cols, files, header),
+            View::Details(ref cols, header) => details_view(&*cols.for_dir(dir), files, header),
             View::Lines                     => lines_view(files),
         }
     }
@@ -120,7 +122,7 @@ fn grid_view(across: bool, console_width: usize, files: Vec<File>) {
     }
 }
 
-fn details_view(columns: &Vec<Column>, files: Vec<File>, header: bool) {
+fn details_view(columns: &[Column], files: Vec<File>, header: bool) {
     // The output gets formatted into columns, which looks nicer. To
     // do this, we have to write the results into a table, instead of
     // displaying each file immediately, then calculating the maximum