Clone this repo:
  1. f990afa Merge branch 'cd/master' into HEAD by Jeff Belgum · 10 days ago master
  2. 8cc322c Add build file by Jeff Belgum · 10 days ago
  3. aef6fe2 Update fuchsia tty to work with latest by Jeff Belgum · 12 days ago upstream/fuchsia-fixup
  4. 41c5518 Merge remote-tracking branch 'upstream/master' into HEAD by Jeff Belgum · 12 days ago
  5. 69e3fe2 [rust] update for the crate directory removal by Benjamin Brittain · 14 days ago

RustyLine

Build Status Build Status dependency status Docs

Readline implementation in Rust that is based on Antirez' Linenoise

Supported Platforms

  • Unix (tested on FreeBSD, Linux and macOS)
  • Windows
    • cmd.exe
    • Powershell

Note:

  • Powershell ISE is not supported, check issue #56
  • Mintty (Cygwin/Mingw) is not supported

Example

extern crate rustyline;

use rustyline::error::ReadlineError;
use rustyline::Editor;

fn main() {
    // `()` can be used when no completer is required
    let mut rl = Editor::<()>::new();
    if rl.load_history("history.txt").is_err() {
        println!("No previous history.");
    }
    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(line) => {
                rl.add_history_entry(line.as_ref());
                println!("Line: {}", line);
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
    }
    rl.save_history("history.txt").unwrap();
}

crates.io

You can use this package in your project by adding the following to your Cargo.toml:

[dependencies]
rustyline = "2.1.0"

Features

Actions

For all modes:

KeystrokeAction
HomeMove cursor to the beginning of line
EndMove cursor to end of line
LeftMove cursor one character left
RightMove cursor one character right
Ctrl-CInterrupt/Cancel edition
Ctrl-D, Del(if line is not empty) Delete character under cursor
Ctrl-D(if line is empty) End of File
Ctrl-J, Ctrl-M, EnterFinish the line entry
Ctrl-RReverse Search history (Ctrl-S forward, Ctrl-G cancel)
Ctrl-TTranspose previous character with current character
Ctrl-UDelete from start of line to cursor
Ctrl-VInsert any special character without perfoming its associated action (#65)
Ctrl-WDelete word leading up to cursor (using white space as a word boundary)
Ctrl-YPaste from Yank buffer
Ctrl-ZSuspend (unix only)
Ctrl-_Undo

Emacs mode (default mode)

KeystrokeAction
Ctrl-A, HomeMove cursor to the beginning of line
Ctrl-B, LeftMove cursor one character left
Ctrl-E, EndMove cursor to end of line
Ctrl-F, RightMove cursor one character right
Ctrl-H, BackSpaceDelete character before cursor
Ctrl-I, TabNext completion
Ctrl-KDelete from cursor to end of line
Ctrl-LClear screen
Ctrl-N, DownNext match from history
Ctrl-P, UpPrevious match from history
Ctrl-X Ctrl-UUndo
Ctrl-YPaste from Yank buffer (Meta-Y to paste next yank instead)
Meta-<Move to first entry in history
Meta->Move to last entry in history
Meta-B, Alt-LeftMove cursor to previous word
Meta-CCapitalize the current word
Meta-DDelete forwards one word
Meta-F, Alt-RightMove cursor to next word
Meta-LLower-case the next word
Meta-TTranspose words
Meta-UUpper-case the next word
Meta-YSee Ctrl-Y
Meta-BackSpaceKill from the start of the current word, or, if between words, to the start of the previous word
Meta-0, 1, ..., -Specify the digit to the argument. starts a negative argument.

Readline Emacs Editing Mode Cheat Sheet

Vi command mode

KeystrokeAction
$, EndMove cursor to end of line
.Redo the last text modification
;Redo the last character finding command
,Redo the last character finding command in opposite direction
0, HomeMove cursor to the beginning of line
^Move to the first non-blank character of line
aInsert after cursor
AInsert at the end of line
bMove one word or token left
BMove one non-blank word left
cChange text of a movement command
CChange text to the end of line (equivalent to c$)
dDelete text of a movement command
D, Ctrl-KDelete to the end of the line
eMove to the end of the current word
EMove to the end of the current non-blank word
fMove right to the next occurance of char
FMove left to the previous occurance of char
h, Ctrl-H, BackSpaceMove one character left
l, SpaceMove one character right
Ctrl-LClear screen
iInsert before cursor
IInsert at the beginning of line
+, j, Ctrl-NMove forward one command in history
-, k, Ctrl-PMove backward one command in history
pInsert the yanked text at the cursor (paste)
PInsert the yanked text before the cursor
rReplaces a single character under the cursor (without leaving command mode)
sDelete a single character under the cursor and enter input mode
SChange current line (equivalent to 0c$)
tMove right to the next occurance of char, then one char backward
TMove left to the previous occurance of char, then one char forward
uUndo
wMove one word or token right
WMove one non-blank word right
xDelete a single character under the cursor
XDelete a character before the cursor
yYank a movement into buffer (copy)

Vi insert mode

KeystrokeAction
Ctrl-H, BackSpaceDelete character before cursor
Ctrl-I, TabNext completion
EscSwitch to command mode

Readline VI Editing Mode Cheat Sheet

Terminal codes (ANSI/VT100)

Wine

$ cargo run --example example --target 'x86_64-pc-windows-gnu'
...
Error: Io(Error { repr: Os { code: 6, message: "Invalid handle." } })
$ wineconsole --backend=curses target/x86_64-pc-windows-gnu/debug/examples/example.exe
...

Terminal checks

$ # current settings of all terminal attributes:
$ stty -a
$ # key bindings:
$ bind -p

Similar projects

Library | Lang | OS | Term | Unicode | History | Completion | Keymap | Kill Ring | Undo | Colors | Hint/Auto suggest | -------- | ---- | -- | ---- | ------- | ------- | ---------- | ------- | --------- | ---- | ------ | ----------------- | Go-prompt | Go | Ux/win | ANSI | Yes | Yes | any | Emacs/prog | No | No | Yes | Yes | Haskeline | Haskell | Ux/Win | Any | Yes | Yes | any | Emacs/Vi/conf | Yes | Yes | ? | ? | Linenoise | C | Ux | ANSI | No | Yes | only line | Emacs | No | No | Ux | Yes | Linenoise-ng | C | Ux/Win | ANSI | Yes | Yes | only line | Emacs | Yes | No | ? | ? | Linefeed | Rust | Ux/Win | Any | | Yes | any | Emacs/conf | Yes | No | ? | No | Liner | Rust | Ux | ANSI | | No inc search | only word | Emacs/Vi/prog | No | Yes | Ux | History based | Prompt-toolkit | Python | Ux/Win | ANSI | Yes | Yes | any | Emacs/Vi/conf | Yes | Yes | Ux/Win | Yes | Rb-readline | Ruby | Ux/Win | ANSI | Yes | Yes | only word | Emacs/Vi/conf | Yes | Yes | ? | No | Replxx | C/C++ | Ux/Win | ANSI | Yes | Yes | only line | Emacs | Yes | No | Ux/Win | Yes | Rustyline | Rust | Ux/Win | ANSI | Yes | Yes | any | Emacs/Vi/bind | Yes | Yes | Ux/Win 10+ | Yes |