mirror of
https://github.com/sharkdp/bat.git
synced 2025-01-02 19:58:51 +01:00
Refactoring, introduce Printer trait
This commit is contained in:
parent
6223ad6d52
commit
ea955c734d
@ -32,8 +32,8 @@ pub struct Config<'a> {
|
|||||||
/// The character width of the terminal
|
/// The character width of the terminal
|
||||||
pub term_width: usize,
|
pub term_width: usize,
|
||||||
|
|
||||||
/// Whether or not the terminal is interactive
|
/// Whether or not to simply loop through all input (`cat` mode)
|
||||||
pub interactive_output: bool,
|
pub loop_through: bool,
|
||||||
|
|
||||||
/// Whether or not the output should be colorized
|
/// Whether or not the output should be colorized
|
||||||
pub colored_output: bool,
|
pub colored_output: bool,
|
||||||
@ -336,6 +336,8 @@ impl App {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
term_width: Term::stdout().size().1 as usize,
|
term_width: Term::stdout().size().1 as usize,
|
||||||
|
loop_through: self.interactive_output
|
||||||
|
&& self.matches.value_of("color") != Some("always"),
|
||||||
files,
|
files,
|
||||||
theme: self
|
theme: self
|
||||||
.matches
|
.matches
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use ansi_term::Style;
|
use ansi_term::Style;
|
||||||
use diff::LineChange;
|
use diff::LineChange;
|
||||||
use printer::{Colors, Printer};
|
use printer::{Colors, InteractivePrinter};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DecorationText {
|
pub struct DecorationText {
|
||||||
@ -9,8 +9,12 @@ pub struct DecorationText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Decoration {
|
pub trait Decoration {
|
||||||
fn generate(&self, line_number: usize, continuation: bool, printer: &Printer)
|
fn generate(
|
||||||
-> DecorationText;
|
&self,
|
||||||
|
line_number: usize,
|
||||||
|
continuation: bool,
|
||||||
|
printer: &InteractivePrinter,
|
||||||
|
) -> DecorationText;
|
||||||
fn width(&self) -> usize;
|
fn width(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +42,7 @@ impl Decoration for LineNumberDecoration {
|
|||||||
&self,
|
&self,
|
||||||
line_number: usize,
|
line_number: usize,
|
||||||
continuation: bool,
|
continuation: bool,
|
||||||
_printer: &Printer,
|
_printer: &InteractivePrinter,
|
||||||
) -> DecorationText {
|
) -> DecorationText {
|
||||||
if continuation {
|
if continuation {
|
||||||
if line_number > self.cached_wrap_invalid_at {
|
if line_number > self.cached_wrap_invalid_at {
|
||||||
@ -97,7 +101,7 @@ impl Decoration for LineChangesDecoration {
|
|||||||
&self,
|
&self,
|
||||||
line_number: usize,
|
line_number: usize,
|
||||||
continuation: bool,
|
continuation: bool,
|
||||||
printer: &Printer,
|
printer: &InteractivePrinter,
|
||||||
) -> DecorationText {
|
) -> DecorationText {
|
||||||
if !continuation {
|
if !continuation {
|
||||||
if let Some(ref changes) = printer.line_changes {
|
if let Some(ref changes) = printer.line_changes {
|
||||||
@ -139,7 +143,7 @@ impl Decoration for GridBorderDecoration {
|
|||||||
&self,
|
&self,
|
||||||
_line_number: usize,
|
_line_number: usize,
|
||||||
_continuation: bool,
|
_continuation: bool,
|
||||||
_printer: &Printer,
|
_printer: &InteractivePrinter,
|
||||||
) -> DecorationText {
|
) -> DecorationText {
|
||||||
self.cached.clone()
|
self.cached.clone()
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use diff::get_git_diff;
|
|||||||
use errors::*;
|
use errors::*;
|
||||||
use line_range::LineRange;
|
use line_range::LineRange;
|
||||||
use output::OutputType;
|
use output::OutputType;
|
||||||
use printer::Printer;
|
use printer::{InteractivePrinter, Printer};
|
||||||
|
|
||||||
pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
|
pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
|
||||||
let mut languages = assets
|
let mut languages = assets
|
||||||
@ -72,7 +72,7 @@ pub fn print_files(assets: &HighlightingAssets, config: &Config) -> Result<bool>
|
|||||||
|
|
||||||
let mut output_type = OutputType::from_mode(config.paging_mode);
|
let mut output_type = OutputType::from_mode(config.paging_mode);
|
||||||
let handle = output_type.handle()?;
|
let handle = output_type.handle()?;
|
||||||
let mut printer = Printer::new(handle, &config, &theme);
|
let mut printer = InteractivePrinter::new(handle, &config, &theme);
|
||||||
let mut no_errors: bool = true;
|
let mut no_errors: bool = true;
|
||||||
|
|
||||||
for file in &config.files {
|
for file in &config.files {
|
||||||
@ -80,7 +80,7 @@ pub fn print_files(assets: &HighlightingAssets, config: &Config) -> Result<bool>
|
|||||||
printer.line_changes = file.and_then(|filename| get_git_diff(filename));
|
printer.line_changes = file.and_then(|filename| get_git_diff(filename));
|
||||||
let syntax = assets.get_syntax(config.language, *file);
|
let syntax = assets.get_syntax(config.language, *file);
|
||||||
|
|
||||||
let result = print_file(theme, &syntax, &mut printer, *file);
|
let result = print_file(config, theme, &syntax, &mut printer, *file);
|
||||||
|
|
||||||
if let Err(error) = result {
|
if let Err(error) = result {
|
||||||
handle_error(&error);
|
handle_error(&error);
|
||||||
@ -91,13 +91,14 @@ pub fn print_files(assets: &HighlightingAssets, config: &Config) -> Result<bool>
|
|||||||
Ok(no_errors)
|
Ok(no_errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_file(
|
fn print_file<P: Printer>(
|
||||||
|
config: &Config,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
syntax: &SyntaxDefinition,
|
syntax: &SyntaxDefinition,
|
||||||
printer: &mut Printer,
|
printer: &mut P,
|
||||||
filename: Option<&str>,
|
filename: Option<&str>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let stdin = io::stdin(); // TODO: this variable is not always needed
|
let stdin = io::stdin();
|
||||||
{
|
{
|
||||||
let reader: Box<BufRead> = match filename {
|
let reader: Box<BufRead> = match filename {
|
||||||
None => Box::new(stdin.lock()),
|
None => Box::new(stdin.lock()),
|
||||||
@ -107,20 +108,22 @@ fn print_file(
|
|||||||
let highlighter = HighlightLines::new(syntax, theme);
|
let highlighter = HighlightLines::new(syntax, theme);
|
||||||
|
|
||||||
printer.print_header(filename)?;
|
printer.print_header(filename)?;
|
||||||
print_file_ranges(printer, reader, highlighter, &printer.config.line_range)?;
|
print_file_ranges(printer, reader, highlighter, &config.line_range)?;
|
||||||
printer.print_footer()?;
|
printer.print_footer()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_file_ranges<'a>(
|
fn print_file_ranges<'a, P: Printer>(
|
||||||
printer: &mut Printer,
|
printer: &mut P,
|
||||||
mut reader: Box<BufRead + 'a>,
|
mut reader: Box<BufRead + 'a>,
|
||||||
mut highlighter: HighlightLines,
|
mut highlighter: HighlightLines,
|
||||||
line_ranges: &Option<LineRange>,
|
line_ranges: &Option<LineRange>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
|
|
||||||
|
let mut line_number: usize = 1;
|
||||||
|
|
||||||
while reader.read_until(b'\n', &mut buffer)? > 0 {
|
while reader.read_until(b'\n', &mut buffer)? > 0 {
|
||||||
{
|
{
|
||||||
let line = String::from_utf8_lossy(&buffer);
|
let line = String::from_utf8_lossy(&buffer);
|
||||||
@ -128,20 +131,21 @@ fn print_file_ranges<'a>(
|
|||||||
|
|
||||||
match line_ranges {
|
match line_ranges {
|
||||||
&Some(ref range) => {
|
&Some(ref range) => {
|
||||||
if printer.line_number + 1 < range.lower {
|
if line_number < range.lower {
|
||||||
// skip line
|
// skip line
|
||||||
printer.line_number += 1;
|
} else if line_number > range.upper {
|
||||||
} else if printer.line_number >= range.upper {
|
|
||||||
// no more lines in range
|
// no more lines in range
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
printer.print_line(®ions)?;
|
printer.print_line(line_number, ®ions)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&None => {
|
&None => {
|
||||||
printer.print_line(®ions)?;
|
printer.print_line(line_number, ®ions)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
line_number += 1;
|
||||||
}
|
}
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,12 @@ fn run() -> Result<bool> {
|
|||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
print_files(&assets, &config)
|
if config.loop_through {
|
||||||
|
// TODO
|
||||||
|
print_files(&assets, &config)
|
||||||
|
} else {
|
||||||
|
print_files(&assets, &config)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,18 +16,27 @@ use errors::*;
|
|||||||
use style::OutputWrap;
|
use style::OutputWrap;
|
||||||
use terminal::{as_terminal_escaped, to_ansi_color};
|
use terminal::{as_terminal_escaped, to_ansi_color};
|
||||||
|
|
||||||
pub struct Printer<'a> {
|
pub trait Printer {
|
||||||
|
fn print_header(&mut self, filename: Option<&str>) -> Result<()>;
|
||||||
|
fn print_footer(&mut self) -> Result<()>;
|
||||||
|
fn print_line(
|
||||||
|
&mut self,
|
||||||
|
line_number: usize,
|
||||||
|
regions: &[(highlighting::Style, &str)],
|
||||||
|
) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InteractivePrinter<'a> {
|
||||||
handle: &'a mut Write,
|
handle: &'a mut Write,
|
||||||
colors: Colors,
|
colors: Colors,
|
||||||
pub config: &'a Config<'a>,
|
pub config: &'a Config<'a>,
|
||||||
decorations: Vec<Box<Decoration>>,
|
decorations: Vec<Box<Decoration>>,
|
||||||
panel_width: usize,
|
panel_width: usize,
|
||||||
pub ansi_prefix_sgr: String,
|
pub ansi_prefix_sgr: String,
|
||||||
pub line_number: usize,
|
|
||||||
pub line_changes: Option<LineChanges>,
|
pub line_changes: Option<LineChanges>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Printer<'a> {
|
impl<'a> InteractivePrinter<'a> {
|
||||||
pub fn new(handle: &'a mut Write, config: &'a Config, theme: &Theme) -> Self {
|
pub fn new(handle: &'a mut Write, config: &'a Config, theme: &Theme) -> Self {
|
||||||
let colors = if config.colored_output {
|
let colors = if config.colored_output {
|
||||||
Colors::colored(theme, config.true_color)
|
Colors::colored(theme, config.true_color)
|
||||||
@ -66,21 +75,36 @@ impl<'a> Printer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create printer.
|
// Create printer.
|
||||||
Printer {
|
InteractivePrinter {
|
||||||
panel_width,
|
panel_width,
|
||||||
handle,
|
handle,
|
||||||
colors,
|
colors,
|
||||||
config,
|
config,
|
||||||
decorations,
|
decorations,
|
||||||
ansi_prefix_sgr: String::new(),
|
ansi_prefix_sgr: String::new(),
|
||||||
line_number: 0,
|
|
||||||
line_changes: None,
|
line_changes: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_header(&mut self, filename: Option<&str>) -> Result<()> {
|
fn print_horizontal_line(&mut self, grid_char: char) -> Result<()> {
|
||||||
self.line_number = 0;
|
if self.panel_width == 0 {
|
||||||
|
writeln!(
|
||||||
|
self.handle,
|
||||||
|
"{}",
|
||||||
|
self.colors.grid.paint("─".repeat(self.config.term_width))
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
|
||||||
|
let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
|
||||||
|
writeln!(self.handle, "{}", self.colors.grid.paint(hline))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Printer for InteractivePrinter<'a> {
|
||||||
|
fn print_header(&mut self, filename: Option<&str>) -> Result<()> {
|
||||||
if !self.config.output_components.header() {
|
if !self.config.output_components.header() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -114,7 +138,7 @@ impl<'a> Printer<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_footer(&mut self) -> Result<()> {
|
fn print_footer(&mut self) -> Result<()> {
|
||||||
if self.config.output_components.grid() {
|
if self.config.output_components.grid() {
|
||||||
self.print_horizontal_line('┴')
|
self.print_horizontal_line('┴')
|
||||||
} else {
|
} else {
|
||||||
@ -122,8 +146,11 @@ impl<'a> Printer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_line(&mut self, regions: &[(highlighting::Style, &str)]) -> Result<()> {
|
fn print_line(
|
||||||
self.line_number += 1;
|
&mut self,
|
||||||
|
line_number: usize,
|
||||||
|
regions: &[(highlighting::Style, &str)],
|
||||||
|
) -> Result<()> {
|
||||||
let mut cursor: usize = 0;
|
let mut cursor: usize = 0;
|
||||||
let mut cursor_max: usize = self.config.term_width;
|
let mut cursor_max: usize = self.config.term_width;
|
||||||
let mut panel_wrap: Option<String> = None;
|
let mut panel_wrap: Option<String> = None;
|
||||||
@ -133,7 +160,7 @@ impl<'a> Printer<'a> {
|
|||||||
let decorations = self
|
let decorations = self
|
||||||
.decorations
|
.decorations
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ref d| d.generate(self.line_number, false, self))
|
.map(|ref d| d.generate(line_number, false, self))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for deco in decorations {
|
for deco in decorations {
|
||||||
@ -218,7 +245,7 @@ impl<'a> Printer<'a> {
|
|||||||
self.decorations
|
self.decorations
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ref d| d
|
.map(|ref d| d
|
||||||
.generate(self.line_number, true, self)
|
.generate(line_number, true, self)
|
||||||
.text).collect::<Vec<String>>()
|
.text).collect::<Vec<String>>()
|
||||||
.join(" ")
|
.join(" ")
|
||||||
))
|
))
|
||||||
@ -260,22 +287,6 @@ impl<'a> Printer<'a> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_horizontal_line(&mut self, grid_char: char) -> Result<()> {
|
|
||||||
if self.panel_width == 0 {
|
|
||||||
writeln!(
|
|
||||||
self.handle,
|
|
||||||
"{}",
|
|
||||||
self.colors.grid.paint("─".repeat(self.config.term_width))
|
|
||||||
)?;
|
|
||||||
} else {
|
|
||||||
let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
|
|
||||||
let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
|
|
||||||
writeln!(self.handle, "{}", self.colors.grid.paint(hline))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_GUTTER_COLOR: u8 = 238;
|
const DEFAULT_GUTTER_COLOR: u8 = 238;
|
||||||
|
Loading…
Reference in New Issue
Block a user