forked from mirrors/jj
formatter: add support for bold text
This commit is contained in:
parent
3b4ed096d0
commit
e93a347f9e
2 changed files with 32 additions and 8 deletions
|
@ -42,8 +42,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
* The `ui.relative-timestamps` option now also affects `jj op log`.
|
||||
|
||||
* Background colors are now supported. You can set e.g.
|
||||
`color.error = { bg = "red" }` in your `~/.jjconfig.toml`.
|
||||
* Background colors and bold text are now supported. You can set e.g.
|
||||
`color.error = { bg = "red", bold = true }` in your `~/.jjconfig.toml`.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
|
|
|
@ -154,12 +154,14 @@ impl<W: Write> Formatter for PlainTextFormatter<W> {
|
|||
pub struct Style {
|
||||
pub fg_color: Option<Color>,
|
||||
pub bg_color: Option<Color>,
|
||||
pub bold: Option<bool>,
|
||||
}
|
||||
|
||||
impl Style {
|
||||
fn merge(&mut self, other: &Style) {
|
||||
self.fg_color = other.fg_color.or(self.fg_color);
|
||||
self.bg_color = other.bg_color.or(self.bg_color);
|
||||
self.bold = other.bold.or(self.bold);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +240,18 @@ impl<W: Write> ColorFormatter<W> {
|
|||
} else if !is_bright(&new_style.fg_color) && is_bright(&self.current_style.fg_color) {
|
||||
queue!(self.output, SetAttribute(Attribute::Reset))?;
|
||||
}
|
||||
if new_style.bold != self.current_style.bold {
|
||||
if new_style.bold.unwrap_or_default() {
|
||||
queue!(self.output, SetAttribute(Attribute::Bold))?;
|
||||
} else {
|
||||
// NoBold results in double underlining on some terminals, so we use reset
|
||||
// instead. However, that resets other attributes as well, so we reset
|
||||
// our record of the current style so we re-apply the other attributes
|
||||
// below.
|
||||
queue!(self.output, SetAttribute(Attribute::Reset))?;
|
||||
self.current_style = Style::default();
|
||||
}
|
||||
}
|
||||
if new_style.fg_color != self.current_style.fg_color {
|
||||
queue!(
|
||||
self.output,
|
||||
|
@ -283,6 +297,7 @@ fn rules_from_config(config: &config::Config) -> HashMap<Vec<String>, Style> {
|
|||
let style = Style {
|
||||
fg_color: color_for_name(&color_name),
|
||||
bg_color: None,
|
||||
bold: None,
|
||||
};
|
||||
result.insert(labels, style);
|
||||
}
|
||||
|
@ -298,6 +313,11 @@ fn rules_from_config(config: &config::Config) -> HashMap<Vec<String>, Style> {
|
|||
style.bg_color = color_for_name(color_name);
|
||||
}
|
||||
}
|
||||
if let Some(value) = style_table.get("bold") {
|
||||
if let config::ValueKind::Boolean(value) = &value.kind {
|
||||
style.bold = Some(*value);
|
||||
}
|
||||
}
|
||||
result.insert(labels, style);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -457,7 +477,8 @@ mod tests {
|
|||
r#"
|
||||
colors.red_fg = { fg = "red" }
|
||||
colors.blue_bg = { bg = "blue" }
|
||||
colors.multiple = { fg = "green", bg = "yellow" }
|
||||
colors.bold_font = { bold = true }
|
||||
colors.multiple = { fg = "green", bg = "yellow", bold = true }
|
||||
"#,
|
||||
);
|
||||
let mut output: Vec<u8> = vec![];
|
||||
|
@ -470,6 +491,10 @@ mod tests {
|
|||
formatter.write_str(" bg only ").unwrap();
|
||||
formatter.remove_label().unwrap();
|
||||
formatter.write_str("\n").unwrap();
|
||||
formatter.add_label("bold_font").unwrap();
|
||||
formatter.write_str(" bold only ").unwrap();
|
||||
formatter.remove_label().unwrap();
|
||||
formatter.write_str("\n").unwrap();
|
||||
formatter.add_label("multiple").unwrap();
|
||||
formatter.write_str(" single rule ").unwrap();
|
||||
formatter.remove_label().unwrap();
|
||||
|
@ -483,7 +508,8 @@ mod tests {
|
|||
insta::assert_snapshot!(String::from_utf8(output).unwrap(), @r###"
|
||||
[38;5;1m fg only [39m
|
||||
[48;5;4m bg only [49m
|
||||
[38;5;2m[48;5;3m single rule [39m[49m
|
||||
[1m bold only [0m
|
||||
[1m[38;5;2m[48;5;3m single rule [0m
|
||||
[38;5;1m[48;5;4m two rules [49m[39m
|
||||
"###);
|
||||
}
|
||||
|
@ -491,11 +517,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_color_formatter_bold_reset() {
|
||||
// Test that we don't lose other attributes when we reset the bold attribute.
|
||||
// TODO: Actually use bold instead of bright when we support that
|
||||
let config = config_from_string(
|
||||
r#"
|
||||
colors.not_bold = { fg = "red", bg = "blue" }
|
||||
colors.bold_font = { fg = "bright red" }
|
||||
colors.bold_font = { bold = true }
|
||||
"#,
|
||||
);
|
||||
let mut output: Vec<u8> = vec![];
|
||||
|
@ -507,8 +532,7 @@ mod tests {
|
|||
formatter.remove_label().unwrap();
|
||||
formatter.write_str(" not bold again ").unwrap();
|
||||
formatter.remove_label().unwrap();
|
||||
// TODO: This loses the blue background when we reset the bold attribute.
|
||||
insta::assert_snapshot!(String::from_utf8(output).unwrap(), @"[38;5;1m[48;5;4m not bold [1m[38;5;9m bold [0m[38;5;1m not bold again [39m[49m");
|
||||
insta::assert_snapshot!(String::from_utf8(output).unwrap(), @"[38;5;1m[48;5;4m not bold [1m bold [0m[38;5;1m[48;5;4m not bold again [39m[49m");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue