on 720a2fb help sign in
bat/src/output.rs
70 lines 1.9 kB history raw
1use std::env;
2use std::io::{self, Write};
3use std::process::{Child, Command, Stdio};
5use app::PagingMode;
6use errors::*;
8pub enum OutputType {
9 Pager(Child),
10 Stdout(io::Stdout),
13impl OutputType {
14 pub fn from_mode(mode: PagingMode) -> Self {
15 use self::PagingMode::*;
16 match mode {
17 Always => OutputType::try_pager(false),
18 QuitIfOneScreen => OutputType::try_pager(true),
19 _ => OutputType::stdout(),
20 }
21 }
23 /// Try to launch the pager. Fall back to stdout in case of errors.
24 fn try_pager(quit_if_one_screen: bool) -> Self {
25 let pager = env::var("BAT_PAGER")
26 .or_else(|_| env::var("PAGER"))
27 .unwrap_or(String::from("less"));
29 let mut process = if pager == "less" {
30 let mut args = vec!["--RAW-CONTROL-CHARS", "--no-init"];
31 if quit_if_one_screen {
32 args.push("--quit-if-one-screen");
33 }
35 let mut p = Command::new("less");
36 p.args(&args).env("LESSCHARSET", "UTF-8");
37 p
38 } else {
39 Command::new(pager)
40 };
42 process
43 .stdin(Stdio::piped())
44 .spawn()
45 .map(OutputType::Pager)
46 .unwrap_or_else(|_| OutputType::stdout())
47 }
49 fn stdout() -> Self {
50 OutputType::Stdout(io::stdout())
51 }
53 pub fn handle(&mut self) -> Result<&mut Write> {
54 Ok(match *self {
55 OutputType::Pager(ref mut command) => command
56 .stdin
57 .as_mut()
58 .chain_err(|| "Could not open stdin for pager")?,
59 OutputType::Stdout(ref mut handle) => handle,
60 })
61 }
64impl Drop for OutputType {
65 fn drop(&mut self) {
66 if let OutputType::Pager(ref mut command) = *self {
67 let _ = command.wait();
68 }
69 }