Merge pull request #453 from sharkdp/line-highlight

Line highlight
This commit is contained in:
David Peter 2018-12-18 09:06:28 +01:00 committed by GitHub
commit 668c8a6703
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 5 deletions

View File

@ -77,7 +77,11 @@ pub struct Config<'a> {
/// Command to start the pager /// Command to start the pager
pub pager: Option<&'a str>, pub pager: Option<&'a str>,
/// Whether or not to use ANSI italics
pub use_italic_text: bool, pub use_italic_text: bool,
/// Lines to highlight
pub highlight_lines: Vec<usize>,
} }
fn is_truecolor_terminal() -> bool { fn is_truecolor_terminal() -> bool {
@ -264,6 +268,11 @@ impl App {
Some("always") => true, Some("always") => true,
_ => false, _ => false,
}, },
highlight_lines: self
.matches
.values_of("highlight-line")
.and_then(|ws| ws.map(|w| w.parse().ok()).collect())
.unwrap_or_default(),
}) })
} }

View File

@ -175,6 +175,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.arg( .arg(
Arg::with_name("line-range") Arg::with_name("line-range")
.long("line-range") .long("line-range")
.short("r")
.multiple(true) .multiple(true)
.takes_value(true) .takes_value(true)
.number_of_values(1) .number_of_values(1)
@ -188,6 +189,19 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
'--line-range 40:' prints lines 40 to the end of the file", '--line-range 40:' prints lines 40 to the end of the file",
), ),
) )
.arg(
Arg::with_name("highlight-line")
.long("highlight-line")
.short("H")
.takes_value(true)
.number_of_values(1)
.multiple(true)
.value_name("N")
.help("Highlight the given line.")
.long_help(
"Highlight the N-th line with a different background color",
),
)
.arg( .arg(
Arg::with_name("color") Arg::with_name("color")
.long("color") .long("color")

View File

@ -7,6 +7,7 @@ use ansi_term::Style;
use console::AnsiCodeIterator; use console::AnsiCodeIterator;
use syntect::easy::HighlightLines; use syntect::easy::HighlightLines;
use syntect::highlighting::Color;
use syntect::highlighting::Theme; use syntect::highlighting::Theme;
use syntect::parsing::SyntaxSet; use syntect::parsing::SyntaxSet;
@ -79,6 +80,7 @@ pub struct InteractivePrinter<'a> {
pub line_changes: Option<LineChanges>, pub line_changes: Option<LineChanges>,
highlighter: Option<HighlightLines<'a>>, highlighter: Option<HighlightLines<'a>>,
syntax_set: &'a SyntaxSet, syntax_set: &'a SyntaxSet,
background_color_highlight: Option<Color>,
} }
impl<'a> InteractivePrinter<'a> { impl<'a> InteractivePrinter<'a> {
@ -90,6 +92,8 @@ impl<'a> InteractivePrinter<'a> {
) -> Self { ) -> Self {
let theme = assets.get_theme(&config.theme); let theme = assets.get_theme(&config.theme);
let background_color_highlight = theme.settings.line_highlight;
let colors = if config.colored_output { let colors = if config.colored_output {
Colors::colored(theme, config.true_color) Colors::colored(theme, config.true_color)
} else { } else {
@ -156,6 +160,7 @@ impl<'a> InteractivePrinter<'a> {
line_changes, line_changes,
highlighter, highlighter,
syntax_set: &assets.syntax_set, syntax_set: &assets.syntax_set,
background_color_highlight,
} }
} }
@ -287,6 +292,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
let mut cursor_total: usize = 0; let mut cursor_total: usize = 0;
let mut panel_wrap: Option<String> = None; let mut panel_wrap: Option<String> = None;
// Line highlighting
let highlight_this_line = self
.config
.highlight_lines
.iter()
.any(|&l| l == line_number);
let background_color = self
.background_color_highlight
.filter(|_| highlight_this_line);
// Line decorations. // Line decorations.
if self.panel_width > 0 { if self.panel_width > 0 {
let decorations = self let decorations = self
@ -313,10 +329,30 @@ impl<'a> Printer for InteractivePrinter<'a> {
write!( write!(
handle, handle,
"{}", "{}",
as_terminal_escaped(style, text_trimmed, true_color, colored_output, italics,) as_terminal_escaped(
style,
text_trimmed,
true_color,
colored_output,
italics,
background_color
)
)?; )?;
if text.len() != text_trimmed.len() {
if let Some(background_color) = background_color {
let mut ansi_style = Style::default();
ansi_style.background = Some(to_ansi_color(background_color, true_color));
let width = if cursor_total <= cursor_max {
cursor_max - cursor_total + 1
} else {
0
};
write!(handle, "{}", ansi_style.paint(" ".repeat(width)))?;
}
write!(handle, "{}", &text[text_trimmed.len()..])?; write!(handle, "{}", &text[text_trimmed.len()..])?;
} }
}
if line.bytes().next_back() != Some(b'\n') { if line.bytes().next_back() != Some(b'\n') {
write!(handle, "\n")?; write!(handle, "\n")?;
@ -370,7 +406,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
), ),
self.config.true_color, self.config.true_color,
self.config.colored_output, self.config.colored_output,
self.config.use_italic_text self.config.use_italic_text,
background_color
) )
)?; )?;
break; break;
@ -410,7 +447,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
), ),
self.config.true_color, self.config.true_color,
self.config.colored_output, self.config.colored_output,
self.config.use_italic_text self.config.use_italic_text,
background_color
), ),
panel_wrap.clone().unwrap() panel_wrap.clone().unwrap()
)?; )?;
@ -423,6 +461,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
} }
} }
if let Some(background_color) = background_color {
let mut ansi_style = Style::default();
ansi_style.background =
Some(to_ansi_color(background_color, self.config.true_color));
write!(
handle,
"{}",
ansi_style.paint(" ".repeat(cursor_max - cursor))
)?;
}
write!(handle, "\n")?; write!(handle, "\n")?;
} }

View File

@ -19,8 +19,9 @@ pub fn as_terminal_escaped(
true_color: bool, true_color: bool,
colored: bool, colored: bool,
italics: bool, italics: bool,
background_color: Option<highlighting::Color>,
) -> String { ) -> String {
let style = if !colored { let mut style = if !colored {
Style::default() Style::default()
} else { } else {
let color = to_ansi_color(style.foreground, true_color); let color = to_ansi_color(style.foreground, true_color);
@ -36,5 +37,6 @@ pub fn as_terminal_escaped(
} }
}; };
style.background = background_color.map(|c| to_ansi_color(c, true_color));
style.paint(text).to_string() style.paint(text).to_string()
} }