mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 09:40:22 -07:00
termcolor: add underline support
This commit adds underline support to the termcolor crate, and exposes it through ripgrep. Fixes #798
This commit is contained in:
parent
d09538c974
commit
d57fc58081
8
FAQ.md
8
FAQ.md
@ -190,10 +190,10 @@ The --colors` flag is a bit more complicated. The general format is:
|
|||||||
* `{attribute}` should be one of `fg`, `bg` or `style`, corresponding to
|
* `{attribute}` should be one of `fg`, `bg` or `style`, corresponding to
|
||||||
foreground color, background color, or miscellaneous styling (such as whether
|
foreground color, background color, or miscellaneous styling (such as whether
|
||||||
to bold the output or not).
|
to bold the output or not).
|
||||||
* `{value}` is determined by the value of `{attribute}`. If `{attribute}` is
|
* `{value}` is determined by the value of `{attribute}`. If
|
||||||
`style`, then `{value}` should be one of `nobold`, `bold`, `nointense` or
|
`{attribute}` is `style`, then `{value}` should be one of `nobold`,
|
||||||
`intense`. If `{attribute}` is `fg` or `bg`, then `{value}` should be a
|
`bold`, `nointense`, `intense`, `nounderline` or `underline`. If
|
||||||
color.
|
`{attribute}` is `fg` or `bg`, then `{value}` should be a color.
|
||||||
|
|
||||||
A color is specified by either one of eight of English names, a single 256-bit
|
A color is specified by either one of eight of English names, a single 256-bit
|
||||||
number or an RGB triple (with over 16 million possible values, or "true
|
number or an RGB triple (with over 16 million possible values, or "true
|
||||||
|
@ -125,7 +125,7 @@ _rg() {
|
|||||||
|
|
||||||
[[ "${state}" == 'style' ]] &&
|
[[ "${state}" == 'style' ]] &&
|
||||||
_values -S ':' 'style value' \
|
_values -S ':' 'style value' \
|
||||||
bold nobold intense nointense && return 0
|
bold nobold intense nointense underline nounderline && return 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
typespec)
|
typespec)
|
||||||
|
@ -682,7 +682,8 @@ fn flag_colors(args: &mut Vec<RGArg>) {
|
|||||||
This flag specifies color settings for use in the output. This flag may be
|
This flag specifies color settings for use in the output. This flag may be
|
||||||
provided multiple times. Settings are applied iteratively. Colors are limited
|
provided multiple times. Settings are applied iteratively. Colors are limited
|
||||||
to one of eight choices: red, blue, green, cyan, magenta, yellow, white and
|
to one of eight choices: red, blue, green, cyan, magenta, yellow, white and
|
||||||
black. Styles are limited to nobold, bold, nointense or intense.
|
black. Styles are limited to nobold, bold, nointense, intense, nounderline
|
||||||
|
or underline.
|
||||||
|
|
||||||
The format of the flag is `{type}:{attribute}:{value}`. `{type}` should be
|
The format of the flag is `{type}:{attribute}:{value}`. `{type}` should be
|
||||||
one of path, line, column or match. `{attribute}` can be fg, bg or style.
|
one of path, line, column or match. `{attribute}` can be fg, bg or style.
|
||||||
|
@ -555,7 +555,8 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
Error::UnrecognizedStyle(ref name) => {
|
Error::UnrecognizedStyle(ref name) => {
|
||||||
write!(f, "Unrecognized style attribute '{}'. Choose from: \
|
write!(f, "Unrecognized style attribute '{}'. Choose from: \
|
||||||
nobold, bold, nointense, intense.", name)
|
nobold, bold, nointense, intense, nounderline, \
|
||||||
|
underline.", name)
|
||||||
}
|
}
|
||||||
Error::InvalidFormat(ref original) => {
|
Error::InvalidFormat(ref original) => {
|
||||||
write!(
|
write!(
|
||||||
@ -627,7 +628,8 @@ pub struct ColorSpecs {
|
|||||||
/// Valid colors are `black`, `blue`, `green`, `red`, `cyan`, `magenta`,
|
/// Valid colors are `black`, `blue`, `green`, `red`, `cyan`, `magenta`,
|
||||||
/// `yellow`, `white`.
|
/// `yellow`, `white`.
|
||||||
///
|
///
|
||||||
/// Valid style instructions are `nobold`, `bold`, `intense`, `nointense`.
|
/// Valid style instructions are `nobold`, `bold`, `intense`, `nointense`,
|
||||||
|
/// `underline`, `nounderline`.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Spec {
|
pub struct Spec {
|
||||||
ty: OutType,
|
ty: OutType,
|
||||||
@ -668,6 +670,8 @@ enum Style {
|
|||||||
NoBold,
|
NoBold,
|
||||||
Intense,
|
Intense,
|
||||||
NoIntense,
|
NoIntense,
|
||||||
|
Underline,
|
||||||
|
NoUnderline
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorSpecs {
|
impl ColorSpecs {
|
||||||
@ -727,6 +731,8 @@ impl SpecValue {
|
|||||||
Style::NoBold => { cspec.set_bold(false); }
|
Style::NoBold => { cspec.set_bold(false); }
|
||||||
Style::Intense => { cspec.set_intense(true); }
|
Style::Intense => { cspec.set_intense(true); }
|
||||||
Style::NoIntense => { cspec.set_intense(false); }
|
Style::NoIntense => { cspec.set_intense(false); }
|
||||||
|
Style::Underline => { cspec.set_underline(true); }
|
||||||
|
Style::NoUnderline => { cspec.set_underline(false); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,6 +812,8 @@ impl FromStr for Style {
|
|||||||
"nobold" => Ok(Style::NoBold),
|
"nobold" => Ok(Style::NoBold),
|
||||||
"intense" => Ok(Style::Intense),
|
"intense" => Ok(Style::Intense),
|
||||||
"nointense" => Ok(Style::NoIntense),
|
"nointense" => Ok(Style::NoIntense),
|
||||||
|
"underline" => Ok(Style::Underline),
|
||||||
|
"nounderline" => Ok(Style::NoUnderline),
|
||||||
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -859,6 +867,12 @@ mod tests {
|
|||||||
value: SpecValue::Style(Style::Intense),
|
value: SpecValue::Style(Style::Intense),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let spec: Spec = "match:style:underline".parse().unwrap();
|
||||||
|
assert_eq!(spec, Spec {
|
||||||
|
ty: OutType::Match,
|
||||||
|
value: SpecValue::Style(Style::Underline),
|
||||||
|
});
|
||||||
|
|
||||||
let spec: Spec = "line:none".parse().unwrap();
|
let spec: Spec = "line:none".parse().unwrap();
|
||||||
assert_eq!(spec, Spec {
|
assert_eq!(spec, Spec {
|
||||||
ty: OutType::Line,
|
ty: OutType::Line,
|
||||||
|
@ -980,6 +980,9 @@ impl<W: io::Write> WriteColor for Ansi<W> {
|
|||||||
if spec.bold {
|
if spec.bold {
|
||||||
self.write_str("\x1B[1m")?;
|
self.write_str("\x1B[1m")?;
|
||||||
}
|
}
|
||||||
|
if spec.underline {
|
||||||
|
self.write_str("\x1B[4m")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1212,6 +1215,7 @@ pub struct ColorSpec {
|
|||||||
bg_color: Option<Color>,
|
bg_color: Option<Color>,
|
||||||
bold: bool,
|
bold: bool,
|
||||||
intense: bool,
|
intense: bool,
|
||||||
|
underline: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorSpec {
|
impl ColorSpec {
|
||||||
@ -1251,6 +1255,19 @@ impl ColorSpec {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get whether this is underline or not.
|
||||||
|
///
|
||||||
|
/// Note that the underline setting has no effect in a Windows console.
|
||||||
|
pub fn underline(&self) -> bool { self.underline }
|
||||||
|
|
||||||
|
/// Set whether the text is underlined or not.
|
||||||
|
///
|
||||||
|
/// Note that the underline setting has no effect in a Windows console.
|
||||||
|
pub fn set_underline(&mut self, yes: bool) -> &mut ColorSpec {
|
||||||
|
self.underline = yes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Get whether this is intense or not.
|
/// Get whether this is intense or not.
|
||||||
pub fn intense(&self) -> bool { self.intense }
|
pub fn intense(&self) -> bool { self.intense }
|
||||||
|
|
||||||
@ -1262,7 +1279,8 @@ impl ColorSpec {
|
|||||||
|
|
||||||
/// Returns true if this color specification has no colors or styles.
|
/// Returns true if this color specification has no colors or styles.
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
self.fg_color.is_none() && self.bg_color.is_none() && !self.bold
|
self.fg_color.is_none() && self.bg_color.is_none()
|
||||||
|
&& !self.bold && !self.underline
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears this color specification so that it has no color/style settings.
|
/// Clears this color specification so that it has no color/style settings.
|
||||||
@ -1270,6 +1288,7 @@ impl ColorSpec {
|
|||||||
self.fg_color = None;
|
self.fg_color = None;
|
||||||
self.bg_color = None;
|
self.bg_color = None;
|
||||||
self.bold = false;
|
self.bold = false;
|
||||||
|
self.underline = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes this color spec to the given Windows console.
|
/// Writes this color spec to the given Windows console.
|
||||||
|
@ -1152,7 +1152,8 @@ clean!(regression_428_unrecognized_style, "Sherlok", ".",
|
|||||||
let output = cmd.output().unwrap();
|
let output = cmd.output().unwrap();
|
||||||
let err = String::from_utf8_lossy(&output.stderr);
|
let err = String::from_utf8_lossy(&output.stderr);
|
||||||
let expected = "\
|
let expected = "\
|
||||||
Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense.
|
Unrecognized style attribute ''. Choose from: nobold, bold, nointense, intense, \
|
||||||
|
nounderline, underline.
|
||||||
";
|
";
|
||||||
assert_eq!(err, expected);
|
assert_eq!(err, expected);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user