summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsharkdp <davidpeter@web.de>2020-04-22 16:27:34 +0200
committerDavid Peter <sharkdp@users.noreply.github.com>2020-04-22 23:55:28 +0200
commit590960f7f5b5454c2da8c36409a8d57a58b2980c (patch)
tree6394f2be335932de3fac3db9f9b197646b825375
parentb4d54106fefebd2a3d41323084eea8c1a199489e (diff)
Completely refactor 'input' module
-rw-r--r--src/assets.rs86
-rw-r--r--src/bin/bat/app.rs37
-rw-r--r--src/bin/bat/main.rs9
-rw-r--r--src/config.rs2
-rw-r--r--src/controller.rs52
-rw-r--r--src/input.rs195
-rw-r--r--src/lib.rs2
-rw-r--r--src/pretty_printer.rs14
-rw-r--r--src/printer.rs36
9 files changed, 233 insertions, 200 deletions
diff --git a/src/assets.rs b/src/assets.rs
index f6b10b3a..6e3190a0 100644
--- a/src/assets.rs
+++ b/src/assets.rs
@@ -10,7 +10,7 @@ use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
use crate::assets_metadata::AssetsMetadata;
use crate::errors::*;
-use crate::input::{Input, InputReader};
+use crate::input::{Input, InputKind, InputReader, OpenedInput, OpenedInputKind};
use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
#[derive(Debug)]
@@ -188,38 +188,46 @@ impl HighlightingAssets {
pub(crate) fn get_syntax(
&self,
language: Option<&str>,
- input: &Input,
- reader: &mut InputReader,
+ input: &mut OpenedInput,
mapping: &SyntaxMapping,
) -> &SyntaxReference {
- let syntax = match (language, input) {
- (Some(language), _) => self.syntax_set.find_syntax_by_token(language),
- (None, Input::Ordinary(ofile)) => {
- let path = Path::new(ofile.provided_path());
- let line_syntax = self.get_first_line_syntax(reader);
-
- let absolute_path = path.canonicalize().ok().unwrap_or(path.to_owned());
- match mapping.get_syntax_for(absolute_path) {
- Some(MappingTarget::MapTo(syntax_name)) => {
- // TODO: we should probably return an error here if this syntax can not be
- // found. Currently, we just fall back to 'plain'.
- self.syntax_set.find_syntax_by_name(syntax_name)
+ let syntax = if let Some(language) = language {
+ self.syntax_set.find_syntax_by_token(language)
+ } else {
+ match input.kind {
+ OpenedInputKind::OrdinaryFile(ref actual_path) => {
+ let path_str = input
+ .metadata
+ .user_provided_name
+ .as_ref()
+ .unwrap_or(actual_path);
+ let path = Path::new(path_str);
+ let line_syntax = self.get_first_line_syntax(&mut input.reader);
+
+ let absolute_path = path.canonicalize().ok().unwrap_or(path.to_owned());
+ match mapping.get_syntax_for(absolute_path) {
+ Some(MappingTarget::MapTo(syntax_name)) => {
+ // TODO: we should probably return an error here if this syntax can not be
+ // found. Currently, we just fall back to 'plain'.
+ self.syntax_set.find_syntax_by_name(syntax_name)
+ }
+ Some(MappingTarget::MapToUnknown) => line_syntax,
+ None => {
+ let file_name = path.file_name().unwrap_or_default();
+ self.get_extension_syntax(file_name).or(line_syntax)
+ }
}
- Some(MappingTarget::MapToUnknown) => line_syntax,
- None => {
- let file_name = path.file_name().unwrap_or_default();
- self.get_extension_syntax(file_name).or(line_syntax)
+ }
+ OpenedInputKind::StdIn | OpenedInputKind::CustomReader => {
+ if let Some(ref name) = input.metadata.user_provided_name {
+ self.get_extension_syntax(&name)
+ .or(self.get_first_line_syntax(&mut input.reader))
+ } else {
+ self.get_first_line_syntax(&mut input.reader)
}
}
+ OpenedInputKind::ThemePreviewFile => self.syntax_set.find_syntax_by_name("Rust"),
}
- (None, Input::StdIn(None)) => String::from_utf8(reader.first_line.clone())
- .ok()
- .and_then(|l| self.syntax_set.find_syntax_by_first_line(&l)),
- (None, Input::StdIn(Some(file_name))) => self
- .get_extension_syntax(&file_name)
- .or(self.get_first_line_syntax(reader)),
- (_, Input::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"),
- (None, Input::FromReader(_, _)) => unimplemented!(),
};
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
@@ -249,8 +257,6 @@ impl HighlightingAssets {
mod tests {
use super::*;
- use crate::input::OrdinaryFile;
-
use std::ffi::{OsStr, OsString};
use std::fs::File;
use std::io;
@@ -281,12 +287,12 @@ mod tests {
writeln!(temp_file, "{}", first_line).unwrap();
}
- let input = Input::Ordinary(OrdinaryFile::from_path(file_path.as_os_str()));
- let stdin = io::stdin();
- let mut reader = input.get_reader(stdin.lock()).unwrap();
+ let input: Input = Input::ordinary_file(file_path.as_os_str());
+ let dummy_stdin: &[u8] = &[];
+ let mut opened_input = input.open(dummy_stdin).unwrap();
let syntax = self
.assets
- .get_syntax(None, &input, &mut reader, &self.syntax_mapping);
+ .get_syntax(None, &mut opened_input, &self.syntax_mapping);
syntax.name.clone()
}
@@ -304,13 +310,13 @@ mod tests {
}
fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String {
- let input = Input::StdIn(Some(OsString::from(file_name)));
- let syntax = self.assets.get_syntax(
- None,
- &input,
- &mut input.get_reader(content).unwrap(),
- &self.syntax_mapping,
- );
+ let mut input = Input::stdin();
+ input.set_provided_name(Some(OsStr::new(file_name)));
+ let mut opened_input = input.open(content).unwrap();
+
+ let syntax = self
+ .assets
+ .get_syntax(None, &mut opened_input, &self.syntax_mapping);
syntax.name.clone()
}
}
diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs
index 569e7b47..b5e8f28e 100644
--- a/src/bin/bat/app.rs
+++ b/src/bin/bat/app.rs
@@ -15,10 +15,11 @@ use console::Term;
use bat::{
config::{
- Config, HighlightedLineRanges, Input, LineRange, LineRanges, MappingTarget, OrdinaryFile,
- PagingMode, StyleComponent, StyleComponents, SyntaxMapping, WrappingMode,
+ Config, HighlightedLineRanges, LineRange, LineRanges, MappingTarget, PagingMode,
+ StyleComponent, StyleComponents, SyntaxMapping, WrappingMode,
},
errors::*,
+ input::Input,
HighlightingAssets,
};
@@ -83,13 +84,7 @@ impl App {
if self.matches.occurrences_of("plain") > 1 {
// If we have -pp as an option when in auto mode, the pager should be disabled.
PagingMode::Never
- } else if inputs.iter().any(|f| {
- if let Input::StdIn(None) = f {
- true
- } else {
- false
- }
- }) {
+ } else if inputs.iter().any(Input::is_stdin) {
// 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.
@@ -251,9 +246,9 @@ impl App {
let files: Option<Vec<&OsStr>> = self.matches.values_of_os("FILE").map(|vs| vs.collect());
if files.is_none() {
- return Ok(vec![Input::StdIn(
- filenames_or_none.nth(0).unwrap().map(|f| f.to_owned()),
- )]);
+ let mut input = Input::stdin();
+ input.set_provided_name(filenames_or_none.nth(0).unwrap_or(None));
+ return Ok(vec![input]);
}
let files_or_none: Box<dyn Iterator<Item = _>> = match files {
Some(ref files) => Box::new(files.into_iter().map(|name| Some(*name))),
@@ -261,16 +256,16 @@ impl App {
};
let mut file_input = Vec::new();
- for (input, name) in files_or_none.zip(filenames_or_none) {
- if let Some(input) = input {
- if input.to_str().unwrap_or_default() == "-" {
- file_input.push(Input::StdIn(name.map(|n| n.to_owned())));
+ for (filepath, provided_name) in files_or_none.zip(filenames_or_none) {
+ if let Some(filepath) = filepath {
+ if filepath.to_str().unwrap_or_default() == "-" {
+ let mut input = Input::stdin();
+ input.set_provided_name(provided_name);
+ file_input.push(input);
} else {
- let mut ofile = OrdinaryFile::from_path(input);
- if let Some(path) = name {
- ofile.set_provided_path(path);
- }
- file_input.push(Input::Ordinary(ofile))
+ let mut input = Input::ordinary_file(filepath);
+ input.set_provided_name(provided_name);
+ file_input.push(input);
}
}
}
diff --git a/src/bin/bat/main.rs b/src/bin/bat/main.rs
index 924461d8..3d8b3ff7 100644
--- a/src/bin/bat/main.rs
+++ b/src/bin/bat/main.rs
@@ -26,8 +26,9 @@ use clap::crate_version;
use directories::PROJECT_DIRS;
use bat::{
- config::{Config, Input, OrdinaryFile, StyleComponent, StyleComponents},
+ config::{Config, StyleComponent, StyleComponents},
errors::*,
+ input::Input,
Controller, HighlightingAssets,
};
@@ -134,7 +135,7 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
)?;
config.theme = theme.to_string();
Controller::new(&config, &assets)
- .run(vec![Input::ThemePreviewFile])
+ .run(vec![Input::theme_preview_file()])
.ok();
writeln!(stdout)?;
}
@@ -167,9 +168,7 @@ fn run() -> Result<bool> {
run_cache_subcommand(cache_matches)?;
Ok(true)
} else {
- let inputs = vec![Input::Ordinary(OrdinaryFile::from_path(OsStr::new(
- "cache",
- )))];
+ let inputs = vec![Input::ordinary_file(OsStr::new("cache"))];
let config = app.config(&inputs)?;
run_controller(inputs, &config)
diff --git a/src/config.rs b/src/config.rs
index 960ac63e..d708fad4 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,5 +1,3 @@
-pub use crate::input::Input;
-pub use crate::input::OrdinaryFile;
pub use crate::line_range::{HighlightedLineRanges, LineRange, LineRanges};
pub use crate::style::{StyleComponent, StyleComponents};
pub use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
diff --git a/src/controller.rs b/src/controller.rs
index 8d6b7fe0..bc37330d 100644
--- a/src/controller.rs
+++ b/src/controller.rs
@@ -5,7 +5,7 @@ use crate::config::Config;
#[cfg(feature = "paging")]
use crate::config::PagingMode;
use crate::errors::*;
-use crate::input::{Input, InputDescription, InputReader};
+use crate::input::{Input, InputDescription, InputKind, InputReader, OpenedInput};
use crate::line_range::{LineRanges, RangeCheckResult};
use crate::output::OutputType;
use crate::printer::{InteractivePrinter, Printer, SimplePrinter};
@@ -38,9 +38,9 @@ impl<'b> Controller<'b> {
// Do not launch the pager if NONE of the input files exist
let mut paging_mode = self.config.paging_mode;
if self.config.paging_mode != PagingMode::Never {
- let call_pager = inputs.iter().any(|file| {
- if let Input::Ordinary(ofile) = file {
- return Path::new(ofile.provided_path()).exists();
+ let call_pager = inputs.iter().any(|ref input| {
+ if let InputKind::OrdinaryFile(ref path) = input.kind {
+ return Path::new(path).exists();
} else {
return true;
}
@@ -61,27 +61,24 @@ impl<'b> Controller<'b> {
let mut no_errors: bool = true;
for input in inputs.into_iter() {
- let description = input.description();
-
- match input.get_reader(io::stdin().lock()) {
+ match input.open(io::stdin().lock()) {
Err(error) => {
handle_error(&error);
no_errors = false;
}
- Ok(mut reader) => {
- let result = if self.config.loop_through {
- let mut printer = SimplePrinter::new();
- self.print_file(reader, &mut printer, writer, &description)
+ Ok(mut opened_input) => {
+ let mut printer: Box<dyn Printer> = if self.config.loop_through {
+ Box::new(SimplePrinter::new())
} else {
- let mut printer = InteractivePrinter::new(
+ Box::new(InteractivePrinter::new(
&self.config,
&self.assets,
- &input,
- &mut reader,
- );
- self.print_file(reader, &mut printer, writer, &description)
+ &mut opened_input,
+ ))
};
+ let result = self.print_file(&mut *printer, writer, &mut opened_input);
+
if let Err(error) = result {
handle_error(&error);
no_errors = false;
@@ -93,30 +90,29 @@ impl<'b> Controller<'b> {
Ok(no_errors)
}
- fn print_file<'a, P: Printer>(
+ fn print_file<'a>(
&self,
- reader: InputReader,
- printer: &mut P,
+ printer: &mut dyn Printer,
writer: &mut dyn Write,
- input_description: &InputDescription,
+ input: &mut OpenedInput,
) -> Result<()> {
- if !reader.first_line.is_empty() || self.config.style_components.header() {
- printer.print_header(writer, input_description)?;
+ if !input.reader.first_line.is_empty() || self.config.style_components.header() {
+ printer.print_header(writer, input)?;
}
- if !reader.first_line.is_empty() {
- self.print_file_ranges(printer, writer, reader, &self.config.line_ranges)?;
+ if !input.reader.first_line.is_empty() {
+ self.print_file_ranges(printer, writer, &mut input.reader, &self.config.line_ranges)?;
}
- printer.print_footer(writer)?;
+ printer.print_footer(writer, input)?;
Ok(())
}
- fn print_file_ranges<P: Printer>(
+ fn print_file_ranges(
&self,
- printer: &mut P,
+ printer: &mut dyn Printer,
writer: &mut dyn Write,
- mut reader: InputReader,
+ reader: &mut InputReader,
line_ranges: &LineRanges,
) -> Result<()> {
let mut line_buffer = Vec::new();
diff --git a/src/input.rs b/src/input.rs
index 7b464824..dae61d49 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -7,30 +7,6 @@ use content_inspector::{self, ContentType};
use crate::errors::*;
const THEME_PREVIEW_FILE: &[u8] = include_bytes!("../assets/theme_preview.rs");
-#[derive(Debug, Clone, PartialEq)]
-pub struct OrdinaryFile {
- path: OsString,
- user_provided_path: Option<OsString>,
-}
-
-impl OrdinaryFile {
- pub fn from_path(path: &OsStr) -> OrdinaryFile {
- OrdinaryFile {
- path: path.to_os_string(),
- user_provided_path: None,
- }
- }
-
- pub fn set_provided_path(&mut self, user_provided_path: &OsStr) {
- self.user_provided_path = Some(user_provided_path.to_os_string());
- }
-
- pub(crate) fn provided_path<'a>(&'a self) -> &'a OsStr {
- self.user_provided_path
- .as_ref()
- .unwrap_or_else(|| &self.path)
- }
-}
#[derive(Debug, Clone)]
pub struct InputDescription {
@@ -39,69 +15,134 @@ pub struct InputDescription {
pub name: String,
}
-pub enum Input {
- StdIn(Option<OsString>),
- Ordinary(OrdinaryFile),
- FromReader(Box<dyn Read>, Option<OsString>),
+pub enum InputKind {
+ OrdinaryFile(OsString),
+ StdIn,
ThemePreviewFile,
+ CustomReader(Box<dyn BufRead>),
+}
+
+#[derive(Clone, Default)]
+pub struct InputMetadata {
+ pub user_provided_name: Option<OsString>,
+}
+
+pub struct Input {
+ pub kind: InputKind,
+ pub metadata: InputMetadata,
+}
+
+pub enum OpenedInputKind {
+ OrdinaryFile(OsString),
+ StdIn,
+ ThemePreviewFile,
+ CustomReader,
+}
+
+pub struct OpenedInput<'a> {
+ pub kind: OpenedInputKind,
+ pub metadata: InputMetadata,
+ pub reader: InputReader<'a>,
}
impl Input {
- pub(crate) fn get_reader<'a, R: BufRead + 'a>(&self, stdin: R) -> Result<InputReader<'a>> {
- match self {
- Input::StdIn(_) => Ok(InputReader::new(stdin)),
- Input::Ordinary(ofile) => {
- let file = File::open(&ofile.path)
- .map_err(|e| format!("'{}': {}", ofile.path.to_string_lossy(), e))?;
-
- if file.metadata()?.is_dir() {
- return Err(
- format!("'{}' is a directory.", ofile.path.to_string_lossy()).into(),
- );
- }
-
- Ok(InputReader::new(BufReader::new(file)))
- }
- Input::ThemePreviewFile => Ok(InputReader::new(THEME_PREVIEW_FILE)),
- Input::FromReader(_, _) => unimplemented!(), //Ok(InputReader::new(BufReader::new(reader))),
+ pub fn ordinary_file(path: &OsStr) -> Self {
+ Input {
+ kind: InputKind::OrdinaryFile(path.to_os_string()),
+ metadata: InputMetadata::default(),
}
}
- pub(crate) fn description(&self) -> InputDescription {
- match self {
- Input::Ordinary(ofile) => InputDescription {
- full: format!("file '{}'", &ofile.provided_path().to_string_lossy()),
- prefix: "File: ".to_owned(),
- name: ofile.provided_path().to_string_lossy().into_owned(),
- },
- Input::StdIn(Some(name)) => InputDescription {
- full: format!(
- "STDIN (with name '{}')",
- name.to_string_lossy().into_owned()
- ),
- prefix: "File: ".to_owned(),
- name: name.to_string_lossy().into_owned(),
- },
- Input::StdIn(None) => InputDescription {
- full: "STDIN".to_owned(),
- prefix: "".to_owned(),
- name: "STDIN".to_owned(),
- },
- Input::ThemePreviewFile => InputDescription {
- full: "".to_owned(),
- prefix: "".to_owned(),
- name: "".to_owned(),
- },
- Input::FromReader(_, Some(name)) => InputDescription {
+ pub fn stdin() -> Self {
+ Input {
+ kind: InputKind::StdIn,
+ metadata: InputMetadata::default(),
+ }
+ }
+
+ pub fn theme_preview_file() -> Self {
+ Input {
+ kind: InputKind::ThemePreviewFile,
+ metadata: InputMetadata::default(),
+ }
+ }
+
+ pub fn is_stdin(&self) -> bool {
+ if let InputKind::StdIn = self.kind {
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn set_provided_name(&mut self, provided_name: Option<&OsStr>) {
+ self.metadata.user_provided_name = provided_name.map(|n| n.to_owned());
+ }
+
+ pub fn open<'a, R: BufRead + 'a>(self, stdin: R) -> Result<OpenedInput<'a>> {
+ match self.kind {
+ InputKind::StdIn => Ok(OpenedInput {
+ kind: OpenedInputKind::StdIn,
+ metadata: self.metadata,
+ reader: InputReader::new(stdin),
+ }),
+ InputKind::OrdinaryFile(path) => Ok(OpenedInput {
+ kind: OpenedInputKind::OrdinaryFile(path.clone()),
+ metadata: self.metadata,
+ reader: {
+ let file = File::open(&path)
+ .map_err(|e| format!("'{}': {}", path.to_string_lossy(), e))?;
+ if file.metadata()?.is_dir() {
+ return Err(format!("'{}' is a directory.", path.to_string_lossy()).into());
+ }
+ InputReader::new(BufReader::new(file))
+ },
+ }),
+ InputKind::ThemePreviewFile => Ok(OpenedInput {
+ kind: OpenedInputKind::ThemePreviewFile,
+ metadata: self.metadata,
+ reader: InputReader::new(THEME_PREVIEW_FILE),
+ }),
+ InputKind::CustomReader(reader) => Ok(OpenedInput {
+ kind: OpenedInputKind::CustomReader,
+ metadata: self.metadata,
+ reader: InputReader::new(BufReader::new(reader)),
+ }),
+ }
+ }
+}
+
+impl<'a> OpenedInput<'a> {
+ pub fn description(&self) -> InputDescription {
+ if let Some(ref name) = self.metadata.user_provided_name {
+ InputDescription {
full: format!("file '{}'", name.to_string_lossy()),
prefix: "File: ".to_owned(),
name: name.to_string_lossy().into_owned(),
- },
- Input::FromReader(_, None) => InputDescription {
- full: "reader".to_owned(),
- prefix: "".to_owned(),
- name: "READER".into(),
- },
+ }
+ } else {
+ match self.kind {
+ OpenedInputKind::OrdinaryFile(ref path) => InputDescription {
+ full: format!("file '{}'", path.to_string_lossy()),
+ prefix: "File: ".to_owned(),
+ name: path.to_string_lossy().into_owned(),
+ },
+ OpenedInputKind::StdIn => InputDescription {
+ full: "STDIN".to_owned(),
+ prefix: "".to_owned(),
+ name: "STDIN".to_owned(),
+ },
+ OpenedInputKind::ThemePreviewFile => InputDescription {
+ full: "".to_owned(),
+ prefix: "".to_owned(),
+ name: "".to_owned(),
+ },
+ OpenedInputKind::CustomReader => InputDescription {
+ full: "reader".to_owned(),
+ prefix: "".to_owned(),
+ name: "READER".into(),
+ },
+ }
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 1352cb2b..cdd5a416 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,7 +8,7 @@ pub(crate) mod controller;
mod decorations;
mod diff;
pub mod errors;
-pub(crate) mod input;
+pub mod input;
mod less;
pub(crate) mod line_range;
mod output;
diff --git a/src/pretty_printer.rs b/src/pretty_printer.rs
index 3d76c920..da46ce9b 100644
--- a/src/pretty_printer.rs
+++ b/src/pretty_printer.rs
@@ -3,10 +3,10 @@ use std::io::Read;
use crate::{
config::{
- Config, HighlightedLineRanges, Input, LineRanges, OrdinaryFile, StyleComponents,
- SyntaxMapping, WrappingMode,
+ Config, HighlightedLineRanges, LineRanges, StyleComponents, SyntaxMapping, WrappingMode,
},
errors::Result,
+ input::{Input, InputKind, OpenedInput},
Controller, HighlightingAssets,
};
@@ -35,8 +35,8 @@ impl<'a> PrettyPrinter<'a> {
/// Add a file which should be pretty-printed
pub fn input_file(&mut self, path: &OsStr) -> &mut Self {
- self.inputs
- .push(Input::Ordinary(OrdinaryFile::from_path(path)));
+ // self.inputs
+ // .push(Input::Ordinary(OrdinaryFile::from_path(path)));
self
}
@@ -47,15 +47,15 @@ impl<'a> PrettyPrinter<'a> {
P: AsRef<OsStr>,
{
for path in paths {
- self.inputs
- .push(Input::Ordinary(OrdinaryFile::from_path(path.as_ref())));
+ // self.inputs
+ // .push(Input::Ordinary(OrdinaryFile::from_path(path.as_ref())));
}
self
}
/// Add STDIN as an input
pub fn input_stdin(&mut self) -> &mut Self {
- self.inputs.push(Input::StdIn(None));
+ // self.inputs.push(Input::StdIn(None));
self
}
diff --git a/src/printer.rs b/src/printer.rs
index 0fc914f2..fc409433 100644
--- a/src/printer.rs
+++ b/src/printer.rs
@@ -27,15 +27,15 @@ use crate::decorations::{Decoration, GridBorderDecoration, LineNumberDecoration}
#[cfg(feature = "git")]
use crate::diff::{get_git_diff, LineChanges};
use crate::errors::*;
-use crate::input::{Input, InputDescription, InputReader};
+use crate::input::{Input, InputDescription, InputKind, InputReader, OpenedInput, OpenedInputKind};
use crate::line_range::RangeCheckResult;
use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::terminal::{as_terminal_escaped, to_ansi_color};
use crate::wrap::WrappingMode;
pub trait Printer {
- fn print_header(&mut self, handle: &mut dyn Write, input: &InputDescription) -> Result<()>;
- fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()>;
+ fn print_header(&mut self, handle: &mut dyn Write, input: &OpenedInput) -> Result<()>;
+ fn print_footer(&mut self, handle: &mut dyn Write, input: &OpenedInput) -> Result<()>;
fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>;
@@ -57,11 +57,11 @@ impl SimplePrinter {
}
impl Printer for SimplePrinter {
- fn print_header(&mut self, _handle: &mut dyn Write, input: &InputDescription) -> Result<()> {
+ fn print_header(&mut self, _handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
Ok(())
}
- fn print_footer(&mut self, _handle: &mut dyn Write) -> Result<()> {
+ fn print_footer(&mut self, _handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
Ok(())
}
@@ -101,8 +101,7 @@ impl<'a> InteractivePrinter<'a> {
pub fn new(
config: &'a Config,
assets: &'a HighlightingAssets,
- input: &Input,
- reader: &mut InputReader,
+ input: &mut OpenedInput,
) -> Self {
let theme = assets.get_theme(&config.theme);
@@ -150,7 +149,8 @@ impl<'a> InteractivePrinter<'a> {
#[cfg(feature = "git")]
let mut line_changes = None;
- let highlighter = if reader
+ let highlighter = if input
+ .reader
.content_type
.map_or(false, |c| c.is_binary() && !config.show_nonprintable)
{
@@ -160,14 +160,14 @@ impl<'a> InteractivePrinter<'a> {
#[cfg(feature = "git")]
{
if config.style_components.changes() {
- if let Input::Ordinary(ofile) = input {
- line_changes = get_git_diff(ofile.provided_path());
+ if let OpenedInputKind::OrdinaryFile(ref path) = input.kind {
+ line_changes = get_git_diff(path);
}
}
}
// Determine the type of syntax for highlighting
- let syntax = assets.get_syntax(config.language, input, reader, &config.syntax_mapping);
+ let syntax = assets.get_syntax(config.language, input, &config.syntax_mapping);
Some(HighlightLines::new(syntax, theme))
};
@@ -176,7 +176,7 @@ impl<'a> InteractivePrinter<'a> {
colors,
config,
decorations,
- content_type: reader.content_type,
+ content_type: input.reader.content_type,
ansi_prefix_sgr: String::new(),
#[cfg(feature = "git")]
line_changes,
@@ -230,11 +230,7 @@ impl<'a> InteractivePrinter<'a> {
}
impl<'a> Printer for InteractivePrinter<'a> {
- fn print_header(
- &mut self,
- handle: &mut dyn Write,
- description: &InputDescription,
- ) -> Result<()> {
+ fn print_header(&mut self, handle: &mut dyn Write, input: &OpenedInput) -> Result<()> {
if !self.config.style_components.header() {
if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
writeln!(
@@ -243,7 +239,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
(but will be present if the output of 'bat' is piped). You can use 'bat -A' \
to show the binary file contents.",
Yellow.paint("[bat warning]"),
- description.full,
+ input.description().full,
)?;
} else {
if self.config.style_components.grid() {
@@ -276,6 +272,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
_ => "",
};
+ let description = input.description();
+
writeln!(
handle,
"{}{}{}",
@@ -295,7 +293,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
Ok(())
}
- fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()> {
+ fn print_footer(&mut self, handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
if self.config.style_components.grid()
&& (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
{