Crates.io | reedline |
lib.rs | reedline |
version | 0.32.0 |
source | src |
created_at | 2021-04-09 21:24:48.470063 |
updated_at | 2024-04-30 22:14:11.145632 |
description | A readline-like crate for CLI text input |
homepage | |
repository | https://github.com/nushell/reedline |
max_upload_size | |
id | 381499 |
size | 709,597 |
Reedline is a project to create a line editor (like bash's readline
or zsh's zle
) that supports many of the modern conveniences of CLIs, including syntax highlighting, completions, multiline support, Unicode support, and more.
It is currently primarily developed as the interactive editor for nushell (starting with v0.60
) striving to provide a pleasant interactive experience.
For the full documentation visit https://docs.rs/reedline. The examples should highlight how you enable the most important features or which traits can be implemented for language-specific behavior.
// Create a default reedline object to handle user input
use reedline::{DefaultPrompt, Reedline, Signal};
let mut line_editor = Reedline::create();
let prompt = DefaultPrompt::default();
loop {
let sig = line_editor.read_line(&prompt);
match sig {
Ok(Signal::Success(buffer)) => {
println!("We processed: {}", buffer);
}
Ok(Signal::CtrlD) | Ok(Signal::CtrlC) => {
println!("\nAborted!");
break;
}
x => {
println!("Event: {:?}", x);
}
}
}
// Configure reedline with custom keybindings
//Cargo.toml
// [dependencies]
// crossterm = "*"
use {
crossterm::event::{KeyCode, KeyModifiers},
reedline::{default_emacs_keybindings, EditCommand, Reedline, Emacs, ReedlineEvent},
};
let mut keybindings = default_emacs_keybindings();
keybindings.add_binding(
KeyModifiers::ALT,
KeyCode::Char('m'),
ReedlineEvent::Edit(vec![EditCommand::BackspaceWord]),
);
let edit_mode = Box::new(Emacs::new(keybindings));
let mut line_editor = Reedline::create().with_edit_mode(edit_mode);
History
// Create a reedline object with history support, including history size limits
use reedline::{FileBackedHistory, Reedline};
let history = Box::new(
FileBackedHistory::with_file(5, "history.txt".into())
.expect("Error configuring history with file"),
);
let mut line_editor = Reedline::create()
.with_history(history);
Highlighter
// Create a reedline object with highlighter support
use reedline::{ExampleHighlighter, Reedline};
let commands = vec![
"test".into(),
"hello world".into(),
"hello world reedline".into(),
"this is the reedline crate".into(),
];
let mut line_editor =
Reedline::create().with_highlighter(Box::new(ExampleHighlighter::new(commands)));
// Create a reedline object with tab completions support
use reedline::{default_emacs_keybindings, ColumnarMenu, DefaultCompleter, Emacs, KeyCode, KeyModifiers, Reedline, ReedlineEvent, ReedlineMenu};
let commands = vec![
"test".into(),
"hello world".into(),
"hello world reedline".into(),
"this is the reedline crate".into(),
];
let completer = Box::new(DefaultCompleter::new_with_wordlen(commands.clone(), 2));
// Use the interactive menu to select options from the completer
let completion_menu = Box::new(ColumnarMenu::default().with_name("completion_menu"));
// Set up the required keybindings
let mut keybindings = default_emacs_keybindings();
keybindings.add_binding(
KeyModifiers::NONE,
KeyCode::Tab,
ReedlineEvent::UntilFound(vec![
ReedlineEvent::Menu("completion_menu".to_string()),
ReedlineEvent::MenuNext,
]),
);
let edit_mode = Box::new(Emacs::new(keybindings));
let mut line_editor = Reedline::create()
.with_completer(completer)
.with_menu(ReedlineMenu::EngineCompleter(completion_menu))
.with_edit_mode(edit_mode);
Hinter
for fish-style history autosuggestions// Create a reedline object with in-line hint support
//Cargo.toml
// [dependencies]
// nu-ansi-term = "*"
use {
nu_ansi_term::{Color, Style},
reedline::{DefaultHinter, Reedline},
};
let mut line_editor = Reedline::create().with_hinter(Box::new(
DefaultHinter::default()
.with_style(Style::new().italic().fg(Color::LightGray)),
));
Validator
// Create a reedline object with line completion validation support
use reedline::{DefaultValidator, Reedline};
let validator = Box::new(DefaultValidator);
let mut line_editor = Reedline::create().with_validator(validator);
EditMode
// Create a reedline object with custom edit mode
// This can define a keybinding setting or enable vi-emulation
use reedline::{
default_vi_insert_keybindings, default_vi_normal_keybindings, EditMode, Reedline, Vi,
};
let mut line_editor = Reedline::create().with_edit_mode(Box::new(Vi::new(
default_vi_insert_keybindings(),
default_vi_normal_keybindings(),
)));
clipboard
: Enable support to use the SystemClipboard
. Enabling this feature will return a SystemClipboard
instead of a local clipboard when calling get_default_clipboard()
.bashisms
: Enable support for special text sequences that recall components from the history. e.g. !!
and !$
. For use in shells like bash
or nushell
.sqlite
: Provides the SqliteBackedHistory
to store richer information in the history. Statically links the required sqlite version.sqlite-dynlib
: Alternative to the feature sqlite
. Will not statically link. Requires sqlite >= 3.38
to link dynamically!external_printer
: Experimental: Thread-safe ExternalPrinter
handle to print lines from concurrently running threads.Reedline has now all the basic features to become the primary line editor for nushell
For more ideas check out the feature discussion or hop on the #reedline
channel of the nushell discord.
If you want to follow along with the history of how reedline got started, you can watch the recordings of JT's live-coding streams.
Playlist: Creating a line editor in Rust
For currently more mature Rust line editing check out: