Skip to content

Commit

Permalink
Add resetted styling (nushell#40)
Browse files Browse the repository at this point in the history
* add reset styling

* cargo fmt

* rename resetted to reset_before_style

* add readme section and example

* cargo fmt
  • Loading branch information
alexkunde authored May 24, 2023
1 parent 564d7ba commit 135430b
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ Red.normal().paint("yet another red string");
Style::default().paint("a completely regular string");
```

Sometimes it is desirable to hard-reset a style/color just before
applying a new one. To reset and apply, the `reset_before_style` method can
be used on either `Color` or `Style` structs.

```rust
use nu_ansi_term::Style;

println!("\x1b[33mHow about some {} \x1b[33mand {}?\x1b[0m",
Style::new().reset_before_style().bold().paint("bold"),
Style::new().reset_before_style().underline().paint("underline"));
```

## Extended colors

You can access the extended range of 256 colors by using the `Color::Fixed` variant, which takes an argument of the color number to use.
Expand Down
14 changes: 14 additions & 0 deletions examples/basic_colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,18 @@ fn main() {
println!("{} {}", Purple.paint("Purple"), Purple.bold().paint("bold"));
println!("{} {}", Cyan.paint("Cyan"), Cyan.bold().paint("bold"));
println!("{} {}", White.paint("White"), White.bold().paint("bold"));
println!("\nreset_before_style at work:");
println!(
"\x1b[33mReset {} \x1b[33mand {}\x1b[0m",
Style::new().reset_before_style().bold().paint("bold"),
Style::new()
.reset_before_style()
.underline()
.paint("underline")
);
println!(
"\x1b[33mDo not reset {} \x1b[33mand {}\x1b[0m",
Style::new().bold().paint("bold"),
Style::new().underline().paint("underline")
);
}
13 changes: 13 additions & 0 deletions src/ansi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ impl Style {
return Ok(());
}

// Prefix everything with reset characters if needed
if self.with_reset {
write!(f, "\x1B[0m")?
}

// Write the codes’ prefix, then write numbers, separated by
// semicolons, for each text style we want to apply.
write!(f, "\x1B[")?;
Expand Down Expand Up @@ -407,6 +412,8 @@ mod test {
test!(magenta_on_white: Magenta.on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(magenta_on_white_2: Magenta.normal().on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(yellow_on_blue_2: Cyan.on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
test!(yellow_on_blue_reset: Cyan.on(Blue).reset_before_style().fg(Yellow); "hi" => "\x1B[0m\x1B[44;33mhi\x1B[0m");
test!(yellow_on_blue_reset_2: Cyan.on(Blue).fg(Yellow).reset_before_style(); "hi" => "\x1B[0m\x1B[44;33mhi\x1B[0m");
test!(cyan_bold_on_white: Cyan.bold().on(White); "hi" => "\x1B[1;47;36mhi\x1B[0m");
test!(cyan_ul_on_white: Cyan.underline().on(White); "hi" => "\x1B[4;47;36mhi\x1B[0m");
test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
Expand All @@ -419,6 +426,8 @@ mod test {
test!(blue_on_rgb: Blue.on(Rgb(70,130,180)); "hi" => "\x1B[48;2;70;130;180;34mhi\x1B[0m");
test!(rgb_on_rgb: Rgb(70,130,180).on(Rgb(5,10,15)); "hi" => "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m");
test!(bold: Style::new().bold(); "hi" => "\x1B[1mhi\x1B[0m");
test!(bold_with_reset: Style::new().reset_before_style().bold(); "hi" => "\x1B[0m\x1B[1mhi\x1B[0m");
test!(bold_with_reset_2: Style::new().bold().reset_before_style(); "hi" => "\x1B[0m\x1B[1mhi\x1B[0m");
test!(underline: Style::new().underline(); "hi" => "\x1B[4mhi\x1B[0m");
test!(bunderline: Style::new().bold().underline(); "hi" => "\x1B[1;4mhi\x1B[0m");
test!(dimmed: Style::new().dimmed(); "hi" => "\x1B[2mhi\x1B[0m");
Expand Down Expand Up @@ -462,6 +471,8 @@ mod gnu_legacy_test {
test!(purple_on_white: Purple.on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(purple_on_white_2: Purple.normal().on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(yellow_on_blue: Style::new().on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
test!(yellow_on_blue_reset: Cyan.on(Blue).reset_before_style().fg(Yellow); "hi" => "\x1B[0m\x1B[44;33mhi\x1B[0m");
test!(yellow_on_blue_reset_2: Cyan.on(Blue).fg(Yellow).reset_before_style(); "hi" => "\x1B[0m\x1B[44;33mhi\x1B[0m");
test!(magenta_on_white: Magenta.on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(magenta_on_white_2: Magenta.normal().on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(yellow_on_blue_2: Cyan.on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
Expand All @@ -477,6 +488,8 @@ mod gnu_legacy_test {
test!(blue_on_rgb: Blue.on(Rgb(70,130,180)); "hi" => "\x1B[48;2;70;130;180;34mhi\x1B[0m");
test!(rgb_on_rgb: Rgb(70,130,180).on(Rgb(5,10,15)); "hi" => "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m");
test!(bold: Style::new().bold(); "hi" => "\x1B[01mhi\x1B[0m");
test!(bold_with_reset: Style::new().reset_before_style().bold(); "hi" => "\x1B[0m\x1B[01mhi\x1B[0m");
test!(bold_with_reset_2: Style::new().bold().reset_before_style(); "hi" => "\x1B[0m\x1B[01mhi\x1B[0m");
test!(underline: Style::new().underline(); "hi" => "\x1B[04mhi\x1B[0m");
test!(bunderline: Style::new().bold().underline(); "hi" => "\x1B[01;04mhi\x1B[0m");
test!(dimmed: Style::new().dimmed(); "hi" => "\x1B[02mhi\x1B[0m");
Expand Down
42 changes: 41 additions & 1 deletion src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub struct Style {

/// Whether this style is struckthrough.
pub is_strikethrough: bool,

/// Wether this style starts with reset code
pub with_reset: bool,
}

impl Style {
Expand All @@ -61,6 +64,23 @@ impl Style {
Style::default()
}

/// Returns a `Style` with the reset_before_style property set.
///
/// # Examples
///
/// ```
/// use nu_ansi_term::Style;
///
/// let style = Style::new().reset_before_style();
/// println!("{}", style.paint("hey"));
/// ```
pub const fn reset_before_style(&self) -> Style {
Style {
with_reset: true,
..*self
}
}

/// Returns a `Style` with the bold property set.
///
/// # Examples
Expand Down Expand Up @@ -269,6 +289,7 @@ impl Default for Style {
is_reverse: false,
is_hidden: false,
is_strikethrough: false,
with_reset: false,
}
}
}
Expand Down Expand Up @@ -542,6 +563,25 @@ impl Color {
}
}

