From 96cc391f2d5865ba256d61b823c50225fc12e7e2 Mon Sep 17 00:00:00 2001 From: sharkdp Date: Sat, 19 May 2018 10:31:10 +0200 Subject: [PATCH] Skip '--quit-if-one-screen' for --paging=always closes #97 --- src/app.rs | 27 +++++++++++++++++++++------ src/main.rs | 35 +++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/app.rs b/src/app.rs index a2625e11..228add91 100644 --- a/src/app.rs +++ b/src/app.rs @@ -181,16 +181,24 @@ impl App { Some("never") => false, Some("auto") | _ => self.interactive_output, }, - paging: match self.matches.value_of("paging") { - Some("always") => true, - Some("never") => false, + paging_mode: match self.matches.value_of("paging") { + Some("always") => PagingMode::Always, + Some("never") => PagingMode::Never, Some("auto") | _ => if files.contains(&None) { // If we are reading from stdin, only enable paging if we write to an // interactive terminal and if we do not *read* from an interactive // terminal. - self.interactive_output && !atty::is(Stream::Stdin) + if self.interactive_output && !atty::is(Stream::Stdin) { + PagingMode::QuitIfOneScreen + } else { + PagingMode::Never + } } else { - self.interactive_output + if self.interactive_output { + PagingMode::QuitIfOneScreen + } else { + PagingMode::Never + } }, }, term_width: Term::stdout().size().1 as usize, @@ -230,13 +238,20 @@ impl App { } } +#[derive(Debug, Clone, Copy)] +pub enum PagingMode { + Always, + QuitIfOneScreen, + Never, +} + pub struct Config<'a> { pub true_color: bool, pub output_wrap: OutputWrap, pub output_components: OutputComponents, pub language: Option<&'a str>, pub colored_output: bool, - pub paging: bool, + pub paging_mode: PagingMode, pub term_width: usize, pub files: Vec>, pub theme: Option<&'a str>, diff --git a/src/main.rs b/src/main.rs index 104c1b27..2ee8d6f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ use syntect::easy::HighlightLines; use syntect::highlighting::Theme; use syntect::parsing::SyntaxDefinition; -use app::App; +use app::{App, PagingMode}; use assets::{config_dir, syntax_set_path, theme_set_path, HighlightingAssets}; use diff::get_git_diff; use printer::Printer; @@ -59,12 +59,27 @@ enum OutputType { } impl OutputType { - fn pager() -> Result { - Ok(OutputType::Pager(Command::new("less") - .args(&["--quit-if-one-screen", "--RAW-CONTROL-CHARS", "--no-init"]) + fn from_mode(mode: PagingMode) -> Self { + use PagingMode::*; + match mode { + Always => OutputType::try_pager(false), + QuitIfOneScreen => OutputType::try_pager(true), + _ => OutputType::stdout(), + } + } + + /// Try to launch the pager. Fall back to stdout in case of errors. + fn try_pager(quit_if_one_screen: bool) -> Self { + let mut args = vec!["--RAW-CONTROL-CHARS", "--no-init"]; + if quit_if_one_screen { + args.push("--quit-if-one-screen"); + } + Command::new("less") + .args(&args) .stdin(Stdio::piped()) .spawn() - .chain_err(|| "Could not spawn pager")?)) + .map(OutputType::Pager) + .unwrap_or_else(|_| OutputType::stdout()) } fn stdout() -> Self { @@ -153,14 +168,6 @@ fn print_file( Ok(()) } -fn get_output_type(paging: bool) -> OutputType { - if paging { - OutputType::pager().unwrap_or_else(|_| OutputType::stdout()) - } else { - OutputType::stdout() - } -} - fn run() -> Result<()> { let app = App::new(); @@ -243,7 +250,7 @@ fn run() -> Result<()> { return Ok(()); } - let mut output_type = get_output_type(config.paging); + let mut output_type = OutputType::from_mode(config.paging_mode); let handle = output_type.handle()?; let mut printer = Printer::new(handle, &config);