Browse Source

Merge branch 'file-namers'

This creates a new type that holds file extensions in preparation for #116. It doesn’t do anything yet, but it will!
Benjamin Sago 8 years ago
parent
commit
f54bc41792
9 changed files with 164 additions and 137 deletions
  1. 5 5
      src/exa.rs
  2. 28 55
      src/info/filetype.rs
  3. 3 3
      src/info/mod.rs
  4. 16 6
      src/options/view.rs
  5. 5 3
      src/output/details.rs
  6. 94 54
      src/output/file_name.rs
  7. 6 4
      src/output/grid.rs
  8. 4 4
      src/output/grid_details.rs
  9. 3 3
      src/output/lines.rs

+ 5 - 5
src/exa.rs

@@ -168,13 +168,13 @@ impl<'w, W: Write + 'w> Exa<'w, W> {
     /// printing differently...
     /// printing differently...
     fn print_files(&mut self, dir: Option<&Dir>, files: Vec<File>) -> IOResult<()> {
     fn print_files(&mut self, dir: Option<&Dir>, files: Vec<File>) -> IOResult<()> {
         if !files.is_empty() {
         if !files.is_empty() {
-            let View { ref mode, ref colours, classify } = self.options.view;
+            let View { ref mode, ref colours, ref style } = self.options.view;
 
 
             match *mode {
             match *mode {
-                Mode::Lines                  => lines::Render { files, colours, classify }.render(self.writer),
-                Mode::Grid(ref opts)         => grid::Render { files, colours, classify, opts }.render(self.writer),
-                Mode::Details(ref opts)      => details::Render { dir, files, colours, classify, opts, filter: &self.options.filter, recurse: self.options.dir_action.recurse_options() }.render(self.writer),
-                Mode::GridDetails(ref grid, ref details) => grid_details::Render { dir, files, colours, classify, grid, details, filter: &self.options.filter }.render(self.writer),
+                Mode::Lines                  => lines::Render { files, colours, style }.render(self.writer),
+                Mode::Grid(ref opts)         => grid::Render { files, colours, style, opts }.render(self.writer),
+                Mode::Details(ref opts)      => details::Render { dir, files, colours, style, opts, filter: &self.options.filter, recurse: self.options.dir_action.recurse_options() }.render(self.writer),
+                Mode::GridDetails(ref grid, ref details) => grid_details::Render { dir, files, colours, style, grid, details, filter: &self.options.filter }.render(self.writer),
             }
             }
         }
         }
         else {
         else {

+ 28 - 55
src/info/filetype.rs

@@ -7,21 +7,24 @@
 use fs::File;
 use fs::File;
 
 
 
 
-impl<'a> File<'a> {
+#[derive(Debug)]
+pub struct FileExtensions;
+
+impl FileExtensions {
 
 
     /// An “immediate” file is something that can be run or activated somehow
     /// An “immediate” file is something that can be run or activated somehow
     /// in order to kick off the build of a project. It’s usually only present
     /// in order to kick off the build of a project. It’s usually only present
     /// in directories full of source code.
     /// in directories full of source code.
-    pub fn is_immediate(&self) -> bool {
-        self.name.starts_with("README") || self.name_is_one_of( &[
+    pub fn is_immediate(&self, file: &File) -> bool {
+        file.name.starts_with("README") || file.name_is_one_of( &[
             "Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
             "Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
             "build.gradle", "Rakefile", "Gruntfile.js",
             "build.gradle", "Rakefile", "Gruntfile.js",
             "Gruntfile.coffee",
             "Gruntfile.coffee",
         ])
         ])
     }
     }
 
 
-    pub fn is_image(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_image(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
             "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
             "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
             "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
             "svg", "stl", "eps", "dvi", "ps", "cbr",
             "svg", "stl", "eps", "dvi", "ps", "cbr",
@@ -29,92 +32,62 @@ impl<'a> File<'a> {
         ])
         ])
     }
     }
 
 
-    pub fn is_video(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_video(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "avi", "flv", "m2v", "mkv", "mov", "mp4", "mpeg",
             "avi", "flv", "m2v", "mkv", "mov", "mp4", "mpeg",
             "mpg", "ogm", "ogv", "vob", "wmv",
             "mpg", "ogm", "ogv", "vob", "wmv",
         ])
         ])
     }
     }
 
 
-    pub fn is_music(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_music(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "aac", "m4a", "mp3", "ogg", "wma",
             "aac", "m4a", "mp3", "ogg", "wma",
         ])
         ])
     }
     }
 
 
     // Lossless music, rather than any other kind of data...
     // Lossless music, rather than any other kind of data...
-    pub fn is_lossless(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_lossless(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "alac", "ape", "flac", "wav",
             "alac", "ape", "flac", "wav",
         ])
         ])
     }
     }
 
 
-    pub fn is_crypto(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_crypto(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "asc", "enc", "gpg", "pgp", "sig", "signature", "pfx", "p12",
             "asc", "enc", "gpg", "pgp", "sig", "signature", "pfx", "p12",
         ])
         ])
     }
     }
 
 
-    pub fn is_document(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_document(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "djvu", "doc", "docx", "dvi", "eml", "eps", "fotd",
             "djvu", "doc", "docx", "dvi", "eml", "eps", "fotd",
             "odp", "odt", "pdf", "ppt", "pptx", "rtf",
             "odp", "odt", "pdf", "ppt", "pptx", "rtf",
             "xls", "xlsx",
             "xls", "xlsx",
         ])
         ])
     }
     }
 
 
-    pub fn is_compressed(&self) -> bool {
-        self.extension_is_one_of( &[
+    pub fn is_compressed(&self, file: &File) -> bool {
+        file.extension_is_one_of( &[
             "zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
             "zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
             "iso", "dmg", "tc", "rar", "par", "tgz",
             "iso", "dmg", "tc", "rar", "par", "tgz",
         ])
         ])
     }
     }
 
 
-    pub fn is_temp(&self) -> bool {
-        self.name.ends_with('~')
-            || (self.name.starts_with('#') && self.name.ends_with('#'))
-            || self.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak" ])
+    pub fn is_temp(&self, file: &File) -> bool {
+        file.name.ends_with('~')
+            || (file.name.starts_with('#') && file.name.ends_with('#'))
+            || file.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak" ])
     }
     }
 
 
-    pub fn is_compiled(&self) -> bool {
-        if self.extension_is_one_of( &[ "class", "elc", "hi", "o", "pyc" ]) {
+    pub fn is_compiled(&self, file: &File) -> bool {
+        if file.extension_is_one_of( &[ "class", "elc", "hi", "o", "pyc" ]) {
             true
             true
         }
         }
-        else if let Some(dir) = self.parent_dir {
-            self.get_source_files().iter().any(|path| dir.contains(path))
+        else if let Some(dir) = file.parent_dir {
+            file.get_source_files().iter().any(|path| dir.contains(path))
         }
         }
         else {
         else {
             false
             false
         }
         }
     }
     }
 }
 }
-
-
-#[cfg(broken_test)]
-mod test {
-    use file::test::{dummy_stat, new_file};
-
-    #[test]
-    fn lowercase() {
-        let file = new_file(dummy_stat(), "/barracks.wav");
-        assert_eq!(FileType::Lossless, file.get_type())
-    }
-
-    #[test]
-    fn uppercase() {
-        let file = new_file(dummy_stat(), "/BARRACKS.WAV");
-        assert_eq!(FileType::Lossless, file.get_type())
-    }
-
-    #[test]
-    fn cargo() {
-        let file = new_file(dummy_stat(), "/Cargo.toml");
-        assert_eq!(FileType::Immediate, file.get_type())
-    }
-
-    #[test]
-    fn not_cargo() {
-        let file = new_file(dummy_stat(), "/cargo.toml");
-        assert_eq!(FileType::Normal, file.get_type())
-    }
-}

+ 3 - 3
src/info/mod.rs

@@ -1,7 +1,7 @@
-//! The "info" module contains routines that aren't about probing the
-//! filesystem nor displaying output to the user, but are internal "business
+//! The “info” module contains routines that aren’t about probing the
+//! filesystem nor displaying output to the user, but are internal business
 //! logic” routines that are performed on a file’s already-read metadata.
 //! logic” routines that are performed on a file’s already-read metadata.
 //! (This counts the file name as metadata.)
 //! (This counts the file name as metadata.)
 
 
-mod filetype;
+pub mod filetype;
 mod sources;
 mod sources;

+ 16 - 6
src/options/view.rs

@@ -2,10 +2,11 @@ use std::env::var_os;
 
 
 use getopts;
 use getopts;
 
 
+use info::filetype::FileExtensions;
 use output::Colours;
 use output::Colours;
 use output::{grid, details};
 use output::{grid, details};
 use output::table::{TimeTypes, Environment, SizeFormat, Options as TableOptions};
 use output::table::{TimeTypes, Environment, SizeFormat, Options as TableOptions};
