crossterm/
lib.rs

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//!
70//! ### Command Execution
71//!
72//! There are two different ways to execute commands:
73//!
74//! * [Lazy Execution](#lazy-execution)
75//! * [Direct Execution](#direct-execution)
76//!
77//! #### Lazy Execution
78//!
79//! Flushing bytes to the terminal buffer is a heavy system call. If we perform a lot of actions with the terminal,
80//! we want to do this periodically - like with a TUI editor - so that we can flush more data to the terminal buffer
81//! at the same time.
82//!
83//! Crossterm offers the possibility to do this with `queue`.
84//! With `queue` you can queue commands, and when you call [Write::flush][flush] these commands will be executed.
85//!
86//! You can pass a custom buffer implementing [std::io::Write][write] to this `queue` operation.
87//! The commands will be executed on that buffer.
88//! The most common buffer is [std::io::stdout][stdout] however, [std::io::stderr][stderr] is used sometimes as well.
89//!
90//! ##### Examples
91//!
92//! A simple demonstration that shows the command API in action with cursor commands.
93//!
94//! Functions:
95//!
96//! ```no_run
97//! use std::io::{Write, stdout};
98//! use crossterm::{QueueableCommand, cursor};
99//!
100//! let mut stdout = stdout();
101//! stdout.queue(cursor::MoveTo(5,5));
102//!
103//! // some other code ...
104//!
105//! stdout.flush();
106//! ```
107//!
108//! The [queue](./trait.QueueableCommand.html) function returns itself, therefore you can use this to queue another
109//! command. Like `stdout.queue(Goto(5,5)).queue(Clear(ClearType::All))`.
110//!
111//! Macros:
112//!
113//! ```no_run
114//! use std::io::{Write, stdout};
115//! use crossterm::{queue, QueueableCommand, cursor};
116//!
117//! let mut stdout = stdout();
118//! queue!(stdout,  cursor::MoveTo(5, 5));
119//!
120//! // some other code ...
121//!
122//! // move operation is performed only if we flush the buffer.
123//! stdout.flush();
124//! ```
125//!
126//! You can pass more than one command into the [queue](./macro.queue.html) macro like
127//! `queue!(stdout, MoveTo(5, 5), Clear(ClearType::All))` and
128//! they will be executed in the given order from left to right.
129//!
130//! #### Direct Execution
131//!
132//! For many applications it is not at all important to be efficient with 'flush' operations.
133//! For this use case there is the `execute` operation.
134//! This operation executes the command immediately, and calls the `flush` under water.
135//!
136//! You can pass a custom buffer implementing [std::io::Write][write] to this `execute` operation.
137//! The commands will be executed on that buffer.
138//! The most common buffer is [std::io::stdout][stdout] however, [std::io::stderr][stderr] is used sometimes as well.
139//!
140//! ##### Examples
141//!
142//! Functions:
143//!
144//! ```no_run
145//! use std::io::{Write, stdout};
146//! use crossterm::{ExecutableCommand, cursor};
147//!
148//! let mut stdout = stdout();
149//! stdout.execute(cursor::MoveTo(5,5));
150//! ```
151//! The [execute](./trait.ExecutableCommand.html) function returns itself, therefore you can use this to queue
152//! another command. Like `stdout.execute(Goto(5,5))?.execute(Clear(ClearType::All))`.
153//!
154//! Macros:
155//!
156//! ```no_run
157//! use std::io::{stdout, Write};
158//! use crossterm::{execute, ExecutableCommand, cursor};
159//!
160//! let mut stdout = stdout();
161//! execute!(stdout, cursor::MoveTo(5, 5));
162//! ```
163//! You can pass more than one command into the [execute](./macro.execute.html) macro like
164//! `execute!(stdout, MoveTo(5, 5), Clear(ClearType::All))` and they will be executed in the given order from
165//! left to right.
166//!
167//! ## Examples
168//!
169//! Print a rectangle colored with magenta and use both direct execution and lazy execution.
170//!
171//! Functions:
172//!
173//! ```no_run
174//! use std::io::{self, Write};
175//! use crossterm::{
176//!     ExecutableCommand, QueueableCommand,
177//!     terminal, cursor, style::{self, Stylize}
178//! };
179//!
180//! fn main() -> io::Result<()> {
181//!   let mut stdout = io::stdout();
182//!
183//!   stdout.execute(terminal::Clear(terminal::ClearType::All))?;
184//!
185//!   for y in 0..40 {
186//!     for x in 0..150 {
187//!       if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
188//!         // in this loop we are more efficient by not flushing the buffer.
189//!         stdout
190//!           .queue(cursor::MoveTo(x,y))?
191//!           .queue(style::PrintStyledContent( "█".magenta()))?;
192//!       }
193//!     }
194//!   }
195//!   stdout.flush()?;
196//!   Ok(())
197//! }
198//! ```
199//!
200//! Macros:
201//!
202//! ```no_run
203//! use std::io::{self, Write};
204//! use crossterm::{
205//!     execute, queue,
206//!     style::{self, Stylize}, cursor, terminal
207//! };
208//!
209//! fn main() -> io::Result<()> {
210//!   let mut stdout = io::stdout();
211//!
212//!   execute!(stdout, terminal::Clear(terminal::ClearType::All))?;
213//!
214//!   for y in 0..40 {
215//!     for x in 0..150 {
216//!       if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
217//!         // in this loop we are more efficient by not flushing the buffer.
218//!         queue!(stdout, cursor::MoveTo(x,y), style::PrintStyledContent( "█".magenta()))?;
219//!       }
220//!     }
221//!   }
222//!   stdout.flush()?;
223//!   Ok(())
224//! }
225//!```
226//!
227//! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
228//! [stdout]: https://doc.rust-lang.org/std/io/fn.stdout.html
229//! [stderr]: https://doc.rust-lang.org/std/io/fn.stderr.html
230//! [flush]: https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.flush
231
232pub use crate::command::{Command, ExecutableCommand, QueueableCommand, SynchronizedUpdate};
233
234/// A module to work with the terminal cursor
235pub mod cursor;
236/// A module to read events.
237#[cfg(feature = "events")]
238pub mod event;
239/// A module to apply attributes and colors on your text.
240pub mod style;
241/// A module to work with the terminal.
242pub mod terminal;
243
244/// A module to query if the current instance is a tty.
245pub mod tty;
246
247#[cfg(windows)]
248/// A module that exposes one function to check if the current terminal supports ANSI sequences.
249pub mod ansi_support;
250mod command;
251pub(crate) mod macros;
252
253#[cfg(all(windows, not(feature = "windows")))]
254compile_error!("Compiling on Windows with \"windows\" feature disabled. Feature \"windows\" should only be disabled when project will never be compiled on Windows.");
255
256#[cfg(all(winapi, not(feature = "winapi")))]
257compile_error!("Compiling on Windows with \"winapi\" feature disabled. Feature \"winapi\" should only be disabled when project will never be compiled on Windows.");
258
259#[cfg(all(crossterm_winapi, not(feature = "crossterm_winapi")))]
260compile_error!("Compiling on Windows with \"crossterm_winapi\" feature disabled. Feature \"crossterm_winapi\" should only be disabled when project will never be compiled on Windows.");