on master help sign in
Add new style component to separate multiple '--line-range's
commit7f2e61d57961e8fa23a91ec1bd6348cbfc33a2c8 authorEthan P <eth-p+git@hidden.email> dateFri 24 May 2019, 18:24 (7 years ago) parente289a2c
4 files changed+76−3
src/clap_app.rs+3−3 src/controller.rs+15 src/printer.rs+50 src/style.rs+8
src/clap_app.rs+3−3
@@ -111,7 +111,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
111111 .validator(|val| {
112112 let mut invalid_vals = val.split(',').filter(|style| {
113113 !&[
114− "auto", "full", "plain", "changes", "header", "grid", "numbers",
114+ "auto", "full", "plain", "changes", "header", "grid", "numbers", "snip"
115115 ]
116116 .contains(style)
117117 });
@@ -124,7 +124,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
124124 })
125125 .help(
126126 "Comma-separated list of style elements to display \
127− (*auto*, full, plain, changes, header, grid, numbers).",
127+ (*auto*, full, plain, changes, header, grid, numbers, snip).",
128128 )
129129 .long_help(
130130 "Configure which elements (line numbers, file headers, grid \
@@ -134,7 +134,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
134134 pre-defined style ('full'). To set a default style, add the \
135135 '--style=\"..\"' option to the configuration file or export the \
136136 BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\"). \
137− Possible values: *auto*, full, plain, changes, header, grid, numbers.",
137+ Possible values: *auto*, full, plain, changes, header, grid, numbers, snip.",
138138 ),
139139 )
140140 .arg(
src/controller.rs+15
@@ -98,14 +98,29 @@ impl<'b> Controller<'b> {
9898 let mut line_buffer = Vec::new();
9999 let mut line_number: usize = 1;
100100
101+ let mut first_range: bool = true;
102+ let mut mid_range: bool = false;
103+
101104 while reader.read_line(&mut line_buffer)? {
102105 match line_ranges.check(line_number) {
103106 RangeCheckResult::OutsideRange => {
104107 // Call the printer in case we need to call the syntax highlighter
105108 // for this line. However, set `out_of_range` to `true`.
106109 printer.print_line(true, writer, line_number, &line_buffer)?;
110+ mid_range = false;
107111 }
112+
108113 RangeCheckResult::InRange => {
114+ if self.config.output_components.snip() {
115+ if first_range {
116+ first_range = false;
117+ mid_range = true;
118+ } else if !mid_range {
119+ mid_range = true;
120+ printer.print_snip(writer)?;
121+ }
122+ }
123+
109124 printer.print_line(false, writer, line_number, &line_buffer)?;
110125 }
111126 RangeCheckResult::AfterLastRange => {
src/printer.rs+50
@@ -32,6 +32,9 @@ use crate::terminal::{as_terminal_escaped, to_ansi_color};
3232pub trait Printer {
3333 fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()>;
3434 fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()>;
35+
36+ fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>;
37+
3538 fn print_line(
3639 &mut self,
3740 out_of_range: bool,
@@ -58,6 +61,10 @@ impl Printer for SimplePrinter {
5861 Ok(())
5962 }
6063
64+ fn print_snip(&mut self, _handle: &mut Write) -> Result<()> {
65+ Ok(())
66+ }
67+
6168 fn print_line(
6269 &mut self,
6370 out_of_range: bool,
@@ -182,6 +189,24 @@ impl<'a> InteractivePrinter<'a> {
182189 Ok(())
183190 }
184191
192+ fn create_fake_panel(&self, text: &str) -> String {
193+ if self.panel_width == 0 {
194+ "".to_string()
195+ } else {
196+ let text_truncated: String = text.chars().take(self.panel_width - 1).collect();
197+ let text_filled: String = format!(
198+ "{}{}",
199+ text_truncated,
200+ " ".repeat(self.panel_width - 1 - text_truncated.len())
201+ );
202+ if self.config.output_components.grid() {
203+ format!("{} │ ", text_filled)
204+ } else {
205+ format!("{}", text_filled)
206+ }
207+ }
208+ }
209+
185210 fn preprocess(&self, text: &str, cursor: &mut usize) -> String {
186211 if self.config.tab_width > 0 {
187212 expand_tabs(text, self.config.tab_width, cursor)
@@ -271,6 +296,31 @@ impl<'a> Printer for InteractivePrinter<'a> {
271296 }
272297 }
273298
299+ fn print_snip(&mut self, handle: &mut Write) -> Result<()> {
300+ let panel = self.create_fake_panel(" ...");
301+ let panel_count = panel.chars().count();
302+
303+ let title = "8<";
304+ let title_count = title.chars().count();
305+
306+ let snip_left =
307+ "─ ".repeat((self.config.term_width - panel_count - (title_count / 2)) / 4);
308+ let snip_left_count = snip_left.chars().count(); // Can't use .len() with Unicode.
309+
310+ let snip_right = " ─"
311+ .repeat((self.config.term_width - panel_count - snip_left_count - title_count) / 2);
312+
313+ write!(
314+ handle,
315+ "{}\n",
316+ self.colors
317+ .grid
318+ .paint(format!("{}{}{}{}", panel, snip_left, title, snip_right))
319+ )?;
320+
321+ Ok(())
322+ }
323+
274324 fn print_line(
275325 &mut self,
276326 out_of_range: bool,
src/style.rs+8
@@ -10,6 +10,7 @@ pub enum OutputComponent {
1010 Grid,
1111 Header,
1212 Numbers,
13+ Snip,
1314 Full,
1415 Plain,
1516}
@@ -34,11 +35,13 @@ impl OutputComponent {
3435 OutputComponent::Grid => &[OutputComponent::Grid],
3536 OutputComponent::Header => &[OutputComponent::Header],
3637 OutputComponent::Numbers => &[OutputComponent::Numbers],
38+ OutputComponent::Snip => &[OutputComponent::Snip],
3739 OutputComponent::Full => &[
3840 OutputComponent::Changes,
3941 OutputComponent::Grid,
4042 OutputComponent::Header,
4143 OutputComponent::Numbers,
44+ OutputComponent::Snip,
4245 ],
4346 OutputComponent::Plain => &[],
4447 }
@@ -55,6 +58,7 @@ impl FromStr for OutputComponent {
5558 "grid" => Ok(OutputComponent::Grid),
5659 "header" => Ok(OutputComponent::Header),
5760 "numbers" => Ok(OutputComponent::Numbers),
61+ "snip" => Ok(OutputComponent::Snip),
5862 "full" => Ok(OutputComponent::Full),
5963 "plain" => Ok(OutputComponent::Plain),
6064 _ => Err(format!("Unknown style '{}'", s).into()),
@@ -82,6 +86,10 @@ impl OutputComponents {
8286 self.0.contains(&OutputComponent::Numbers)
8387 }
8488
89+ pub fn snip(&self) -> bool {
90+ self.0.contains(&OutputComponent::Snip)
91+ }
92+
8593 pub fn plain(&self) -> bool {
8694 self.0.iter().all(|c| c == &OutputComponent::Plain)
8795 }