on master help sign in
Separate inputs from config
commit1dc328ad495edbd98bff9e89a059d1e66f9780ef authorsharkdp <davidpeter@web.de> dateTue 21 Apr 2020, 21:14 (7 years ago) parent5e5cb89
10 files changed+61−41
examples/cat.rs+6−4 examples/simple.rs+5−4 src/assets.rs+1 src/bin/bat/app.rs+9−5 src/bin/bat/main.rs+11−9 src/config.rs−3 src/controller.rs+12−8 src/inputfile.rs+3−2 src/pretty_printer.rs+6−6 src/printer.rs+8
examples/cat.rs+6−4
@@ -4,14 +4,16 @@ use bat::{PrettyPrinter, StyleComponent, StyleComponents};
44use console::Term;
55
66fn main() {
7− PrettyPrinter::new()
7+ let mut printer = PrettyPrinter::new();
8+
9+ printer
810 .term_width(Term::stdout().size().1 as usize)
911 .style_components(StyleComponents::new(&[
1012 StyleComponent::Header,
1113 StyleComponent::Grid,
1214 StyleComponent::Numbers,
1315 ]))
14− .files(std::env::args_os().skip(1))
15− .run()
16− .expect("no errors");
16+ .files(std::env::args_os().skip(1));
17+
18+ printer.run().expect("no errors");
1719}
examples/simple.rs+5−4
@@ -5,8 +5,9 @@ use std::ffi::OsStr;
55fn main() {
66 let path_to_this_file = OsStr::new(file!());
77
8− PrettyPrinter::new()
9− .file(path_to_this_file)
10− .run()
11− .expect("no errors");
8+ let mut printer = PrettyPrinter::new();
9+
10+ printer.file(path_to_this_file);
11+
12+ printer.run().expect("no errors");
1213}
src/assets.rs+1
@@ -219,6 +219,7 @@ impl HighlightingAssets {
219219 .get_extension_syntax(&file_name)
220220 .or(self.get_first_line_syntax(reader)),
221221 (_, InputFile::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"),
222+ (None, InputFile::FromReader(s, _)) => None,
222223 };
223224
224225 syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
src/bin/bat/app.rs+9−5
@@ -73,8 +73,7 @@ impl App {
7373 Ok(clap_app::build_app(interactive_output).get_matches_from(args))
7474 }
7575
76− pub fn config(&self) -> Result<Config> {
77− let files = self.files()?;
76+ pub fn config(&self, inputs: &[InputFile]) -> Result<Config> {
7877 let style_components = self.style_components()?;
7978
8079 let paging_mode = match self.matches.value_of("paging") {
@@ -84,7 +83,13 @@ impl App {
8483 if self.matches.occurrences_of("plain") > 1 {
8584 // If we have -pp as an option when in auto mode, the pager should be disabled.
8685 PagingMode::Never
87− } else if files.contains(&InputFile::StdIn(None)) {
86+ } else if inputs.iter().any(|f| {
87+ if let InputFile::StdIn(None) = f {
88+ true
89+ } else {
90+ false
91+ }
92+ }) {
8893 // If we are reading from stdin, only enable paging if we write to an
8994 // interactive terminal and if we do not *read* from an interactive
9095 // terminal.
@@ -170,7 +175,6 @@ impl App {
170175 loop_through: !(self.interactive_output
171176 || self.matches.value_of("color") == Some("always")
172177 || self.matches.value_of("decorations") == Some("always")),
173− files,
174178 tab_width: self
175179 .matches
176180 .value_of("tabs")
@@ -222,7 +226,7 @@ impl App {
222226 })
223227 }
224228
225− fn files(&self) -> Result<Vec<InputFile>> {
229+ pub fn inputs(&self) -> Result<Vec<InputFile>> {
226230 // verify equal length of file-names and input FILEs
227231 match self.matches.values_of("file-name") {
228232 Some(ref filenames)
src/bin/bat/main.rs+11−9
@@ -120,7 +120,6 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
120120 let mut config = cfg.clone();
121121 let mut style = HashSet::new();
122122 style.insert(StyleComponent::Plain);
123− config.files = vec![InputFile::ThemePreviewFile];
124123 config.style_components = StyleComponents(style);
125124
126125 let stdout = io::stdout();
@@ -134,7 +133,9 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
134133 Style::new().bold().paint(theme.to_string())
135134 )?;
136135 config.theme = theme.to_string();
137− let _controller = Controller::new(&config, &assets).run();
136+ Controller::new(&config, &assets)
137+ .run(vec![InputFile::ThemePreviewFile])
138+ .ok();
138139 writeln!(stdout)?;
139140 }
140141 } else {
@@ -146,10 +147,10 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
146147 Ok(())
147148}
148149
149−fn run_controller(config: &Config) -> Result<bool> {
150+fn run_controller(inputs: Vec<InputFile>, config: &Config) -> Result<bool> {
150151 let assets = assets_from_cache_or_binary()?;
151152 let controller = Controller::new(&config, &assets);
152− controller.run()
153+ controller.run(inputs)
153154}
154155
155156/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and
@@ -166,16 +167,17 @@ fn run() -> Result<bool> {
166167 run_cache_subcommand(cache_matches)?;
167168 Ok(true)
168169 } else {
169− let mut config = app.config()?;
170− config.files = vec![InputFile::Ordinary(OrdinaryFile::from_path(OsStr::new(
170+ let inputs = vec![InputFile::Ordinary(OrdinaryFile::from_path(OsStr::new(
171171 "cache",
172172 )))];
173+ let mut config = app.config(&inputs)?;
173174
174− run_controller(&config)
175+ run_controller(inputs, &config)
175176 }
176177 }
177178 _ => {
178− let config = app.config()?;
179+ let inputs = app.inputs()?;
180+ let config = app.config(&inputs)?;
179181
180182 if app.matches.is_present("list-languages") {
181183 list_languages(&config)?;
@@ -196,7 +198,7 @@ fn run() -> Result<bool> {
196198 writeln!(io::stdout(), "{}", cache_dir())?;
197199 Ok(true)
198200 } else {
199− run_controller(&config)
201+ run_controller(inputs, &config)
200202 }
201203 }
202204 }
src/config.rs−3
@@ -22,9 +22,6 @@ impl Default for PagingMode {
2222
2323#[derive(Debug, Clone, Default)]
2424pub struct Config<'a> {
25− /// List of files to print
26− pub files: Vec<InputFile>,
27−
2825 /// The explicitly configured language, if any
2926 pub language: Option<&'a str>,
3027
src/controller.rs+12−8
@@ -20,11 +20,15 @@ impl<'b> Controller<'b> {
2020 Controller { config, assets }
2121 }
2222
23− pub fn run(&self) -> Result<bool> {
24− self.run_with_error_handler(default_error_handler)
23+ pub fn run(&self, inputs: Vec<InputFile>) -> Result<bool> {
24+ self.run_with_error_handler(inputs, default_error_handler)
2525 }
2626
27− pub fn run_with_error_handler(&self, handle_error: impl Fn(&Error)) -> Result<bool> {
27+ pub fn run_with_error_handler(
28+ &self,
29+ inputs: Vec<InputFile>,
30+ handle_error: impl Fn(&Error),
31+ ) -> Result<bool> {
2832 let mut output_type;
2933
3034 #[cfg(feature = "paging")]
@@ -34,7 +38,7 @@ impl<'b> Controller<'b> {
3438 // Do not launch the pager if NONE of the input files exist
3539 let mut paging_mode = self.config.paging_mode;
3640 if self.config.paging_mode != PagingMode::Never {
37− let call_pager = self.config.files.iter().any(|file| {
41+ let call_pager = inputs.iter().any(|file| {
3842 if let InputFile::Ordinary(ofile) = file {
3943 return Path::new(ofile.provided_path()).exists();
4044 } else {
@@ -56,7 +60,7 @@ impl<'b> Controller<'b> {
5660 let writer = output_type.handle()?;
5761 let mut no_errors: bool = true;
5862
59− for input_file in self.config.files.iter() {
63+ for input_file in inputs.into_iter() {
6064 match input_file.get_reader(io::stdin().lock()) {
6165 Err(error) => {
6266 handle_error(&error);
@@ -65,15 +69,15 @@ impl<'b> Controller<'b> {
6569 Ok(mut reader) => {
6670 let result = if self.config.loop_through {
6771 let mut printer = SimplePrinter::new();
68− self.print_file(reader, &mut printer, writer, input_file)
72+ self.print_file(reader, &mut printer, writer, &input_file)
6973 } else {
7074 let mut printer = InteractivePrinter::new(
7175 &self.config,
7276 &self.assets,
73− input_file,
77+ &input_file,
7478 &mut reader,
7579 );
76− self.print_file(reader, &mut printer, writer, input_file)
80+ self.print_file(reader, &mut printer, writer, &input_file)
7781 };
7882
7983 if let Err(error) = result {
src/inputfile.rs+3−2
@@ -1,6 +1,6 @@
11use std::ffi::{OsStr, OsString};
22use std::fs::File;
3−use std::io::{self, BufRead, BufReader};
3+use std::io::{self, BufRead, BufReader, Read};
44
55use content_inspector::{self, ContentType};
66
@@ -77,10 +77,10 @@ impl OrdinaryFile {
7777 }
7878}
7979
80−#[derive(Debug, Clone, PartialEq)]
8180pub enum InputFile {
8281 StdIn(Option<OsString>),
8382 Ordinary(OrdinaryFile),
83+ FromReader(Box<dyn Read>, Option<OsString>),
8484 ThemePreviewFile,
8585}
8686
@@ -101,6 +101,7 @@ impl InputFile {
101101 Ok(InputFileReader::new(BufReader::new(file)))
102102 }
103103 InputFile::ThemePreviewFile => Ok(InputFileReader::new(THEME_PREVIEW_FILE)),
104+ InputFile::FromReader(reader, _) => unimplemented!(), //Ok(InputFileReader::new(BufReader::new(reader))),
104105 }
105106 }
106107}
src/pretty_printer.rs+6−6
@@ -13,6 +13,7 @@ use crate::{
1313use crate::config::PagingMode;
1414
1515pub struct PrettyPrinter<'a> {
16+ inputs: Vec<InputFile>,
1617 config: Config<'a>,
1718 assets: HighlightingAssets,
1819}
@@ -25,6 +26,7 @@ impl<'a> PrettyPrinter<'a> {
2526 config.true_color = true;
2627
2728 PrettyPrinter {
29+ inputs: vec![],
2830 config,
2931 assets: HighlightingAssets::from_binary(),
3032 }
@@ -32,8 +34,7 @@ impl<'a> PrettyPrinter<'a> {
3234
3335 /// Add a file which should be pretty-printed
3436 pub fn file(&mut self, path: &OsStr) -> &mut Self {
35− self.config
36− .files
37+ self.inputs
3738 .push(InputFile::Ordinary(OrdinaryFile::from_path(path)));
3839 self
3940 }
@@ -45,8 +46,7 @@ impl<'a> PrettyPrinter<'a> {
4546 P: AsRef<OsStr>,
4647 {
4748 for path in paths {
48− self.config
49− .files
49+ self.inputs
5050 .push(InputFile::Ordinary(OrdinaryFile::from_path(path.as_ref())));
5151 }
5252 self
@@ -137,8 +137,8 @@ impl<'a> PrettyPrinter<'a> {
137137 self
138138 }
139139
140− pub fn run(&'a self) -> Result<bool> {
140+ pub fn run(self) -> Result<bool> {
141141 let controller = Controller::new(&self.config, &self.assets);
142− controller.run()
142+ controller.run(self.inputs)
143143 }
144144}
src/printer.rs+8
@@ -243,6 +243,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
243243 ),
244244 InputFile::StdIn(None) => "STDIN".to_owned(),
245245 InputFile::ThemePreviewFile => "".to_owned(),
246+ InputFile::FromReader(_, Some(name)) => {
247+ format!("file '{}'", name.to_string_lossy())
248+ }
249+ InputFile::FromReader(_, None) => "READER".to_owned(),
246250 };
247251
248252 writeln!(
@@ -286,6 +290,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
286290 }
287291 InputFile::StdIn(None) => ("File: ", Cow::from("STDIN".to_owned())),
288292 InputFile::ThemePreviewFile => ("", Cow::from("")),
293+ InputFile::FromReader(_, Some(name)) => {
294+ ("File: ", Cow::from(name.to_string_lossy().to_owned()))
295+ }
296+ InputFile::FromReader(_, None) => ("File: ", Cow::from("READER".to_owned())),
289297 };
290298
291299 let mode = match self.content_type {