diff --git a/src/exa.rs b/src/exa.rs index 2316e9c..8442dd5 100644 --- a/src/exa.rs +++ b/src/exa.rs @@ -35,7 +35,7 @@ use fs::feature::git::GitCache; use options::{Options, Vars}; pub use options::vars; pub use options::Misfire; -use output::{escape, lines, grid, grid_details, details, View, Mode}; +use output::{escape, icons, lines, grid, grid_details, details, View, Mode}; mod fs; mod info; @@ -221,6 +221,11 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> { let View { ref mode, ref colours, ref style } = self.options.view; match *mode { + Mode::Icons(ref opts) => { + println!("ICONS MODE"); + let r = icons::Render { files, colours, style, opts }; + r.render(self.writer) + } Mode::Lines => { let r = lines::Render { files, colours, style }; r.render(self.writer) diff --git a/src/options/view.rs b/src/options/view.rs index bf7b6e9..17238c2 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -1,4 +1,4 @@ -use output::{View, Mode, grid, details}; +use output::{View, Mode, grid, details, icons}; use output::grid_details::{self, RowThreshold}; use output::table::{TimeTypes, Environment, SizeFormat, Columns, Options as TableOptions}; use output::time::TimeFormat; @@ -63,6 +63,13 @@ impl Mode { Ok(Mode::Details(details)) } + else if matches.has(&flags::ICONS)? { + let grid = icons::Options { + across: matches.has(&flags::ACROSS)?, + console_width: width, + }; + Ok(Mode::Icons(grid)) + } else { let grid = grid::Options { across: matches.has(&flags::ACROSS)?, diff --git a/src/output/icons.rs b/src/output/icons.rs new file mode 100644 index 0000000..db2560d --- /dev/null +++ b/src/output/icons.rs @@ -0,0 +1,64 @@ +use std::io::{Write, Result as IOResult}; + +use term_grid as tg; + +use fs::File; +use style::Colours; +use output::file_name::FileStyle; + + +#[derive(PartialEq, Debug, Copy, Clone)] +pub struct Options { + pub across: bool, + pub console_width: usize, +} + +impl Options { + pub fn direction(&self) -> tg::Direction { + if self.across { tg::Direction::LeftToRight } + else { tg::Direction::TopToBottom } + } +} + + +pub struct Render<'a> { + pub files: Vec>, + pub colours: &'a Colours, + pub style: &'a FileStyle, + pub opts: &'a Options, +} + +impl<'a> Render<'a> { + pub fn render(&self, w: &mut W) -> IOResult<()> { + let mut grid = tg::Grid::new(tg::GridOptions { + direction: self.opts.direction(), + filling: tg::Filling::Spaces(2), + }); + + grid.reserve(self.files.len()); + + for file in self.files.iter() { + let filename = self.style.for_file(file, self.colours).paint(); + let width = filename.width(); + + grid.add(tg::Cell { + contents: format!("<>{}", filename.strings().to_string()), + width: *width, + }); + } + + if let Some(display) = grid.fit_into_width(self.opts.console_width) { + write!(w, "{}", display) + } + 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, self.colours).paint(); + writeln!(w, "{}", name_cell.strings())?; + } + Ok(()) + } + } +} diff --git a/src/output/mod.rs b/src/output/mod.rs index dee899c..e697905 100644 --- a/src/output/mod.rs +++ b/src/output/mod.rs @@ -8,6 +8,7 @@ pub mod details; pub mod file_name; pub mod grid_details; pub mod grid; +pub mod icons; pub mod lines; pub mod render; pub mod table; @@ -33,5 +34,6 @@ pub enum Mode { Grid(grid::Options), Details(details::Options), GridDetails(grid_details::Options), + Icons(icons::Options), Lines, }