on master help sign in
Merge pull request #453 from sharkdp/line-highlight

Line highlight

commit668c8a67038d0b466c3f6c5c644c02fc71a011f6 authorDavid Peter <sharkdp@users.noreply.github.com> dateTue 18 Dec 2018, 09:06 (8 years ago) parentb68c5d8bd68684
4 files changed+79−5
src/app.rs+9 src/clap_app.rs+14 src/printer.rs+53−4 src/terminal.rs+3−1
src/app.rs+9
@@ -77,7 +77,11 @@ pub struct Config<'a> {
7777 /// Command to start the pager
7878 pub pager: Option<&'a str>,
7979
80+ /// Whether or not to use ANSI italics
8081 pub use_italic_text: bool,
82+
83+ /// Lines to highlight
84+ pub highlight_lines: Vec<usize>,
8185}
8286
8387fn is_truecolor_terminal() -> bool {
@@ -264,6 +268,11 @@ impl App {
264268 Some("always") => true,
265269 _ => false,
266270 },
271+ highlight_lines: self
272+ .matches
273+ .values_of("highlight-line")
274+ .and_then(|ws| ws.map(|w| w.parse().ok()).collect())
275+ .unwrap_or_default(),
267276 })
268277 }
269278
src/clap_app.rs+14
@@ -175,6 +175,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
175175 .arg(
176176 Arg::with_name("line-range")
177177 .long("line-range")
178+ .short("r")
178179 .multiple(true)
179180 .takes_value(true)
180181 .number_of_values(1)
@@ -188,6 +189,19 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
188189 '--line-range 40:' prints lines 40 to the end of the file",
189190 ),
190191 )
192+ .arg(
193+ Arg::with_name("highlight-line")
194+ .long("highlight-line")
195+ .short("H")
196+ .takes_value(true)
197+ .number_of_values(1)
198+ .multiple(true)
199+ .value_name("N")
200+ .help("Highlight the given line.")
201+ .long_help(
202+ "Highlight the N-th line with a different background color",
203+ ),
204+ )
191205 .arg(
192206 Arg::with_name("color")
193207 .long("color")
src/printer.rs+53−4
@@ -7,6 +7,7 @@ use ansi_term::Style;
77use console::AnsiCodeIterator;
88
99use syntect::easy::HighlightLines;
10+use syntect::highlighting::Color;
1011use syntect::highlighting::Theme;
1112use syntect::parsing::SyntaxSet;
1213
@@ -79,6 +80,7 @@ pub struct InteractivePrinter<'a> {
7980 pub line_changes: Option<LineChanges>,
8081 highlighter: Option<HighlightLines<'a>>,
8182 syntax_set: &'a SyntaxSet,
83+ background_color_highlight: Option<Color>,
8284}
8385
8486impl<'a> InteractivePrinter<'a> {
@@ -90,6 +92,8 @@ impl<'a> InteractivePrinter<'a> {
9092 ) -> Self {
9193 let theme = assets.get_theme(&config.theme);
9294
95+ let background_color_highlight = theme.settings.line_highlight;
96+
9397 let colors = if config.colored_output {
9498 Colors::colored(theme, config.true_color)
9599 } else {
@@ -156,6 +160,7 @@ impl<'a> InteractivePrinter<'a> {
156160 line_changes,
157161 highlighter,
158162 syntax_set: &assets.syntax_set,
163+ background_color_highlight,
159164 }
160165 }
161166
@@ -287,6 +292,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
287292 let mut cursor_total: usize = 0;
288293 let mut panel_wrap: Option<String> = None;
289294
295+ // Line highlighting
296+ let highlight_this_line = self
297+ .config
298+ .highlight_lines
299+ .iter()
300+ .any(|&l| l == line_number);
301+
302+ let background_color = self
303+ .background_color_highlight
304+ .filter(|_| highlight_this_line);
305+
290306 // Line decorations.
291307 if self.panel_width > 0 {
292308 let decorations = self
@@ -313,9 +329,29 @@ impl<'a> Printer for InteractivePrinter<'a> {
313329 write!(
314330 handle,
315331 "{}",
316− as_terminal_escaped(style, text_trimmed, true_color, colored_output, italics,)
332+ as_terminal_escaped(
333+ style,
334+ text_trimmed,
335+ true_color,
336+ colored_output,
337+ italics,
338+ background_color
339+ )
317340 )?;
318− write!(handle, "{}", &text[text_trimmed.len()..])?;
341+
342+ if text.len() != text_trimmed.len() {
343+ if let Some(background_color) = background_color {
344+ let mut ansi_style = Style::default();
345+ ansi_style.background = Some(to_ansi_color(background_color, true_color));
346+ let width = if cursor_total <= cursor_max {
347+ cursor_max - cursor_total + 1
348+ } else {
349+ 0
350+ };
351+ write!(handle, "{}", ansi_style.paint(" ".repeat(width)))?;
352+ }
353+ write!(handle, "{}", &text[text_trimmed.len()..])?;
354+ }
319355 }
320356
321357 if line.bytes().next_back() != Some(b'\n') {
@@ -370,7 +406,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
370406 ),
371407 self.config.true_color,
372408 self.config.colored_output,
373− self.config.use_italic_text
409+ self.config.use_italic_text,
410+ background_color
374411 )
375412 )?;
376413 break;
@@ -410,7 +447,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
410447 ),
411448 self.config.true_color,
412449 self.config.colored_output,
413− self.config.use_italic_text
450+ self.config.use_italic_text,
451+ background_color
414452 ),
415453 panel_wrap.clone().unwrap()
416454 )?;
@@ -423,6 +461,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
423461 }
424462 }
425463
464+ if let Some(background_color) = background_color {
465+ let mut ansi_style = Style::default();
466+ ansi_style.background =
467+ Some(to_ansi_color(background_color, self.config.true_color));
468+
469+ write!(
470+ handle,
471+ "{}",
472+ ansi_style.paint(" ".repeat(cursor_max - cursor))
473+ )?;
474+ }
426475 write!(handle, "\n")?;
427476 }
428477
src/terminal.rs+3−1
@@ -19,8 +19,9 @@ pub fn as_terminal_escaped(
1919 true_color: bool,
2020 colored: bool,
2121 italics: bool,
22+ background_color: Option<highlighting::Color>,
2223) -> String {
23− let style = if !colored {
24+ let mut style = if !colored {
2425 Style::default()
2526 } else {
2627 let color = to_ansi_color(style.foreground, true_color);
@@ -36,5 +37,6 @@ pub fn as_terminal_escaped(
3637 }
3738 };
3839
40+ style.background = background_color.map(|c| to_ansi_color(c, true_color));
3941 style.paint(text).to_string()
4042}