bat/src/printer.rs

161 lines
4.5 KiB
Rust
Raw Normal View History

use ansi_term::Style;
2018-05-10 23:39:13 +02:00
use app::Config;
use diff::{LineChange, LineChanges};
use errors::*;
use std::io::Write;
use syntect::highlighting;
use terminal::as_terminal_escaped;
2018-05-10 23:39:13 +02:00
use Colors;
const PANEL_WIDTH: usize = 7;
pub struct Printer<'a> {
handle: &'a mut Write,
colors: Colors,
2018-05-10 23:39:13 +02:00
config: &'a Config<'a>,
pub line_changes: Option<LineChanges>,
}
impl<'a> Printer<'a> {
2018-05-10 23:39:13 +02:00
pub fn new(handle: &'a mut Write, config: &'a Config) -> Self {
let colors = if config.colored_output {
Colors::colored()
} else {
Colors::plain()
};
Printer {
handle,
colors,
2018-05-10 23:39:13 +02:00
config,
line_changes: None,
}
}
pub fn print_header(&mut self, filename: Option<&str>) -> Result<()> {
2018-05-10 23:39:13 +02:00
if !self.config.output_components.header() {
return Ok(());
}
2018-05-10 23:39:13 +02:00
if self.config.output_components.grid() {
self.print_horizontal_line('┬')?;
write!(
self.handle,
"{}{} ",
" ".repeat(PANEL_WIDTH),
self.colors.grid.paint(""),
)?;
}
writeln!(
self.handle,
"{}{}",
filename.map_or("", |_| "File: "),
self.colors.filename.paint(filename.unwrap_or("STDIN"))
)?;
2018-05-10 23:39:13 +02:00
if self.config.output_components.grid() {
self.print_horizontal_line('┼')?;
}
Ok(())
}
pub fn print_footer(&mut self) -> Result<()> {
2018-05-10 23:39:13 +02:00
if self.config.output_components.grid() {
self.print_horizontal_line('┴')
} else {
Ok(())
}
}
pub fn print_line(
&mut self,
line_number: usize,
regions: &[(highlighting::Style, &str)],
) -> Result<()> {
let decorations = vec![
self.print_line_number(line_number),
self.print_git_marker(line_number),
self.print_line_border(),
2018-05-09 22:31:38 +02:00
Some(as_terminal_escaped(
&regions,
2018-05-10 23:39:13 +02:00
self.config.true_color,
self.config.colored_output,
2018-05-09 22:31:38 +02:00
)),
];
2018-05-10 23:39:13 +02:00
let grid_requested = self.config.output_components.grid();
write!(
self.handle,
"{}",
decorations
.into_iter()
.filter_map(|dec| if grid_requested {
2018-05-10 12:50:40 +02:00
Some(dec.unwrap_or_else(|| " ".to_owned()))
} else {
dec
})
.collect::<Vec<_>>()
.join(" ")
)?;
Ok(())
}
2018-05-10 11:45:42 +02:00
fn print_line_number(&self, line_number: usize) -> Option<String> {
2018-05-10 23:39:13 +02:00
if self.config.output_components.numbers() {
Some(
self.colors
.line_number
.paint(format!("{:4}", line_number))
2018-05-09 22:31:38 +02:00
.to_string(),
)
2018-05-10 23:39:13 +02:00
} else if self.config.output_components.grid() {
2018-05-09 22:31:38 +02:00
Some(" ".to_owned())
} else {
None
}
}
2018-05-10 11:45:42 +02:00
fn print_git_marker(&self, line_number: usize) -> Option<String> {
2018-05-10 23:39:13 +02:00
if self.config.output_components.changes() {
Some(
if let Some(ref changes) = self.line_changes {
match changes.get(&(line_number as u32)) {
Some(&LineChange::Added) => self.colors.git_added.paint("+"),
Some(&LineChange::RemovedAbove) => self.colors.git_removed.paint(""),
Some(&LineChange::RemovedBelow) => self.colors.git_removed.paint("_"),
Some(&LineChange::Modified) => self.colors.git_modified.paint("~"),
_ => Style::default().paint(" "),
}
} else {
Style::default().paint(" ")
2018-05-09 22:31:38 +02:00
}.to_string(),
)
2018-05-10 23:39:13 +02:00
} else if self.config.output_components.grid() {
2018-05-09 22:31:38 +02:00
Some(" ".to_owned())
} else {
None
}
}
2018-05-10 11:45:42 +02:00
fn print_line_border(&self) -> Option<String> {
2018-05-10 23:39:13 +02:00
if self.config.output_components.grid() {
2018-05-09 22:31:38 +02:00
Some(self.colors.grid.paint("").to_string())
} else {
None
}
}
fn print_horizontal_line(&mut self, grid_char: char) -> Result<()> {
2018-05-10 23:39:13 +02:00
let hline = "".repeat(self.config.term_width - (PANEL_WIDTH + 1));
let hline = format!("{}{}{}", "".repeat(PANEL_WIDTH), grid_char, hline);
writeln!(self.handle, "{}", self.colors.grid.paint(hline))?;
Ok(())
}
}