formatter: add support for reversing colors

This commit is contained in:
Daniel Luz 2025-03-23 23:11:49 -03:00 committed by Daniel Luz
parent 83ce245995
commit 05c77a853f
4 changed files with 32 additions and 5 deletions

View File

@ -85,6 +85,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
now show up in `git diff` (as if you had run `git add --intent-to-add` on now show up in `git diff` (as if you had run `git add --intent-to-add` on
them). them).
* Reversing colors is now supported. For example, to highlight words by
reversing colors rather than underlining, you can set
`colors."diff token"={ underline = false, reverse = true }` in your config.
### Fixed bugs ### Fixed bugs
* `jj log -p --stat` now shows diff stats as well as the default color-words/git * `jj log -p --stat` now shows diff stats as well as the default color-words/git

View File

@ -342,6 +342,9 @@
}, },
"underline": { "underline": {
"type": "boolean" "type": "boolean"
},
"reverse": {
"type": "boolean"
} }
} }
} }

View File

@ -266,6 +266,7 @@ pub struct Style {
pub bold: Option<bool>, pub bold: Option<bool>,
pub italic: Option<bool>, pub italic: Option<bool>,
pub underline: Option<bool>, pub underline: Option<bool>,
pub reverse: Option<bool>,
} }
impl Style { impl Style {
@ -275,6 +276,7 @@ impl Style {
self.bold = other.bold.or(self.bold); self.bold = other.bold.or(self.bold);
self.italic = other.italic.or(self.italic); self.italic = other.italic.or(self.italic);
self.underline = other.underline.or(self.underline); self.underline = other.underline.or(self.underline);
self.reverse = other.reverse.or(self.reverse);
} }
} }
@ -396,6 +398,13 @@ impl<W: Write> ColorFormatter<W> {
queue!(self.output, SetAttribute(Attribute::NoUnderline))?; queue!(self.output, SetAttribute(Attribute::NoUnderline))?;
} }
} }
if new_style.reverse != self.current_style.reverse {
if new_style.reverse.unwrap_or_default() {
queue!(self.output, SetAttribute(Attribute::Reverse))?;
} else {
queue!(self.output, SetAttribute(Attribute::NoReverse))?;
}
}
if new_style.fg != self.current_style.fg { if new_style.fg != self.current_style.fg {
queue!( queue!(
self.output, self.output,
@ -436,6 +445,7 @@ fn rules_from_config(config: &StackedConfig) -> Result<Rules, ConfigGetError> {
bold: None, bold: None,
italic: None, italic: None,
underline: None, underline: None,
reverse: None,
}) })
} else if value.is_inline_table() { } else if value.is_inline_table() {
Style::deserialize(value.into_deserializer()) Style::deserialize(value.into_deserializer())
@ -884,7 +894,8 @@ mod tests {
colors.bold_font = { bold = true } colors.bold_font = { bold = true }
colors.italic_text = { italic = true } colors.italic_text = { italic = true }
colors.underlined_text = { underline = true } colors.underlined_text = { underline = true }
colors.multiple = { fg = "green", bg = "yellow", bold = true, italic = true, underline = true } colors.reversed_colors = { reverse = true }
colors.multiple = { fg = "green", bg = "yellow", bold = true, italic = true, underline = true, reverse = true }
"#, "#,
); );
let mut output: Vec<u8> = vec![]; let mut output: Vec<u8> = vec![];
@ -909,6 +920,10 @@ mod tests {
write!(formatter, " underlined only ").unwrap(); write!(formatter, " underlined only ").unwrap();
formatter.pop_label().unwrap(); formatter.pop_label().unwrap();
writeln!(formatter).unwrap(); writeln!(formatter).unwrap();
formatter.push_label("reversed_colors").unwrap();
write!(formatter, " reverse only ").unwrap();
formatter.pop_label().unwrap();
writeln!(formatter).unwrap();
formatter.push_label("multiple").unwrap(); formatter.push_label("multiple").unwrap();
write!(formatter, " single rule ").unwrap(); write!(formatter, " single rule ").unwrap();
formatter.pop_label().unwrap(); formatter.pop_label().unwrap();
@ -926,7 +941,8 @@ mod tests {
 bold only   bold only 
 italic only   italic only 
 underlined only   underlined only 
 single rule   reverse only 
 single rule 
 two rules   two rules 
[EOF] [EOF]
"); ");

View File

@ -129,12 +129,14 @@ change_id = "#ff1525"
``` ```
If you use a string value for a color, as in the examples above, it will be used If you use a string value for a color, as in the examples above, it will be used
for the foreground color. You can also set the background color, or make the for the foreground color. You can also set the background color, reverse colors
text bold, italic, or underlined. For that, you need to use a table: (swap foreground and background), or make the text bold, italic, or underlined.
For that, you need to use a table:
```toml ```toml
[colors] [colors]
commit_id = { fg = "green", bg = "#ff1525", bold = true, italic = true, underline = true } commit_id = { fg = "green", bg = "#ff1525", bold = true, underline = true }
change_id = { reverse = true, italic = true }
``` ```
The key names are called "labels". The above used `commit_id` as label. You can The key names are called "labels". The above used `commit_id` as label. You can
@ -205,6 +207,8 @@ can override the default style with the following keys:
# Highlight hunks with background # Highlight hunks with background
"diff removed token" = { bg = "#221111", underline = false } "diff removed token" = { bg = "#221111", underline = false }
"diff added token" = { bg = "#002200", underline = false } "diff added token" = { bg = "#002200", underline = false }
# Alternatively, swap colors
"diff token" = { reverse = true, underline = false }
``` ```
### Diff format ### Diff format