summaryrefslogtreecommitdiffstats
path: root/src/output
diff options
context:
space:
mode:
authorBen S <ogham@bsago.me>2015-08-25 21:08:25 +0100
committerBen S <ogham@bsago.me>2015-08-26 09:03:43 +0100
commit69b22a0d669f6cb741290b96fe717e30efb70216 (patch)
tree72242c1fc2a3882253ab99dfb8ebaba71c0c4881 /src/output
parent17c493b370a2226d416b0710b016bcc3e1b706c2 (diff)
Print xattrs in tree view like we do errors
This changes the way extended attributes (xattrs) are printed. Before, they were artificially printed out on their own line both in lines mode *and* details mode, which looked a bit weird. Now, they are additional 'child nodes' of that item that get printed alongside errors. All this allows all the 'extra info' that is going to be present for very few entries to be consolidated and listed in the same way, without resorting to extra printlns. As a great side-effect, it allows taking out some of the more redundant code in the Table impl -- it is now *always* going to be in create-child-nodes mode, as *any* file now can, not only when we have the --tree flag in use. Also, it now actually displays errors when failing to read the extended attributes, such as if the user doesn't have permission to read them. The extended attribute flag has been temporarily disabled while I work out the best way to do it!
Diffstat (limited to 'src/output')
-rw-r--r--src/output/details.rs79
-rw-r--r--src/output/grid_details.rs2
2 files changed, 38 insertions, 43 deletions
diff --git a/src/output/details.rs b/src/output/details.rs
index acc3f7d..72dc1ba 100644
--- a/src/output/details.rs
+++ b/src/output/details.rs
@@ -1,13 +1,12 @@
use std::error::Error;
use std::io;
-use std::iter::repeat;
use std::path::Path;
use std::string::ToString;
use colours::Colours;
use column::{Alignment, Column, Cell};
use dir::Dir;
-use feature::xattr::Attribute;
+use feature::xattr::{Attribute, FileAttributes};
use file::fields as f;
use file::File;
use options::{Columns, FileFilter, RecurseOptions, SizeFormat};
@@ -78,7 +77,7 @@ impl Details {
// Then add files to the table and print it out.
self.add_files_to_table(&mut table, files, 0);
- for cell in table.print_table(self.xattr, self.recurse.is_some()) {
+ for cell in table.print_table() {
println!("{}", cell.text);
}
}
@@ -89,6 +88,17 @@ impl Details {
for (index, file) in src.iter().enumerate() {
table.add_file(file, depth, index == src.len() - 1, true);
+ if self.xattr {
+ match file.path.attributes() {
+ Ok(xattrs) => {
+ for xattr in xattrs {
+ table.add_xattr(xattr, depth + 1, false);
+ }
+ },
+ Err(e) => table.add_error(&e, depth + 1, true, None),
+ }
+ }
+
// There are two types of recursion that exa supports: a tree
// view, which is dealt with here, and multiple listings, which is
// dealt with in the main module. So only actually recurse if we
@@ -149,16 +159,9 @@ struct Row {
/// on top have depth 0.
depth: usize,
- /// Vector of this file's extended attributes, if that feature is active.
- attrs: Vec<Attribute>,
-
/// Whether this is the last entry in the directory. This flag is used
/// when calculating the tree view.
last: bool,
-
- /// Whether this file is a directory and has any children. Also used when
- /// calculating the tree view.
- children: bool,
}
impl Row {
@@ -232,8 +235,6 @@ impl<U> Table<U> where U: Users {
cells: Some(self.columns.iter().map(|c| Cell::paint(self.colours.header, c.header())).collect()),
name: Cell::paint(self.colours.header, "Name"),
last: false,
- attrs: Vec::new(),
- children: false,
};
self.rows.push(row);
@@ -250,8 +251,17 @@ impl<U> Table<U> where U: Users {
cells: None,
name: Cell::paint(self.colours.broken_arrow, &error_message),
last: last,
- attrs: Vec::new(),
- children: false,
+ };
+
+ self.rows.push(row);
+ }
+
+ pub fn add_xattr(&mut self, xattr: Attribute, depth: usize, last: bool) {
+ let row = Row {
+ depth: depth,
+ cells: None,
+ name: Cell::paint(self.colours.perms.attribute, &format!("{}\t{}", xattr.name, xattr.size)),
+ last: last,
};
self.rows.push(row);
@@ -269,8 +279,6 @@ impl<U> Table<U> where U: Users {
cells: Some(cells),
name: Cell { text: filename(file, &self.colours, links), length: file.file_name_width() },
last: last,
- attrs: file.xattrs.clone(),
- children: file.this.is_some(),
};
self.rows.push(row);
@@ -445,7 +453,7 @@ impl<U> Table<U> where U: Users {
}
/// Render the table as a vector of Cells, to be displayed on standard output.
- pub fn print_table(&self, xattr: bool, show_children: bool) -> Vec<Cell> {
+ pub fn print_table(&self) -> Vec<Cell> {
let mut stack = Vec::new();
let mut cells = Vec::new();
@@ -482,40 +490,27 @@ impl<U> Table<U> where U: Users {
// necessary to maintain information about the previously-printed
// lines, as the output will change based on whether the
// *previous* entry was the last in its directory.
- if show_children {
- stack.resize(row.depth + 1, TreePart::Edge);
- stack[row.depth] = if row.last { TreePart::Corner } else { TreePart::Edge };
+ stack.resize(row.depth + 1, TreePart::Edge);
+ stack[row.depth] = if row.last { TreePart::Corner } else { TreePart::Edge };
- for i in 1 .. row.depth + 1 {
- filename.push_str(&*self.colours.punctuation.paint(stack[i].ascii_art()).to_string());
- filename_length += 4;
- }
+ for i in 1 .. row.depth + 1 {
+ filename.push_str(&*self.colours.punctuation.paint(stack[i].ascii_art()).to_string());
+ filename_length += 4;
+ }
- if row.children {
- stack[row.depth] = if row.last { TreePart::Blank } else { TreePart::Line };
- }
+ stack[row.depth] = if row.last { TreePart::Blank } else { TreePart::Line };
- // If any tree characters have been printed, then add an extra
- // space, which makes the output look much better.
- if row.depth != 0 {
- filename.push(' ');
- filename_length += 1;
- }
+ // If any tree characters have been printed, then add an extra
+ // space, which makes the output look much better.
+ if row.depth != 0 {
+ filename.push(' ');
+ filename_length += 1;
}
// Print the name without worrying about padding.
filename.push_str(&*row.name.text);
filename_length += row.name.length;
- if xattr {
- let width = row.attrs.iter().map(|a| a.name.len()).max().unwrap_or(0);
- for attr in row.attrs.iter() {
- let name = &*attr.name;
- let spaces: String = repeat(" ").take(width - name.len()).collect();
- filename.push_str(&*format!("\n{}{} {}", name, spaces, attr.size))
- }
- }
-
cell.append(&Cell { text: filename, length: filename_length });
cells.push(cell);
}
diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs
index 4daf85a..5a5804d 100644
--- a/src/output/grid_details.rs
+++ b/src/output/grid_details.rs
@@ -73,7 +73,7 @@ impl GridDetails {
tables[index].add_file_with_cells(row, file, 0, false, false);
}
- let columns: Vec<_> = tables.iter().map(|t| t.print_table(false, false)).collect();
+ let columns: Vec<_> = tables.iter().map(|t| t.print_table()).collect();
let direction = if self.grid.across { grid::Direction::LeftToRight }
else { grid::Direction::TopToBottom };