summaryrefslogtreecommitdiffstats
path: root/src/paint.rs
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2020-03-01 13:13:18 -0600
committerDan Davison <dandavison7@gmail.com>2020-03-01 16:25:10 -0600
commit37cc69ea434303ec8ebf4f248d4bd7f1febfe3e2 (patch)
tree9858059d214be7d3e9405d11403be418cc71f062 /src/paint.rs
parenteeee3d4732479295248b49164f8db58d3244b1ff (diff)
Support 256-color terminal environments
Fixes #110 With this commit, delta enters "24 bit color mode" iff either of the following are true: 1. The --24-bit-color command line option value is "always" 2. The --24-bit-color command line option value is "auto" and the COLORTERM environment variable is set to "truecolor" or "24bit". See https://gist.github.com/XVilka/8346728#true-color-detection https://github.com/sharkdp/bat/blob/7779d9f6221b3e98c43a43ceb5596ba285fdf4f8/src/bin/bat/app.rs#L29-L33 Otherwise, delta enters "8-bit color mode". In "24 bit color mode", delta will 1. Emit 24-bit RGB color shell escape sequences that will only be displayed correctly by a terminal application that supports 24 bit colors. 2. Select default background colors that will only be displayed correctly by a terminal application that supports 24 bit colors. In "8-bit color mode", delta will 1. Emit color shell escape sequences specifying the entry in the ANSI 256 color palette that is closest (according to the ansi_colours library) to the requested color. 2. Select default background colors that will work well in a terminal application that supports 8-bit color but not 24-bit color.
Diffstat (limited to 'src/paint.rs')
-rw-r--r--src/paint.rs36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/paint.rs b/src/paint.rs
index cf6968e1..f85c64a1 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -1,6 +1,7 @@
use std::io::Write;
use std::str::FromStr;
+use ansi_colours;
use syntect::easy::HighlightLines;
use syntect::highlighting::{Color, Style, StyleModifier};
use syntect::parsing::{SyntaxReference, SyntaxSet};
@@ -109,7 +110,7 @@ impl<'a> Painter<'a> {
{
let mut text_width = 0;
for (style, text) in superimpose_style_sections(syntax_sections, diff_sections) {
- paint_text(&text, style, output_buffer);
+ paint_text(&text, style, output_buffer, config.true_color);
if config.width.is_some() {
text_width += text.graphemes(true).count();
}
@@ -127,6 +128,7 @@ impl<'a> Painter<'a> {
&" ".repeat(width - text_width),
background_style,
output_buffer,
+ config.true_color,
);
}
_ => (),
@@ -206,22 +208,34 @@ impl<'a> Painter<'a> {
}
/// Write section text to buffer with shell escape codes specifying foreground and background color.
-pub fn paint_text(text: &str, style: Style, output_buffer: &mut String) {
+pub fn paint_text(text: &str, style: Style, output_buffer: &mut String, true_color: bool) {
if text.is_empty() {
return;
}
if style.background != style::NO_COLOR {
- output_buffer.push_str(&get_color_escape_sequence(style.background, false));
+ output_buffer.push_str(&get_color_escape_sequence(
+ style.background,
+ false,
+ true_color,
+ ));
}
if style.foreground != style::NO_COLOR {
- output_buffer.push_str(&get_color_escape_sequence(style.foreground, true));
+ output_buffer.push_str(&get_color_escape_sequence(
+ style.foreground,
+ true,
+ true_color,
+ ));
}
output_buffer.push_str(text);
}
/// Return text together with shell escape codes specifying the foreground color.
-pub fn paint_text_foreground(text: &str, color: Color) -> String {
- format!("{}{}", get_color_escape_sequence(color, true), text)
+pub fn paint_text_foreground(text: &str, color: Color, true_color: bool) -> String {
+ format!(
+ "{}{}",
+ get_color_escape_sequence(color, true, true_color),
+ text,
+ )
}
/// Return shell escape sequence specifying either an RGB color, or a user-customizable 8-bit ANSI
@@ -229,11 +243,11 @@ pub fn paint_text_foreground(text: &str, color: Color) -> String {
// See
// https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
// https://github.com/ogham/rust-ansi-term/blob/ff7eba98d55ad609c7fcc8c7bb0859b37c7545cc/src/ansi.rs#L82-L112
-fn get_color_escape_sequence(color: Color, foreground: bool) -> String {
+fn get_color_escape_sequence(color: Color, foreground: bool, true_color: bool) -> String {
if color.a == 0 {
// See https://github.com/sharkdp/bat/pull/543
format!("\x1b[{};5;{}m", if foreground { 38 } else { 48 }, color.r)
- } else {
+ } else if true_color {
format!(
"\x1b[{};2;{};{};{}m",
if foreground { 38 } else { 48 },
@@ -241,6 +255,12 @@ fn get_color_escape_sequence(color: Color, foreground: bool) -> String {
color.g,
color.b
)
+ } else {
+ format!(
+ "\x1b[{};5;{}m",
+ if foreground { 38 } else { 48 },
+ ansi_colours::ansi256_from_rgb((color.r, color.g, color.b))
+ )
}
}