[][src]Crate crossterm

Crossterm

Have you ever been disappointed when a terminal library for rust was only written for UNIX systems? 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.

This crate supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested see Tested Terminals for more info).

Command API

The command API makes the use of crossterm much easier and offers more control over when and how a command is executed. A command is just an action you can perform on the terminal e.g. cursor movement.

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.

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. For older windows systems a WinApi call is made.

Supported Commands

Command NameDescription
crossterm::cursor module
cursor::DisableBlinkingdisables blinking of the terminal cursor.
cursor::EnableBlinkingenables blinking of the terminal cursor.
cursor::Hidehides the terminal cursor.
cursor::MoveDownmoves the terminal cursor a given number of rows down.
cursor::MoveLeftmoves the terminal cursor a given number of columns to the left.
cursor::MoveRightmoves the terminal cursor a given number of columns to the right.
cursor::MoveTomoves the terminal cursor to the given position (column, row).
cursor::MoveUpmoves the terminal cursor a given number of rows up.
cursor::RestorePositionrestores the saved terminal cursor position.
cursor::SavePositionsaves the current terminal cursor position.
cursor::Showshows the terminal cursor.
crossterm::input module
input::DisableMouseCapturedisables mouse event monitoring.
input::EnableMouseCaptureenables mouse mode
screen::EnterAlternateScreenswitches to the alternate screen.
screen::LeaveAlternateScreenswitches back to the main screen.
crossterm::style module
style::PrintStyledContentprints styled content.
style::ResetColorresets the colors back to default.
style::SetAttributesets an attribute.
style::SetBackgroundColorsets the the background color.
style::SetForegroundColorsets the the foreground color.
crossterm::terminal module
terminal::Clearclears the terminal screen buffer.
terminal::ScrollDownscrolls the terminal screen a given number of rows down.
terminal::ScrollUpscrolls the terminal screen a given number of rows up.
terminal::SetSizesets the terminal size (columns, rows).

There are two different way's to execute commands.

Lazy Execution

Flushing bytes to the terminal buffer is a heavy system call. If we perform a lot of actions with the terminal, we want to do this periodically - like with a TUI editor - so that we can flush more data to the terminal buffer at the same time.

Crossterm offers the possibility to do this with queue. With queue you can queue commands, and when you call Write::flush these commands will be executed.

You can pass a custom buffer implementing std::io::Write to this queue operation. The commands will be executed on that buffer. The most common buffer is std::io::stdout however, std::io::stderr is used sometimes as well.

Examples

A simple demonstration that shows the command API in action with cursor commands.

Functions

use std::io::{Write, stdout};
use crossterm::{QueueableCommand, cursor};

let mut stdout = stdout();
stdout.queue(cursor::MoveTo(5,5));

// 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

use std::io::{Write, stdout};
use crossterm::{queue, QueueableCommand, cursor};

let mut stdout = stdout();
queue!(stdout,  cursor::MoveTo(5, 5));

// some other code ...

// move operation is performed only if we flush the buffer.
stdout.flush();

You can pass more than one command into the queue macro like queue!(stdout, MoveTo(5, 5), Clear(ClearType::All)) and they will be executed in the given order from left to right.

Direct Execution

For many applications it is not at all important to be efficient with 'flush' operations. For this use case there is the execute operation. This operation executes the command immediately, and calls the flush under water.

You can pass a custom buffer implementing std::io::Write to this execute operation. The commands will be executed on that buffer. The most common buffer is std::io::stdout however, std::io::stderr is used sometimes as well.

Examples

Functions

use std::io::{Write, stdout};
use crossterm::{ExecutableCommand, cursor};

let mut stdout = stdout();
stdout.execute(cursor::MoveTo(5,5));

The execute function returns itself, therefore you can use this to queue another command. Like stdout.queue(Goto(5,5)).queue(Clear(ClearType::All)).

Macros

use std::io::{Write, stdout};
use crossterm::{execute, ExecutableCommand, cursor};

let mut stdout = stdout();
execute!(stdout, cursor::MoveTo(5, 5));

You can pass more than one command into the execute macro like execute!(stdout, MoveTo(5, 5), Clear(ClearType::All)) and they will be executed in the given order from left to right.

Examples

Print a rectangle colored with magenta and use both direct execution and lazy execution.

Functions

use std::io::{stdout, Write};
use crossterm::{
    ExecutableCommand, QueueableCommand,
    terminal, cursor, style::{self, Colorize}, Result
};

fn main() -> Result<()> {
  let mut stdout = stdout();

  stdout.execute(terminal::Clear(terminal::ClearType::All))?;

  for y in 0..40 {
    for x in 0..150 {
      if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
        // in this loop we are more efficient by not flushing the buffer.
        stdout
          .queue(cursor::MoveTo(x,y))?
          .queue(style::PrintStyledContent( "█".magenta()))?;
      }
    }
  }
  stdout.flush()?;
  Ok(())
}

Macros:

use std::io::{stdout, Write};
use crossterm::{
    execute, queue,
    style::{self, Colorize}, cursor, terminal, Result
};

fn main() -> Result<()> {
  let mut stdout = stdout();

  execute!(stdout, terminal::Clear(terminal::ClearType::All))?;

  for y in 0..40 {
    for x in 0..150 {
      if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
        // in this loop we are more efficient by not flushing the buffer.
        queue!(stdout, cursor::MoveTo(x,y), style::PrintStyledContent( "█".magenta()))?;
      }
    }
  }
  stdout.flush()?;
  Ok(())
}

Modules

cursor

A module to work with the terminal cursor

input

A module to read the input events.

screen

A module to work with the terminal screen.

style

A module to apply attributes and colors on your text.

terminal

A module to work with the terminal.

utils

Shared utilities.

Macros

execute

Execute one or more command(s)

queue

Queue one or more command(s) for execution in the near future.

Structs

Output

When executed, this command will output the given displayable to the buffer.

Enums

ErrorKind

Wrapper for all errors that can occur in crossterm.

Traits

Command

A command is an action that can be performed on the terminal.

ExecutableCommand

A trait that defines behaviour for a command that will be executed immediately.

QueueableCommand

A trait that defines behaviour for a command that can be used to be executed at a later time point. This can be used in order to get more performance.

Functions

supports_ansi

Type Definitions

Result

The crossterm result type.