mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-11-23 21:54:45 +02:00
colors: add highlight type support for matching lines
This lets users highlight non-matching text in matching lines. Closes #3024, Closes #3107
This commit is contained in:
committed by
Andrew Gallant
parent
126bbeab8c
commit
99fe884536
@@ -51,13 +51,13 @@ impl std::fmt::Display for ColorError {
|
||||
ColorError::UnrecognizedOutType(ref name) => write!(
|
||||
f,
|
||||
"unrecognized output type '{}'. Choose from: \
|
||||
path, line, column, match.",
|
||||
path, line, column, match, highlight.",
|
||||
name,
|
||||
),
|
||||
ColorError::UnrecognizedSpecType(ref name) => write!(
|
||||
f,
|
||||
"unrecognized spec type '{}'. Choose from: \
|
||||
fg, bg, style, none.",
|
||||
fg, bg, style, none.",
|
||||
name,
|
||||
),
|
||||
ColorError::UnrecognizedColor(_, ref msg) => write!(f, "{}", msg),
|
||||
@@ -70,8 +70,8 @@ impl std::fmt::Display for ColorError {
|
||||
),
|
||||
ColorError::InvalidFormat(ref original) => write!(
|
||||
f,
|
||||
"invalid color spec format: '{}'. Valid format \
|
||||
is '(path|line|column|match):(fg|bg|style):(value)'.",
|
||||
"invalid color spec format: '{}'. Valid format is \
|
||||
'(path|line|column|match|highlight):(fg|bg|style):(value)'.",
|
||||
original,
|
||||
),
|
||||
}
|
||||
@@ -90,6 +90,7 @@ pub struct ColorSpecs {
|
||||
line: ColorSpec,
|
||||
column: ColorSpec,
|
||||
matched: ColorSpec,
|
||||
highlight: ColorSpec,
|
||||
}
|
||||
|
||||
/// A single color specification provided by the user.
|
||||
@@ -99,7 +100,7 @@ pub struct ColorSpecs {
|
||||
/// The format of a `Spec` is a triple: `{type}:{attribute}:{value}`. Each
|
||||
/// component is defined as follows:
|
||||
///
|
||||
/// * `{type}` can be one of `path`, `line`, `column` or `match`.
|
||||
/// * `{type}` can be one of `path`, `line`, `column`, `match` or `highlight`.
|
||||
/// * `{attribute}` can be one of `fg`, `bg` or `style`. `{attribute}` may also
|
||||
/// be the special value `none`, in which case, `{value}` can be omitted.
|
||||
/// * `{value}` is either a color name (for `fg`/`bg`) or a style instruction.
|
||||
@@ -181,6 +182,7 @@ enum OutType {
|
||||
Line,
|
||||
Column,
|
||||
Match,
|
||||
Highlight,
|
||||
}
|
||||
|
||||
/// The specification type.
|
||||
@@ -216,6 +218,7 @@ impl ColorSpecs {
|
||||
OutType::Line => spec.merge_into(&mut merged.line),
|
||||
OutType::Column => spec.merge_into(&mut merged.column),
|
||||
OutType::Match => spec.merge_into(&mut merged.matched),
|
||||
OutType::Highlight => spec.merge_into(&mut merged.highlight),
|
||||
}
|
||||
}
|
||||
merged
|
||||
@@ -249,6 +252,12 @@ impl ColorSpecs {
|
||||
pub fn matched(&self) -> &ColorSpec {
|
||||
&self.matched
|
||||
}
|
||||
|
||||
/// Return the color specification for coloring entire line if there is a
|
||||
/// matched text.
|
||||
pub fn highlight(&self) -> &ColorSpec {
|
||||
&self.highlight
|
||||
}
|
||||
}
|
||||
|
||||
impl UserColorSpec {
|
||||
@@ -348,6 +357,7 @@ impl std::str::FromStr for OutType {
|
||||
"line" => Ok(OutType::Line),
|
||||
"column" => Ok(OutType::Column),
|
||||
"match" => Ok(OutType::Match),
|
||||
"highlight" => Ok(OutType::Highlight),
|
||||
_ => Err(ColorError::UnrecognizedOutType(s.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1320,6 +1320,7 @@ impl<'a, M: Matcher, W: WriteColor> StandardImpl<'a, M, W> {
|
||||
self.write(&bytes[line])?;
|
||||
return Ok(());
|
||||
}
|
||||
self.start_line_highlight()?;
|
||||
while !line.is_empty() {
|
||||
if matches[*match_index].end() <= line.start() {
|
||||
if *match_index + 1 < matches.len() {
|
||||
@@ -1346,6 +1347,7 @@ impl<'a, M: Matcher, W: WriteColor> StandardImpl<'a, M, W> {
|
||||
}
|
||||
}
|
||||
self.end_color_match()?;
|
||||
self.end_line_highlight()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1547,11 +1549,37 @@ impl<'a, M: Matcher, W: WriteColor> StandardImpl<'a, M, W> {
|
||||
if !self.in_color_match.get() {
|
||||
return Ok(());
|
||||
}
|
||||
self.wtr().borrow_mut().reset()?;
|
||||
if self.highlight_on() {
|
||||
self.wtr()
|
||||
.borrow_mut()
|
||||
.set_color(self.config().colors.highlight())?;
|
||||
} else {
|
||||
self.wtr().borrow_mut().reset()?;
|
||||
}
|
||||
self.in_color_match.set(false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn highlight_on(&self) -> bool {
|
||||
!self.config().colors.highlight().is_none() && !self.is_context()
|
||||
}
|
||||
|
||||
fn start_line_highlight(&self) -> io::Result<()> {
|
||||
if self.highlight_on() {
|
||||
self.wtr()
|
||||
.borrow_mut()
|
||||
.set_color(self.config().colors.highlight())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_line_highlight(&self) -> io::Result<()> {
|
||||
if self.highlight_on() {
|
||||
self.wtr().borrow_mut().reset()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&self, buf: &[u8]) -> io::Result<()> {
|
||||
self.wtr().borrow_mut().write_all(buf)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user