| 1 | #![deny (unused_imports, unused_must_use)]
|
| 2 |
|
| 3 | //! # Cross-platform Terminal Manipulation Library
|
| 4 | //!
|
| 5 | //! Crossterm is a pure-rust, terminal manipulation library that makes it possible to write cross-platform text-based interfaces.
|
| 6 | //!
|
| 7 | //! This crate supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested
|
| 8 | //! see [Tested Terminals](https://github.com/crossterm-rs/crossterm#tested-terminals)
|
| 9 | //! for more info).
|
| 10 | //!
|
| 11 | //! ## Command API
|
| 12 | //!
|
| 13 | //! The command API makes the use of `crossterm` much easier and offers more control over when and how a
|
| 14 | //! command is executed. A command is just an action you can perform on the terminal e.g. cursor movement.
|
| 15 | //!
|
| 16 | //! The command API offers:
|
| 17 | //!
|
| 18 | //! * Better Performance.
|
| 19 | //! * Complete control over when to flush.
|
| 20 | //! * Complete control over where the ANSI escape commands are executed to.
|
| 21 | //! * Way easier and nicer API.
|
| 22 | //!
|
| 23 | //! There are two ways to use the API command:
|
| 24 | //!
|
| 25 | //! * Functions can execute commands on types that implement Write. Functions are easier to use and debug.
|
| 26 | //! There is a disadvantage, and that is that there is a boilerplate code involved.
|
| 27 | //! * Macros are generally seen as more difficult and aren't always well supported by editors but offer an API with less boilerplate code. If you are
|
| 28 | //! not afraid of macros, this is a recommendation.
|
| 29 | //!
|
| 30 | //! Linux and Windows 10 systems support ANSI escape codes. Those ANSI escape codes are strings or rather a
|
| 31 | //! byte sequence. When we `write` and `flush` those to the terminal we can perform some action.
|
| 32 | //! For older windows systems a WinAPI call is made.
|
| 33 | //!
|
| 34 | //! ### Supported Commands
|
| 35 | //!
|
| 36 | //! - Module [`cursor`](cursor/index.html)
|
| 37 | //! - Visibility - [`Show`](cursor/struct.Show.html), [`Hide`](cursor/struct.Hide.html)
|
| 38 | //! - Appearance - [`EnableBlinking`](cursor/struct.EnableBlinking.html),
|
| 39 | //! [`DisableBlinking`](cursor/struct.DisableBlinking.html),
|
| 40 | //! [`SetCursorStyle`](cursor/enum.SetCursorStyle.html)
|
| 41 | //! - Position -
|
| 42 | //! [`SavePosition`](cursor/struct.SavePosition.html), [`RestorePosition`](cursor/struct.RestorePosition.html),
|
| 43 | //! [`MoveUp`](cursor/struct.MoveUp.html), [`MoveDown`](cursor/struct.MoveDown.html),
|
| 44 | //! [`MoveLeft`](cursor/struct.MoveLeft.html), [`MoveRight`](cursor/struct.MoveRight.html),
|
| 45 | //! [`MoveTo`](cursor/struct.MoveTo.html), [`MoveToColumn`](cursor/struct.MoveToColumn.html),[`MoveToRow`](cursor/struct.MoveToRow.html),
|
| 46 | //! [`MoveToNextLine`](cursor/struct.MoveToNextLine.html), [`MoveToPreviousLine`](cursor/struct.MoveToPreviousLine.html)
|
| 47 | //! - Module [`event`](event/index.html)
|
| 48 | //! - Keyboard events -
|
| 49 | //! [`PushKeyboardEnhancementFlags`](event/struct.PushKeyboardEnhancementFlags.html),
|
| 50 | //! [`PopKeyboardEnhancementFlags`](event/struct.PopKeyboardEnhancementFlags.html)
|
| 51 | //! - Mouse events - [`EnableMouseCapture`](event/struct.EnableMouseCapture.html),
|
| 52 | //! [`DisableMouseCapture`](event/struct.DisableMouseCapture.html)
|
| 53 | //! - Module [`style`](style/index.html)
|
| 54 | //! - Colors - [`SetForegroundColor`](style/struct.SetForegroundColor.html),
|
| 55 | //! [`SetBackgroundColor`](style/struct.SetBackgroundColor.html),
|
| 56 | //! [`ResetColor`](style/struct.ResetColor.html), [`SetColors`](style/struct.SetColors.html)
|
| 57 | //! - Attributes - [`SetAttribute`](style/struct.SetAttribute.html), [`SetAttributes`](style/struct.SetAttributes.html),
|
| 58 | //! [`PrintStyledContent`](style/struct.PrintStyledContent.html)
|
| 59 | //! - Module [`terminal`](terminal/index.html)
|
| 60 | //! - Scrolling - [`ScrollUp`](terminal/struct.ScrollUp.html),
|
| 61 | //! [`ScrollDown`](terminal/struct.ScrollDown.html)
|
| 62 | //! - Miscellaneous - [`Clear`](terminal/struct.Clear.html),
|
| 63 | //! [`SetSize`](terminal/struct.SetSize.html),
|
| 64 | //! [`SetTitle`](terminal/struct.SetTitle.html),
|
| 65 | //! [`DisableLineWrap`](terminal/struct.DisableLineWrap.html),
|
| 66 | //! [`EnableLineWrap`](terminal/struct.EnableLineWrap.html)
|
| 67 | //! - Alternate screen - [`EnterAlternateScreen`](terminal/struct.EnterAlternateScreen.html),
|
| 68 | //! [`LeaveAlternateScreen`](terminal/struct.LeaveAlternateScreen.html)
|
| 69 | //! - Module [`clipboard`](clipboard/index.html) (requires
|
| 70 | //! [`feature = "osc52"`](#optional-features))
|
| 71 | //! - Clipboard - [`CopyToClipboard`](clipboard/struct.CopyToClipboard.html)
|
| 72 | //!
|
| 73 | //! ### Command Execution
|
| 74 | //!
|
| 75 | //! There are two different ways to execute commands:
|
| 76 | //!
|
| 77 | //! * [Lazy Execution](#lazy-execution)
|
| 78 | //! * [Direct Execution](#direct-execution)
|
| 79 | //!
|
| 80 | //! #### Lazy Execution
|
| 81 | //!
|
| 82 | //! Flushing bytes to the terminal buffer is a heavy system call. If we perform a lot of actions with the terminal,
|
| 83 | //! we want to do this periodically - like with a TUI editor - so that we can flush more data to the terminal buffer
|
| 84 | //! at the same time.
|
| 85 | //!
|
| 86 | //! Crossterm offers the possibility to do this with `queue`.
|
| 87 | //! With `queue` you can queue commands, and when you call [Write::flush][flush] these commands will be executed.
|
| 88 | //!
|
| 89 | //! You can pass a custom buffer implementing [std::io::Write][write] to this `queue` operation.
|
| 90 | //! The commands will be executed on that buffer.
|
| 91 | //! The most common buffer is [std::io::stdout][stdout] however, [std::io::stderr][stderr] is used sometimes as well.
|
| 92 | //!
|
| 93 | //! ##### Examples
|
| 94 | //!
|
| 95 | //! A simple demonstration that shows the command API in action with cursor commands.
|
| 96 | //!
|
| 97 | //! Functions:
|
| 98 | //!
|
| 99 | //! ```no_run
|
| 100 | //! use std::io::{Write, stdout};
|
| 101 | //! use crossterm::{QueueableCommand, cursor};
|
| 102 | //!
|
| 103 | //! let mut stdout = stdout();
|
| 104 | //! stdout.queue(cursor::MoveTo(5,5));
|
| 105 | //!
|
| 106 | //! // some other code ...
|
| 107 | //!
|
| 108 | //! stdout.flush();
|
| 109 | //! ```
|
| 110 | //!
|
| 111 | //! The [queue](./trait.QueueableCommand.html) function returns itself, therefore you can use this to queue another
|
| 112 | //! command. Like `stdout.queue(Goto(5,5)).queue(Clear(ClearType::All))`.
|
| 113 | //!
|
| 114 | //! Macros:
|
| 115 | //!
|
| 116 | //! ```no_run
|
| 117 | //! use std::io::{Write, stdout};
|
| 118 | //! use crossterm::{queue, QueueableCommand, cursor};
|
| 119 | //!
|
| 120 | //! let mut stdout = stdout();
|
| 121 | //! queue!(stdout, cursor::MoveTo(5, 5));
|
| 122 | //!
|
| 123 | //! // some other code ...
|
| 124 | //!
|
| 125 | //! // move operation is performed only if we flush the buffer.
|
| 126 | //! stdout.flush();
|
| 127 | //! ```
|
| 128 | //!
|
| 129 | //! You can pass more than one command into the [queue](./macro.queue.html) macro like
|
| 130 | //! `queue!(stdout, MoveTo(5, 5), Clear(ClearType::All))` and
|
| 131 | //! they will be executed in the given order from left to right.
|
| 132 | //!
|
| 133 | //! #### Direct Execution
|
| 134 | //!
|
| 135 | //! For many applications it is not at all important to be efficient with 'flush' operations.
|
| 136 | //! For this use case there is the `execute` operation.
|
| 137 | //! This operation executes the command immediately, and calls the `flush` under water.
|
| 138 | //!
|
| 139 | //! You can pass a custom buffer implementing [std::io::Write][write] to this `execute` operation.
|
| 140 | //! The commands will be executed on that buffer.
|
| 141 | //! The most common buffer is [std::io::stdout][stdout] however, [std::io::stderr][stderr] is used sometimes as well.
|
| 142 | //!
|
| 143 | //! ##### Examples
|
| 144 | //!
|
| 145 | //! Functions:
|
| 146 | //!
|
| 147 | //! ```no_run
|
| 148 | //! use std::io::{Write, stdout};
|
| 149 | //! use crossterm::{ExecutableCommand, cursor};
|
| 150 | //!
|
| 151 | //! let mut stdout = stdout();
|
| 152 | //! stdout.execute(cursor::MoveTo(5,5));
|
| 153 | //! ```
|
| 154 | //! The [execute](./trait.ExecutableCommand.html) function returns itself, therefore you can use this to queue
|
| 155 | //! another command. Like `stdout.execute(Goto(5,5))?.execute(Clear(ClearType::All))`.
|
| 156 | //!
|
| 157 | //! Macros:
|
| 158 | //!
|
| 159 | //! ```no_run
|
| 160 | //! use std::io::{stdout, Write};
|
| 161 | //! use crossterm::{execute, ExecutableCommand, cursor};
|
| 162 | //!
|
| 163 | //! let mut stdout = stdout();
|
| 164 | //! execute!(stdout, cursor::MoveTo(5, 5));
|
| 165 | //! ```
|
| 166 | //! You can pass more than one command into the [execute](./macro.execute.html) macro like
|
| 167 | //! `execute!(stdout, MoveTo(5, 5), Clear(ClearType::All))` and they will be executed in the given order from
|
| 168 | //! left to right.
|
| 169 | //!
|
| 170 | //! ## Examples
|
| 171 | //!
|
| 172 | //! Print a rectangle colored with magenta and use both direct execution and lazy execution.
|
| 173 | //!
|
| 174 | //! Functions:
|
| 175 | //!
|
| 176 | //! ```no_run
|
| 177 | //! use std::io::{self, Write};
|
| 178 | //! use crossterm::{
|
| 179 | //! ExecutableCommand, QueueableCommand,
|
| 180 | //! terminal, cursor, style::{self, Stylize}
|
| 181 | //! };
|
| 182 | //!
|
| 183 | //! fn main() -> io::Result<()> {
|
| 184 | //! let mut stdout = io::stdout();
|
| 185 | //!
|
| 186 | //! stdout.execute(terminal::Clear(terminal::ClearType::All))?;
|
| 187 | //!
|
| 188 | //! for y in 0..40 {
|
| 189 | //! for x in 0..150 {
|
| 190 | //! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
| 191 | //! // in this loop we are more efficient by not flushing the buffer.
|
| 192 | //! stdout
|
| 193 | //! .queue(cursor::MoveTo(x,y))?
|
| 194 | //! .queue(style::PrintStyledContent( "█" .magenta()))?;
|
| 195 | //! }
|
| 196 | //! }
|
| 197 | //! }
|
| 198 | //! stdout.flush()?;
|
| 199 | //! Ok(())
|
| 200 | //! }
|
| 201 | //! ```
|
| 202 | //!
|
| 203 | //! Macros:
|
| 204 | //!
|
| 205 | //! ```no_run
|
| 206 | //! use std::io::{self, Write};
|
| 207 | //! use crossterm::{
|
| 208 | //! execute, queue,
|
| 209 | //! style::{self, Stylize}, cursor, terminal
|
| 210 | //! };
|
| 211 | //!
|
| 212 | //! fn main() -> io::Result<()> {
|
| 213 | //! let mut stdout = io::stdout();
|
| 214 | //!
|
| 215 | //! execute!(stdout, terminal::Clear(terminal::ClearType::All))?;
|
| 216 | //!
|
| 217 | //! for y in 0..40 {
|
| 218 | //! for x in 0..150 {
|
| 219 | //! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
| 220 | //! // in this loop we are more efficient by not flushing the buffer.
|
| 221 | //! queue!(stdout, cursor::MoveTo(x,y), style::PrintStyledContent( "█" .magenta()))?;
|
| 222 | //! }
|
| 223 | //! }
|
| 224 | //! }
|
| 225 | //! stdout.flush()?;
|
| 226 | //! Ok(())
|
| 227 | //! }
|
| 228 | //!```
|
| 229 | //! ## Feature Flags
|
| 230 | #![doc = document_features::document_features!()]
|
| 231 | //!
|
| 232 | //! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
|
| 233 | //! [stdout]: https://doc.rust-lang.org/std/io/fn.stdout.html
|
| 234 | //! [stderr]: https://doc.rust-lang.org/std/io/fn.stderr.html
|
| 235 | //! [flush]: https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.flush
|
| 236 |
|
| 237 | pub use crate::command::{Command, ExecutableCommand, QueueableCommand, SynchronizedUpdate};
|
| 238 |
|
| 239 | /// A module to work with the terminal cursor
|
| 240 | pub mod cursor;
|
| 241 | /// A module to read events.
|
| 242 | #[cfg (feature = "events" )]
|
| 243 | pub mod event;
|
| 244 | /// A module to apply attributes and colors on your text.
|
| 245 | pub mod style;
|
| 246 | /// A module to work with the terminal.
|
| 247 | pub mod terminal;
|
| 248 |
|
| 249 | /// A module to query if the current instance is a tty.
|
| 250 | pub mod tty;
|
| 251 |
|
| 252 | /// A module for clipboard interaction
|
| 253 | #[cfg (feature = "osc52" )]
|
| 254 | pub mod clipboard;
|
| 255 |
|
| 256 | #[cfg (windows)]
|
| 257 | /// A module that exposes one function to check if the current terminal supports ANSI sequences.
|
| 258 | pub mod ansi_support;
|
| 259 | mod command;
|
| 260 | pub(crate) mod macros;
|
| 261 |
|
| 262 | #[cfg (all(windows, not(feature = "windows" )))]
|
| 263 | compile_error!("Compiling on Windows with \"windows \" feature disabled. Feature \"windows \" should only be disabled when project will never be compiled on Windows." );
|
| 264 | |