From a0582132e512d87552453157d10bfe3617bf76c6 Mon Sep 17 00:00:00 2001 From: Ben S Date: Thu, 22 May 2014 01:02:47 +0100 Subject: [PATCH] Have each row use the same column widths This involves putting the entire output into a table before anything is actually printed, in order to determine what the width of each column should be. This should make it appear to output slower, as the first line can only be printed after every file has been examined, but it's still fast to me. --- colours.rs | 5 +++++ exa.rs | 26 ++++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/colours.rs b/colours.rs index 06182a0..8ba9e65 100644 --- a/colours.rs +++ b/colours.rs @@ -82,3 +82,8 @@ impl Colour { Style(StyleStruct { foreground: *self, background: Some(background), bold: false, underline: false }) } } + +pub fn strip_formatting(input: &~str) -> ~str { + let re = regex!("\x1B\\[.+?m"); + re.replace_all(*input, "").to_owned() +} diff --git a/exa.rs b/exa.rs index ca28d73..9dda3f6 100644 --- a/exa.rs +++ b/exa.rs @@ -1,3 +1,7 @@ +#![feature(phase)] +extern crate regex; +#[phase(syntax)] extern crate regex_macros; + extern crate getopts; use std::os; use std::io::fs; @@ -51,25 +55,31 @@ fn list(opts: Options, path: Path) { Err(e) => fail!("readdir: {}", e), }; files.sort_by(|a, b| a.filename_str().cmp(&b.filename_str())); - for subpath in files.iter() { - let file = File::from_path(subpath); - if file.is_dotfile() && !opts.showInvisibles { - continue; - } + let columns = defaultColumns(); - let columns = defaultColumns(); + let table: Vec> = files.iter() + .map(|p| File::from_path(p)) + .filter(|f| !f.is_dotfile() || opts.showInvisibles ) + .map(|f| columns.iter().map(|c| f.display(c)).collect()) + .collect(); - let mut cells = columns.iter().map(|c| file.display(c)); + let maxes: Vec = range(0, columns.len()) + .map(|n| table.iter().map(|row| colours::strip_formatting(row.get(n)).len()).max().unwrap()) + .collect(); + for row in table.iter() { let mut first = true; - for cell in cells { + for (length, cell) in maxes.iter().zip(row.iter()) { if first { first = false; } else { print!(" "); } print!("{}", cell); + for _ in range(cell.len(), *length) { + print!(" "); + } } print!("\n"); }