-use output::file_name::Classify;
+use output::file_name::{Classify, FileStyle};
 use output::time::TimeFormat;
 use output::time::TimeFormat;
 use options::Misfire;
 use options::Misfire;
 use fs::feature::xattr;
 use fs::feature::xattr;
@@ -16,17 +17,17 @@ use fs::feature::xattr;
 pub struct View {
 pub struct View {
     pub mode: Mode,
     pub mode: Mode,
     pub colours: Colours,
     pub colours: Colours,
-    pub classify: Classify,
+    pub style: FileStyle,
 }
 }
 
 
 impl View {
 impl View {
 
 
     /// Determine which view to use and all of that view’s arguments.
     /// Determine which view to use and all of that view’s arguments.
     pub fn deduce(matches: &getopts::Matches) -> Result<View, Misfire> {
     pub fn deduce(matches: &getopts::Matches) -> Result<View, Misfire> {
-        let mode     = Mode::deduce(matches)?;
-        let colours  = Colours::deduce(matches)?;
-        let classify = Classify::deduce(matches);
-        Ok(View { mode, colours, classify })
+        let mode = Mode::deduce(matches)?;
+        let colours = Colours::deduce(matches)?;
+        let style = FileStyle::deduce(matches);
+        Ok(View { mode, colours, style })
     }
     }
 }
 }
 
 
