crossterm/
lib.rs

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