1#![deny(missing_docs)]
39#![deny(clippy::all)]
40#![warn(clippy::pedantic)]
41#![allow(clippy::module_name_repetitions)]
42
43mod color;
44mod escape;
45mod modifier;
46mod parser;
47mod sequence;
48mod style;
49
50pub use color::Color;
51#[cfg(feature = "brand")]
52pub use color::brand;
53pub use escape::{Escape, EscapeKind};
54pub use modifier::Modifier;
55pub use parser::{parse, strip_ansi, visible_len, ParsedSequence};
56pub use sequence::{Sequence, SequenceBuilder};
57pub use style::{style, Style, Styled};
58
59pub const CSI: &str = "\x1b[";
61
62pub const OSC: &str = "\x1b]";
64
65pub const SGR_SUFFIX: &str = "m";
67
68pub const RESET: &str = "\x1b[0m";
70
71pub mod sequences {
73 pub const CLEAR_SCREEN: &str = "\x1b[2J";
75
76 pub const CLEAR_TO_END: &str = "\x1b[0J";
78
79 pub const CLEAR_TO_START: &str = "\x1b[1J";
81
82 pub const CLEAR_LINE: &str = "\x1b[2K";
84
85 pub const CLEAR_LINE_TO_END: &str = "\x1b[0K";
87
88 pub const CLEAR_LINE_TO_START: &str = "\x1b[1K";
90
91 pub const CURSOR_HOME: &str = "\x1b[H";
93
94 pub const CURSOR_HIDE: &str = "\x1b[?25l";
96
97 pub const CURSOR_SHOW: &str = "\x1b[?25h";
99
100 pub const CURSOR_SAVE: &str = "\x1b[s";
102
103 pub const CURSOR_RESTORE: &str = "\x1b[u";
105
106 pub const ALT_SCREEN_ENTER: &str = "\x1b[?1049h";
108
109 pub const ALT_SCREEN_EXIT: &str = "\x1b[?1049l";
111
112 pub const MOUSE_ENABLE: &str = "\x1b[?1000h";
114
115 pub const MOUSE_DISABLE: &str = "\x1b[?1000l";
117
118 pub const BRACKETED_PASTE_ENABLE: &str = "\x1b[?2004h";
120
121 pub const BRACKETED_PASTE_DISABLE: &str = "\x1b[?2004l";
123}
124
125pub mod cursor {
127 #[must_use]
129 pub fn up(n: u16) -> String {
130 format!("\x1b[{n}A")
131 }
132
133 #[must_use]
135 pub fn down(n: u16) -> String {
136 format!("\x1b[{n}B")
137 }
138
139 #[must_use]
141 pub fn right(n: u16) -> String {
142 format!("\x1b[{n}C")
143 }
144
145 #[must_use]
147 pub fn left(n: u16) -> String {
148 format!("\x1b[{n}D")
149 }
150
151 #[must_use]
153 pub fn goto(row: u16, col: u16) -> String {
154 format!("\x1b[{row};{col}H")
155 }
156
157 #[must_use]
159 pub fn column(col: u16) -> String {
160 format!("\x1b[{col}G")
161 }
162}
163
164pub mod prelude {
166 pub use crate::color::Color;
167 pub use crate::modifier::Modifier;
168 pub use crate::style::{style, Style, Styled};
169 pub use crate::{cursor, sequences, RESET};
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[test]
177 fn test_style_basic() {
178 let s = style("test").fg(Color::Red).to_string();
179 assert!(s.contains("\x1b["));
180 assert!(s.contains("test"));
181 assert!(s.ends_with(RESET));
182 }
183
184 #[test]
185 fn test_cursor_movement() {
186 assert_eq!(cursor::up(5), "\x1b[5A");
187 assert_eq!(cursor::goto(10, 20), "\x1b[10;20H");
188 }
189}