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 |
|
233 | pub use crate::command::{Command, ExecutableCommand, QueueableCommand, SynchronizedUpdate};
|
234 |
|
235 | /// A module to work with the terminal cursor
|
236 | pub mod cursor;
|
237 | /// A module to read events.
|
238 | #[cfg (feature = "events" )]
|
239 | pub mod event;
|
240 | /// A module to apply attributes and colors on your text.
|
241 | pub mod style;
|
242 | /// A module to work with the terminal.
|
243 | pub mod terminal;
|
244 |
|
245 | /// A module to query if the current instance is a tty.
|
246 | pub mod tty;
|
247 |
|
248 | #[cfg (windows)]
|
249 | /// A module that exposes one function to check if the current terminal supports ANSI sequences.
|
250 | pub mod ansi_support;
|
251 | mod command;
|
252 | pub(crate) mod macros;
|
253 |
|
254 | #[cfg (all(windows, not(feature = "windows" )))]
|
255 | compile_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" )))]
|
258 | compile_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" )))]
|
261 | compile_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 | |