mirror of
https://github.com/nushell/reedline.git
synced 2024-11-09 23:46:01 +03:00
A readline replacement written in Rust
cd3516c0d5
Changes initiated by @elferherrera in #266 to enable flexibility in the keymapping and simplify the individual event handlers in `handle_editor_events` To make complex keybindings that behave differently based on context use the `ReedlineEvent::UntilFound(Vec<ReedlineEvent>)` start with the most special case that will fail to handle if conditions are not met and end with the most general handler. TODO: Check how this interacts with vi normal mode * multiple options for keybindings * corrected tests and keybindings * with handled flag * Fix repaint usage Don't repaint on inapplicable cases Repaint for the ctrl-d Delete action * Use enum to indicate the handling status of event * Revert to explicit event keybinding method Makes the unique situation with UntilFound more prominent * Fix ordering of Arrow events * Make emacs arrow commands fully compatible Co-authored-by: Fernando Herrera <fernando.j.herrera@gmail.com> |
||
---|---|---|
.github | ||
assets/sample_docs | ||
src | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
LICENSE | ||
README.md | ||
TODO.txt | ||
UX_TESTING.md |
A readline replacement written in Rust
Introduction
Reedline is a project to create a readline-style crate for Rust that supports many of the modern conveniences of CLIs, including syntax highlighting, completions, multiline support, Unicode support, and more.
Examples
Basic example
// Create a default reedline object to handle user input
use reedline::{DefaultPrompt, Reedline, Signal};
fn main() {
let mut line_editor = Reedline::create()?;
let prompt = DefaultPrompt::default();
loop {
let sig = line_editor.read_line(&prompt).unwrap();
match sig {
Signal::Success(buffer) => {
println!("We processed: {}", buffer);
}
Signal::CtrlD | Signal::CtrlC => {
println!("\nAborted!");
break;
}
Signal::CtrlL => {
line_editor.clear_screen().unwrap();
}
}
}
}
Integrate with custom Keybindings
// Configure reedline with custom keybindings
//Cargo.toml
// [dependencies]
// crossterm = "*"
use {
crossterm::event::{KeyCode, KeyModifiers},
reedline::{default_emacs_keybindings, EditCommand, Reedline},
};
let mut keybindings = default_emacs_keybindings();
keybindings.add_binding(
KeyModifiers::ALT,
KeyCode::Char('m'),
vec![EditCommand::BackspaceWord],
);
let mut line_editor = Reedline::create()?.with_keybindings(keybindings);
Integrate with custom 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)
.expect("Error configuring reedline with history");
Integrate with custom 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)));
Integrate with custom Tab-Handler
// Create a reedline object with tab completions support
use reedline::{DefaultCompleter, CircularCompletionHandler, Reedline};
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));
let mut line_editor = Reedline::create()?.with_completion_action_handler(Box::new(
CircularCompletionHandler::default().with_completer(completer),
));
Integrate with custom Hinter
// 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)),
));
Integrate with custom line completion 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);
Integrate with custom Edit Mode
// Create a reedline object with custom edit mode
use reedline::{EditMode, Reedline};
let mut line_editor = Reedline::create()?.with_edit_mode(
EditMode::ViNormal, // or EditMode::Emacs or EditMode::ViInsert
);
Are we prompt yet? (Development status)
This crate is currently under active development in JT's live-coding streams. If you want to see a feature, jump by the streams, file an issue or contribute a PR!
- Basic unicode grapheme aware cursor editing.
- Configurable prompt
- Basic EMACS-style editing shortcuts.
- Configurable keybindings.
- Basic system integration with clipboard or optional stored history file.
- Content aware highlighting.
- Autocompletion.
- Undo support.
- Multiline aware editing with line completion validation.
For a more detailed roadmap check out TODO.txt.
Join the vision discussion in the vision milestone list by contributing suggestions or voting.
Alternatives
For currently more mature Rust line editing check out: