Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Add support for "reverse" color effect #74

Open
bwpge opened this issue May 20, 2023 · 1 comment
Open

Feature request: Add support for "reverse" color effect #74

bwpge opened this issue May 20, 2023 · 1 comment

Comments

@bwpge
Copy link

bwpge commented May 20, 2023

Just wanted to prefix this with a sincere thank you for all your hard work and great libraries/tools you given to us 馃槃

I tried searching the closed issues for anything related to "reverse", "invert", or "negative" keywords but did not find anything.

Issue

termcolor does not expose any way to use the "reverse" color effect (see n = 7: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters).

Using the reverse effect instead of hardcoding "black/white on green background" or something similar provides more consistent styled output, since many terminal themes use different primary/intense colors than the background color.

It also properly handles light and dark backgrounds, which cannot be determined using 16 theme colors. Hardcoding RGB colors can guarantee legible output, but will not be consistent with the user's theme.

Proposed Feature

ColorSpec could offer reverse and set_reverse methods, similar to effects such as bold and underline.

Usage might look something like:

let mut stdout = StandardStream::stdout(ColorChoice::Always);
stdout.set_color(ColorSpec::new().set_reverse(true))?;

Naive Implementation

Adding a field to ColorSpec:

/// A color specification.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ColorSpec {
    fg_color: Option<Color>,
    bg_color: Option<Color>,
    bold: bool,
    reverse: bool, // added
    intense: bool,
    underline: bool,
    dimmed: bool,
    italic: bool,
    reset: bool,
    strikethrough: bool,
}

For the WriteColor implementation for Ansi<W>, a small adjustment might work fine for non-Windows terminals;

fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
    if spec.reset {
        self.reset()?;
    }
    // begin: added
    if spec.reverse {
        self.write_str("\x1B[7m")?;
    }
    // end: added
    if spec.bold {
        self.write_str("\x1B[1m")?;
    }
    // ...
    Ok(())
}

Windows Considerations

I have no clue how windows handles this, nor am I familiar with GetConsoleMode or SetConsoleMode. It seems some of that is handled by the winapi-utils crate, so I haven't really dug in too much on it.

References

@bwpge bwpge changed the title Feature: Add support for "reverse" color effect Feature request: Add support for "reverse" color effect May 21, 2023
@bwpge
Copy link
Author

bwpge commented Jun 21, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant