2019-10-23 01:33:38 +11:00
//! # Style
//!
//! The `style` module provides a functionality to apply attributes and colors on your text.
//!
//! This documentation does not contain a lot of examples. The reason is that it's fairly
//! obvious how to use this crate. Although, we do provide
2019-12-13 17:12:35 +11:00
//! [examples](https://github.com/crossterm-rs/crossterm/tree/master/examples) repository
2019-10-23 01:33:38 +11:00
//! to demonstrate the capabilities.
//!
//! ## Platform-specific Notes
//!
//! Not all features are supported on all terminals/platforms. You should always consult
//! platform-specific notes of the following types:
//!
//! * [Color](enum.Color.html#platform-specific-notes)
//! * [Attribute](enum.Attribute.html#platform-specific-notes)
//!
//! ## Examples
2019-11-19 07:50:57 +11:00
//!
2019-11-02 04:09:05 +11:00
//! A few examples of how to use the style module.
2019-10-23 01:33:38 +11:00
//!
//! ### Colors
2019-11-19 07:50:57 +11:00
//!
2019-11-02 04:09:05 +11:00
//! How to change the terminal text color.
2019-10-23 01:33:38 +11:00
//!
2019-11-19 07:50:57 +11:00
//! Command API:
2019-11-02 04:09:05 +11:00
//!
//! Using the Command API to color text.
2019-10-23 01:33:38 +11:00
//!
//! ```no_run
//! use std::io::{stdout, Write};
//!
2019-12-05 03:26:57 +11:00
//! use crossterm::{execute, Result};
//! use crossterm::style::{Print, SetForegroundColor, SetBackgroundColor, ResetColor, Color, Attribute};
2019-10-23 01:33:38 +11:00
//!
//! fn main() -> Result<()> {
//! execute!(
//! stdout(),
//! // Blue foreground
2019-11-01 07:02:04 +11:00
//! SetForegroundColor(Color::Blue),
2019-10-23 01:33:38 +11:00
//! // Red background
2019-11-01 07:02:04 +11:00
//! SetBackgroundColor(Color::Red),
2019-12-05 03:26:57 +11:00
//! // Print text
//! Print("Blue text on Red.".to_string()),
2019-10-23 01:33:38 +11:00
//! // Reset to default colors
//! ResetColor
//! )
//! }
//! ```
//!
2019-11-19 07:50:57 +11:00
//! Functions:
2019-11-02 04:09:05 +11:00
//!
//! Using functions from [`Colorize`](trait.Colorize.html) on a `String` or `&'static str` to color it.
2019-10-23 01:33:38 +11:00
//!
//! ```no_run
2019-11-01 07:02:04 +11:00
//! use crossterm::style::Colorize;
2019-10-23 01:33:38 +11:00
//!
//! println!("{}", "Red foreground color & blue background.".red().on_blue());
//! ```
//!
//! ### Attributes
2019-11-19 07:50:57 +11:00
//!
2019-11-02 04:09:05 +11:00
//! How to appy terminal attributes to text.
//!
2019-11-19 07:50:57 +11:00
//! Command API:
2019-10-23 01:33:38 +11:00
//!
2019-11-02 04:09:05 +11:00
//! Using the Command API to set attributes.
2019-10-23 01:33:38 +11:00
//!
//! ```no_run
//! use std::io::{stdout, Write};
//!
2019-12-05 03:26:57 +11:00
//! use crossterm::{execute, Result, style::Print};
2019-11-01 07:02:04 +11:00
//! use crossterm::style::{SetAttribute, Attribute};
2019-10-23 01:33:38 +11:00
//!
//! fn main() -> Result<()> {
//! execute!(
//! stdout(),
//! // Set to bold
2019-11-01 07:02:04 +11:00
//! SetAttribute(Attribute::Bold),
2019-12-05 03:26:57 +11:00
//! Print("Bold text here.".to_string()),
2019-10-23 01:33:38 +11:00
//! // Reset all attributes
2019-11-01 07:02:04 +11:00
//! SetAttribute(Attribute::Reset)
2019-10-23 01:33:38 +11:00
//! )
//! }
//! ```
//!
2019-11-19 07:50:57 +11:00
//! Functions:
2019-11-02 04:09:05 +11:00
//!
//! Using [`Styler`](trait.Styler.html) functions on a `String` or `&'static str` to set attributes to it.
2019-10-23 01:33:38 +11:00
//!
//! ```no_run
2019-11-01 07:02:04 +11:00
//! use crossterm::style::Styler;
2019-10-23 01:33:38 +11:00
//!
//! println!("{}", "Bold".bold());
//! println!("{}", "Underlined".underlined());
//! println!("{}", "Negative".negative());
//! ```
//!
2019-11-19 07:50:57 +11:00
//! Displayable:
2019-11-02 04:09:05 +11:00
//!
//! [`Attribute`](enum.Attribute.html) implements [Display](https://doc.rust-lang.org/beta/std/fmt/trait.Display.html) and therefore it can be formatted like:
2019-10-23 01:33:38 +11:00
//!
//! ```no_run
2019-11-01 07:02:04 +11:00
//! use crossterm::style::Attribute;
2019-10-23 01:33:38 +11:00
//!
//! println!(
//! "{} Underlined {} No Underline",
//! Attribute::Underlined,
//! Attribute::NoUnderline
//! );
//! ```
2019-11-19 07:50:57 +11:00
use std ::{ env , fmt ::Display } ;
2019-10-23 01:33:38 +11:00
#[ cfg(windows) ]
2019-11-01 07:02:04 +11:00
use crate ::Result ;
2019-12-12 03:10:34 +11:00
use crate ::{ impl_display , Command } ;
2019-10-23 01:33:38 +11:00
2019-11-01 07:02:04 +11:00
pub ( crate ) use self ::enums ::Colored ;
2019-11-19 07:50:57 +11:00
pub use self ::{
content_style ::ContentStyle ,
enums ::{ Attribute , Color } ,
styled_content ::StyledContent ,
traits ::{ Colorize , Styler } ,
} ;
2019-10-23 01:33:38 +11:00
#[ macro_use ]
mod macros ;
2019-11-01 07:02:04 +11:00
mod ansi ;
mod content_style ;
2019-10-23 01:33:38 +11:00
mod enums ;
2019-11-01 07:02:04 +11:00
mod styled_content ;
mod sys ;
2019-10-23 01:33:38 +11:00
mod traits ;
2019-10-28 07:07:09 +11:00
/// Creates a `StyledContent`.
2019-10-23 01:33:38 +11:00
///
/// This could be used to style any type that implements `Display` with colors and text attributes.
///
2019-10-28 07:07:09 +11:00
/// See [`StyledContent`](struct.StyledContent.html) for more info.
2019-10-23 01:33:38 +11:00
///
/// # Examples
///
/// ```no_run
2019-11-01 07:02:04 +11:00
/// use crossterm::style::{style, Color};
2019-10-23 01:33:38 +11:00
///
2019-10-28 07:07:09 +11:00
/// let styled_content = style("Blue colored text on yellow background")
2019-10-23 01:33:38 +11:00
/// .with(Color::Blue)
/// .on(Color::Yellow);
///
2019-10-28 07:07:09 +11:00
/// println!("{}", styled_content);
2019-10-23 01:33:38 +11:00
/// ```
2019-10-28 07:07:09 +11:00
pub fn style < ' a , D : ' a > ( val : D ) -> StyledContent < D >
2019-10-23 01:33:38 +11:00
where
D : Display + Clone ,
{
2019-10-28 07:07:09 +11:00
ContentStyle ::new ( ) . apply ( val )
2019-10-23 01:33:38 +11:00
}
impl Colorize < & 'static str > for & 'static str {
// foreground colors
2019-11-01 07:02:04 +11:00
def_str_color! ( foreground_color : black = > Color ::Black ) ;
def_str_color! ( foreground_color : dark_grey = > Color ::DarkGrey ) ;
def_str_color! ( foreground_color : red = > Color ::Red ) ;
def_str_color! ( foreground_color : dark_red = > Color ::DarkRed ) ;
def_str_color! ( foreground_color : green = > Color ::Green ) ;
def_str_color! ( foreground_color : dark_green = > Color ::DarkGreen ) ;
def_str_color! ( foreground_color : yellow = > Color ::Yellow ) ;
def_str_color! ( foreground_color : dark_yellow = > Color ::DarkYellow ) ;
def_str_color! ( foreground_color : blue = > Color ::Blue ) ;
def_str_color! ( foreground_color : dark_blue = > Color ::DarkBlue ) ;
def_str_color! ( foreground_color : magenta = > Color ::Magenta ) ;
def_str_color! ( foreground_color : dark_magenta = > Color ::DarkMagenta ) ;
def_str_color! ( foreground_color : cyan = > Color ::Cyan ) ;
def_str_color! ( foreground_color : dark_cyan = > Color ::DarkCyan ) ;
def_str_color! ( foreground_color : white = > Color ::White ) ;
def_str_color! ( foreground_color : grey = > Color ::Grey ) ;
2019-10-23 01:33:38 +11:00
// background colors
2019-11-01 07:02:04 +11:00
def_str_color! ( background_color : on_black = > Color ::Black ) ;
def_str_color! ( background_color : on_dark_grey = > Color ::DarkGrey ) ;
def_str_color! ( background_color : on_red = > Color ::Red ) ;
def_str_color! ( background_color : on_dark_red = > Color ::DarkRed ) ;
def_str_color! ( background_color : on_green = > Color ::Green ) ;
def_str_color! ( background_color : on_dark_green = > Color ::DarkGreen ) ;
def_str_color! ( background_color : on_yellow = > Color ::Yellow ) ;
def_str_color! ( background_color : on_dark_yellow = > Color ::DarkYellow ) ;
def_str_color! ( background_color : on_blue = > Color ::Blue ) ;
def_str_color! ( background_color : on_dark_blue = > Color ::DarkBlue ) ;
def_str_color! ( background_color : on_magenta = > Color ::Magenta ) ;
def_str_color! ( background_color : on_dark_magenta = > Color ::DarkMagenta ) ;
def_str_color! ( background_color : on_cyan = > Color ::Cyan ) ;
def_str_color! ( background_color : on_dark_cyan = > Color ::DarkCyan ) ;
def_str_color! ( background_color : on_white = > Color ::White ) ;
def_str_color! ( background_color : on_grey = > Color ::Grey ) ;
2019-10-23 01:33:38 +11:00
}
impl Styler < & 'static str > for & 'static str {
def_str_attr! ( reset = > Attribute ::Reset ) ;
def_str_attr! ( bold = > Attribute ::Bold ) ;
def_str_attr! ( underlined = > Attribute ::Underlined ) ;
def_str_attr! ( reverse = > Attribute ::Reverse ) ;
def_str_attr! ( dim = > Attribute ::Dim ) ;
def_str_attr! ( italic = > Attribute ::Italic ) ;
def_str_attr! ( negative = > Attribute ::Reverse ) ;
def_str_attr! ( slow_blink = > Attribute ::SlowBlink ) ;
def_str_attr! ( rapid_blink = > Attribute ::RapidBlink ) ;
def_str_attr! ( hidden = > Attribute ::Hidden ) ;
def_str_attr! ( crossed_out = > Attribute ::CrossedOut ) ;
}
2019-11-01 07:02:04 +11:00
/// Returns available color count.
2019-10-23 01:33:38 +11:00
///
2019-11-01 07:02:04 +11:00
/// # Notes
2019-10-23 01:33:38 +11:00
///
2019-11-01 07:02:04 +11:00
/// This does not always provide a good result.
pub fn available_color_count ( ) -> u16 {
env ::var ( " TERM " )
. map ( | x | if x . contains ( " 256color " ) { 256 } else { 8 } )
. unwrap_or ( 8 )
2019-10-23 01:33:38 +11:00
}
2019-11-01 07:02:04 +11:00
/// A command that sets the the foreground color.
2019-10-23 01:33:38 +11:00
///
/// See [`Color`](enum.Color.html) for more info.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
2020-01-29 06:20:26 +11:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2019-11-01 07:02:04 +11:00
pub struct SetForegroundColor ( pub Color ) ;
2019-10-23 01:33:38 +11:00
2019-11-01 07:02:04 +11:00
impl Command for SetForegroundColor {
2019-10-23 01:33:38 +11:00
type AnsiType = String ;
fn ansi_code ( & self ) -> Self ::AnsiType {
ansi ::set_fg_csi_sequence ( self . 0 )
}
#[ cfg(windows) ]
fn execute_winapi ( & self ) -> Result < ( ) > {
2019-11-01 07:02:04 +11:00
sys ::windows ::set_foreground_color ( self . 0 )
2019-10-23 01:33:38 +11:00
}
}
2019-11-01 07:02:04 +11:00
/// A command that sets the the background color.
2019-10-23 01:33:38 +11:00
///
/// See [`Color`](enum.Color.html) for more info.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
2020-01-29 06:20:26 +11:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2019-11-01 07:02:04 +11:00
pub struct SetBackgroundColor ( pub Color ) ;
2019-10-23 01:33:38 +11:00
2019-11-01 07:02:04 +11:00
impl Command for SetBackgroundColor {
2019-10-23 01:33:38 +11:00
type AnsiType = String ;
fn ansi_code ( & self ) -> Self ::AnsiType {
ansi ::set_bg_csi_sequence ( self . 0 )
}
#[ cfg(windows) ]
fn execute_winapi ( & self ) -> Result < ( ) > {
2019-11-01 07:02:04 +11:00
sys ::windows ::set_background_color ( self . 0 )
2019-10-23 01:33:38 +11:00
}
}
2019-11-01 07:02:04 +11:00
/// A command that sets an attribute.
2019-10-23 01:33:38 +11:00
///
/// See [`Attribute`](enum.Attribute.html) for more info.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
2020-01-29 06:20:26 +11:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2019-11-01 07:02:04 +11:00
pub struct SetAttribute ( pub Attribute ) ;
2019-10-23 01:33:38 +11:00
2019-11-01 07:02:04 +11:00
impl Command for SetAttribute {
2019-10-23 01:33:38 +11:00
type AnsiType = String ;
fn ansi_code ( & self ) -> Self ::AnsiType {
ansi ::set_attr_csi_sequence ( self . 0 )
}
#[ cfg(windows) ]
fn execute_winapi ( & self ) -> Result < ( ) > {
// attributes are not supported by WinAPI.
Ok ( ( ) )
}
}
2019-11-01 07:02:04 +11:00
/// A command that prints styled content.
2019-10-23 01:33:38 +11:00
///
2019-10-28 07:07:09 +11:00
/// See [`StyledContent`](struct.StyledContent.html) for more info.
2019-10-23 01:33:38 +11:00
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
2020-01-29 06:20:26 +11:00
#[ derive(Debug, Clone) ]
2019-10-30 17:37:57 +11:00
pub struct PrintStyledContent < D : Display + Clone > ( pub StyledContent < D > ) ;
2019-10-23 01:33:38 +11:00
2019-10-30 17:37:57 +11:00
impl < D > Command for PrintStyledContent < D >
2019-10-23 01:33:38 +11:00
where
D : Display + Clone ,
{
2019-10-28 07:07:09 +11:00
type AnsiType = StyledContent < D > ;
2019-10-23 01:33:38 +11:00
fn ansi_code ( & self ) -> Self ::AnsiType {
self . 0. clone ( )
}
#[ cfg(windows) ]
fn execute_winapi ( & self ) -> Result < ( ) > {
Ok ( ( ) )
}
}
2019-11-01 07:02:04 +11:00
/// A command that resets the colors back to default.
2019-10-23 01:33:38 +11:00
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
2020-01-29 06:20:26 +11:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2019-10-23 01:33:38 +11:00
pub struct ResetColor ;
impl Command for ResetColor {
2020-01-29 06:20:26 +11:00
type AnsiType = & 'static str ;
2019-10-23 01:33:38 +11:00
fn ansi_code ( & self ) -> Self ::AnsiType {
2020-01-29 06:20:26 +11:00
ansi ::RESET_CSI_SEQUENCE
2019-10-23 01:33:38 +11:00
}
#[ cfg(windows) ]
fn execute_winapi ( & self ) -> Result < ( ) > {
2019-11-01 07:02:04 +11:00
sys ::windows ::reset ( )
2019-10-23 01:33:38 +11:00
}
}
2019-12-05 03:26:57 +11:00
/// A command that prints the given displayable type.
///
/// Commands must be executed/queued for execution otherwise they do nothing.
2020-01-29 06:20:26 +11:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2019-12-05 03:26:57 +11:00
pub struct Print < T : Display + Clone > ( pub T ) ;
impl < T : Display + Clone > Command for Print < T > {
type AnsiType = T ;
fn ansi_code ( & self ) -> Self ::AnsiType {
self . 0. clone ( )
}
#[ cfg(windows) ]
fn execute_winapi ( & self ) -> Result < ( ) > {
print! ( " {} " , self . 0 ) ;
Ok ( ( ) )
}
}
impl < T : Display + Clone > Display for Print < T > {
fn fmt (
& self ,
f : & mut ::std ::fmt ::Formatter < '_ > ,
) -> ::std ::result ::Result < ( ) , ::std ::fmt ::Error > {
write! ( f , " {} " , self . ansi_code ( ) )
}
}
2019-11-01 07:02:04 +11:00
impl_display! ( for SetForegroundColor ) ;
impl_display! ( for SetBackgroundColor ) ;
impl_display! ( for SetAttribute ) ;
2019-10-30 17:37:57 +11:00
impl_display! ( for PrintStyledContent < String > ) ;
impl_display! ( for PrintStyledContent < & 'static str > ) ;
2019-10-23 01:33:38 +11:00
impl_display! ( for ResetColor ) ;