Add new style component to separate multiple '--line-range's

This commit is contained in:
Ethan P 2019-05-24 18:24:13 -07:00 committed by David Peter
parent e289a2c698
commit 7f2e61d579
4 changed files with 76 additions and 3 deletions

View File

@ -111,7 +111,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.validator(|val| {
let mut invalid_vals = val.split(',').filter(|style| {
!&[
"auto", "full", "plain", "changes", "header", "grid", "numbers",
"auto", "full", "plain", "changes", "header", "grid", "numbers", "snip"
]
.contains(style)
});
@ -124,7 +124,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
})
.help(
"Comma-separated list of style elements to display \
(*auto*, full, plain, changes, header, grid, numbers).",
(*auto*, full, plain, changes, header, grid, numbers, snip).",
)
.long_help(
"Configure which elements (line numbers, file headers, grid \
@ -134,7 +134,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
pre-defined style ('full'). To set a default style, add the \
'--style=\"..\"' option to the configuration file or export the \
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\"). \
Possible values: *auto*, full, plain, changes, header, grid, numbers.",
Possible values: *auto*, full, plain, changes, header, grid, numbers, snip.",
),
)
.arg(

View File

@ -98,14 +98,29 @@ impl<'b> Controller<'b> {
let mut line_buffer = Vec::new();
let mut line_number: usize = 1;
let mut first_range: bool = true;
let mut mid_range: bool = false;
while reader.read_line(&mut line_buffer)? {
match line_ranges.check(line_number) {
RangeCheckResult::OutsideRange => {
// Call the printer in case we need to call the syntax highlighter
// for this line. However, set `out_of_range` to `true`.
printer.print_line(true, writer, line_number, &line_buffer)?;
mid_range = false;
}
RangeCheckResult::InRange => {
if self.config.output_components.snip() {
if first_range {
first_range = false;
mid_range = true;
} else if !mid_range {
mid_range = true;
printer.print_snip(writer)?;
}
}
printer.print_line(false, writer, line_number, &line_buffer)?;
}
RangeCheckResult::AfterLastRange => {

View File

@ -32,6 +32,9 @@ use crate::terminal::{as_terminal_escaped, to_ansi_color};
pub trait Printer {
fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()>;
fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()>;
fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>;
fn print_line(
&mut self,
out_of_range: bool,
@ -58,6 +61,10 @@ impl Printer for SimplePrinter {
Ok(())
}
fn print_snip(&mut self, _handle: &mut Write) -> Result<()> {
Ok(())
}
fn print_line(
&mut self,
out_of_range: bool,
@ -182,6 +189,24 @@ impl<'a> InteractivePrinter<'a> {
Ok(())
}
fn create_fake_panel(&self, text: &str) -> String {
if self.panel_width == 0 {
"".to_string()
} else {
let text_truncated: String = text.chars().take(self.panel_width - 1).collect();
let text_filled: String = format!(
"{}{}",
text_truncated,
" ".repeat(self.panel_width - 1 - text_truncated.len())
);
if self.config.output_components.grid() {
format!("{}", text_filled)
} else {
format!("{}", text_filled)
}
}
}
fn preprocess(&self, text: &str, cursor: &mut usize) -> String {
if self.config.tab_width > 0 {
expand_tabs(text, self.config.tab_width, cursor)
@ -271,6 +296,31 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
}
fn print_snip(&mut self, handle: &mut Write) -> Result<()> {
let panel = self.create_fake_panel(" ...");
let panel_count = panel.chars().count();
let title = "8<";
let title_count = title.chars().count();
let snip_left =
"".repeat((self.config.term_width - panel_count - (title_count / 2)) / 4);
let snip_left_count = snip_left.chars().count(); // Can't use .len() with Unicode.
let snip_right = ""
.repeat((self.config.term_width - panel_count - snip_left_count - title_count) / 2);
write!(
handle,
"{}\n",
self.colors
.grid
.paint(format!("{}{}{}{}", panel, snip_left, title, snip_right))
)?;
Ok(())
}
fn print_line(
&mut self,
out_of_range: bool,

View File

@ -10,6 +10,7 @@ pub enum OutputComponent {
Grid,
Header,
Numbers,
Snip,
Full,
Plain,
}
@ -34,11 +35,13 @@ impl OutputComponent {
OutputComponent::Grid => &[OutputComponent::Grid],
OutputComponent::Header => &[OutputComponent::Header],
OutputComponent::Numbers => &[OutputComponent::Numbers],
OutputComponent::Snip => &[OutputComponent::Snip],
OutputComponent::Full => &[
OutputComponent::Changes,
OutputComponent::Grid,
OutputComponent::Header,
OutputComponent::Numbers,
OutputComponent::Snip,
],
OutputComponent::Plain => &[],
}
@ -55,6 +58,7 @@ impl FromStr for OutputComponent {
"grid" => Ok(OutputComponent::Grid),
"header" => Ok(OutputComponent::Header),
"numbers" => Ok(OutputComponent::Numbers),
"snip" => Ok(OutputComponent::Snip),
"full" => Ok(OutputComponent::Full),
"plain" => Ok(OutputComponent::Plain),
_ => Err(format!("Unknown style '{}'", s).into()),
@ -82,6 +86,10 @@ impl OutputComponents {
self.0.contains(&OutputComponent::Numbers)
}
pub fn snip(&self) -> bool {
self.0.contains(&OutputComponent::Snip)
}
pub fn plain(&self) -> bool {
self.0.iter().all(|c| c == &OutputComponent::Plain)
}