Permalink
Browse files

Merge branch 'row-threshold'

This merge adds the EXA_GRID_ROWS environment variable, which disables the grid-details view if it doesn’t result in enough rows of output.

Fixes #138.
  • Loading branch information...
ogham committed Aug 13, 2017
2 parents e45e515 + bcf5213 commit e933fa6a88cc5feb2e1409ea4fc7a7cb33d28bbf
Showing with 159 additions and 39 deletions.
  1. +3 −3 Cargo.lock
  2. +1 −1 Cargo.toml
  3. +13 −5 src/exa.rs
  4. +3 −3 src/options/help.rs
  5. +8 −9 src/options/mod.rs
  6. +1 −1 src/options/version.rs
  7. +34 −11 src/options/view.rs
  8. +95 −5 src/output/grid_details.rs
  9. +1 −1 src/output/mod.rs

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -34,7 +34,7 @@ natord = "1.0.7"
num_cpus = "1.3.0"
number_prefix = "0.2.3"
scoped_threadpool = "0.1.*"
term_grid = "0.1.2"
term_grid = "0.1.6"
unicode-width = "0.1.4"
users = "0.5.2"
term_size = "0.3.0"
@@ -69,7 +69,7 @@ impl Vars for LiveVars {
impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
pub fn new<I>(args: I, writer: &'w mut W) -> Result<Exa<'args, 'w, W>, Misfire>
where I: Iterator<Item=&'args OsString> {
Options::parse(args, LiveVars).map(move |(options, args)| {
Options::parse(args, &LiveVars).map(move |(options, args)| {
Exa { options, writer, args }
})
}
@@ -181,10 +181,18 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
let View { ref mode, ref colours, ref style } = self.options.view;
match *mode {
Mode::Lines => lines::Render { files, colours, style }.render(self.writer),
Mode::Grid(ref opts) => grid::Render { files, colours, style, opts }.render(self.writer),
Mode::Details(ref opts) => details::Render { dir, files, colours, style, opts, filter: &self.options.filter, recurse: self.options.dir_action.recurse_options() }.render(self.writer),
Mode::GridDetails(ref grid, ref details) => grid_details::Render { dir, files, colours, style, grid, details, filter: &self.options.filter }.render(self.writer),
Mode::Lines => {
lines::Render { files, colours, style }.render(self.writer)
}
Mode::Grid(ref opts) => {
grid::Render { files, colours, style, opts }.render(self.writer)
}
Mode::Details(ref opts) => {
details::Render { dir, files, colours, style, opts, filter: &self.options.filter, recurse: self.options.dir_action.recurse_options() }.render(self.writer)
}
Mode::GridDetails(ref opts) => {
grid_details::Render { dir, files, colours, style, grid: &opts.grid, details: &opts.details, filter: &self.options.filter, row_threshold: opts.row_threshold }.render(self.writer)
}
}
}
else {
@@ -130,21 +130,21 @@ mod test {
#[test]
fn help() {
let args = [ os("--help") ];
let opts = Options::parse(&args, None);
let opts = Options::parse(&args, &None);
assert!(opts.is_err())
}
#[test]
fn help_with_file() {
let args = [ os("--help"), os("me") ];
let opts = Options::parse(&args, None);
let opts = Options::parse(&args, &None);
assert!(opts.is_err())
}
#[test]
fn unhelpful() {
let args = [];
let opts = Options::parse(&args, None);
let opts = Options::parse(&args, &None);
assert!(opts.is_ok()) // no help when --help isn’t passed
}
}
@@ -73,8 +73,7 @@ use std::ffi::{OsStr, OsString};
use fs::dir_action::DirAction;
use fs::filter::FileFilter;
use output::{View, Mode};
use output::details;
use output::{View, Mode, details, grid_details};
mod dir_action;
mod filter;
@@ -116,7 +115,7 @@ impl Options {
/// struct and a list of free filenames, using the environment variables
/// for extra options.
#[allow(unused_results)]
pub fn parse<'args, I, V>(args: I, vars: V) -> Result<(Options, Vec<&'args OsStr>), Misfire>
pub fn parse<'args, I, V>(args: I, vars: &V) -> Result<(Options, Vec<&'args OsStr>), Misfire>
where I: IntoIterator<Item=&'args OsString>,
V: Vars {
use options::parser::{Matches, Strictness};
@@ -145,14 +144,14 @@ impl Options {
pub fn should_scan_for_git(&self) -> bool {
match self.view.mode {
Mode::Details(details::Options { table: Some(ref table), .. }) |
Mode::GridDetails(_, details::Options { table: Some(ref table), .. }) => table.extra_columns.should_scan_for_git(),
Mode::GridDetails(grid_details::Options { details: details::Options { table: Some(ref table), .. }, .. }) => table.extra_columns.should_scan_for_git(),
_ => false,
}
}
/// Determines the complete set of options based on the given command-line
/// arguments, after they’ve been parsed.
fn deduce<V: Vars>(matches: &MatchedFlags, vars: V) -> Result<Options, Misfire> {
fn deduce<V: Vars>(matches: &MatchedFlags, vars: &V) -> Result<Options, Misfire> {
let dir_action = DirAction::deduce(matches)?;
let filter = FileFilter::deduce(matches)?;
let view = View::deduce(matches, vars)?;
@@ -231,28 +230,28 @@ pub mod test {
#[test]
fn files() {
let args = [ os("this file"), os("that file") ];
let outs = Options::parse(&args, None).unwrap().1;
let outs = Options::parse(&args, &None).unwrap().1;
assert_eq!(outs, vec![ &os("this file"), &os("that file") ])
}
#[test]
fn no_args() {
let nothing: Vec<OsString> = Vec::new();
let outs = Options::parse(&nothing, None).unwrap().1;
let outs = Options::parse(&nothing, &None).unwrap().1;
assert!(outs.is_empty()); // Listing the `.` directory is done in main.rs
}
#[test]
fn long_across() {
let args = [ os("--long"), os("--across") ];
let opts = Options::parse(&args, None);
let opts = Options::parse(&args, &None);
assert_eq!(opts.unwrap_err(), Misfire::Useless(&flags::ACROSS, true, &flags::LONG))
}
#[test]
fn oneline_across() {
let args = [ os("--oneline"), os("--across") ];
let opts = Options::parse(&args, None);
let opts = Options::parse(&args, &None);
assert_eq!(opts.unwrap_err(), Misfire::Useless(&flags::ACROSS, true, &flags::ONE_LINE))
}
}
@@ -54,7 +54,7 @@ mod test {
#[test]
fn help() {
let args = [ os("--version") ];
let opts = Options::parse(&args, None);
let opts = Options::parse(&args, &None);
assert!(opts.is_err())
}
}
@@ -1,5 +1,6 @@
use output::Colours;
use output::{View, Mode, grid, details};
use output::grid_details::{self, RowThreshold};
use output::table::{TimeTypes, Environment, SizeFormat, Columns, Options as TableOptions};
use output::file_name::{Classify, FileStyle};
use output::time::TimeFormat;
@@ -13,7 +14,7 @@ use info::filetype::FileExtensions;
impl View {
/// Determine which view to use and all of that view’s arguments.
pub fn deduce<V: Vars>(matches: &MatchedFlags, vars: V) -> Result<View, Misfire> {
pub fn deduce<V: Vars>(matches: &MatchedFlags, vars: &V) -> Result<View, Misfire> {
let mode = Mode::deduce(matches, vars)?;
let colours = Colours::deduce(matches)?;
let style = FileStyle::deduce(matches)?;
@@ -25,7 +26,7 @@ impl View {
impl Mode {
/// Determine the mode from the command-line arguments.
pub fn deduce<V: Vars>(matches: &MatchedFlags, vars: V) -> Result<Mode, Misfire> {
pub fn deduce<V: Vars>(matches: &MatchedFlags, vars: &V) -> Result<Mode, Misfire> {
use options::misfire::Misfire::*;
let long = || {
@@ -95,10 +96,14 @@ impl Mode {
if matches.has(&flags::LONG)? {
let details = long()?;
if matches.has(&flags::GRID)? {
match other_options_scan()? {
Mode::Grid(grid) => return Ok(Mode::GridDetails(grid, details)),
others => return Ok(others),
};
let other_options_mode = other_options_scan()?;
if let Mode::Grid(grid) = other_options_mode {
let row_threshold = RowThreshold::deduce(vars)?;
return Ok(Mode::GridDetails(grid_details::Options { grid, details, row_threshold }));
}
else {
return Ok(other_options_mode);
}
}
else {
return Ok(Mode::Details(details));
@@ -149,7 +154,7 @@ impl TerminalWidth {
/// Determine a requested terminal width from the command-line arguments.
///
/// Returns an error if a requested width doesn’t parse to an integer.
fn deduce<V: Vars>(vars: V) -> Result<TerminalWidth, Misfire> {
fn deduce<V: Vars>(vars: &V) -> Result<TerminalWidth, Misfire> {
if let Some(columns) = vars.get("COLUMNS").and_then(|s| s.into_string().ok()) {
match columns.parse() {
Ok(width) => Ok(TerminalWidth::Set(width)),
@@ -174,6 +179,24 @@ impl TerminalWidth {
}
impl RowThreshold {
/// Determine whether to use a row threshold based on the given
/// environment variables.
fn deduce<V: Vars>(vars: &V) -> Result<RowThreshold, Misfire> {
if let Some(columns) = vars.get("EXA_GRID_ROWS").and_then(|s| s.into_string().ok()) {
match columns.parse() {
Ok(rows) => Ok(RowThreshold::MinimumRows(rows)),
Err(e) => Err(Misfire::FailedParse(e)),
}
}
else {
Ok(RowThreshold::AlwaysGrid)
}
}
}
impl TableOptions {
fn deduce(matches: &MatchedFlags) -> Result<Self, Misfire> {
let env = Environment::load_all();
@@ -478,7 +501,7 @@ mod test {
/// Like above, but with $vars.
#[test]
fn $name() {
for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf, $vars)) {
for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf, &$vars)) {
assert_eq!(result.unwrap_err(), $result);
}
}
@@ -488,7 +511,7 @@ mod test {
/// Like further above, but with $vars.
#[test]
fn $name() {
for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf, $vars)) {
for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf, &$vars)) {
println!("Testing {:?}", result);
match result {
$pat => assert!(true),
@@ -643,8 +666,8 @@ mod test {
test!(ell: Mode <- ["-l"], None; Both => like Ok(Mode::Details(_)));
// Grid-details views
test!(lid: Mode <- ["--long", "--grid"], None; Both => like Ok(Mode::GridDetails(_, _)));
test!(leg: Mode <- ["-lG"], None; Both => like Ok(Mode::GridDetails(_, _)));
test!(lid: Mode <- ["--long", "--grid"], None; Both => like Ok(Mode::GridDetails(_)));
test!(leg: Mode <- ["-lG"], None; Both => like Ok(Mode::GridDetails(_)));
// Options that do nothing without --long
Oops, something went wrong.

0 comments on commit e933fa6

Please sign in to comment.