2019-10-23 01:33:38 +11:00
|
|
|
#![deny(unused_imports, unused_must_use)]
|
|
|
|
|
2019-10-02 17:37:49 +10:00
|
|
|
//! # Crossterm
|
|
|
|
//!
|
2019-07-25 04:10:27 +10:00
|
|
|
//! Have you ever been disappointed when a terminal library for rust was only written for UNIX systems?
|
2019-10-02 17:37:49 +10:00
|
|
|
//! Crossterm provides clearing, input handling, styling, cursor movement, and terminal actions for both
|
|
|
|
//! Windows and UNIX systems.
|
|
|
|
//!
|
|
|
|
//! Crossterm aims to be simple and easy to call in code. Through the simplicity of Crossterm, you do not
|
|
|
|
//! have to worry about the platform you are working with.
|
2019-07-25 04:10:27 +10:00
|
|
|
//!
|
2019-10-02 17:37:49 +10:00
|
|
|
//! This crate supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested
|
|
|
|
//! see [Tested Terminals](https://github.com/crossterm-rs/crossterm/tree/zrzka/docs-update#tested-terminals)
|
|
|
|
//! for more info).
|
2019-07-25 04:10:27 +10:00
|
|
|
//!
|
2019-10-23 01:33:38 +11:00
|
|
|
//! ## Command API
|
|
|
|
//!
|
|
|
|
//! The command API makes the use of `crossterm` much easier and offers more control over when and how a
|
|
|
|
//! command such as moving the cursor is executed. The command API offers:
|
|
|
|
//!
|
|
|
|
//! * Better Performance.
|
|
|
|
//! * Complete control over when to flush.
|
|
|
|
//! * Complete control over where the ANSI escape commands are executed to.
|
|
|
|
//! * Way easier and nicer API.
|
|
|
|
//!
|
|
|
|
//! There are two ways to use the API command:
|
|
|
|
//!
|
|
|
|
//! * Functions can execute commands on types that implement Write. Functions are easier to use and debug.
|
|
|
|
//! There is a disadvantage, and that is that there is a boilerplate code involved.
|
|
|
|
//! * Macros are generally seen as more difficult but offer an API with less boilerplate code. If you are
|
|
|
|
//! not afraid of macros, this is a recommendation.
|
|
|
|
//!
|
|
|
|
//! Before `crossterm` 10.0 was released, `crossterm` had some performance issues. It did a `flush` after each command
|
|
|
|
//! (cursor movement). A `flush` is heavy action on the terminal, and if it is done more often the performance
|
|
|
|
//! will go down quickly.
|
|
|
|
//!
|
|
|
|
//! Linux and Windows 10 systems support ANSI escape codes. Those ANSI escape codes are strings or rather a
|
|
|
|
//! byte sequence. When we `write` and `flush` those to the terminal we can perform some action.
|
|
|
|
//!
|
|
|
|
//! ## Lazy Execution
|
|
|
|
//!
|
|
|
|
//! Because `flush` is a heavy system call we can instead `write` the commands to the `stdout` without flushing.
|
|
|
|
//! When can do a `flush` when we do want to execute the commands.
|
|
|
|
//!
|
|
|
|
//! If you create a terminal editor or TUI, it is wise to use this option. For example, you can `write` commands
|
|
|
|
//! to the terminal `stdout` and `flush` the `stdout` at every frame. By doing this you can make efficient use of the
|
|
|
|
//! terminal buffer and get better performance because you are not calling `flush` after every command.
|
|
|
|
//!
|
|
|
|
//! ### Examples
|
|
|
|
//!
|
|
|
|
//! Functions:
|
|
|
|
//!
|
|
|
|
//! ```no_run
|
|
|
|
//! use std::io::Write;
|
2019-10-28 00:33:47 +11:00
|
|
|
//! use crossterm::{QueueableCommand, cursor};
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! let mut stdout = std::io::stdout();
|
2019-10-28 00:33:47 +11:00
|
|
|
//! stdout.queue(cursor::MoveTo(5,5));
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! // some other code ...
|
|
|
|
//!
|
|
|
|
//! stdout.flush();
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! The `queue` function returns itself, therefore you can use this to queue another command. Like
|
|
|
|
//! `stdout.queue(Goto(5,5)).queue(Clear(ClearType::All))`.
|
|
|
|
//!
|
|
|
|
//! Macros:
|
|
|
|
//!
|
|
|
|
//! ```no_run
|
|
|
|
//! use std::io::Write;
|
2019-10-28 00:33:47 +11:00
|
|
|
//! use crossterm::{queue, QueueableCommand, cursor};
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! let mut stdout = std::io::stdout();
|
2019-10-28 00:33:47 +11:00
|
|
|
//! queue!(stdout, cursor::MoveTo(5, 5));
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! // some other code ...
|
|
|
|
//!
|
|
|
|
//! stdout.flush();
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! You can pass more than one command into the macro like `queue!(stdout, Goto(5, 5), Clear(ClearType::All))` and
|
|
|
|
//! they will be executed in the given order from left to right.
|
|
|
|
//!
|
|
|
|
//! ## Direct Execution
|
|
|
|
//!
|
|
|
|
//! If you want to execute commands directly, this is also possible. You don't have to flush the 'stdout',
|
|
|
|
//! as described above. This is fine if you are not executing lots of commands.
|
2019-07-25 04:10:27 +10:00
|
|
|
//!
|
2019-10-23 01:33:38 +11:00
|
|
|
//! ### Examples
|
|
|
|
//!
|
|
|
|
//! Functions:
|
|
|
|
//!
|
|
|
|
//! ```no_run
|
|
|
|
//! use std::io::Write;
|
2019-10-28 00:33:47 +11:00
|
|
|
//! use crossterm::{ExecutableCommand, cursor};
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! let mut stdout = std::io::stdout();
|
2019-10-28 00:33:47 +11:00
|
|
|
//! stdout.execute(cursor::MoveTo(5,5));
|
2019-10-23 01:33:38 +11:00
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Macros:
|
|
|
|
//!
|
|
|
|
//! ```no_run
|
|
|
|
//! use std::io::Write;
|
2019-10-28 00:33:47 +11:00
|
|
|
//! use crossterm::{execute, ExecutableCommand, cursor};
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! let mut stdout = std::io::stdout();
|
2019-10-28 00:33:47 +11:00
|
|
|
//! execute!(stdout, cursor::MoveTo(5, 5));
|
2019-10-23 01:33:38 +11:00
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! ## Examples
|
|
|
|
//!
|
|
|
|
//! Print a rectangle colored with magenta and use both direct execution and lazy execution.
|
|
|
|
//!
|
|
|
|
//! Functions:
|
|
|
|
//!
|
|
|
|
//! ```no_run
|
|
|
|
//! use std::io::{stdout, Write};
|
2019-10-28 00:33:47 +11:00
|
|
|
//! use crossterm::{
|
2019-10-29 19:14:47 +11:00
|
|
|
//! ExecutableCommand, QueueableCommand, Color,
|
|
|
|
//! Colorize, terminal, cursor, style, Result
|
2019-10-28 00:33:47 +11:00
|
|
|
//! };
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! fn main() -> Result<()> {
|
|
|
|
//! let mut stdout = stdout();
|
|
|
|
//!
|
2019-10-29 19:14:47 +11:00
|
|
|
//! stdout.execute(terminal::Clear(terminal::ClearType::All))?;
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! for y in 0..40 {
|
|
|
|
//! for x in 0..150 {
|
|
|
|
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
|
|
|
//! stdout
|
2019-10-29 19:14:47 +11:00
|
|
|
//! .queue(cursor::MoveTo(x,y))?
|
|
|
|
//! .queue(style::PrintStyledFont( "█".magenta()))?;
|
2019-10-23 01:33:38 +11:00
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! stdout.flush()?;
|
|
|
|
//! Ok(())
|
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Macros:
|
|
|
|
//!
|
|
|
|
//! ```no_run
|
|
|
|
//! use std::io::{stdout, Write};
|
2019-10-28 00:33:47 +11:00
|
|
|
//! use crossterm::{
|
|
|
|
//! execute, queue, Color, PrintStyledFont,
|
2019-10-29 19:14:47 +11:00
|
|
|
//! Colorize, cursor, terminal, style, Result
|
2019-10-28 00:33:47 +11:00
|
|
|
//! };
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! fn main() -> Result<()> {
|
|
|
|
//! let mut stdout = stdout();
|
|
|
|
//!
|
2019-10-29 19:14:47 +11:00
|
|
|
//! execute!(stdout, terminal::Clear(terminal::ClearType::All))?;
|
2019-10-23 01:33:38 +11:00
|
|
|
//!
|
|
|
|
//! for y in 0..40 {
|
|
|
|
//! for x in 0..150 {
|
|
|
|
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
2019-10-29 19:14:47 +11:00
|
|
|
//! queue!(stdout, cursor::MoveTo(x,y), style::PrintStyledFont( "█".magenta()))?;
|
2019-10-23 01:33:38 +11:00
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! stdout.flush()?;
|
|
|
|
//! Ok(())
|
|
|
|
//! }
|
|
|
|
//!```
|
2019-07-25 04:10:27 +10:00
|
|
|
|
2019-01-28 07:16:14 +11:00
|
|
|
#[cfg(feature = "input")]
|
2019-10-23 01:33:38 +11:00
|
|
|
pub use input::{
|
2019-04-05 03:45:47 +11:00
|
|
|
input, AsyncReader, InputEvent, KeyEvent, MouseButton, MouseEvent, SyncReader, TerminalInput,
|
|
|
|
};
|
2019-01-28 07:16:14 +11:00
|
|
|
#[cfg(feature = "screen")]
|
2019-10-23 01:33:38 +11:00
|
|
|
pub use screen::{
|
2019-10-18 07:38:01 +11:00
|
|
|
AlternateScreen, EnterAlternateScreen, IntoRawMode, LeaveAlternateScreen, RawScreen,
|
|
|
|
};
|
2019-01-28 07:16:14 +11:00
|
|
|
#[cfg(feature = "style")]
|
2019-10-23 01:33:38 +11:00
|
|
|
pub use style::{
|
2019-10-28 07:07:09 +11:00
|
|
|
color, style, Attribute, Color, Colored, Colorize, ContentStyle, PrintStyledFont, ResetColor,
|
|
|
|
SetAttr, SetBg, SetFg, StyledContent, Styler, TerminalColor,
|
2018-12-29 00:58:09 +11:00
|
|
|
};
|
2019-10-23 01:33:38 +11:00
|
|
|
pub use utils::{Command, ErrorKind, ExecutableCommand, Output, QueueableCommand, Result};
|
2019-01-28 07:16:14 +11:00
|
|
|
|
|
|
|
pub use self::crossterm::Crossterm;
|
2019-09-16 21:34:08 +10:00
|
|
|
|
|
|
|
mod crossterm;
|
2019-10-28 00:33:47 +11:00
|
|
|
|
2019-10-23 01:33:38 +11:00
|
|
|
/// A functionality to work with the terminal cursor
|
|
|
|
#[cfg(feature = "cursor")]
|
|
|
|
pub mod cursor;
|
|
|
|
/// A functionality to read the input events.
|
|
|
|
#[cfg(feature = "input")]
|
|
|
|
pub mod input;
|
|
|
|
/// A functionality to work with the terminal screen.
|
|
|
|
#[cfg(feature = "screen")]
|
|
|
|
pub mod screen;
|
|
|
|
/// A functionality to apply attributes and colors on your text.
|
|
|
|
#[cfg(feature = "style")]
|
|
|
|
pub mod style;
|
|
|
|
/// A functionality to work with the terminal.
|
|
|
|
#[cfg(feature = "terminal")]
|
|
|
|
pub mod terminal;
|
|
|
|
/// Shared utilities.
|
|
|
|
pub mod utils;
|