From 0d613652a798ea59b450e68195278362caa91f9d Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Sat, 8 Jul 2017 12:11:11 +0100 Subject: [PATCH 1/4] Replace FileName::new with a factory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new FileStyles value will contain all the fields necessary to “style” a file’s name. Right now this is only the Classify field, but there can be more later. The benefit of this is that when we add more, we won’t need to update all the places where file names are displayed. --- src/exa.rs | 10 ++-- src/options/view.rs | 20 +++++-- src/output/details.rs | 6 +- src/output/file_name.rs | 109 ++++++++++++++++++++++--------------- src/output/grid.rs | 8 +-- src/output/grid_details.rs | 8 +-- src/output/lines.rs | 6 +- 7 files changed, 97 insertions(+), 70 deletions(-) diff --git a/src/exa.rs b/src/exa.rs index 061ff02..2434bc0 100644 --- a/src/exa.rs +++ b/src/exa.rs @@ -168,13 +168,13 @@ impl<'w, W: Write + 'w> Exa<'w, W> { /// printing differently... fn print_files(&mut self, dir: Option<&Dir>, files: Vec) -> IOResult<()> { 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 { - 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 { diff --git a/src/options/view.rs b/src/options/view.rs index 2f1c7fa..24b8eec 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -5,7 +5,7 @@ use getopts; use output::Colours; use output::{grid, details}; 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 options::Misfire; use fs::feature::xattr; @@ -16,17 +16,17 @@ use fs::feature::xattr; pub struct View { pub mode: Mode, pub colours: Colours, - pub classify: Classify, + pub style: FileStyle, } impl View { /// Determine which view to use and all of that view’s arguments. pub fn deduce(matches: &getopts::Matches) -> Result { - 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 +370,14 @@ impl Colours { +impl FileStyle { + fn deduce(matches: &getopts::Matches) -> FileStyle { + let classify = Classify::deduce(matches); + FileStyle { classify } + } + +} + impl Classify { fn deduce(matches: &getopts::Matches) -> Classify { if matches.opt_present("classify") { Classify::AddFileIndicators } diff --git a/src/output/details.rs b/src/output/details.rs index 09cf475..bf93ea8 100644 --- a/src/output/details.rs +++ b/src/output/details.rs @@ -70,7 +70,7 @@ use options::{FileFilter, RecurseOptions}; use output::colours::Colours; use output::cell::TextCell; use output::tree::{TreeTrunk, TreeParams, TreeDepth}; -use output::file_name::{FileName, LinkStyle, Classify}; +use output::file_name::{FileStyle, LinkStyle}; use output::table::{Table, Options as TableOptions, Row as TableRow}; @@ -107,7 +107,7 @@ pub struct Render<'a> { pub dir: Option<&'a Dir>, pub files: Vec>, pub colours: &'a Colours, - pub classify: Classify, + pub style: &'a FileStyle, pub opts: &'a Options, /// Whether to recurse through directories with a tree view, and if so, @@ -233,7 +233,7 @@ impl<'a> Render<'a> { let row = Row { tree: tree_params, cells: egg.table_row, - name: FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, self.colours).paint().promote(), + name: self.style.for_file(&egg.file, LinkStyle::FullLinkPaths, self.colours).paint().promote(), }; rows.push(row); diff --git a/src/output/file_name.rs b/src/output/file_name.rs index a2b138a..b908481 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -8,6 +8,62 @@ use output::escape; use output::cell::TextCellContents; +/// Basically a file name factory. +#[derive(PartialEq, Debug)] +pub struct FileStyle { + + /// Whether to append file class characters to file names. + pub classify: Classify, +} + +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>(&self, file: &'a File<'dir>, link_style: LinkStyle, 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: self.classify } + } +} + + +/// 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 + } +} + + + /// A **file name** holds all the information necessary to display the name /// of the given file. This is used in all of the views. pub struct FileName<'a, 'dir: 'a> { @@ -31,15 +87,6 @@ pub struct FileName<'a, 'dir: 'a> { 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 } - } - - /// Paints the name of the file using the colours, resulting in a vector /// of coloured cells that can be printed to the terminal. /// @@ -73,7 +120,14 @@ impl<'a, 'dir> FileName<'a, 'dir> { } 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, + }; + for bit in target.coloured_file_name() { bits.push(bit); } @@ -195,38 +249,3 @@ impl<'a, 'dir> FileName<'a, 'dir> { } } } - - -/// 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 - } -} diff --git a/src/output/grid.rs b/src/output/grid.rs index 7f9637c..8058225 100644 --- a/src/output/grid.rs +++ b/src/output/grid.rs @@ -4,7 +4,7 @@ use term_grid as tg; use fs::File; use output::colours::Colours; -use output::file_name::{FileName, LinkStyle, Classify}; +use output::file_name::{FileStyle, LinkStyle}; #[derive(PartialEq, Debug, Copy, Clone)] @@ -24,7 +24,7 @@ impl Options { pub struct Render<'a> { pub files: Vec>, pub colours: &'a Colours, - pub classify: Classify, + pub style: &'a FileStyle, pub opts: &'a Options, } @@ -38,7 +38,7 @@ impl<'a> Render<'a> { grid.reserve(self.files.len()); 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, LinkStyle::JustFilenames, self.colours).paint(); let width = filename.width(); grid.add(tg::Cell { @@ -53,7 +53,7 @@ impl<'a> Render<'a> { else { // File names too long for a grid - drop down to just listing them! 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, LinkStyle::JustFilenames, self.colours).paint(); writeln!(w, "{}", name_cell.strings())?; } Ok(()) diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index 788c3f2..e481ecb 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -11,7 +11,7 @@ use output::cell::TextCell; use output::colours::Colours; use output::details::{Options as DetailsOptions, Row as DetailsRow, Render as DetailsRender}; use output::grid::Options as GridOptions; -use output::file_name::{FileName, LinkStyle, Classify}; +use output::file_name::{FileStyle, LinkStyle}; use output::table::{Table, Row as TableRow, Options as TableOptions}; use output::tree::{TreeParams, TreeDepth}; @@ -20,7 +20,7 @@ pub struct Render<'a> { pub dir: Option<&'a Dir>, pub files: Vec>, pub colours: &'a Colours, - pub classify: Classify, + pub style: &'a FileStyle, pub grid: &'a GridOptions, pub details: &'a DetailsOptions, pub filter: &'a FileFilter, @@ -32,7 +32,7 @@ impl<'a> Render<'a> { dir: self.dir.clone(), files: Vec::new(), colours: self.colours, - classify: self.classify, + style: self.style, opts: self.details, recurse: None, filter: self.filter, @@ -52,7 +52,7 @@ impl<'a> Render<'a> { .collect::>(); 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, LinkStyle::JustFilenames, self.colours).paint().promote()) .collect::>(); let mut last_working_table = self.make_grid(1, options, &file_names, rows.clone(), &drender); diff --git a/src/output/lines.rs b/src/output/lines.rs index 19a86d7..778cb10 100644 --- a/src/output/lines.rs +++ b/src/output/lines.rs @@ -4,7 +4,7 @@ use ansi_term::ANSIStrings; use fs::File; -use output::file_name::{FileName, LinkStyle, Classify}; +use output::file_name::{FileName, FileStyle, LinkStyle}; use super::colours::Colours; @@ -12,7 +12,7 @@ use super::colours::Colours; pub struct Render<'a> { pub files: Vec>, pub colours: &'a Colours, - pub classify: Classify, + pub style: &'a FileStyle, } impl<'a> Render<'a> { @@ -26,6 +26,6 @@ impl<'a> Render<'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, LinkStyle::FullLinkPaths, self.colours) } } From bfa65b3becd50e1c3da1cc76764d5f48f8b7164f Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Sat, 8 Jul 2017 12:24:22 +0100 Subject: [PATCH 2/4] Make not showing paths in link targets the default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit replaces the “two normal cases” of showing a link’s target or not with “one default and one special case” of preferring to hide them, displaying the link targets by setting a flag instead. Doing this simplifies the file name constructor, which gets to remove an argument. --- src/output/details.rs | 6 ++++-- src/output/file_name.rs | 21 ++++++++++++++++----- src/output/grid.rs | 8 +++++--- src/output/grid_details.rs | 4 ++-- src/output/lines.rs | 4 ++-- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/output/details.rs b/src/output/details.rs index bf93ea8..8371a34 100644 --- a/src/output/details.rs +++ b/src/output/details.rs @@ -70,7 +70,7 @@ use options::{FileFilter, RecurseOptions}; use output::colours::Colours; use output::cell::TextCell; use output::tree::{TreeTrunk, TreeParams, TreeDepth}; -use output::file_name::{FileStyle, LinkStyle}; +use output::file_name::FileStyle; use output::table::{Table, Options as TableOptions, Row as TableRow}; @@ -233,7 +233,9 @@ impl<'a> Render<'a> { let row = Row { tree: tree_params, cells: egg.table_row, - name: self.style.for_file(&egg.file, LinkStyle::FullLinkPaths, self.colours).paint().promote(), + name: self.style.for_file(&egg.file, self.colours) + .with_link_paths() + .paint().promote(), }; rows.push(row); diff --git a/src/output/file_name.rs b/src/output/file_name.rs index b908481..bced071 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -20,10 +20,14 @@ 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>(&self, file: &'a File<'dir>, link_style: LinkStyle, 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: self.classify } + pub fn for_file<'a, 'dir>(&self, file: &'a File<'dir>, colours: &'a Colours) -> FileName<'a, 'dir> { + FileName { + file, colours, + link_style: LinkStyle::JustFilenames, + classify: self.classify, + target: if file.is_link() { Some(file.link_target()) } + else { None } + } } } @@ -31,7 +35,7 @@ impl FileStyle { /// 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 { +enum LinkStyle { /// Just display the file names, but colour them differently if they’re /// a broken link or can’t be followed. @@ -87,6 +91,13 @@ pub struct FileName<'a, 'dir: 'a> { impl<'a, 'dir> FileName<'a, 'dir> { + /// 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 /// of coloured cells that can be printed to the terminal. /// diff --git a/src/output/grid.rs b/src/output/grid.rs index 8058225..a28a409 100644 --- a/src/output/grid.rs +++ b/src/output/grid.rs @@ -4,7 +4,7 @@ use term_grid as tg; use fs::File; use output::colours::Colours; -use output::file_name::{FileStyle, LinkStyle}; +use output::file_name::FileStyle; #[derive(PartialEq, Debug, Copy, Clone)] @@ -38,7 +38,7 @@ impl<'a> Render<'a> { grid.reserve(self.files.len()); for file in self.files.iter() { - let filename = self.style.for_file(file, LinkStyle::JustFilenames, self.colours).paint(); + let filename = self.style.for_file(file, self.colours).paint(); let width = filename.width(); grid.add(tg::Cell { @@ -52,8 +52,10 @@ impl<'a> Render<'a> { } else { // 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() { - let name_cell = self.style.for_file(file, LinkStyle::JustFilenames, self.colours).paint(); + let name_cell = self.style.for_file(file, self.colours).paint(); writeln!(w, "{}", name_cell.strings())?; } Ok(()) diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index e481ecb..1f1ffc6 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -11,7 +11,7 @@ use output::cell::TextCell; use output::colours::Colours; use output::details::{Options as DetailsOptions, Row as DetailsRow, Render as DetailsRender}; use output::grid::Options as GridOptions; -use output::file_name::{FileStyle, LinkStyle}; +use output::file_name::FileStyle; use output::table::{Table, Row as TableRow, Options as TableOptions}; use output::tree::{TreeParams, TreeDepth}; @@ -52,7 +52,7 @@ impl<'a> Render<'a> { .collect::>(); let file_names = self.files.iter() - .map(|file| self.style.for_file(file, LinkStyle::JustFilenames, self.colours).paint().promote()) + .map(|file| self.style.for_file(file, self.colours).paint().promote()) .collect::>(); let mut last_working_table = self.make_grid(1, options, &file_names, rows.clone(), &drender); diff --git a/src/output/lines.rs b/src/output/lines.rs index 778cb10..8ea73d2 100644 --- a/src/output/lines.rs +++ b/src/output/lines.rs @@ -4,7 +4,7 @@ use ansi_term::ANSIStrings; use fs::File; -use output::file_name::{FileName, FileStyle, LinkStyle}; +use output::file_name::{FileName, FileStyle}; use super::colours::Colours; @@ -26,6 +26,6 @@ impl<'a> Render<'a> { } fn render_file<'f>(&self, file: &'f File<'a>) -> FileName<'f, 'a> { - self.style.for_file(file, LinkStyle::FullLinkPaths, self.colours) + self.style.for_file(file, self.colours).with_link_paths() } } From 0d8d7234086ef608a60d90f19b7b030880d96b36 Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Mon, 10 Jul 2017 13:31:20 +0100 Subject: [PATCH 3/4] Reify file extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having a File do its own extension checking, create a new type that takes a file and checks *that*. This new type (FileExtensions) is currently empty, but were it to contain values, those values could be used to determine the file’s colour. --- src/info/filetype.rs | 82 ++++++++++++++--------------------------- src/info/mod.rs | 6 +-- src/output/file_name.rs | 29 +++++++++------ 3 files changed, 48 insertions(+), 69 deletions(-) diff --git a/src/info/filetype.rs b/src/info/filetype.rs index 47af438..77a9654 100644 --- a/src/info/filetype.rs +++ b/src/info/filetype.rs @@ -7,21 +7,23 @@ use fs::File; -impl<'a> File<'a> { +pub struct FileExtensions; + +impl FileExtensions { /// 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 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", "build.gradle", "Rakefile", "Gruntfile.js", "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", "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw", "svg", "stl", "eps", "dvi", "ps", "cbr", @@ -29,92 +31,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", "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", ]) } // 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", ]) } - 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", ]) } - 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", "odp", "odt", "pdf", "ppt", "pptx", "rtf", "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", "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 } - 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 { 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()) - } -} diff --git a/src/info/mod.rs b/src/info/mod.rs index ba00019..1fdd535 100644 --- a/src/info/mod.rs +++ b/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. //! (This counts the file name as metadata.) -mod filetype; +pub mod filetype; mod sources; diff --git a/src/output/file_name.rs b/src/output/file_name.rs index bced071..79628ee 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -3,6 +3,7 @@ use std::path::Path; use ansi_term::{ANSIString, Style}; use fs::{File, FileTarget}; +use info::filetype::FileExtensions; use output::Colours; use output::escape; use output::cell::TextCellContents; @@ -23,6 +24,7 @@ impl FileStyle { pub fn for_file<'a, 'dir>(&self, file: &'a File<'dir>, colours: &'a Colours) -> FileName<'a, 'dir> { FileName { file, colours, + exts: FileExtensions, link_style: LinkStyle::JustFilenames, classify: self.classify, target: if file.is_link() { Some(file.link_target()) } @@ -86,6 +88,9 @@ pub struct FileName<'a, 'dir: 'a> { /// Whether to append file class characters to file names. classify: Classify, + + /// Mapping of file extensions to colours, to highlight regular files. + exts: FileExtensions, } @@ -137,6 +142,7 @@ impl<'a, 'dir> FileName<'a, 'dir> { target: None, link_style: LinkStyle::FullLinkPaths, classify: Classify::JustFilenames, + exts: FileExtensions, }; for bit in target.coloured_file_name() { @@ -246,17 +252,18 @@ impl<'a, 'dir> FileName<'a, 'dir> { | f.is_block_device() => self.colours.filetypes.device, f if f.is_socket() => self.colours.filetypes.socket, 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, + + 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, } } } From c29170e34559e4d1f6731ed59975a6b9d068df71 Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Mon, 10 Jul 2017 14:01:38 +0100 Subject: [PATCH 4/4] Get the list of file extensions from the Options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FileExtensions in the FileName is now a reference to the one in the original FileStyle, which gets put there in the options module. This allows the extensions to be derived from the user, somehow, in the future when that part’s done. --- src/info/filetype.rs | 1 + src/options/view.rs | 4 +++- src/output/file_name.rs | 13 ++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/info/filetype.rs b/src/info/filetype.rs index 77a9654..608aff7 100644 --- a/src/info/filetype.rs +++ b/src/info/filetype.rs @@ -7,6 +7,7 @@ use fs::File; +#[derive(Debug)] pub struct FileExtensions; impl FileExtensions { diff --git a/src/options/view.rs b/src/options/view.rs index 24b8eec..03ae3f0 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -2,6 +2,7 @@ use std::env::var_os; use getopts; +use info::filetype::FileExtensions; use output::Colours; use output::{grid, details}; use output::table::{TimeTypes, Environment, SizeFormat, Options as TableOptions}; @@ -373,7 +374,8 @@ impl Colours { impl FileStyle { fn deduce(matches: &getopts::Matches) -> FileStyle { let classify = Classify::deduce(matches); - FileStyle { classify } + let exts = FileExtensions; + FileStyle { classify, exts } } } diff --git a/src/output/file_name.rs b/src/output/file_name.rs index 79628ee..bfb5b31 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -10,22 +10,25 @@ use output::cell::TextCellContents; /// Basically a file name factory. -#[derive(PartialEq, Debug)] +#[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>(&self, file: &'a File<'dir>, colours: &'a Colours) -> FileName<'a, 'dir> { + pub fn for_file<'a, 'dir>(&'a self, file: &'a File<'dir>, colours: &'a Colours) -> FileName<'a, 'dir> { FileName { file, colours, - exts: FileExtensions, link_style: LinkStyle::JustFilenames, + exts: &self.exts, classify: self.classify, target: if file.is_link() { Some(file.link_target()) } else { None } @@ -90,7 +93,7 @@ pub struct FileName<'a, 'dir: 'a> { classify: Classify, /// Mapping of file extensions to colours, to highlight regular files. - exts: FileExtensions, + exts: &'a FileExtensions, } @@ -142,7 +145,7 @@ impl<'a, 'dir> FileName<'a, 'dir> { target: None, link_style: LinkStyle::FullLinkPaths, classify: Classify::JustFilenames, - exts: FileExtensions, + exts: self.exts, }; for bit in target.coloured_file_name() {