From 51c0ab60121cc731be505775d8accb693d7dde7b Mon Sep 17 00:00:00 2001 From: Timon_Post Date: Sat, 4 May 2019 12:29:30 +0200 Subject: [PATCH 1/4] Added resetting color support --- crossterm_style/examples/style.rs | 8 +++ crossterm_style/src/ansi_color.rs | 20 ++++-- crossterm_style/src/color.rs | 19 ++--- crossterm_style/src/enums/attribute.rs | 8 --- crossterm_style/src/enums/color.rs | 5 +- crossterm_style/src/winapi_color.rs | 98 +++++++++++++++----------- docs/know_problems.md | 2 + examples/terminal.rs | 2 +- 8 files changed, 98 insertions(+), 64 deletions(-) diff --git a/crossterm_style/examples/style.rs b/crossterm_style/examples/style.rs index 9d614b2..857d3c5 100644 --- a/crossterm_style/examples/style.rs +++ b/crossterm_style/examples/style.rs @@ -387,3 +387,11 @@ pub fn print_supported_colors() { println!("Test {}", Colored::Bg(Color::AnsiValue(i as u8))); } } + +fn main() { + println!("{}", Colored::Bg(Color::Red)); + println!("{}", Colored::Fg(Color::Blue)); + + println!("{}", Colored::Fg(Color::Reset)); + println!("{}", Colored::Bg(Color::Reset)); +} diff --git a/crossterm_style/src/ansi_color.rs b/crossterm_style/src/ansi_color.rs index c3d65f3..b973fd0 100644 --- a/crossterm_style/src/ansi_color.rs +++ b/crossterm_style/src/ansi_color.rs @@ -45,12 +45,22 @@ impl ITerminalColor for AnsiColor { match colored { Colored::Fg(new_color) => { - ansi_value.push_str("38;"); - color = new_color; + if new_color == Color::Reset { + ansi_value.push_str("39"); + return ansi_value; + }else { + ansi_value.push_str("38;"); + color = new_color; + } } Colored::Bg(new_color) => { - ansi_value.push_str("48;"); - color = new_color; + if new_color == Color::Reset { + ansi_value.push_str("49"); + return ansi_value; + }else { + ansi_value.push_str("48;"); + color = new_color; + } } } @@ -73,7 +83,6 @@ impl ITerminalColor for AnsiColor { Color::DarkCyan => "5;6", Color::White => "5;15", Color::Grey => "5;7", - Color::Rgb { r, g, b } => { rgb_val = format!("2;{};{};{}", r, g, b); rgb_val.as_str() @@ -82,6 +91,7 @@ impl ITerminalColor for AnsiColor { rgb_val = format!("5;{}", val); rgb_val.as_str() } + _ => "" }; ansi_value.push_str(color_val); diff --git a/crossterm_style/src/color.rs b/crossterm_style/src/color.rs index 400bb1d..4fcf074 100644 --- a/crossterm_style/src/color.rs +++ b/crossterm_style/src/color.rs @@ -31,16 +31,17 @@ pub struct TerminalColor { impl TerminalColor { /// Create new instance whereon color related actions can be performed. pub fn new() -> TerminalColor { - #[cfg(windows)] - let color = if supports_ansi() { - Box::from(AnsiColor::new()) as Box<(dyn ITerminalColor + Sync + Send)> - } else { - WinApiColor::new() as Box<(dyn ITerminalColor + Sync + Send)> - }; - - #[cfg(unix)] - let color = AnsiColor::new(); +// #[cfg(windows)] +// let color = if supports_ansi() { +// Box::from(AnsiColor::new()) as Box<(dyn ITerminalColor + Sync + Send)> +// } else { +// WinApiColor::new() as Box<(dyn ITerminalColor + Sync + Send)> +// }; +// +// #[cfg(unix)] +// let color = AnsiColor::new(); + let color = WinApiColor::new() as Box<(dyn ITerminalColor + Sync + Send)>; TerminalColor { color } } diff --git a/crossterm_style/src/enums/attribute.rs b/crossterm_style/src/enums/attribute.rs index 1c00fed..35aad41 100644 --- a/crossterm_style/src/enums/attribute.rs +++ b/crossterm_style/src/enums/attribute.rs @@ -112,14 +112,6 @@ pub enum Attribute { /// [info]: Opposite of `CrossedOut`(9) /// [Supportability]: Not widely supported NotCrossedOut = 29, - /// This will reset the foreground color to default. - /// [info]: Implementation defined (according to standard) - /// [Supportability]: Unknown - DefaultForegroundColor = 48, - /// This will reset the background color to default. - /// [info]: Implementation defined (according to standard) - /// [Supportability]: Unknown - DefaultBackgroundColor = 49, /// Framed font. /// [Supportability]: Not widely supported Framed = 51, diff --git a/crossterm_style/src/enums/color.rs b/crossterm_style/src/enums/color.rs index 51dcdb0..04d0a03 100644 --- a/crossterm_style/src/enums/color.rs +++ b/crossterm_style/src/enums/color.rs @@ -2,8 +2,11 @@ use std::convert::AsRef; use std::str::FromStr; /// Colors that are available for coloring the terminal font. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)] pub enum Color { + // This resets the color. + Reset, + Black, DarkGrey, diff --git a/crossterm_style/src/winapi_color.rs b/crossterm_style/src/winapi_color.rs index 6d34a99..da4f69c 100644 --- a/crossterm_style/src/winapi_color.rs +++ b/crossterm_style/src/winapi_color.rs @@ -8,6 +8,16 @@ use std::io; use std::sync::{Once, ONCE_INIT}; use winapi::um::wincon; +const FG_GREEN: u16 = wincon::FOREGROUND_GREEN; +const FG_RED: u16 = wincon::FOREGROUND_RED; +const FG_BLUE: u16 = wincon::FOREGROUND_BLUE; +const FG_INTENSITY: u16 = wincon::FOREGROUND_INTENSITY; + +const BG_GREEN: u16 = wincon::BACKGROUND_GREEN; +const BG_RED: u16 = wincon::BACKGROUND_RED; +const BG_BLUE: u16 = wincon::BACKGROUND_BLUE; +const BG_INTENSITY: u16 = wincon::BACKGROUND_INTENSITY; + /// This struct is a WinApi implementation for color related actions. pub struct WinApiColor; @@ -85,35 +95,35 @@ impl ITerminalColor for WinApiColor { fn color_value(&self, color: Colored) -> String { let winapi_color: u16; - let fg_green = wincon::FOREGROUND_GREEN; - let fg_red = wincon::FOREGROUND_RED; - let fg_blue = wincon::FOREGROUND_BLUE; - let fg_intensity = wincon::FOREGROUND_INTENSITY; - - let bg_green = wincon::BACKGROUND_GREEN; - let bg_red = wincon::BACKGROUND_RED; - let bg_blue = wincon::BACKGROUND_BLUE; - let bg_intensity = wincon::BACKGROUND_INTENSITY; - match color { Colored::Fg(color) => { winapi_color = match color { Color::Black => 0, - Color::DarkGrey => fg_intensity, - Color::Red => fg_intensity | fg_red, - Color::DarkRed => fg_red, - Color::Green => fg_intensity | fg_green, - Color::DarkGreen => fg_green, - Color::Yellow => fg_intensity | fg_green | fg_red, - Color::DarkYellow => fg_green | fg_red, - Color::Blue => fg_intensity | fg_blue, - Color::DarkBlue => fg_blue, - Color::Magenta => fg_intensity | fg_red | fg_blue, - Color::DarkMagenta => fg_red | fg_blue, - Color::Cyan => fg_intensity | fg_green | fg_blue, - Color::DarkCyan => fg_green | fg_blue, - Color::White => fg_red | fg_green | fg_blue, - Color::Grey => fg_intensity | fg_red | fg_green | fg_blue, + Color::DarkGrey => FG_INTENSITY, + Color::Red => FG_INTENSITY | FG_RED, + Color::DarkRed => FG_RED, + Color::Green => FG_INTENSITY | FG_GREEN, + Color::DarkGreen => FG_GREEN, + Color::Yellow => FG_INTENSITY | FG_GREEN | FG_RED, + Color::DarkYellow => FG_GREEN | FG_RED, + Color::Blue => FG_INTENSITY | FG_BLUE, + Color::DarkBlue => FG_BLUE, + Color::Magenta => FG_INTENSITY | FG_RED | FG_BLUE, + Color::DarkMagenta => FG_RED | FG_BLUE, + Color::Cyan => FG_INTENSITY | FG_GREEN | FG_BLUE, + Color::DarkCyan => FG_GREEN | FG_BLUE, + Color::White => FG_RED | FG_GREEN | FG_BLUE, + Color::Grey => FG_INTENSITY | FG_RED | FG_GREEN | FG_BLUE, + + Color::Reset => { + // init the original color in case it is not set. + let mut original_color = original_console_color(); + + const mask: u16 = BG_INTENSITY | BG_RED | BG_GREEN | BG_BLUE; + original_color &= !(mask); + + original_color + } /* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/ Color::Rgb { r: _, g: _, b: _ } => 0, @@ -123,22 +133,30 @@ impl ITerminalColor for WinApiColor { Colored::Bg(color) => { winapi_color = match color { Color::Black => 0, - Color::DarkGrey => bg_intensity, - Color::Red => bg_intensity | bg_red, - Color::DarkRed => bg_red, - Color::Green => bg_intensity | bg_green, - Color::DarkGreen => bg_green, - Color::Yellow => bg_intensity | bg_green | bg_red, - Color::DarkYellow => bg_green | bg_red, - Color::Blue => bg_intensity | bg_blue, - Color::DarkBlue => bg_blue, - Color::Magenta => bg_intensity | bg_red | bg_blue, - Color::DarkMagenta => bg_red | bg_blue, - Color::Cyan => bg_intensity | bg_green | bg_blue, - Color::DarkCyan => bg_green | bg_blue, - Color::White => bg_intensity | bg_red | bg_green | bg_blue, - Color::Grey => bg_red | bg_green | bg_blue, + Color::DarkGrey => BG_INTENSITY, + Color::Red => BG_INTENSITY | BG_RED, + Color::DarkRed => BG_RED, + Color::Green => BG_INTENSITY | BG_GREEN, + Color::DarkGreen => BG_GREEN, + Color::Yellow => BG_INTENSITY | BG_GREEN | BG_RED, + Color::DarkYellow => BG_GREEN | BG_RED, + Color::Blue => BG_INTENSITY | BG_BLUE, + Color::DarkBlue => BG_BLUE, + Color::Magenta => BG_INTENSITY | BG_RED | BG_BLUE, + Color::DarkMagenta => BG_RED | BG_BLUE, + Color::Cyan => BG_INTENSITY | BG_GREEN | BG_BLUE, + Color::DarkCyan => BG_GREEN | BG_BLUE, + Color::White => BG_INTENSITY | BG_RED | BG_GREEN | BG_BLUE, + Color::Grey => BG_RED | BG_GREEN | BG_BLUE, + Color::Reset => { + // init the original color in case it is not set. + let mut original_color = original_console_color(); + + const mask: u16 = FG_INTENSITY | FG_RED | FG_GREEN | FG_BLUE; + original_color &= !(mask); + original_color + }, /* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/ Color::Rgb { r: _, g: _, b: _ } => 0, Color::AnsiValue(_val) => 0, diff --git a/docs/know_problems.md b/docs/know_problems.md index baea455..adb6135 100644 --- a/docs/know_problems.md +++ b/docs/know_problems.md @@ -3,6 +3,8 @@ And I don't think it has to do anything with crossterm but it has to do whit how # Winapi-problems - Power shell does not interpreter 'DarkYellow' and is instead using gray instead, cmd is working perfectly fine. +- Power shell inserts an '\n' (enter) when the program starts, this enter is the one you pressed when running the command. +- After the program ran, power shell will reset the background color. # UNIX-terminals The Arc and Manjaro KDE Konsole's are not seeming to resize the terminal instead they are resizing the buffer. \ No newline at end of file diff --git a/examples/terminal.rs b/examples/terminal.rs index 119ec79..ecac273 100644 --- a/examples/terminal.rs +++ b/examples/terminal.rs @@ -146,5 +146,5 @@ pub fn exit() { } fn main() { - print_terminal_size(); + clear_until_new_line(); } From e1a46d5fb54df1c3c50e7172a6d85f3a9af7ec79 Mon Sep 17 00:00:00 2001 From: Timon_Post Date: Sat, 4 May 2019 12:40:59 +0200 Subject: [PATCH 2/4] fmt --- crossterm_cursor/src/sys/unix.rs | 31 +++++++++++++++-------------- crossterm_style/src/ansi_color.rs | 6 +++--- crossterm_style/src/color.rs | 19 +++++++++--------- crossterm_style/src/winapi_color.rs | 2 +- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/crossterm_cursor/src/sys/unix.rs b/crossterm_cursor/src/sys/unix.rs index edd6145..2380a63 100644 --- a/crossterm_cursor/src/sys/unix.rs +++ b/crossterm_cursor/src/sys/unix.rs @@ -44,24 +44,25 @@ pub fn pos_raw() -> io::Result<(u16, u16)> { } // Read rows and cols through a ad-hoc integer parsing function - let read_num: fn() -> Result<(i32, char), Error> = || -> Result<(i32, char), Error> { - let mut num = 0; - let mut c: char; + let read_num: fn() -> Result<(i32, char) -> Result<(i32, char), Error> = + || -> Result<(i32, char), Error> { + let mut num = 0; + let mut c: char; - loop { - let mut buf = [0u8; 1]; - io::stdin().read_exact(&mut buf)?; - c = buf[0] as char; - if let Some(d) = c.to_digit(10) { - num = if num == 0 { 0 } else { num * 10 }; - num += d as i32; - } else { - break; + loop { + let mut buf = [0u8; 1]; + io::stdin().read_exact(&mut buf)?; + c = buf[0] as char; + if let Some(d) = c.to_digit(10) { + num = if num == 0 { 0 } else { num * 10 }; + num += d as i32; + } else { + break; + } } - } - Ok((num, c)) - }; + Ok((num, c)) + }; // Read rows and expect `;` let (rows, c) = read_num()?; diff --git a/crossterm_style/src/ansi_color.rs b/crossterm_style/src/ansi_color.rs index b973fd0..6fb4a3a 100644 --- a/crossterm_style/src/ansi_color.rs +++ b/crossterm_style/src/ansi_color.rs @@ -48,7 +48,7 @@ impl ITerminalColor for AnsiColor { if new_color == Color::Reset { ansi_value.push_str("39"); return ansi_value; - }else { + } else { ansi_value.push_str("38;"); color = new_color; } @@ -57,7 +57,7 @@ impl ITerminalColor for AnsiColor { if new_color == Color::Reset { ansi_value.push_str("49"); return ansi_value; - }else { + } else { ansi_value.push_str("48;"); color = new_color; } @@ -91,7 +91,7 @@ impl ITerminalColor for AnsiColor { rgb_val = format!("5;{}", val); rgb_val.as_str() } - _ => "" + _ => "", }; ansi_value.push_str(color_val); diff --git a/crossterm_style/src/color.rs b/crossterm_style/src/color.rs index 4fcf074..400bb1d 100644 --- a/crossterm_style/src/color.rs +++ b/crossterm_style/src/color.rs @@ -31,17 +31,16 @@ pub struct TerminalColor { impl TerminalColor { /// Create new instance whereon color related actions can be performed. pub fn new() -> TerminalColor { -// #[cfg(windows)] -// let color = if supports_ansi() { -// Box::from(AnsiColor::new()) as Box<(dyn ITerminalColor + Sync + Send)> -// } else { -// WinApiColor::new() as Box<(dyn ITerminalColor + Sync + Send)> -// }; -// -// #[cfg(unix)] -// let color = AnsiColor::new(); + #[cfg(windows)] + let color = if supports_ansi() { + Box::from(AnsiColor::new()) as Box<(dyn ITerminalColor + Sync + Send)> + } else { + WinApiColor::new() as Box<(dyn ITerminalColor + Sync + Send)> + }; + + #[cfg(unix)] + let color = AnsiColor::new(); - let color = WinApiColor::new() as Box<(dyn ITerminalColor + Sync + Send)>; TerminalColor { color } } diff --git a/crossterm_style/src/winapi_color.rs b/crossterm_style/src/winapi_color.rs index da4f69c..e02078f 100644 --- a/crossterm_style/src/winapi_color.rs +++ b/crossterm_style/src/winapi_color.rs @@ -156,7 +156,7 @@ impl ITerminalColor for WinApiColor { const mask: u16 = FG_INTENSITY | FG_RED | FG_GREEN | FG_BLUE; original_color &= !(mask); original_color - }, + } /* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/ Color::Rgb { r: _, g: _, b: _ } => 0, Color::AnsiValue(_val) => 0, From ee406d47fa4c2f777b7888023373386513d435a4 Mon Sep 17 00:00:00 2001 From: Timon_Post Date: Sat, 4 May 2019 13:03:18 +0200 Subject: [PATCH 3/4] fmt --- crossterm_style/examples/style.rs | 9 +++++---- crossterm_style/src/winapi_color.rs | 10 ++++++---- docs/CHANGELOG.md | 6 ++++++ docs/know_problems.md | 2 +- examples/style.rs | 8 +++++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/crossterm_style/examples/style.rs b/crossterm_style/examples/style.rs index 857d3c5..8de4e73 100644 --- a/crossterm_style/examples/style.rs +++ b/crossterm_style/examples/style.rs @@ -388,10 +388,11 @@ pub fn print_supported_colors() { } } -fn main() { - println!("{}", Colored::Bg(Color::Red)); - println!("{}", Colored::Fg(Color::Blue)); - +pub fn reset_fg_and_bg() { println!("{}", Colored::Fg(Color::Reset)); println!("{}", Colored::Bg(Color::Reset)); } + +fn main() { + print_all_background_colors_with_method() +} diff --git a/crossterm_style/src/winapi_color.rs b/crossterm_style/src/winapi_color.rs index e02078f..ee0c84d 100644 --- a/crossterm_style/src/winapi_color.rs +++ b/crossterm_style/src/winapi_color.rs @@ -119,8 +119,9 @@ impl ITerminalColor for WinApiColor { // init the original color in case it is not set. let mut original_color = original_console_color(); - const mask: u16 = BG_INTENSITY | BG_RED | BG_GREEN | BG_BLUE; - original_color &= !(mask); + const REMOVE_BG_MASK: u16 = BG_INTENSITY | BG_RED | BG_GREEN | BG_BLUE; + // remove all background values from the original color, we don't want to reset those. + original_color &= !(REMOVE_BG_MASK); original_color } @@ -153,8 +154,9 @@ impl ITerminalColor for WinApiColor { // init the original color in case it is not set. let mut original_color = original_console_color(); - const mask: u16 = FG_INTENSITY | FG_RED | FG_GREEN | FG_BLUE; - original_color &= !(mask); + const REMOVE_FG_MASK: u16 = FG_INTENSITY | FG_RED | FG_GREEN | FG_BLUE; + // remove all foreground values from the original color, we don't want to reset those. + original_color &= !(REMOVE_FG_MASK); original_color } /* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index da8d0cb..939c97f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,3 +1,9 @@ +# Changes crossterm_input 0.9.4 +- Reset foreground and background color individually. [PR](https://github.com/TimonPost/crossterm/pull/138) +- Backtap input support. [PR](https://github.com/TimonPost/crossterm/pull/129) +- Corrected white/grey and added dark grey. +- Fixed getting cursor position with raw screen enabled. [PR](https://github.com/TimonPost/crossterm/pull/134) + # Changes crossterm_input 0.9.3 - Removed println from `SyncReader` diff --git a/docs/know_problems.md b/docs/know_problems.md index adb6135..7bc8eb0 100644 --- a/docs/know_problems.md +++ b/docs/know_problems.md @@ -4,7 +4,7 @@ And I don't think it has to do anything with crossterm but it has to do whit how # Winapi-problems - Power shell does not interpreter 'DarkYellow' and is instead using gray instead, cmd is working perfectly fine. - Power shell inserts an '\n' (enter) when the program starts, this enter is the one you pressed when running the command. -- After the program ran, power shell will reset the background color. +- After the program ran, power shell will reset the background and foreground colors. # UNIX-terminals The Arc and Manjaro KDE Konsole's are not seeming to resize the terminal instead they are resizing the buffer. \ No newline at end of file diff --git a/examples/style.rs b/examples/style.rs index fa3503e..c1508c6 100644 --- a/examples/style.rs +++ b/examples/style.rs @@ -405,7 +405,9 @@ pub fn print_supported_colors() { } } -fn main() { - print_all_background_colors_with_method(); - print_all_foreground_colors_with_method(); +pub fn reset_fg_and_bg() { + println!("{}", Colored::Fg(Color::Reset)); + println!("{}", Colored::Bg(Color::Reset)); } + +fn main() {} From 81a0c85f6efdb254bbbea5db4ad100738fc77fc7 Mon Sep 17 00:00:00 2001 From: Timon_Post Date: Sat, 4 May 2019 13:46:36 +0200 Subject: [PATCH 4/4] fmt --- crossterm_cursor/src/sys/unix.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/crossterm_cursor/src/sys/unix.rs b/crossterm_cursor/src/sys/unix.rs index 2380a63..edd6145 100644 --- a/crossterm_cursor/src/sys/unix.rs +++ b/crossterm_cursor/src/sys/unix.rs @@ -44,25 +44,24 @@ pub fn pos_raw() -> io::Result<(u16, u16)> { } // Read rows and cols through a ad-hoc integer parsing function - let read_num: fn() -> Result<(i32, char) -> Result<(i32, char), Error> = - || -> Result<(i32, char), Error> { - let mut num = 0; - let mut c: char; + let read_num: fn() -> Result<(i32, char), Error> = || -> Result<(i32, char), Error> { + let mut num = 0; + let mut c: char; - loop { - let mut buf = [0u8; 1]; - io::stdin().read_exact(&mut buf)?; - c = buf[0] as char; - if let Some(d) = c.to_digit(10) { - num = if num == 0 { 0 } else { num * 10 }; - num += d as i32; - } else { - break; - } + loop { + let mut buf = [0u8; 1]; + io::stdin().read_exact(&mut buf)?; + c = buf[0] as char; + if let Some(d) = c.to_digit(10) { + num = if num == 0 { 0 } else { num * 10 }; + num += d as i32; + } else { + break; } + } - Ok((num, c)) - }; + Ok((num, c)) + }; // Read rows and expect `;` let (rows, c) = read_num()?;