Go to file
Xavier L'Heureux e81a1c4cfc Make the keys return their inner error, if any. For example, when permission to access the TTY is denied, don't loop infinitely and instead return to the outer scope to error and exit (or not) there. 2019-06-26 18:48:53 +00:00
examples Reset style in color example before exit (#138) 2018-05-08 20:44:29 -07:00
src Make the keys return their inner error, if any. For example, when permission to access the TTY is denied, don't loop infinitely and instead return to the outer scope to error and exit (or not) there. 2019-06-26 18:48:53 +00:00
.gitignore Add README 2016-03-06 14:55:01 +01:00
.gitlab-ci.yml Reconfigure CI 2018-08-20 22:19:19 +00:00
.travis.yml run travis builds on osx also 2017-06-01 12:48:02 -05:00
CHANGELOG.md Fix tables 2016-07-24 11:30:51 +02:00
Cargo.toml 1.5.3 2019-06-12 17:05:22 -06:00
LICENSE Add license 2016-03-08 09:30:24 +01:00
README.md Update references to repository 2018-05-07 01:41:46 +01:00
image.png Example image 2016-03-16 08:11:35 +01:00
logo.svg Optimize SVG. 2016-12-19 19:56:49 +01:00

README.md

Termion logo

Build Status Latest Version Documentation Examples Changelog Tutorial

Termion is a pure Rust, bindless library for low-level handling, manipulating and reading information about terminals. This provides a full-featured alternative to Termbox.

Termion aims to be simple and yet expressive. It is bindless, meaning that it is not a front-end to some other library (e.g., ncurses or termbox), but a standalone library directly talking to the TTY.

Termion is quite convenient, due to its complete coverage of essential TTY features, providing one consistent API. Termion is rather low-level containing only abstraction aligned with what actually happens behind the scenes. For something more high-level, refer to inquirer-rs, which uses Termion as backend.

Termion generates escapes and API calls for the user. This makes it a whole lot cleaner to use escapes.

Supports Redox, Mac OS X, BSD, and Linux (or, in general, ANSI terminals).

A note on stability

This crate is stable.

Cargo.toml

[dependencies]
termion = "*"

0.1.0 to 1.0.0 guide

This sample table gives an idea of how to go about converting to the new major version of Termion.

0.1.0 1.0.0
use termion::IntoRawMode use termion::raw::IntoRawMode
use termion::TermRead use termion::input::TermRead
stdout.color(color::Red); write!(stdout, "{}", color::Fg(color::Red));
stdout.color_bg(color::Red); write!(stdout, "{}", color::Bg(color::Red));
stdout.goto(x, y); write!(stdout, "{}", cursor::Goto(x, y));
color::rgb(r, g, b); color::Rgb(r, g, b) (truecolor)
x.with_mouse() MouseTerminal::from(x)

Features

  • Raw mode.
  • TrueColor.
  • 256-color mode.
  • Cursor movement.
  • Text formatting.
  • Console size.
  • TTY-only stream.
  • Control sequences.
  • Termios control.
  • Password input.
  • Redox support.
  • Safe isatty wrapper.
  • Panic-free error handling.
  • Special keys events (modifiers, special keys, etc.).
  • Allocation-free.
  • Asynchronous key events.
  • Mouse input.
  • Carefully tested.
  • Detailed documentation on every item.

and much more.

Examples

Style and colors.

extern crate termion;

use termion::{color, style};

use std::io;

fn main() {
    println!("{}Red", color::Fg(color::Red));
    println!("{}Blue", color::Fg(color::Blue));
    println!("{}Blue'n'Bold{}", style::Bold, style::Reset);
    println!("{}Just plain italic", style::Italic);
}

Moving the cursor

extern crate termion;

fn main() {
    print!("{}{}Stuff", termion::clear::All, termion::cursor::Goto(1, 1));
}

Mouse

extern crate termion;

use termion::event::{Key, Event, MouseEvent};
use termion::input::{TermRead, MouseTerminal};
use termion::raw::IntoRawMode;
use std::io::{Write, stdout, stdin};

fn main() {
    let stdin = stdin();
    let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());

    write!(stdout, "{}{}q to exit. Click, click, click!", termion::clear::All, termion::cursor::Goto(1, 1)).unwrap();
    stdout.flush().unwrap();

    for c in stdin.events() {
        let evt = c.unwrap();
        match evt {
            Event::Key(Key::Char('q')) => break,
            Event::Mouse(me) => {
                match me {
                    MouseEvent::Press(_, x, y) => {
                        write!(stdout, "{}x", termion::cursor::Goto(x, y)).unwrap();
                    },
                    _ => (),
                }
            }
            _ => {}
        }
        stdout.flush().unwrap();
    }
}

Read a password

extern crate termion;

use termion::input::TermRead;
use std::io::{Write, stdout, stdin};

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let stdin = stdin();
    let mut stdin = stdin.lock();

    stdout.write_all(b"password: ").unwrap();
    stdout.flush().unwrap();

    let pass = stdin.read_passwd(&mut stdout);

    if let Ok(Some(pass)) = pass {
        stdout.write_all(pass.as_bytes()).unwrap();
        stdout.write_all(b"\n").unwrap();
    } else {
        stdout.write_all(b"Error\n").unwrap();
    }
}

Usage

See examples/, and the documentation, which can be rendered using cargo doc.

For a more complete example, see a minesweeper implementation, that I made for Redox using termion.

License

MIT/X11.