/// Returns a `Style` thats resets all styling before applying
/// the foreground color set to this color.
///
/// # Examples
///
/// ```
/// use nu_ansi_term::Color;
///
/// let style = Color::Fixed(244).reset_before_style();
/// println!("{}", style.paint("yo"));
/// ```
pub fn reset_before_style(self) -> Style {
Style {
foreground: Some(self),
with_reset: true,
..Style::default()
}
}

/// Returns a `Style` with the foreground color set to this color and the
/// background color property set to the given color.
///
Expand Down Expand Up @@ -619,6 +659,6 @@ mod serde_json_tests {
fn style_serialization() {
let style = Style::default();

assert_eq!(serde_json::to_string(&style).unwrap(), "{\"foreground\":null,\"background\":null,\"is_bold\":false,\"is_dimmed\":false,\"is_italic\":false,\"is_underline\":false,\"is_blink\":false,\"is_reverse\":false,\"is_hidden\":false,\"is_strikethrough\":false}".to_string());
assert_eq!(serde_json::to_string(&style).unwrap(), "{\"foreground\":null,\"background\":null,\"is_bold\":false,\"is_dimmed\":false,\"is_italic\":false,\"is_underline\":false,\"is_blink\":false,\"is_reverse\":false,\"is_hidden\":false,\"is_strikethrough\":false,\"with_reset\":false}".to_string());
}
}

0 comments on commit 135430b

Please sign in to comment.