## ragout - terminal Raw Mode Input Handler
ragout is a library crate offering shell functionalities inside the terminal raw mode.
## Features
- **input movements**
- move to start/end of input line
- move to the next/prev item (basically a word)
- **input deletion**
- delete whole input line
- delete all input to the right/left of cursor
- **history**
- save input to input history on user submission (hits enter/return)
- navigate through saved history entries with the up/down keys
- **exit** the program with CTRL-C (uses std::process::exit())
## Examples
### Basic usage
```sh
$ cargo run --example basic
```
```rust
use ragout::{init, run};
fn main() {
// enter raw mode and initialize necessary variables
// the string literal argument will be the value of the prompt
let (mut sol, mut i, mut h, mut ui) = init("some prompt 🐱 ", true);
'main: loop {
let input = run(&mut i, &mut h, &mut sol, &mut ui);
if !input.is_empty() {
// do some stuff with the user input
}
}
}
```
### Using the macro
```sh
$ cargo run --example macro --no-default-features --features custom_events
```
```rust
use ragout::ragout_custom_events;
ragout_custom_events! {
KeyCode::F(5), 0x0, TestF(u8),
|| {
let date = std::process::Command::new("date")
.output()
.unwrap()
.stdout.into_iter()
.map(|u| u as char)
.collect::()
.replacen("\"", "", 2);
self.overwrite_prompt(date
.trim_end_matches('\n'));
self.write_prompt(sol);
// TODO: sol.write input, should be called from inside input.write_prompt() right before
// sol.flush() at the end
};
KeyCode::Esc, 0x0, TestPrintScreen,
|| {
// requires that the grim cli tool (or something similar, replace as needed) is installed
let cmd = std::process::Command::new("grim").arg("target/screenshot.png").output().unwrap();
let inst = std::time::Instant::now();
let temp = self.prompt.drain(..).collect::();
self.overwrite_prompt("saved screenshot to target/screenshot.png> ");
self.write_prompt(sol);
let notify = std::thread::spawn(move || loop {
if inst.elapsed() > std::time::Duration::from_secs(3) {
break true;
}
});
let notify = notify.join().unwrap();
if notify {
self.overwrite_prompt(&temp);
self.write_prompt(sol);
}
};
}
fn main() {
let (mut sol, mut i, mut h, mut ui) = init("some prompt 🐭 ", true);
'main: loop {
let input = run(&mut i, &mut h, &mut sol, &mut ui);
if !input.is_empty() {
// do some stuff with the user input
}
}
}
```
## License
Licensed under the MIT license.
## Versioning
Follows the [SemVer Spec](https://semver.org/).
Until the time arrives for the version to reach 1.0.0, the repo will adhere to the following rules for versions x.y.z:
- x is constant at 0.
- aside from a number of exceptions, changes incrementing y are accompanied by a milestone creation,
i.e., the first pr of a new milestone increments y.
- everything else increments z. Consecutive small changes may be combined into a single incrementation of z.
- the above three rules are not always respected.
WARN:
This crate is still unstable, if something breaks, or you want a feature, feel free to open an issue.