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