mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 09:40:22 -07:00
Rejigger bold and intense settings.
Previously, ripgrep would only emit the 'bold' ANSI escape sequence if no foreground or background color was set. Instead, it would convert colors to their "intense" versions if bold was set. The intent was to do the same thing on Windows and Unix. However, this had a few negative side effects: 1. Omitting the 'bold' ANSI escape when 'bold' was set is surprising. 2. Intense colors can look quite bad and be hard to read. To fix this, we introduce a new setting called 'intense' in the --colors flag, and thread that down through to the public API of the `termcolor` crate. The 'intense' setting has environment specific behavior: 1. In ANSI mode, it will convert the selected color to its "intense" variant. 2. In the Windows console, it will make the text "intense." There is no longer any "smart" handling of the 'bold' style. The 'bold' ANSI escape is always emitted when it is selected. In the Windows console, the 'bold' setting now has no effect. Note that this is a breaking change. Fixes #266, #293
This commit is contained in:
parent
f7a2fe30d4
commit
b187c1a817
4
doc/rg.1
4
doc/rg.1
@ -1,6 +1,6 @@
|
|||||||
.\" Automatically generated by Pandoc 1.19.1
|
.\" Automatically generated by Pandoc 1.19.1
|
||||||
.\"
|
.\"
|
||||||
.TH "" "" "" "" ""
|
.TH "rg" "1"
|
||||||
.hy
|
.hy
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.PP
|
.PP
|
||||||
@ -162,7 +162,7 @@ This flag may be provided multiple times.
|
|||||||
Settings are applied iteratively.
|
Settings are applied iteratively.
|
||||||
Colors are limited to one of eight choices: red, blue, green, cyan,
|
Colors are limited to one of eight choices: red, blue, green, cyan,
|
||||||
magenta, yellow, white and black.
|
magenta, yellow, white and black.
|
||||||
Styles are limited to either nobold or bold.
|
Styles are limited to nobold, bold, nointense or intense.
|
||||||
.RS
|
.RS
|
||||||
.PP
|
.PP
|
||||||
The format of the flag is {type}:{attribute}:{value}.
|
The format of the flag is {type}:{attribute}:{value}.
|
||||||
|
@ -111,7 +111,7 @@ Project home page: https://github.com/BurntSushi/ripgrep
|
|||||||
: 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 either nobold or bold.
|
black. Styles are limited to nobold, bold, nointense or intense.
|
||||||
|
|
||||||
The format of the flag is {type}:{attribute}:{value}. {type} should be one
|
The format of the flag is {type}:{attribute}:{value}. {type} should be one
|
||||||
of path, line or match. {attribute} can be fg, bg or style. Value is either
|
of path, line or match. {attribute} can be fg, bg or style. Value is either
|
||||||
|
16
src/app.rs
16
src/app.rs
@ -237,14 +237,14 @@ lazy_static! {
|
|||||||
This flag may be provided multiple times. Settings are applied \
|
This flag may be provided multiple times. Settings are applied \
|
||||||
iteratively. Colors are limited to one of eight choices: \
|
iteratively. Colors are limited to one of eight choices: \
|
||||||
red, blue, green, cyan, magenta, yellow, white and black. \
|
red, blue, green, cyan, magenta, yellow, white and black. \
|
||||||
Styles are limited to either nobold or bold.\n\nThe format \
|
Styles are limited to nobold, bold, nointense or intense.\n\n
|
||||||
of the flag is {type}:{attribute}:{value}. {type} should be \
|
The format of the flag is {type}:{attribute}:{value}. {type} \
|
||||||
one of path, line or match. {attribute} can be fg, bg or style. \
|
should be one of path, line or match. {attribute} can be fg, bg \
|
||||||
{value} is either a color (for fg and bg) or a text style. \
|
or style. {value} is either a color (for fg and bg) or a text \
|
||||||
A special format, {type}:none, will clear all color settings \
|
style. A special format, {type}:none, will clear all color \
|
||||||
for {type}.\n\nFor example, the following command will change \
|
settings for {type}.\n\nFor example, the following command will \
|
||||||
the match color to magenta and the background color for line \
|
change the match color to magenta and the background color for \
|
||||||
numbers to yellow:\n\n\
|
line numbers to yellow:\n\n\
|
||||||
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
|
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
|
||||||
doc!(h, "fixed-strings",
|
doc!(h, "fixed-strings",
|
||||||
"Treat the pattern as a literal string.",
|
"Treat the pattern as a literal string.",
|
||||||
|
@ -640,11 +640,10 @@ impl<'a> ArgMatches<'a> {
|
|||||||
fn color_specs(&self) -> Result<ColorSpecs> {
|
fn color_specs(&self) -> Result<ColorSpecs> {
|
||||||
// Start with a default set of color specs.
|
// Start with a default set of color specs.
|
||||||
let mut specs = vec![
|
let mut specs = vec![
|
||||||
"path:fg:green".parse().unwrap(),
|
"path:fg:magenta".parse().unwrap(),
|
||||||
"path:style:bold".parse().unwrap(),
|
"line:fg:green".parse().unwrap(),
|
||||||
"line:fg:blue".parse().unwrap(),
|
|
||||||
"line:style:bold".parse().unwrap(),
|
|
||||||
"match:fg:red".parse().unwrap(),
|
"match:fg:red".parse().unwrap(),
|
||||||
|
"match:style:intense".parse().unwrap(),
|
||||||
"match:style:bold".parse().unwrap(),
|
"match:style:bold".parse().unwrap(),
|
||||||
];
|
];
|
||||||
for spec_str in self.values_of_lossy_vec("colors") {
|
for spec_str in self.values_of_lossy_vec("colors") {
|
||||||
|
@ -523,6 +523,8 @@ enum SpecType {
|
|||||||
enum Style {
|
enum Style {
|
||||||
Bold,
|
Bold,
|
||||||
NoBold,
|
NoBold,
|
||||||
|
Intense,
|
||||||
|
NoIntense,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorSpecs {
|
impl ColorSpecs {
|
||||||
@ -574,6 +576,8 @@ impl SpecValue {
|
|||||||
match *style {
|
match *style {
|
||||||
Style::Bold => { cspec.set_bold(true); }
|
Style::Bold => { cspec.set_bold(true); }
|
||||||
Style::NoBold => { cspec.set_bold(false); }
|
Style::NoBold => { cspec.set_bold(false); }
|
||||||
|
Style::Intense => { cspec.set_intense(true); }
|
||||||
|
Style::NoIntense => { cspec.set_intense(false); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -650,6 +654,8 @@ impl FromStr for Style {
|
|||||||
match &*s.to_lowercase() {
|
match &*s.to_lowercase() {
|
||||||
"bold" => Ok(Style::Bold),
|
"bold" => Ok(Style::Bold),
|
||||||
"nobold" => Ok(Style::NoBold),
|
"nobold" => Ok(Style::NoBold),
|
||||||
|
"intense" => Ok(Style::Intense),
|
||||||
|
"nointense" => Ok(Style::NoIntense),
|
||||||
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,6 +702,12 @@ mod tests {
|
|||||||
value: SpecValue::Style(Style::Bold),
|
value: SpecValue::Style(Style::Bold),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let spec: Spec = "match:style:intense".parse().unwrap();
|
||||||
|
assert_eq!(spec, Spec {
|
||||||
|
ty: OutType::Match,
|
||||||
|
value: SpecValue::Style(Style::Intense),
|
||||||
|
});
|
||||||
|
|
||||||
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,
|
||||||
|
@ -760,12 +760,12 @@ impl<W: io::Write> WriteColor for Ansi<W> {
|
|||||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||||
try!(self.reset());
|
try!(self.reset());
|
||||||
if let Some(ref c) = spec.fg_color {
|
if let Some(ref c) = spec.fg_color {
|
||||||
try!(self.write_color(true, c, spec.bold));
|
try!(self.write_color(true, c, spec.intense));
|
||||||
}
|
}
|
||||||
if let Some(ref c) = spec.bg_color {
|
if let Some(ref c) = spec.bg_color {
|
||||||
try!(self.write_color(false, c, spec.bold));
|
try!(self.write_color(false, c, spec.intense));
|
||||||
}
|
}
|
||||||
if spec.bold && spec.fg_color.is_none() && spec.bg_color.is_none() {
|
if spec.bold {
|
||||||
try!(self.write_str("\x1B[1m"));
|
try!(self.write_str("\x1B[1m"));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -785,11 +785,8 @@ impl<W: io::Write> Ansi<W> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
fg: bool,
|
fg: bool,
|
||||||
c: &Color,
|
c: &Color,
|
||||||
bold: bool,
|
intense: bool,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
// *sigh*... The termion crate doesn't compile on Windows, and we
|
|
||||||
// need to be able to write ANSI escape sequences on Windows, so I
|
|
||||||
// guess we have to roll this ourselves.
|
|
||||||
macro_rules! w {
|
macro_rules! w {
|
||||||
($selfie:expr, $fg:expr, $clr:expr) => {
|
($selfie:expr, $fg:expr, $clr:expr) => {
|
||||||
if $fg {
|
if $fg {
|
||||||
@ -799,7 +796,7 @@ impl<W: io::Write> Ansi<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bold {
|
if intense {
|
||||||
match *c {
|
match *c {
|
||||||
Color::Black => w!(self, fg, "8"),
|
Color::Black => w!(self, fg, "8"),
|
||||||
Color::Blue => w!(self, fg, "12"),
|
Color::Blue => w!(self, fg, "12"),
|
||||||
@ -935,12 +932,13 @@ pub struct ColorSpec {
|
|||||||
fg_color: Option<Color>,
|
fg_color: Option<Color>,
|
||||||
bg_color: Option<Color>,
|
bg_color: Option<Color>,
|
||||||
bold: bool,
|
bold: bool,
|
||||||
|
intense: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorSpec {
|
impl ColorSpec {
|
||||||
/// Create a new color specification that has no colors or styles.
|
/// Create a new color specification that has no colors or styles.
|
||||||
pub fn new() -> ColorSpec {
|
pub fn new() -> ColorSpec {
|
||||||
ColorSpec { fg_color: None, bg_color: None, bold: false }
|
ColorSpec::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the foreground color.
|
/// Get the foreground color.
|
||||||
@ -962,14 +960,27 @@ impl ColorSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get whether this is bold or not.
|
/// Get whether this is bold or not.
|
||||||
|
///
|
||||||
|
/// Note that the bold setting has no effect in a Windows console.
|
||||||
pub fn bold(&self) -> bool { self.bold }
|
pub fn bold(&self) -> bool { self.bold }
|
||||||
|
|
||||||
/// Set whether the text is bolded or not.
|
/// Set whether the text is bolded or not.
|
||||||
|
///
|
||||||
|
/// Note that the bold setting has no effect in a Windows console.
|
||||||
pub fn set_bold(&mut self, yes: bool) -> &mut ColorSpec {
|
pub fn set_bold(&mut self, yes: bool) -> &mut ColorSpec {
|
||||||
self.bold = yes;
|
self.bold = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get whether this is intense or not.
|
||||||
|
pub fn intense(&self) -> bool { self.intense }
|
||||||
|
|
||||||
|
/// Set whether the text is intense or not.
|
||||||
|
pub fn set_intense(&mut self, yes: bool) -> &mut ColorSpec {
|
||||||
|
self.intense = yes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
@ -990,7 +1001,7 @@ impl ColorSpec {
|
|||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
use wincolor::Intense;
|
use wincolor::Intense;
|
||||||
|
|
||||||
let intense = if self.bold { Intense::Yes } else { Intense::No };
|
let intense = if self.intense { Intense::Yes } else { Intense::No };
|
||||||
if let Some(color) = self.fg_color.as_ref().map(|c| c.to_windows()) {
|
if let Some(color) = self.fg_color.as_ref().map(|c| c.to_windows()) {
|
||||||
try!(console.fg(intense, color));
|
try!(console.fg(intense, color));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user