mirror of
https://github.com/sharkdp/bat.git
synced 2024-11-22 15:53:29 +01:00
Separate inputs from config
This commit is contained in:
parent
5e5cb89da6
commit
1dc328ad49
@ -4,14 +4,16 @@ use bat::{PrettyPrinter, StyleComponent, StyleComponents};
|
|||||||
use console::Term;
|
use console::Term;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
PrettyPrinter::new()
|
let mut printer = PrettyPrinter::new();
|
||||||
|
|
||||||
|
printer
|
||||||
.term_width(Term::stdout().size().1 as usize)
|
.term_width(Term::stdout().size().1 as usize)
|
||||||
.style_components(StyleComponents::new(&[
|
.style_components(StyleComponents::new(&[
|
||||||
StyleComponent::Header,
|
StyleComponent::Header,
|
||||||
StyleComponent::Grid,
|
StyleComponent::Grid,
|
||||||
StyleComponent::Numbers,
|
StyleComponent::Numbers,
|
||||||
]))
|
]))
|
||||||
.files(std::env::args_os().skip(1))
|
.files(std::env::args_os().skip(1));
|
||||||
.run()
|
|
||||||
.expect("no errors");
|
printer.run().expect("no errors");
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,9 @@ use std::ffi::OsStr;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let path_to_this_file = OsStr::new(file!());
|
let path_to_this_file = OsStr::new(file!());
|
||||||
|
|
||||||
PrettyPrinter::new()
|
let mut printer = PrettyPrinter::new();
|
||||||
.file(path_to_this_file)
|
|
||||||
.run()
|
printer.file(path_to_this_file);
|
||||||
.expect("no errors");
|
|
||||||
|
printer.run().expect("no errors");
|
||||||
}
|
}
|
||||||
|
@ -219,6 +219,7 @@ impl HighlightingAssets {
|
|||||||
.get_extension_syntax(&file_name)
|
.get_extension_syntax(&file_name)
|
||||||
.or(self.get_first_line_syntax(reader)),
|
.or(self.get_first_line_syntax(reader)),
|
||||||
(_, InputFile::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"),
|
(_, InputFile::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"),
|
||||||
|
(None, InputFile::FromReader(s, _)) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
|
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
|
||||||
|
@ -73,8 +73,7 @@ impl App {
|
|||||||
Ok(clap_app::build_app(interactive_output).get_matches_from(args))
|
Ok(clap_app::build_app(interactive_output).get_matches_from(args))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn config(&self) -> Result<Config> {
|
pub fn config(&self, inputs: &[InputFile]) -> Result<Config> {
|
||||||
let files = self.files()?;
|
|
||||||
let style_components = self.style_components()?;
|
let style_components = self.style_components()?;
|
||||||
|
|
||||||
let paging_mode = match self.matches.value_of("paging") {
|
let paging_mode = match self.matches.value_of("paging") {
|
||||||
@ -84,7 +83,13 @@ impl App {
|
|||||||
if self.matches.occurrences_of("plain") > 1 {
|
if self.matches.occurrences_of("plain") > 1 {
|
||||||
// If we have -pp as an option when in auto mode, the pager should be disabled.
|
// If we have -pp as an option when in auto mode, the pager should be disabled.
|
||||||
PagingMode::Never
|
PagingMode::Never
|
||||||
} else if files.contains(&InputFile::StdIn(None)) {
|
} else if inputs.iter().any(|f| {
|
||||||
|
if let InputFile::StdIn(None) = f {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}) {
|
||||||
// If we are reading from stdin, only enable paging if we write to an
|
// 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
|
// interactive terminal and if we do not *read* from an interactive
|
||||||
// terminal.
|
// terminal.
|
||||||
@ -170,7 +175,6 @@ impl App {
|
|||||||
loop_through: !(self.interactive_output
|
loop_through: !(self.interactive_output
|
||||||
|| self.matches.value_of("color") == Some("always")
|
|| self.matches.value_of("color") == Some("always")
|
||||||
|| self.matches.value_of("decorations") == Some("always")),
|
|| self.matches.value_of("decorations") == Some("always")),
|
||||||
files,
|
|
||||||
tab_width: self
|
tab_width: self
|
||||||
.matches
|
.matches
|
||||||
.value_of("tabs")
|
.value_of("tabs")
|
||||||
@ -222,7 +226,7 @@ impl App {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn files(&self) -> Result<Vec<InputFile>> {
|
pub fn inputs(&self) -> Result<Vec<InputFile>> {
|
||||||
// verify equal length of file-names and input FILEs
|
// verify equal length of file-names and input FILEs
|
||||||
match self.matches.values_of("file-name") {
|
match self.matches.values_of("file-name") {
|
||||||
Some(ref filenames)
|
Some(ref filenames)
|
||||||
|
@ -120,7 +120,6 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
|
|||||||
let mut config = cfg.clone();
|
let mut config = cfg.clone();
|
||||||
let mut style = HashSet::new();
|
let mut style = HashSet::new();
|
||||||
style.insert(StyleComponent::Plain);
|
style.insert(StyleComponent::Plain);
|
||||||
config.files = vec![InputFile::ThemePreviewFile];
|
|
||||||
config.style_components = StyleComponents(style);
|
config.style_components = StyleComponents(style);
|
||||||
|
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
@ -134,7 +133,9 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
|
|||||||
Style::new().bold().paint(theme.to_string())
|
Style::new().bold().paint(theme.to_string())
|
||||||
)?;
|
)?;
|
||||||
config.theme = theme.to_string();
|
config.theme = theme.to_string();
|
||||||
let _controller = Controller::new(&config, &assets).run();
|
Controller::new(&config, &assets)
|
||||||
|
.run(vec![InputFile::ThemePreviewFile])
|
||||||
|
.ok();
|
||||||
writeln!(stdout)?;
|
writeln!(stdout)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -146,10 +147,10 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_controller(config: &Config) -> Result<bool> {
|
fn run_controller(inputs: Vec<InputFile>, config: &Config) -> Result<bool> {
|
||||||
let assets = assets_from_cache_or_binary()?;
|
let assets = assets_from_cache_or_binary()?;
|
||||||
let controller = Controller::new(&config, &assets);
|
let controller = Controller::new(&config, &assets);
|
||||||
controller.run()
|
controller.run(inputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and
|
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and
|
||||||
@ -166,16 +167,17 @@ fn run() -> Result<bool> {
|
|||||||
run_cache_subcommand(cache_matches)?;
|
run_cache_subcommand(cache_matches)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
let mut config = app.config()?;
|
let inputs = vec![InputFile::Ordinary(OrdinaryFile::from_path(OsStr::new(
|
||||||
config.files = vec![InputFile::Ordinary(OrdinaryFile::from_path(OsStr::new(
|
|
||||||
"cache",
|
"cache",
|
||||||
)))];
|
)))];
|
||||||
|
let mut config = app.config(&inputs)?;
|
||||||
|
|
||||||
run_controller(&config)
|
run_controller(inputs, &config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let config = app.config()?;
|
let inputs = app.inputs()?;
|
||||||
|
let config = app.config(&inputs)?;
|
||||||
|
|
||||||
if app.matches.is_present("list-languages") {
|
if app.matches.is_present("list-languages") {
|
||||||
list_languages(&config)?;
|
list_languages(&config)?;
|
||||||
@ -196,7 +198,7 @@ fn run() -> Result<bool> {
|
|||||||
writeln!(io::stdout(), "{}", cache_dir())?;
|
writeln!(io::stdout(), "{}", cache_dir())?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
run_controller(&config)
|
run_controller(inputs, &config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,6 @@ impl Default for PagingMode {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Config<'a> {
|
pub struct Config<'a> {
|
||||||
/// List of files to print
|
|
||||||
pub files: Vec<InputFile>,
|
|
||||||
|
|
||||||
/// The explicitly configured language, if any
|
/// The explicitly configured language, if any
|
||||||
pub language: Option<&'a str>,
|
pub language: Option<&'a str>,
|
||||||
|
|
||||||
|
@ -20,11 +20,15 @@ impl<'b> Controller<'b> {
|
|||||||
Controller { config, assets }
|
Controller { config, assets }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self) -> Result<bool> {
|
pub fn run(&self, inputs: Vec<InputFile>) -> Result<bool> {
|
||||||
self.run_with_error_handler(default_error_handler)
|
self.run_with_error_handler(inputs, default_error_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_with_error_handler(&self, handle_error: impl Fn(&Error)) -> Result<bool> {
|
pub fn run_with_error_handler(
|
||||||
|
&self,
|
||||||
|
inputs: Vec<InputFile>,
|
||||||
|
handle_error: impl Fn(&Error),
|
||||||
|
) -> Result<bool> {
|
||||||
let mut output_type;
|
let mut output_type;
|
||||||
|
|
||||||
#[cfg(feature = "paging")]
|
#[cfg(feature = "paging")]
|
||||||
@ -34,7 +38,7 @@ impl<'b> Controller<'b> {
|
|||||||
// Do not launch the pager if NONE of the input files exist
|
// Do not launch the pager if NONE of the input files exist
|
||||||
let mut paging_mode = self.config.paging_mode;
|
let mut paging_mode = self.config.paging_mode;
|
||||||
if self.config.paging_mode != PagingMode::Never {
|
if self.config.paging_mode != PagingMode::Never {
|
||||||
let call_pager = self.config.files.iter().any(|file| {
|
let call_pager = inputs.iter().any(|file| {
|
||||||
if let InputFile::Ordinary(ofile) = file {
|
if let InputFile::Ordinary(ofile) = file {
|
||||||
return Path::new(ofile.provided_path()).exists();
|
return Path::new(ofile.provided_path()).exists();
|
||||||
} else {
|
} else {
|
||||||
@ -56,7 +60,7 @@ impl<'b> Controller<'b> {
|
|||||||
let writer = output_type.handle()?;
|
let writer = output_type.handle()?;
|
||||||
let mut no_errors: bool = true;
|
let mut no_errors: bool = true;
|
||||||
|
|
||||||
for input_file in self.config.files.iter() {
|
for input_file in inputs.into_iter() {
|
||||||
match input_file.get_reader(io::stdin().lock()) {
|
match input_file.get_reader(io::stdin().lock()) {
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
handle_error(&error);
|
handle_error(&error);
|
||||||
@ -65,15 +69,15 @@ impl<'b> Controller<'b> {
|
|||||||
Ok(mut reader) => {
|
Ok(mut reader) => {
|
||||||
let result = if self.config.loop_through {
|
let result = if self.config.loop_through {
|
||||||
let mut printer = SimplePrinter::new();
|
let mut printer = SimplePrinter::new();
|
||||||
self.print_file(reader, &mut printer, writer, input_file)
|
self.print_file(reader, &mut printer, writer, &input_file)
|
||||||
} else {
|
} else {
|
||||||
let mut printer = InteractivePrinter::new(
|
let mut printer = InteractivePrinter::new(
|
||||||
&self.config,
|
&self.config,
|
||||||
&self.assets,
|
&self.assets,
|
||||||
input_file,
|
&input_file,
|
||||||
&mut reader,
|
&mut reader,
|
||||||
);
|
);
|
||||||
self.print_file(reader, &mut printer, writer, input_file)
|
self.print_file(reader, &mut printer, writer, &input_file)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(error) = result {
|
if let Err(error) = result {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, BufRead, BufReader};
|
use std::io::{self, BufRead, BufReader, Read};
|
||||||
|
|
||||||
use content_inspector::{self, ContentType};
|
use content_inspector::{self, ContentType};
|
||||||
|
|
||||||
@ -77,10 +77,10 @@ impl OrdinaryFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum InputFile {
|
pub enum InputFile {
|
||||||
StdIn(Option<OsString>),
|
StdIn(Option<OsString>),
|
||||||
Ordinary(OrdinaryFile),
|
Ordinary(OrdinaryFile),
|
||||||
|
FromReader(Box<dyn Read>, Option<OsString>),
|
||||||
ThemePreviewFile,
|
ThemePreviewFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +101,7 @@ impl InputFile {
|
|||||||
Ok(InputFileReader::new(BufReader::new(file)))
|
Ok(InputFileReader::new(BufReader::new(file)))
|
||||||
}
|
}
|
||||||
InputFile::ThemePreviewFile => Ok(InputFileReader::new(THEME_PREVIEW_FILE)),
|
InputFile::ThemePreviewFile => Ok(InputFileReader::new(THEME_PREVIEW_FILE)),
|
||||||
|
InputFile::FromReader(reader, _) => unimplemented!(), //Ok(InputFileReader::new(BufReader::new(reader))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ use crate::{
|
|||||||
use crate::config::PagingMode;
|
use crate::config::PagingMode;
|
||||||
|
|
||||||
pub struct PrettyPrinter<'a> {
|
pub struct PrettyPrinter<'a> {
|
||||||
|
inputs: Vec<InputFile>,
|
||||||
config: Config<'a>,
|
config: Config<'a>,
|
||||||
assets: HighlightingAssets,
|
assets: HighlightingAssets,
|
||||||
}
|
}
|
||||||
@ -25,6 +26,7 @@ impl<'a> PrettyPrinter<'a> {
|
|||||||
config.true_color = true;
|
config.true_color = true;
|
||||||
|
|
||||||
PrettyPrinter {
|
PrettyPrinter {
|
||||||
|
inputs: vec![],
|
||||||
config,
|
config,
|
||||||
assets: HighlightingAssets::from_binary(),
|
assets: HighlightingAssets::from_binary(),
|
||||||
}
|
}
|
||||||
@ -32,8 +34,7 @@ impl<'a> PrettyPrinter<'a> {
|
|||||||
|
|
||||||
/// Add a file which should be pretty-printed
|
/// Add a file which should be pretty-printed
|
||||||
pub fn file(&mut self, path: &OsStr) -> &mut Self {
|
pub fn file(&mut self, path: &OsStr) -> &mut Self {
|
||||||
self.config
|
self.inputs
|
||||||
.files
|
|
||||||
.push(InputFile::Ordinary(OrdinaryFile::from_path(path)));
|
.push(InputFile::Ordinary(OrdinaryFile::from_path(path)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -45,8 +46,7 @@ impl<'a> PrettyPrinter<'a> {
|
|||||||
P: AsRef<OsStr>,
|
P: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
for path in paths {
|
for path in paths {
|
||||||
self.config
|
self.inputs
|
||||||
.files
|
|
||||||
.push(InputFile::Ordinary(OrdinaryFile::from_path(path.as_ref())));
|
.push(InputFile::Ordinary(OrdinaryFile::from_path(path.as_ref())));
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
@ -137,8 +137,8 @@ impl<'a> PrettyPrinter<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&'a self) -> Result<bool> {
|
pub fn run(self) -> Result<bool> {
|
||||||
let controller = Controller::new(&self.config, &self.assets);
|
let controller = Controller::new(&self.config, &self.assets);
|
||||||
controller.run()
|
controller.run(self.inputs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
|||||||
),
|
),
|
||||||
InputFile::StdIn(None) => "STDIN".to_owned(),
|
InputFile::StdIn(None) => "STDIN".to_owned(),
|
||||||
InputFile::ThemePreviewFile => "".to_owned(),
|
InputFile::ThemePreviewFile => "".to_owned(),
|
||||||
|
InputFile::FromReader(_, Some(name)) => {
|
||||||
|
format!("file '{}'", name.to_string_lossy())
|
||||||
|
}
|
||||||
|
InputFile::FromReader(_, None) => "READER".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
@ -286,6 +290,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
|||||||
}
|
}
|
||||||
InputFile::StdIn(None) => ("File: ", Cow::from("STDIN".to_owned())),
|
InputFile::StdIn(None) => ("File: ", Cow::from("STDIN".to_owned())),
|
||||||
InputFile::ThemePreviewFile => ("", Cow::from("")),
|
InputFile::ThemePreviewFile => ("", Cow::from("")),
|
||||||
|
InputFile::FromReader(_, Some(name)) => {
|
||||||
|
("File: ", Cow::from(name.to_string_lossy().to_owned()))
|
||||||
|
}
|
||||||
|
InputFile::FromReader(_, None) => ("File: ", Cow::from("READER".to_owned())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mode = match self.content_type {
|
let mode = match self.content_type {
|
||||||
|
Loading…
Reference in New Issue
Block a user