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) } }