Skip to main content

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