提交 a53c268c 编写于 作者: B Benjamin Sago

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.
上级 28fce347
......@@ -5,8 +5,6 @@ use std::ops::{Add, Deref, DerefMut};
use ansi_term::{Style, ANSIString, ANSIStrings};
use unicode_width::UnicodeWidthStr;
use fs::File;
/// An individual cell that holds text in a table, used in the details and
/// lines views to store ANSI-terminal-formatted data before it is printed.
......@@ -161,6 +159,11 @@ impl TextCellContents {
pub fn strings(&self) -> ANSIStrings {
ANSIStrings(&self.0)
}
pub fn width(&self) -> DisplayWidth {
let foo = self.0.iter().map(|anstr| anstr.chars().count()).sum();
DisplayWidth(foo)
}
}
......@@ -180,19 +183,6 @@ impl TextCellContents {
#[derive(PartialEq, Debug, Clone, Copy, Default)]
pub struct DisplayWidth(usize);
impl DisplayWidth {
pub fn from_file(file: &File, classify: bool) -> DisplayWidth {
let name_width = *DisplayWidth::from(&*file.name);
if classify {
if file.is_executable_file() || file.is_directory() ||
file.is_pipe() || file.is_link() || file.is_socket() {
return DisplayWidth(name_width + 1);
}
}
DisplayWidth(name_width)
}
}
impl<'a> From<&'a str> for DisplayWidth {
fn from(input: &'a str) -> DisplayWidth {
DisplayWidth(UnicodeWidthStr::width(input))
......
......@@ -306,7 +306,9 @@ impl Details {
for (index, egg) in file_eggs.into_iter().enumerate() {
let mut files = Vec::new();
let mut errors = egg.errors;
let mut width = DisplayWidth::from_file(&egg.file, self.classify);
let filename = filename(&egg.file, &self.colours, true, self.classify);
let mut width = filename.width();
if egg.file.dir.is_none() {
if let Some(parent) = egg.file.path.parent() {
......@@ -315,7 +317,7 @@ impl Details {
}
let name = TextCell {
contents: filename(&egg.file, &self.colours, true, self.classify),
contents: filename,
width: width,
};
......@@ -456,7 +458,8 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
}
pub fn filename_cell(&self, file: File, links: bool) -> TextCell {
let mut width = DisplayWidth::from_file(&file, self.opts.classify);
let filename = filename(&file, &self.opts.colours, links, self.opts.classify);
let mut width = filename.width();
if file.dir.is_none() {
if let Some(parent) = file.path.parent() {
......@@ -465,7 +468,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
}
TextCell {
contents: filename(&file, &self.opts.colours, links, self.opts.classify),
contents: filename,
width: width,
}
}
......
......@@ -29,8 +29,9 @@ impl Grid {
grid.reserve(files.len());
for file in files.iter() {
let mut width = DisplayWidth::from_file(file, self.classify);
let filename = filename(file, &self.colours, false, self.classify);
let mut width = filename.width();
if file.dir.is_none() {
if let Some(parent) = file.path.parent() {
width = width + 1 + DisplayWidth::from(parent.to_string_lossy().as_ref());
......@@ -38,7 +39,7 @@ impl Grid {
}
grid.add(grid::Cell {
contents: filename(file, &self.colours, false, self.classify).strings().to_string(),
contents: filename.strings().to_string(),
width: *width,
});
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册