diff --git a/CHANGELOG.md b/CHANGELOG.md index ab7e262c..07b8ce95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ ## New themes +- `ansi` replaces `ansi-dark` and `ansi-light`, see #1104 and #1412 (@mk12) + ## `bat` as a library ## Packaging diff --git a/README.md b/README.md index f84a2b5f..cbd83731 100644 --- a/README.md +++ b/README.md @@ -390,12 +390,11 @@ You can also use a custom theme by following the ### 8-bit themes -`bat` has four themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors), +`bat` has three themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors), even when truecolor support is available: -- `ansi-dark` looks decent on any terminal with a dark background. It uses 3-bit colors: black, red, - green, yellow, blue, magenta, cyan, and white. -- `ansi-light` is like `ansi-dark`, but for terminals with a light background. +- `ansi` looks decent on any terminal. It uses 3-bit colors: black, red, green, + yellow, blue, magenta, cyan, and white. - `base16` is designed for [base16](https://github.com/chriskempson/base16) terminal themes. It uses 4-bit colors (3-bit colors plus bright variants) in accordance with the [base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md). diff --git a/assets/themes/ansi-light.tmTheme b/assets/themes/ansi-light.tmTheme deleted file mode 100644 index 5dfb94e8..00000000 --- a/assets/themes/ansi-light.tmTheme +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - author - Template: Chris Kempson, Scheme: Mitchell Kember - name - ANSI Light - colorSpaceName - sRGB - settings - - - settings - - background - #07000000 - caret - #00000000 - foreground - #00000000 - invisibles - #00000000 - lineHighlight - #00000000 - selection - #00000000 - gutter - #07000000 - gutterForeground - #00000000 - - - - name - Text - scope - variable.parameter.function - settings - - foreground - #00000000 - - - - name - Comments - scope - comment, punctuation.definition.comment - settings - - foreground - #02000000 - - - - name - Punctuation - scope - punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array - settings - - foreground - #00000000 - - - - name - Delimiters - scope - none - settings - - foreground - #00000000 - - - - name - Operators - scope - keyword.operator - settings - - foreground - #00000000 - - - - name - Keywords - scope - keyword - settings - - foreground - #05000000 - - - - name - Variables - scope - variable - settings - - foreground - #00000000 - - - - name - Functions - scope - entity.name.function, meta.require, support.function.any-method - settings - - foreground - #04000000 - - - - name - Labels - scope - entity.name.label - settings - - foreground - #06000000 - - - - name - Classes - scope - support.class, entity.name.class, entity.name.type.class - settings - - foreground - #03000000 - - - - name - Classes - scope - meta.class - settings - - foreground - #00000000 - - - - name - Methods - scope - keyword.other.special-method - settings - - foreground - #04000000 - - - - name - Storage - scope - storage - settings - - foreground - #05000000 - - - - name - Support - scope - support.function - settings - - foreground - #06000000 - - - - name - Strings, Inherited Class - scope - string, constant.other.symbol, entity.other.inherited-class - settings - - foreground - #02000000 - - - - name - Integers - scope - constant.numeric - settings - - foreground - #03000000 - - - - name - Floats - scope - none - settings - - foreground - #03000000 - - - - name - Boolean - scope - none - settings - - foreground - #03000000 - - - - name - Constants - scope - constant - settings - - foreground - #03000000 - - - - name - Tags - scope - entity.name.tag - settings - - foreground - #01000000 - - - - name - Attributes - scope - entity.other.attribute-name - settings - - foreground - #03000000 - - - - name - Attribute IDs - scope - entity.other.attribute-name.id, punctuation.definition.entity - settings - - foreground - #04000000 - - - - name - Selector - scope - meta.selector - settings - - foreground - #05000000 - - - - name - Values - scope - none - settings - - foreground - #03000000 - - - - name - Headings - scope - markup.heading punctuation.definition.heading, entity.name.section - settings - - fontStyle - - foreground - #04000000 - - - - name - Units - scope - keyword.other.unit - settings - - foreground - #03000000 - - - - name - Bold - scope - markup.bold, punctuation.definition.bold - settings - - fontStyle - bold - foreground - #03000000 - - - - name - Italic - scope - markup.italic, punctuation.definition.italic - settings - - fontStyle - italic - foreground - #05000000 - - - - name - Code - scope - markup.raw.inline - settings - - foreground - #02000000 - - - - name - Link Text - scope - string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown - settings - - foreground - #01000000 - - - - name - Link Url - scope - meta.link - settings - - foreground - #03000000 - - - - name - Quotes - scope - markup.quote - settings - - foreground - #03000000 - - - - name - Inserted - scope - markup.inserted - settings - - foreground - #02000000 - - - - name - Deleted - scope - markup.deleted - settings - - foreground - #01000000 - - - - name - Changed - scope - markup.changed - settings - - foreground - #05000000 - - - - name - Colors - scope - constant.other.color - settings - - foreground - #06000000 - - - - name - Regular Expressions - scope - string.regexp - settings - - foreground - #06000000 - - - - name - Escape Characters - scope - constant.character.escape - settings - - foreground - #06000000 - - - - name - Embedded - scope - punctuation.section.embedded, variable.interpolation - settings - - foreground - #05000000 - - - - name - Illegal - scope - invalid.illegal - settings - - background - #01000000 - foreground - #00000000 - - - - name - Broken - scope - invalid.broken - settings - - background - #03000000 - foreground - #07000000 - - - - uuid - uuid - - diff --git a/assets/themes/ansi-dark.tmTheme b/assets/themes/ansi.tmTheme similarity index 81% rename from assets/themes/ansi-dark.tmTheme rename to assets/themes/ansi.tmTheme index a7976951..957f42bb 100644 --- a/assets/themes/ansi-dark.tmTheme +++ b/assets/themes/ansi.tmTheme @@ -3,14 +3,14 @@ author Template: Chris Kempson, Scheme: Mitchell Kember name - ANSI Dark + ANSI colorSpaceName sRGB settings @@ -19,32 +19,17 @@ settings background - #00000000 - caret - #07000000 + #00000001 foreground - #07000000 - invisibles - #07000000 - lineHighlight - #07000000 - selection - #07000000 + #00000001 + gutter - #00000000 + #00000001 gutterForeground - #07000000 - - - - name - Text - scope - variable.parameter.function - settings - - foreground - #07000000 + #00000001 @@ -58,39 +43,6 @@ #02000000 - - name - Punctuation - scope - punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array - settings - - foreground - #07000000 - - - - name - Delimiters - scope - none - settings - - foreground - #07000000 - - - - name - Operators - scope - keyword.operator - settings - - foreground - #07000000 - - name Keywords @@ -102,17 +54,6 @@ #05000000 - - name - Variables - scope - variable - settings - - foreground - #07000000 - - name Functions @@ -146,17 +87,6 @@ #03000000 - - name - Classes - scope - meta.class - settings - - foreground - #07000000 - - name Methods @@ -480,8 +410,6 @@ background #01000000 - foreground - #07000000 @@ -493,8 +421,6 @@ background #03000000 - foreground - #00000000 diff --git a/src/assets.rs b/src/assets.rs index eecb0693..734c6d20 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -189,6 +189,15 @@ impl HighlightingAssets { match self.theme_set.themes.get(theme) { Some(theme) => theme, None => { + if theme == "ansi-light" || theme == "ansi-dark" { + use ansi_term::Colour::Yellow; + eprintln!( + "{}: Theme '{}' is deprecated, using 'ansi' instead.", + Yellow.paint("[bat warning]"), + theme + ); + return self.get_theme("ansi"); + } if theme != "" { use ansi_term::Colour::Yellow; eprintln!( diff --git a/src/printer.rs b/src/printer.rs index d588083e..a4b143d4 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -448,7 +448,7 @@ impl<'a> Printer for InteractivePrinter<'a> { if text.len() != text_trimmed.len() { if let Some(background_color) = background_color { let mut ansi_style = Style::default(); - ansi_style.background = Some(to_ansi_color(background_color, true_color)); + ansi_style.background = to_ansi_color(background_color, true_color); let width = if cursor_total <= cursor_max { cursor_max - cursor_total + 1 } else { @@ -589,8 +589,7 @@ impl<'a> Printer for InteractivePrinter<'a> { if let Some(background_color) = background_color { let mut ansi_style = Style::default(); - ansi_style.background = - Some(to_ansi_color(background_color, self.config.true_color)); + ansi_style.background = to_ansi_color(background_color, self.config.true_color); write!( handle, @@ -624,20 +623,27 @@ impl Colors { } fn colored(theme: &Theme, true_color: bool) -> Self { - let gutter_color = theme - .settings - .gutter_foreground - .map(|c| to_ansi_color(c, true_color)) - .unwrap_or(Fixed(DEFAULT_GUTTER_COLOR)); + let gutter_style = Style { + foreground: match theme.settings.gutter_foreground { + // If the theme provides a gutter foreground color, use it. + // Note: It might be the special value #00000001, in which case + // to_ansi_color returns None and we use an empty Style + // (resulting in the terminal's default foreground color). + Some(c) => to_ansi_color(c, true_color), + // Otherwise, use a specific fallback color. + None => Some(Fixed(DEFAULT_GUTTER_COLOR)), + }, + ..Style::default() + }; Colors { - grid: gutter_color.normal(), - rule: gutter_color.normal(), + grid: gutter_style, + rule: gutter_style, filename: Style::new().bold(), git_added: Green.normal(), git_removed: Red.normal(), git_modified: Yellow.normal(), - line_number: gutter_color.normal(), + line_number: gutter_style, } } } diff --git a/src/terminal.rs b/src/terminal.rs index b744ba9a..b7159347 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -3,13 +3,13 @@ use ansi_term::{self, Style}; use syntect::highlighting::{self, FontStyle}; -pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> ansi_term::Color { +pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> Option { 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 8-bit color palette number. The built-in themes ansi-light, - // ansi-dark, base16, and base16-256 use this. - match 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 @@ -31,11 +31,18 @@ pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> ansi_term: // 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, + )))) } } @@ -54,7 +61,10 @@ pub fn as_terminal_escaped( let mut style = if !colored { Style::default() } else { - let mut color = Style::from(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 = color.bold(); } @@ -67,6 +77,6 @@ pub fn as_terminal_escaped( 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() }