3 releases
new 0.1.2 | Feb 16, 2025 |
---|---|
0.1.1 | Feb 16, 2025 |
0.1.0 | Feb 16, 2025 |
#224 in Command-line interface
252 downloads per month
18KB
244 lines
string_cmd
A Rust library for building powerful string editing components with support for Emacs and Vi-style keybindings. Perfect for terminal applications that need sophisticated text input handling with more flexibility than readline
provides.
string_cmd
provides default keybindings for Emacs and Vi modes, or you can forego the default keybindings and implement your own.
Installation
cargo add string_cmd
# If you want to use the crossterm events integration:
cargo add string_cmd --features crossterm
Basic Usage
use string_cmd::StringEditor;
// Create a new empty editor
let mut editor = StringEditor::new();
// Or initialize with existing text
let mut editor = StringEditor::with_string("Hello, world!");
// Get the current text
println!("Current text: {}", editor.get_text());
// Get cursor position
println!("Cursor at: {}", editor.cursor_pos());
See the StringEditor
documentation for more details.
Crossterm Integration
The library provides seamless integration with crossterm for terminal applications. Here's a complete example:
use std::time::Duration;
use crossterm::{
cursor, event::{self, KeyCode},
terminal::{disable_raw_mode, enable_raw_mode},
execute, terminal,
};
use string_cmd::{StringEditor, events::event_to_command};
fn main() -> std::io::Result<()> {
let mut editor = StringEditor::new();
let mut stdout = std::io::stdout();
println!("Enter text below:");
enable_raw_mode()?;
let input = loop {
if event::poll(Duration::from_millis(10))? {
let event = event::read()?;
if let event::Event::Key(key) = &event {
let ctrl = key.modifiers.contains(event::KeyModifiers::CONTROL);
match key.code {
KeyCode::Esc => break None,
KeyCode::Char('q') if ctrl => break None,
KeyCode::Enter => break Some(editor.get_text()),
_ => {}
}
}
if let Some(command) = event_to_command(&event) {
editor.execute(command);
}
}
execute!(
stdout,
cursor::MoveToColumn(0),
terminal::Clear(terminal::ClearType::CurrentLine)
)?;
print!("{}", editor.get_text());
execute!(stdout, cursor::MoveToColumn(editor.cursor_pos() as u16))?;
};
disable_raw_mode()?;
println!("\nFinal input: {:?}", input);
Ok(())
}
Supported Keybindings (with crossterm feature)
Navigation
Ctrl+B
orLeft Arrow
: Move cursor leftCtrl+F
orRight Arrow
: Move cursor rightCtrl+A
orHome
: Move to start of lineCtrl+E
orEnd
: Move to end of line
Editing
Ctrl+H
orBackspace
: Delete character before cursorCtrl+D
orDelete
: Delete character at cursorCtrl+K
: Delete from cursor to end of lineCtrl+U
: Delete from start of line to cursorCtrl+W
: Delete word leading to cursor
Usage
use string_cmd::StringEditor;
let mut editor = StringEditor::new();
// how you get the event is up to you;
// most commonly, you'll use `crossterm::event::poll()` and `crossterm::event::read()`
let event = get_crossterm_event();
if let Some(command) = event_to_command(&event) {
editor.execute(command);
}
License
This project is licensed under the MIT License.
Dependencies
~2–11MB
~134K SLoC