Skip to content

Commit

Permalink
Rejigger bold and intense settings.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
BurntSushi committed Jan 7, 2017
1 parent f7a2fe3 commit b187c1a
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 25 deletions.
4 changes: 2 additions & 2 deletions doc/rg.1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 1.19.1
.\"
.TH "" "" "" "" ""
.TH "rg" "1"
.hy
.SH NAME
.PP
Expand Down Expand Up @@ -162,7 +162,7 @@ This flag may be provided multiple times.
Settings are applied iteratively.
Colors are limited to one of eight choices: red, blue, green, cyan,
magenta, yellow, white and black.
Styles are limited to either nobold or bold.
Styles are limited to nobold, bold, nointense or intense.
.RS
.PP
The format of the flag is {type}:{attribute}:{value}.
Expand Down
2 changes: 1 addition & 1 deletion doc/rg.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
provided multiple times. Settings are applied iteratively. Colors are limited
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
of path, line or match. {attribute} can be fg, bg or style. Value is either
Expand Down
16 changes: 8 additions & 8 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,14 @@ lazy_static! {
This flag may be provided multiple times. Settings are applied \
iteratively. Colors are limited to one of eight choices: \
red, blue, green, cyan, magenta, yellow, white and black. \
Styles are limited to either nobold or bold.\n\nThe 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 a color (for fg and bg) or a text style. \
A special format, {type}:none, will clear all color settings \
for {type}.\n\nFor example, the following command will change \
the match color to magenta and the background color for line \
numbers to yellow:\n\n\
Styles are limited to nobold, bold, nointense or intense.\n\n
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 a color (for fg and bg) or a text \
style. A special format, {type}:none, will clear all color \
settings for {type}.\n\nFor example, the following command will \
change the match color to magenta and the background color for \
line numbers to yellow:\n\n\
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
doc!(h, "fixed-strings",
"Treat the pattern as a literal string.",
Expand Down
7 changes: 3 additions & 4 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,11 +640,10 @@ impl<'a> ArgMatches<'a> {
fn color_specs(&self) -> Result<ColorSpecs> {
// Start with a default set of color specs.
let mut specs = vec![
"path:fg:green".parse().unwrap(),
"path:style:bold".parse().unwrap(),
"line:fg:blue".parse().unwrap(),
"line:style:bold".parse().unwrap(),
"path:fg:magenta".parse().unwrap(),
"line:fg:green".parse().unwrap(),
"match:fg:red".parse().unwrap(),
"match:style:intense".parse().unwrap(),
"match:style:bold".parse().unwrap(),
];
for spec_str in self.values_of_lossy_vec("colors") {
Expand Down
12 changes: 12 additions & 0 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ enum SpecType {
enum Style {
Bold,
NoBold,
Intense,
NoIntense,
}

impl ColorSpecs {
Expand Down Expand Up @@ -574,6 +576,8 @@ impl SpecValue {
match *style {
Style::Bold => { cspec.set_bold(true); }
Style::NoBold => { cspec.set_bold(false); }
Style::Intense => { cspec.set_intense(true); }
Style::NoIntense => { cspec.set_intense(false); }
}
}
}
Expand Down Expand Up @@ -650,6 +654,8 @@ impl FromStr for Style {
match &*s.to_lowercase() {
"bold" => Ok(Style::Bold),
"nobold" => Ok(Style::NoBold),
"intense" => Ok(Style::Intense),
"nointense" => Ok(Style::NoIntense),
_ => Err(Error::UnrecognizedStyle(s.to_string())),
}
}
Expand Down Expand Up @@ -696,6 +702,12 @@ mod tests {
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();
assert_eq!(spec, Spec {
ty: OutType::Line,
Expand Down
31 changes: 21 additions & 10 deletions termcolor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,12 +760,12 @@ impl<W: io::Write> WriteColor for Ansi<W> {
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
try!(self.reset());
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 {
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"));
}
Ok(())
Expand All @@ -785,11 +785,8 @@ impl<W: io::Write> Ansi<W> {
&mut self,
fg: bool,
c: &Color,
bold: bool,
intense: bool,
) -> 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 {
($selfie:expr, $fg:expr, $clr:expr) => {
if $fg {
Expand All @@ -799,7 +796,7 @@ impl<W: io::Write> Ansi<W> {
}
}
}
if bold {
if intense {
match *c {
Color::Black => w!(self, fg, "8"),
Color::Blue => w!(self, fg, "12"),
Expand Down Expand Up @@ -935,12 +932,13 @@ pub struct ColorSpec {
fg_color: Option<Color>,
bg_color: Option<Color>,
bold: bool,
intense: bool,
}

impl ColorSpec {
/// Create a new color specification that has no colors or styles.
pub fn new() -> ColorSpec {
ColorSpec { fg_color: None, bg_color: None, bold: false }
ColorSpec::default()
}

/// Get the foreground color.
Expand All @@ -962,14 +960,27 @@ impl ColorSpec {
}

/// 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 }

/// 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 {
self.bold = yes;
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.
pub fn is_none(&self) -> bool {
self.fg_color.is_none() && self.bg_color.is_none() && !self.bold
Expand All @@ -990,7 +1001,7 @@ impl ColorSpec {
) -> io::Result<()> {
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()) {
try!(console.fg(intense, color));
}
Expand Down

0 comments on commit b187c1a

Please sign in to comment.