Skip to content

Commit

Permalink
Merge branch 'long-grid-view'
Browse files Browse the repository at this point in the history
  • Loading branch information
ogham committed Jun 29, 2015
2 parents 8d6f628 + 56895ab commit 090cebe
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 122 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 20 additions & 22 deletions src/column.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::iter::repeat;

use ansi_term::Style;
use unicode_width::UnicodeWidthStr;

Expand Down Expand Up @@ -58,37 +56,37 @@ impl Column {
}
}

/// Pad a string with the given number of spaces.
fn spaces(length: usize) -> String {
repeat(" ").take(length).collect()
}

impl Alignment {
/// Pad a string with the given alignment and number of spaces.
///
/// This doesn't take the width the string *should* be, rather the number
/// of spaces to add: this is because the strings are usually full of
/// invisible control characters, so getting the displayed width of the
/// string is not as simple as just getting its length.
pub fn pad_string(&self, string: &str, padding: usize) -> String {
match *self {
Alignment::Left => format!("{}{}", string, spaces(padding)),
Alignment::Right => format!("{}{}", spaces(padding), string),
}
}
}

#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
pub struct Cell {
pub length: usize,
pub text: String,
}

impl Cell {
pub fn empty() -> Cell {
Cell {
text: String::new(),
length: 0,
}
}

pub fn paint(style: Style, string: &str) -> Cell {
Cell {
text: style.paint(string).to_string(),
length: UnicodeWidthStr::width(string),
}
}

pub fn add_spaces(&mut self, count: usize) {
self.length += count;
for _ in 0 .. count {
self.text.push(' ');
}
}

pub fn append(&mut self, other: &Cell) {
self.length += other.length;
self.text.push_str(&*other.text);
}
}
7 changes: 4 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@ impl<'dir> Exa<'dir> {

fn print(&self, dir: Option<&Dir>, files: &[File]) {
match self.options.view {
View::Grid(g) => g.view(files),
View::Details(d) => d.view(dir, files),
View::Lines(l) => l.view(files),
View::Grid(g) => g.view(files),
View::Details(d) => d.view(dir, files),
View::GridDetails(gd) => gd.view(dir, files),
View::Lines(l) => l.view(files),
}
}
}
Expand Down
138 changes: 73 additions & 65 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use column::Column::*;
use dir::Dir;
use feature::Attribute;
use file::File;
use output::{Grid, Details, Lines};
use output::{Grid, Details, GridDetails, Lines};
use term::dimensions;


Expand All @@ -37,6 +37,7 @@ impl Options {
opts.optflag("B", "bytes", "list file sizes in bytes, without prefixes");
opts.optflag("d", "list-dirs", "list directories as regular files");
opts.optflag("g", "group", "show group as well as user");
opts.optflag("G", "grid", "display entries in a grid view (default)");
opts.optflag("", "group-directories-first", "list directories before other files");
opts.optflag("h", "header", "show a header row at the top");
opts.optflag("H", "links", "show number of hard links");
Expand Down Expand Up @@ -248,16 +249,17 @@ impl fmt::Display for Misfire {
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum View {
Details(Details),
Lines(Lines),
Grid(Grid),
GridDetails(GridDetails),
Lines(Lines),
}

impl View {
pub fn deduce(matches: &getopts::Matches, filter: FileFilter, dir_action: DirAction) -> Result<View, Misfire> {
use self::Misfire::*;

if matches.opt_present("long") {
if matches.opt_present("across") {
let long = || {
if matches.opt_present("across") && !matches.opt_present("grid") {
Err(Useless("across", true, "long"))
}
else if matches.opt_present("oneline") {
Expand All @@ -272,78 +274,85 @@ impl View {
colours: if dimensions().is_some() { Colours::colourful() } else { Colours::plain() },
};

Ok(View::Details(details))
Ok(details)
}
}
else if matches.opt_present("binary") {
Err(Useless("binary", false, "long"))
}
else if matches.opt_present("bytes") {
Err(Useless("bytes", false, "long"))
}
else if matches.opt_present("inode") {
Err(Useless("inode", false, "long"))
}
else if matches.opt_present("links") {
Err(Useless("links", false, "long"))
}
else if matches.opt_present("header") {
Err(Useless("header", false, "long"))
}
else if matches.opt_present("blocks") {
Err(Useless("blocks", false, "long"))
}
else if cfg!(feature="git") && matches.opt_present("git") {
Err(Useless("git", false, "long"))
}
else if matches.opt_present("time") {
Err(Useless("time", false, "long"))
}
else if matches.opt_present("tree") {
Err(Useless("tree", false, "long"))
}
else if matches.opt_present("group") {
Err(Useless("group", false, "long"))
}
else if matches.opt_present("level") && !matches.opt_present("recurse") {
Err(Useless2("level", "recurse", "tree"))
}
else if Attribute::feature_implemented() && matches.opt_present("extended") {
Err(Useless("extended", false, "long"))
}
else if let Some((width, _)) = dimensions() {
if matches.opt_present("oneline") {
if matches.opt_present("across") {
Err(Useless("across", true, "oneline"))
};

let long_options_scan = || {
for option in &[ "binary", "bytes", "inode", "links", "header", "blocks", "time", "tree", "group" ] {
if matches.opt_present(option) {
return Err(Useless(option, false, "long"));
}
}

if cfg!(feature="git") && matches.opt_present("git") {
Err(Useless("git", false, "long"))
}
else if matches.opt_present("level") && !matches.opt_present("recurse") {
Err(Useless2("level", "recurse", "tree"))
}
else if Attribute::feature_implemented() && matches.opt_present("extended") {
Err(Useless("extended", false, "long"))
}
else {
Ok(())
}
};

let other_options_scan = || {
if let Some((width, _)) = dimensions() {
if matches.opt_present("oneline") {
if matches.opt_present("across") {
Err(Useless("across", true, "oneline"))
}
else {
let lines = Lines {
colours: Colours::colourful(),
};

Ok(View::Lines(lines))
}
}
else {
let lines = Lines {
colours: Colours::colourful(),
let grid = Grid {
across: matches.opt_present("across"),
console_width: width,
colours: Colours::colourful(),
};

Ok(View::Lines(lines))
Ok(View::Grid(grid))
}
}
else {
let grid = Grid {
across: matches.opt_present("across"),
console_width: width,
colours: Colours::colourful(),
// If the terminal width couldn't be matched for some reason, such
// as the program's stdout being connected to a file, then
// fallback to the lines view.
let lines = Lines {
colours: Colours::plain(),
};

Ok(View::Grid(grid))
Ok(View::Lines(lines))
}
};

if matches.opt_present("long") {
let long_options = try!(long());

if matches.opt_present("grid") {
match other_options_scan() {
Ok(View::Grid(grid)) => return Ok(View::GridDetails(GridDetails { grid: grid, details: long_options })),
Ok(lines) => return Ok(lines),
Err(e) => return Err(e),
};
}
else {
return Ok(View::Details(long_options));
}
}
else {
// If the terminal width couldn't be matched for some reason, such
// as the program's stdout being connected to a file, then
// fallback to the lines view.
let lines = Lines {
colours: Colours::plain(),
};

Ok(View::Lines(lines))
}

try!(long_options_scan());

other_options_scan()
}
}

Expand Down Expand Up @@ -718,5 +727,4 @@ mod test {
let opts = Options::getopts(&[ "--level".to_string(), "69105".to_string() ]);
assert_eq!(opts.unwrap_err(), Misfire::Useless2("level", "recurse", "tree"))
}

}
Loading

0 comments on commit 090cebe

Please sign in to comment.