summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-04-29 22:16:23 -0400
committerGitHub <noreply@github.com>2021-04-29 22:16:23 -0400
commit0e99a10e07b5b684b618b0a7a176fa254f8ef884 (patch)
tree9200fb820ae78e68717936fdac9b9bed40c150b8
parent656a1f939d4854fc16295b472bb8d10a044aae47 (diff)
Fix ansi syntax theme (#581)
* Update to latest version of bat::terminal::to_ansi_color Fixes #447 * Delete mention of historical syntax theme ansi-light * Update tests
-rw-r--r--src/bat_utils/terminal.rs68
-rw-r--r--src/color.rs2
-rw-r--r--src/options/theme.rs3
-rw-r--r--src/paint.rs4
-rw-r--r--src/parse_style.rs58
5 files changed, 72 insertions, 63 deletions
diff --git a/src/bat_utils/terminal.rs b/src/bat_utils/terminal.rs
index 50351c48..15c75d24 100644
--- a/src/bat_utils/terminal.rs
+++ b/src/bat_utils/terminal.rs
@@ -1,21 +1,48 @@
-extern crate ansi_colours;
-
-use ansi_term::Colour::{Fixed, RGB};
+use ansi_term::Color::{self, Fixed, RGB};
use ansi_term::{self, Style};
use syntect::highlighting::{self, FontStyle};
-pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> ansi_term::Colour {
+pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> Option<ansi_term::Color> {
if color.a == 0 {
// Themes can specify one of the user-configurable terminal colors by
// encoding them as #RRGGBBAA with AA set to 00 (transparent) and RR set
- // to the color palette number. The built-in themes ansi-light,
- // ansi-dark, and base16 use this.
- Fixed(color.r)
+ // to the 8-bit color palette number. The built-in themes ansi, base16,
+ // and base16-256 use this.
+ Some(match color.r {
+ // For the first 8 colors, use the Color enum to produce ANSI escape
+ // sequences using codes 30-37 (foreground) and 40-47 (background).
+ // For example, red foreground is \x1b[31m. This works on terminals
+ // without 256-color support.
+ 0x00 => Color::Black,
+ 0x01 => Color::Red,
+ 0x02 => Color::Green,
+ 0x03 => Color::Yellow,
+ 0x04 => Color::Blue,
+ 0x05 => Color::Purple,
+ 0x06 => Color::Cyan,
+ 0x07 => Color::White,
+ // For all other colors, use Fixed to produce escape sequences using
+ // codes 38;5 (foreground) and 48;5 (background). For example,
+ // bright red foreground is \x1b[38;5;9m. This only works on
+ // terminals with 256-color support.
+ //
+ // TODO: When ansi_term adds support for bright variants using codes
+ // 90-97 (foreground) and 100-107 (background), we should use those
+ // for values 0x08 to 0x0f and only use Fixed for 0x10 to 0xff.
+ n => Fixed(n),
+ })
+ } else if color.a == 1 {
+ // Themes can specify the terminal's default foreground/background color
+ // (i.e. no escape sequence) using the encoding #RRGGBBAA with AA set to
+ // 01. The built-in theme ansi uses this.
+ None
} else if true_color {
- RGB(color.r, color.g, color.b)
+ Some(RGB(color.r, color.g, color.b))
} else {
- Fixed(ansi_colours::ansi256_from_rgb((color.r, color.g, color.b)))
+ Some(Fixed(ansi_colours::ansi256_from_rgb((
+ color.r, color.g, color.b,
+ ))))
}
}
@@ -35,19 +62,22 @@ pub fn as_terminal_escaped(
let mut style = if !colored {
Style::default()
} else {
- let color = to_ansi_color(style.foreground, true_color);
-
+ let mut color = Style {
+ foreground: to_ansi_color(style.foreground, true_color),
+ ..Style::default()
+ };
if style.font_style.contains(FontStyle::BOLD) {
- color.bold()
- } else if style.font_style.contains(FontStyle::UNDERLINE) {
- color.underline()
- } else if italics && style.font_style.contains(FontStyle::ITALIC) {
- color.italic()
- } else {
- color.normal()
+ color = color.bold();
+ }
+ if style.font_style.contains(FontStyle::UNDERLINE) {
+ color = color.underline();
+ }
+ if italics && style.font_style.contains(FontStyle::ITALIC) {
+ color = color.italic();
}
+ color
};
- style.background = background_color.map(|c| to_ansi_color(c, true_color));
+ style.background = background_color.and_then(|c| to_ansi_color(c, true_color));
style.paint(text).to_string()
}
diff --git a/src/color.rs b/src/color.rs
index d8b8a9f7..10d9cafd 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -26,7 +26,7 @@ pub fn parse_color(s: &str, true_color: bool) -> Option<Color> {
.or_else(|| syntect_color::syntect_color_from_ansi_name(s))
.unwrap_or_else(die)
};
- Some(to_ansi_color(syntect_color, true_color))
+ to_ansi_color(syntect_color, true_color)
}
pub fn color_to_string(color: Color) -> String {
diff --git a/src/options/theme.rs b/src/options/theme.rs
index ef46dbea..fa5cbef0 100644
--- a/src/options/theme.rs
+++ b/src/options/theme.rs
@@ -38,13 +38,12 @@ pub fn is_light_syntax_theme(theme: &str) -> bool {
LIGHT_SYNTAX_THEMES.contains(&theme)
}
-const LIGHT_SYNTAX_THEMES: [&str; 7] = [
+const LIGHT_SYNTAX_THEMES: [&str; 6] = [
"GitHub",
"gruvbox-light",
"gruvbox-white",
"Monokai Extended Light",
"OneHalfLight",
- "ansi-light",
"Solarized (light)",
];
diff --git a/src/paint.rs b/src/paint.rs
index bf85fb13..0c31f094 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -667,7 +667,7 @@ mod superimpose_style_sections {
if style.is_syntax_highlighted && syntect_style != null_syntect_style {
Style {
ansi_term_style: ansi_term::Style {
- foreground: Some(to_ansi_color(syntect_style.foreground, true_color)),
+ foreground: to_ansi_color(syntect_style.foreground, true_color),
..style.ansi_term_style
},
..style
@@ -755,7 +755,7 @@ mod superimpose_style_sections {
lazy_static! {
static ref SUPERIMPOSED_STYLE: Style = Style {
ansi_term_style: ansi_term::Style {
- foreground: Some(to_ansi_color(SyntectColor::BLACK, true)),
+ foreground: to_ansi_color(SyntectColor::BLACK, true),
background: Some(Color::White),
is_underline: true,
..ansi_term::Style::new()
diff --git a/src/parse_style.rs b/src/parse_style.rs
index cf595553..02c455b0 100644
--- a/src/parse_style.rs
+++ b/src/parse_style.rs
@@ -334,8 +334,6 @@ mod tests {
use ansi_term;
- use crate::color::ansi_16_color_name_to_number;
-
#[test]
fn test_parse_ansi_term_style() {
assert_eq!(
@@ -346,9 +344,7 @@ mod tests {
parse_ansi_term_style("red", None, false),
(
ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("red").unwrap()
- )),
+ foreground: Some(ansi_term::Color::Red),
..ansi_term::Style::new()
},
false,
@@ -360,12 +356,8 @@ mod tests {
parse_ansi_term_style("red green", None, false),
(
ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("red").unwrap()
- )),
- background: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("green").unwrap()
- )),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
..ansi_term::Style::new()
},
false,
@@ -377,12 +369,8 @@ mod tests {
parse_ansi_term_style("bold red underline green blink", None, false),
(
ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("red").unwrap()
- )),
- background: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("green").unwrap()
- )),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
is_blink: true,
is_bold: true,
is_underline: true,
@@ -405,9 +393,7 @@ mod tests {
parse_ansi_term_style("syntax italic white hidden", None, false),
(
ansi_term::Style {
- background: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("white").unwrap()
- )),
+ background: Some(ansi_term::Color::White),
is_italic: true,
is_hidden: true,
..ansi_term::Style::new()
@@ -421,9 +407,7 @@ mod tests {
parse_ansi_term_style("bold syntax italic white hidden", None, false),
(
ansi_term::Style {
- background: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("white").unwrap()
- )),
+ background: Some(ansi_term::Color::White),
is_bold: true,
is_italic: true,
is_hidden: true,
@@ -447,9 +431,7 @@ mod tests {
parse_ansi_term_style("omit syntax italic white hidden", None, false),
(
ansi_term::Style {
- background: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("white").unwrap()
- )),
+ background: Some(ansi_term::Color::White),
is_italic: true,
is_hidden: true,
..ansi_term::Style::new()
@@ -472,9 +454,7 @@ mod tests {
parse_ansi_term_style("raw syntax italic white hidden", None, false),
(
ansi_term::Style {
- background: Some(ansi_term::Color::Fixed(
- ansi_16_color_name_to_number("white").unwrap()
- )),
+ background: Some(ansi_term::Color::White),
is_italic: true,
is_hidden: true,
..ansi_term::Style::new()
@@ -542,8 +522,8 @@ mod tests {
assert_eq!(
DecorationStyle::from_str("ol red box bold green ul", true),
DecorationStyle::BoxWithUnderOverline(ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(1)),
- background: Some(ansi_term::Color::Fixed(2)),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
is_bold: true,
..ansi_term::Style::new()
})
@@ -560,8 +540,8 @@ mod tests {
false,
);
let red_green_bold = ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(1)),
- background: Some(ansi_term::Color::Fixed(2)),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
is_bold: true,
..ansi_term::Style::new()
};
@@ -594,8 +574,8 @@ mod tests {
fn test_style_from_str_decoration_style_only() {
let actual_style = Style::from_str("", None, Some("ol red box bold green ul"), true, false);
let red_green_bold = ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(1)),
- background: Some(ansi_term::Color::Fixed(2)),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
is_bold: true,
..ansi_term::Style::new()
};
@@ -618,8 +598,8 @@ mod tests {
false,
);
let expected_decoration_style = DecorationStyle::BoxWithUnderOverline(ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(1)),
- background: Some(ansi_term::Color::Fixed(2)),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
is_bold: true,
..ansi_term::Style::new()
});
@@ -657,8 +637,8 @@ mod tests {
fn test_style_from_str_with_handling_of_special_decoration_attributes_and_respecting_deprecated_foreground_color_arg(
) {
let expected_decoration_style = DecorationStyle::BoxWithUnderOverline(ansi_term::Style {
- foreground: Some(ansi_term::Color::Fixed(1)),
- background: Some(ansi_term::Color::Fixed(2)),
+ foreground: Some(ansi_term::Color::Red),
+ background: Some(ansi_term::Color::Green),
is_bold: true,
..ansi_term::Style::new()
});