use repl_lang::{Edit, Editor};
use unicode_lang::str_width;
enum Key {
Type(&'static str),
Edit(&'static str, Edit),
Enter,
}
const PROMPT: &str = "> ";
fn main() {
let mut editor = Editor::with_history(100);
for saved in ["let width = 12", "width * 2"] {
editor.add_history(saved);
}
let keys = [
Key::Type("print hello"),
Key::Edit("Ctrl-W (kill word)", Edit::KillWordLeft),
Key::Type("世界"),
Key::Edit("Home", Edit::Home),
Key::Edit("Alt-F (word right)", Edit::WordRight),
Key::Type("ln"),
Key::Edit("End", Edit::End),
Key::Edit("Backspace", Edit::Backspace),
Key::Edit("Ctrl-Y (yank)", Edit::Yank),
Key::Enter,
Key::Type("caf\u{0065}\u{0301}"),
Key::Edit("←", Edit::Left),
Key::Edit("←", Edit::Left),
Key::Edit("Ctrl-K (kill to end)", Edit::KillToEnd),
Key::Edit("Ctrl-U (kill to start)", Edit::KillToStart),
Key::Edit("↑", Edit::HistoryPrev),
Key::Edit("↑", Edit::HistoryPrev),
Key::Edit("↑", Edit::HistoryPrev),
Key::Edit("↓", Edit::HistoryNext),
Key::Type(" + 1"),
Key::Enter,
];
for key in &keys {
let (label, changed) = match key {
Key::Type(text) => (format!("type {text:?}"), editor.insert(text)),
Key::Edit(label, edit) => ((*label).to_owned(), editor.apply(*edit)),
Key::Enter => {
let line = editor.submit().to_owned();
println!("{} submitted {line:?}\n", pad("Enter"));
continue;
}
};
let note = if changed { "" } else { " (no change)" };
println!("{} {PROMPT}{}{note}", pad(&label), editor.line());
println!(
"{} {}^",
pad(""),
" ".repeat(PROMPT.len() + editor.column())
);
}
println!("History, oldest first:");
for (i, line) in editor.history().enumerate() {
println!(" {:>2} {line}", i + 1);
}
}
fn pad(label: &str) -> String {
let fill = 26_usize.saturating_sub(str_width(label));
format!("{label}{}", " ".repeat(fill))
}