@@ -370,6 +371,15 @@ impl Colours {
 
 
 
 
 
 
+impl FileStyle {
+    fn deduce(matches: &getopts::Matches) -> FileStyle {
+        let classify = Classify::deduce(matches);
+        let exts = FileExtensions;
+        FileStyle { classify, exts }
+    }
+
+}
+
 impl Classify {
 impl Classify {
     fn deduce(matches: &getopts::Matches) -> Classify {
     fn deduce(matches: &getopts::Matches) -> Classify {
         if matches.opt_present("classify") { Classify::AddFileIndicators }
         if matches.opt_present("classify") { Classify::AddFileIndicators }

+ 5 - 3
src/output/details.rs

@@ -70,7 +70,7 @@ use options::{FileFilter, RecurseOptions};
 use output::colours::Colours;
 use output::colours::Colours;
 use output::cell::TextCell;
 use output::cell::TextCell;
 use output::tree::{TreeTrunk, TreeParams, TreeDepth};
 use output::tree::{TreeTrunk, TreeParams, TreeDepth};
-use output::file_name::{FileName, LinkStyle, Classify};
+use output::file_name::FileStyle;
 use output::table::{Table, Options as TableOptions, Row as TableRow};
 use output::table::{Table, Options as TableOptions, Row as TableRow};
 
 
 
 
@@ -107,7 +107,7 @@ pub struct Render<'a> {
     pub dir: Option<&'a Dir>,
     pub dir: Option<&'a Dir>,
     pub files: Vec<File<'a>>,
     pub files: Vec<File<'a>>,
     pub colours: &'a Colours,
     pub colours: &'a Colours,
-    pub classify: Classify,
+    pub style: &'a FileStyle,
     pub opts: &'a Options,
     pub opts: &'a Options,
 
 
     /// Whether to recurse through directories with a tree view, and if so,
     /// Whether to recurse through directories with a tree view, and if so,
@@ -233,7 +233,9 @@ impl<'a> Render<'a> {
             let row = Row {
             let row = Row {
                 tree:   tree_params,
                 tree:   tree_params,
                 cells:  egg.table_row,
                 cells:  egg.table_row,
-                name:   FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, self.colours).paint().promote(),
+                name:   self.style.for_file(&egg.file, self.colours)
+                                  .with_link_paths()
+                                  .paint().promote(),
             };
             };
 
 
             rows.push(row);
             rows.push(row);

+ 94 - 54
src/output/file_name.rs

@@ -3,11 +3,76 @@ use std::path::Path;
 use ansi_term::{ANSIString, Style};
 use ansi_term::{ANSIString, Style};
 
 
 use fs::{File, FileTarget};
 use fs::{File, FileTarget};
+use info::filetype::FileExtensions;
 use output::Colours;
 use output::Colours;
 use output::escape;
 use output::escape;
 use output::cell::TextCellContents;
 use output::cell::TextCellContents;
 
 
 
 
+/// Basically a file name factory.
+#[derive(Debug)]
+pub struct FileStyle {
+
+    /// Whether to append file class characters to file names.
+    pub classify: Classify,
+
+    /// Mapping of file extensions to colours, to highlight regular files.
+    pub exts: FileExtensions,
+}
+
+impl FileStyle {
+
+    /// Create a new `FileName` that prints the given file’s name, painting it
+    /// with the remaining arguments.
+    pub fn for_file<'a, 'dir>(&'a self, file: &'a File<'dir>, colours: &'a Colours) -> FileName<'a, 'dir> {
+        FileName {
+            file, colours,
+            link_style: LinkStyle::JustFilenames,
+            exts:       &self.exts,
+            classify:   self.classify,
+            target:     if file.is_link() { Some(file.link_target()) }
+                                     else { None }
+        }
+    }
+}
+
+
+/// When displaying a file name, there needs to be some way to handle broken
+/// links, depending on how long the resulting Cell can be.
+#[derive(PartialEq, Debug, Copy, Clone)]
+enum LinkStyle {
+
+    /// Just display the file names, but colour them differently if they’re
+    /// a broken link or can’t be followed.
+    JustFilenames,
+
+    /// Display all files in their usual style, but follow each link with an
+    /// arrow pointing to their path, colouring the path differently if it’s
+    /// a broken link, and doing nothing if it can’t be followed.
+    FullLinkPaths,
+}
+
+
+/// Whether to append file class characters to the file names.
+#[derive(PartialEq, Debug, Copy, Clone)]
+pub enum Classify {
+
+    /// Just display the file names, without any characters.
+    JustFilenames,
+
+    /// Add a character after the file name depending on what class of file
+    /// it is.
+    AddFileIndicators,
+}
+
+impl Default for Classify {
+    fn default() -> Classify {
+        Classify::JustFilenames
+    }
+}
+
+
+
 /// A **file name** holds all the information necessary to display the name
 /// A **file name** holds all the information necessary to display the name
 /// of the given file. This is used in all of the views.
 /// of the given file. This is used in all of the views.
 pub struct FileName<'a, 'dir: 'a> {
 pub struct FileName<'a, 'dir: 'a> {
@@ -26,20 +91,21 @@ pub struct FileName<'a, 'dir: 'a> {
 
 
     /// Whether to append file class characters to file names.
     /// Whether to append file class characters to file names.
     classify: Classify,
     classify: Classify,
+
+    /// Mapping of file extensions to colours, to highlight regular files.
+    exts: &'a FileExtensions,
 }
 }
 
 
 
 
 impl<'a, 'dir> FileName<'a, 'dir> {
 impl<'a, 'dir> FileName<'a, 'dir> {
 
 
-    /// Create a new `FileName` that prints the given file’s name, painting it
-    /// with the remaining arguments.
-    pub fn new(file: &'a File<'dir>, link_style: LinkStyle, classify: Classify, colours: &'a Colours) -> FileName<'a, 'dir> {
-        let target = if file.is_link() { Some(file.link_target()) }
-                                                      else { None };
-        FileName { file, colours, target, link_style, classify }
+    /// Sets the flag on this file name to display link targets with an
+    /// arrow followed by their path.
+    pub fn with_link_paths(mut self) -> Self {
+        self.link_style = LinkStyle::FullLinkPaths;
+        self
     }
     }
 
 
-
     /// Paints the name of the file using the colours, resulting in a vector
     /// Paints the name of the file using the colours, resulting in a vector
     /// of coloured cells that can be printed to the terminal.
     /// of coloured cells that can be printed to the terminal.
     ///
     ///
@@ -73,7 +139,15 @@ impl<'a, 'dir> FileName<'a, 'dir> {
                     }
                     }
 
 
                     if !target.name.is_empty() {
                     if !target.name.is_empty() {
-                        let target = FileName::new(target, LinkStyle::FullLinkPaths, Classify::JustFilenames, self.colours);
+                        let target = FileName {
+                            file: target,
+                            colours: self.colours,
+                            target: None,
+                            link_style: LinkStyle::FullLinkPaths,
+                            classify: Classify::JustFilenames,
+                            exts: self.exts,
+                        };
+
                         for bit in target.coloured_file_name() {
                         for bit in target.coloured_file_name() {
                             bits.push(bit);
                             bits.push(bit);
                         }
                         }
@@ -181,52 +255,18 @@ impl<'a, 'dir> FileName<'a, 'dir> {
                | f.is_block_device()     => self.colours.filetypes.device,
                | f.is_block_device()     => self.colours.filetypes.device,
             f if f.is_socket()           => self.colours.filetypes.socket,
             f if f.is_socket()           => self.colours.filetypes.socket,
             f if !f.is_file()            => self.colours.filetypes.special,
             f if !f.is_file()            => self.colours.filetypes.special,
-            f if f.is_immediate()        => self.colours.filetypes.immediate,
-            f if f.is_image()            => self.colours.filetypes.image,
-            f if f.is_video()            => self.colours.filetypes.video,
-            f if f.is_music()            => self.colours.filetypes.music,
-            f if f.is_lossless()         => self.colours.filetypes.lossless,
-            f if f.is_crypto()           => self.colours.filetypes.crypto,
-            f if f.is_document()         => self.colours.filetypes.document,
-            f if f.is_compressed()       => self.colours.filetypes.compressed,
-            f if f.is_temp()             => self.colours.filetypes.temp,
-            f if f.is_compiled()         => self.colours.filetypes.compiled,
-            _                            => self.colours.filetypes.normal,
-        }
-    }
-}
-
-
-/// When displaying a file name, there needs to be some way to handle broken
-/// links, depending on how long the resulting Cell can be.
-#[derive(PartialEq, Debug, Copy, Clone)]
-pub enum LinkStyle {
-
-    /// Just display the file names, but colour them differently if they’re
-    /// a broken link or can’t be followed.
-    JustFilenames,
-
-    /// Display all files in their usual style, but follow each link with an
-    /// arrow pointing to their path, colouring the path differently if it’s
-    /// a broken link, and doing nothing if it can’t be followed.
-    FullLinkPaths,
-}
-
-
-/// Whether to append file class characters to the file names.
-#[derive(PartialEq, Debug, Copy, Clone)]
-pub enum Classify {
-
-    /// Just display the file names, without any characters.
-    JustFilenames,
 
 
-    /// Add a character after the file name depending on what class of file
-    /// it is.
-    AddFileIndicators,
-}
-
-impl Default for Classify {
-    fn default() -> Classify {
-        Classify::JustFilenames
+            f if self.exts.is_immediate(f)   => self.colours.filetypes.immediate,
+            f if self.exts.is_image(f)       => self.colours.filetypes.image,
+            f if self.exts.is_video(f)       => self.colours.filetypes.video,
+            f if self.exts.is_music(f)       => self.colours.filetypes.music,
+            f if self.exts.is_lossless(f)    => self.colours.filetypes.lossless,
+            f if self.exts.is_crypto(f)      => self.colours.filetypes.crypto,
+            f if self.exts.is_document(f)    => self.colours.filetypes.document,
+            f if self.exts.is_compressed(f)  => self.colours.filetypes.compressed,
+            f if self.exts.is_temp(f)        => self.colours.filetypes.temp,
+            f if self.exts.is_compiled(f)    => self.colours.filetypes.compiled,
+            _                                => self.colours.filetypes.normal,
+        }
     }
     }
 }
 }

+ 6 - 4
src/output/grid.rs

@@ -4,7 +4,7 @@ use term_grid as tg;
 
 
 use fs::File;
 use fs::File;
 use output::colours::Colours;
 use output::colours::Colours;
-use output::file_name::{FileName, LinkStyle, Classify};
+use output::file_name::FileStyle;
 
 
 
 
 #[derive(PartialEq, Debug, Copy, Clone)]
 #[derive(PartialEq, Debug, Copy, Clone)]
@@ -24,7 +24,7 @@ impl Options {
 pub struct Render<'a> {
 pub struct Render<'a> {
     pub files: Vec<File<'a>>,
     pub files: Vec<File<'a>>,
     pub colours: &'a Colours,
     pub colours: &'a Colours,
-    pub classify: Classify,
+    pub style: &'a FileStyle,
     pub opts: &'a Options,
     pub opts: &'a Options,
 }
 }
 
 
