on master help sign in
Add less pager
commit418b3c5ea1b0673d061f29ce268a4ee6c07c5219 authorEzinwa Okpoechi <ezinwa.okpoechi@auto1.com> dateThu 3 May 2018, 18:12 (9 years ago) parent9dca312
2 files changed+57−9
.travis.yml+3−2 src/main.rs+54−7
.travis.yml+3−2
@@ -55,8 +55,9 @@ script:
5555 - cargo build --target $TARGET --verbose
5656 - cargo test --target $TARGET --verbose
5757 # Run 'bat' on its own source code and the README
58− - cargo run --target $TARGET -- src/main.rs
59− - cargo run --target $TARGET -- README.md
58+ # Piping to 'cat' forces the tty check to fail so that a pager is not used
59+ - cargo run --target $TARGET -- src/main.rs | cat
60+ - cargo run --target $TARGET -- README.md | cat
6061
6162before_deploy:
6263 - bash ci/before_deploy.bash
src/main.rs+54−7
@@ -22,9 +22,9 @@ mod terminal;
2222use std::collections::HashMap;
2323use std::env;
2424use std::fs::{self, File};
25−use std::io::{self, BufRead, BufReader, StdoutLock, Write};
25+use std::io::{self, BufRead, BufReader, Stdout, StdoutLock, Write};
2626use std::path::Path;
27−use std::process;
27+use std::process::{self, Command, Child, Stdio};
2828
2929use ansi_term::Colour::{Fixed, Green, Red, White, Yellow};
3030use ansi_term::Style;
@@ -65,6 +65,42 @@ struct Options<'a> {
6565 true_color: bool,
6666 style: OptionsStyle,
6767 language: Option<&'a str>,
68+ interactive_terminal: bool,
69+}
70+
71+enum OutputType<'a> {
72+ Pager(Child),
73+ Stdout(StdoutLock<'a>),
74+}
75+
76+impl<'a> OutputType<'a> {
77+ fn new_pager() -> Result<Self> {
78+ Ok(OutputType::Pager(Command::new("less")
79+ .args(&["--quit-if-one-screen", "--RAW-CONTROL-CHARS", "--no-init"])
80+ .stdin(Stdio::piped())
81+ .spawn()
82+ .chain_err(|| "Could not spawn pager")?
83+ ))
84+ }
85+
86+ fn new_stdout(stdout: &'a Stdout) -> Self {
87+ OutputType::Stdout(stdout.lock())
88+ }
89+
90+ fn stdout(&mut self) -> Result<&mut Write> {
91+ Ok(match *self {
92+ OutputType::Pager(ref mut command) => command.stdin.as_mut().chain_err(|| "Could not open stdin for pager")?,
93+ OutputType::Stdout(ref mut handle) => handle,
94+ })
95+ }
96+}
97+
98+impl<'a> Drop for OutputType<'a> {
99+ fn drop(&mut self) {
100+ if let OutputType::Pager(ref mut command) = *self {
101+ let _ = command.wait();
102+ }
103+ }
68104}
69105
70106#[derive(Copy, Clone, Debug)]
@@ -81,7 +117,7 @@ const PANEL_WIDTH: usize = 7;
81117const GRID_COLOR: u8 = 238;
82118
83119fn print_horizontal_line(
84− handle: &mut StdoutLock,
120+ handle: &mut Write,
85121 grid_char: char,
86122 term_width: usize,
87123) -> Result<()> {
@@ -112,7 +148,15 @@ fn print_file<P: AsRef<Path>>(
112148 let mut highlighter = HighlightLines::new(syntax, theme);
113149
114150 let stdout = io::stdout();
115− let mut handle = stdout.lock();
151+ let mut output_type= if options.interactive_terminal {
152+ match OutputType::new_pager() {
153+ Ok(pager) => pager,
154+ Err(_) => OutputType::new_stdout(&stdout),
155+ }
156+ } else {
157+ OutputType::new_stdout(&stdout)
158+ };
159+ let mut handle = output_type.stdout()?;
116160
117161 let term = Term::stdout();
118162 let (_, term_width) = term.size();
@@ -131,7 +175,7 @@ fn print_file<P: AsRef<Path>>(
131175 White.bold().paint(filename.as_ref().to_string_lossy())
132176 )?;
133177
134− print_horizontal_line(&mut handle, '┼', term_width)?;
178+ print_horizontal_line(handle, '┼', term_width)?;
135179 }
136180 OptionsStyle::Plain => {}
137181 };
@@ -179,7 +223,7 @@ fn print_file<P: AsRef<Path>>(
179223 // Show bars for all but plain style
180224 match options.style {
181225 OptionsStyle::LineNumbers | OptionsStyle::Full =>
182− print_horizontal_line(&mut handle, '┴', term_width)?,
226+ print_horizontal_line(handle, '┴', term_width)?,
183227 OptionsStyle::Plain => {}
184228 };
185229
@@ -370,7 +414,9 @@ impl HighlightingAssets {
370414}
371415
372416fn run() -> Result<()> {
373− let clap_color_setting = if atty::is(Stream::Stdout) {
417+ let interactive_terminal = atty::is(Stream::Stdout);
418+
419+ let clap_color_setting = if interactive_terminal {
374420 AppSettings::ColoredHelp
375421 } else {
376422 AppSettings::ColorNever
@@ -428,6 +474,7 @@ fn run() -> Result<()> {
428474 _ => OptionsStyle::Full,
429475 },
430476 language: app_matches.value_of("language"),
477+ interactive_terminal,
431478 };
432479
433480 let assets =