2016-04-18 17:39:32 +00:00
|
|
|
|
use std::io::{Write, Result as IOResult};
|
|
|
|
|
|
2017-06-25 23:53:48 +00:00
|
|
|
|
use term_grid as tg;
|
2015-12-20 06:56:57 +00:00
|
|
|
|
|
2016-04-16 17:59:25 +00:00
|
|
|
|
use fs::File;
|
2017-08-26 20:40:37 +00:00
|
|
|
|
use style::Colours;
|
2017-07-08 11:24:22 +00:00
|
|
|
|
use output::file_name::FileStyle;
|
2015-02-05 14:39:56 +00:00
|
|
|
|
|
|
|
|
|
|
2015-04-03 22:14:49 +00:00
|
|
|
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
2017-06-25 23:53:48 +00:00
|
|
|
|
pub struct Options {
|
2015-02-05 14:39:56 +00:00
|
|
|
|
pub across: bool,
|
|
|
|
|
pub console_width: usize,
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-25 23:53:48 +00:00
|
|
|
|
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<File<'a>>,
|
|
|
|
|
pub colours: &'a Colours,
|
2017-07-08 11:11:11 +00:00
|
|
|
|
pub style: &'a FileStyle,
|
2017-06-25 23:53:48 +00:00
|
|
|
|
pub opts: &'a Options,
|
|
|
|
|
}
|
2015-02-05 14:39:56 +00:00
|
|
|
|
|
2017-06-25 23:53:48 +00:00
|
|
|
|
impl<'a> Render<'a> {
|
|
|
|
|
pub fn render<W: Write>(&self, w: &mut W) -> IOResult<()> {
|
|
|
|
|
let mut grid = tg::Grid::new(tg::GridOptions {
|
|
|
|
|
direction: self.opts.direction(),
|
|
|
|
|
filling: tg::Filling::Spaces(2),
|
2015-06-23 09:54:57 +00:00
|
|
|
|
});
|
2015-02-05 14:39:56 +00:00
|
|
|
|
|
2017-06-25 23:53:48 +00:00
|
|
|
|
grid.reserve(self.files.len());
|
2015-02-05 14:39:56 +00:00
|
|
|
|
|
2018-06-19 12:58:03 +00:00
|
|
|
|
for file in &self.files {
|
2017-07-08 11:24:22 +00:00
|
|
|
|
let filename = self.style.for_file(file, self.colours).paint();
|
2017-05-02 16:40:32 +00:00
|
|
|
|
let width = filename.width();
|
Print the parent path for passed-in files
This commit changes all the views to accommodate printing each path's prefix, if it has one.
Previously, each file was stripped of its ancestry, leaving only its file name to be displayed. So running "exa /usr/bin/*" would display only filenames, while running "ls /usr/bin/*" would display each file prefixed with "/usr/bin/". But running "ls /usr/bin/" -- without the glob -- would run ls on just the directory, printing out the file names with no prefix or anything.
This functionality turned out to be useful in quite a few situations: firstly, if the user passes in files from different directories, it would be hard to tell where they came from (especially if they have the same name, such as find | xargs). Secondly, this also applied when following symlinks, making it unclear exactly which file a symlink would be pointing to.
The reason that it did it this way beforehand was that I didn't think of these use-cases, rather than for any technical reason; this new method should not have any drawbacks save making the output slightly wider in a few cases. Compatibility with ls is also a big plus.
Fixes #104, and relates to #88 and #92.
2016-04-11 18:10:55 +00:00
|
|
|
|
|
2017-06-25 23:53:48 +00:00
|
|
|
|
grid.add(tg::Cell {
|
Measure, rather than calculating, cell widths
exa deals with cells and widths a lot: the items in a grid need to be aligned according to their *contents’* widths, rather than the length of their strings, which often included ANSI escape characters. As an optimisation, it used to calculate this separately based on the filename, and dealing with any extra characters (such as the classify ones) in that function too.
Recently, though, file names have become a lot more complicated. Classification added zero to one extra characters, and now with escaped control characters in file names, it’s not so easy to calculate the display width of a filename.
This commit removes the function that calculated the width, in favour of building the output string (it’s going to be displayed anyway) and just getting the width of what it displays instead.
2017-05-01 13:11:16 +00:00
|
|
|
|
contents: filename.strings().to_string(),
|
Print the parent path for passed-in files
This commit changes all the views to accommodate printing each path's prefix, if it has one.
Previously, each file was stripped of its ancestry, leaving only its file name to be displayed. So running "exa /usr/bin/*" would display only filenames, while running "ls /usr/bin/*" would display each file prefixed with "/usr/bin/". But running "ls /usr/bin/" -- without the glob -- would run ls on just the directory, printing out the file names with no prefix or anything.
This functionality turned out to be useful in quite a few situations: firstly, if the user passes in files from different directories, it would be hard to tell where they came from (especially if they have the same name, such as find | xargs). Secondly, this also applied when following symlinks, making it unclear exactly which file a symlink would be pointing to.
The reason that it did it this way beforehand was that I didn't think of these use-cases, rather than for any technical reason; this new method should not have any drawbacks save making the output slightly wider in a few cases. Compatibility with ls is also a big plus.
Fixes #104, and relates to #88 and #92.
2016-04-11 18:10:55 +00:00
|
|
|
|
width: *width,
|
2015-06-23 09:54:57 +00:00
|
|
|
|
});
|
2015-02-05 14:39:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-25 23:53:48 +00:00
|
|
|
|
if let Some(display) = grid.fit_into_width(self.opts.console_width) {
|
2016-04-18 17:39:32 +00:00
|
|
|
|
write!(w, "{}", display)
|
2015-02-05 14:39:56 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2015-06-23 09:54:57 +00:00
|
|
|
|
// File names too long for a grid - drop down to just listing them!
|
2017-07-08 11:24:22 +00:00
|
|
|
|
// This isn’t *quite* the same as the lines view, which also
|
|
|
|
|
// displays full link paths.
|
2018-06-19 12:58:03 +00:00
|
|
|
|
for file in &self.files {
|
2017-07-08 11:24:22 +00:00
|
|
|
|
let name_cell = self.style.for_file(file, self.colours).paint();
|
2017-05-02 07:52:24 +00:00
|
|
|
|
writeln!(w, "{}", name_cell.strings())?;
|
2015-06-23 09:54:57 +00:00
|
|
|
|
}
|
2016-04-18 17:39:32 +00:00
|
|
|
|
Ok(())
|
2015-02-05 14:39:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|