@@ -38,7 +38,7 @@ impl<'a> Render<'a> {
         grid.reserve(self.files.len());
         grid.reserve(self.files.len());
 
 
         for file in self.files.iter() {
         for file in self.files.iter() {
-            let filename = FileName::new(file, LinkStyle::JustFilenames, self.classify, self.colours).paint();
+            let filename = self.style.for_file(file, self.colours).paint();
             let width = filename.width();
             let width = filename.width();
 
 
             grid.add(tg::Cell {
             grid.add(tg::Cell {
@@ -52,8 +52,10 @@ impl<'a> Render<'a> {
         }
         }
         else {
         else {
             // File names too long for a grid - drop down to just listing them!
             // File names too long for a grid - drop down to just listing them!
+            // This isn’t *quite* the same as the lines view, which also
+            // displays full link paths.
             for file in self.files.iter() {
             for file in self.files.iter() {
-                let name_cell = FileName::new(file, LinkStyle::JustFilenames, self.classify, self.colours).paint();
+                let name_cell = self.style.for_file(file, self.colours).paint();
                 writeln!(w, "{}", name_cell.strings())?;
                 writeln!(w, "{}", name_cell.strings())?;
             }
             }
             Ok(())
             Ok(())

+ 4 - 4
src/output/grid_details.rs

@@ -11,7 +11,7 @@ use output::cell::TextCell;
 use output::colours::Colours;
 use output::colours::Colours;
 use output::details::{Options as DetailsOptions, Row as DetailsRow, Render as DetailsRender};
 use output::details::{Options as DetailsOptions, Row as DetailsRow, Render as DetailsRender};
 use output::grid::Options as GridOptions;
 use output::grid::Options as GridOptions;
-use output::file_name::{FileName, LinkStyle, Classify};
+use output::file_name::FileStyle;
 use output::table::{Table, Row as TableRow, Options as TableOptions};
 use output::table::{Table, Row as TableRow, Options as TableOptions};
 use output::tree::{TreeParams, TreeDepth};
 use output::tree::{TreeParams, TreeDepth};
 
 
@@ -20,7 +20,7 @@ pub struct Render<'a> {
     pub dir: Option<&'a Dir>,
     pub dir: Option<&'a Dir>,
     pub files: Vec<File<'a>>,
     pub files: Vec<File<'a>>,
     pub colours: &'a Colours,
     pub colours: &'a Colours,
-    pub classify: Classify,
+    pub style: &'a FileStyle,
     pub grid: &'a GridOptions,
     pub grid: &'a GridOptions,
     pub details: &'a DetailsOptions,
     pub details: &'a DetailsOptions,
     pub filter: &'a FileFilter,
     pub filter: &'a FileFilter,
@@ -32,7 +32,7 @@ impl<'a> Render<'a> {
             dir: self.dir.clone(),
             dir: self.dir.clone(),
             files: Vec::new(),
             files: Vec::new(),
             colours: self.colours,
             colours: self.colours,
-            classify: self.classify,
+            style: self.style,
             opts: self.details,
             opts: self.details,
             recurse: None,
             recurse: None,
             filter: self.filter,
             filter: self.filter,
@@ -52,7 +52,7 @@ impl<'a> Render<'a> {
                        .collect::<Vec<TableRow>>();
                        .collect::<Vec<TableRow>>();
 
 
         let file_names = self.files.iter()
         let file_names = self.files.iter()
-                             .map(|file| FileName::new(file, LinkStyle::JustFilenames, self.classify, self.colours).paint().promote())
+                             .map(|file| self.style.for_file(file, self.colours).paint().promote())
                              .collect::<Vec<TextCell>>();
                              .collect::<Vec<TextCell>>();
 
 
         let mut last_working_table = self.make_grid(1, options, &file_names, rows.clone(), &drender);
         let mut last_working_table = self.make_grid(1, options, &file_names, rows.clone(), &drender);

+ 3 - 3
src/output/lines.rs

@@ -4,7 +4,7 @@ use ansi_term::ANSIStrings;
 
 
 use fs::File;
 use fs::File;
 
 
-use output::file_name::{FileName, LinkStyle, Classify};
+use output::file_name::{FileName, FileStyle};
 use super::colours::Colours;
 use super::colours::Colours;
 
 
 
 
@@ -12,7 +12,7 @@ use super::colours::Colours;
 pub struct Render<'a> {
 pub struct Render<'a> {
     pub files: Vec<File<'a>>,
     pub files: Vec<File<'a>>,
     pub colours: &'a Colours,
     pub colours: &'a Colours,
-    pub classify: Classify,
+    pub style: &'a FileStyle,
 }
 }
 
 
 impl<'a> Render<'a> {
 impl<'a> Render<'a> {
@@ -26,6 +26,6 @@ impl<'a> Render<'a> {
     }
     }
 
 
     fn render_file<'f>(&self, file: &'f File<'a>) -> FileName<'f, 'a> {
     fn render_file<'f>(&self, file: &'f File<'a>) -> FileName<'f, 'a> {
-        FileName::new(file, LinkStyle::FullLinkPaths, self.classify, self.colours)
+        self.style.for_file(file, self.colours).with_link_paths()
     }
     }
 }
 }