mod vim;
pub use vim::VimLineEditor;
use std::ops::Range;
pub trait LineEditor {
fn handle_key(&mut self, key: Key, text: &str) -> EditResult;
fn cursor(&self) -> usize;
fn status(&self) -> &str;
fn selection(&self) -> Option<Range<usize>>;
fn reset(&mut self);
fn set_cursor(&mut self, pos: usize, text: &str);
}
#[derive(Debug, Clone, Default)]
pub struct EditResult {
pub edits: Vec<TextEdit>,
pub yanked: Option<String>,
pub action: Option<Action>,
}
impl EditResult {
pub fn none() -> Self {
Self::default()
}
pub fn action(action: Action) -> Self {
Self {
action: Some(action),
..Default::default()
}
}
pub fn cursor_only() -> Self {
Self::default()
}
pub fn edit(edit: TextEdit) -> Self {
Self {
edits: vec![edit],
..Default::default()
}
}
pub fn edit_and_yank(edit: TextEdit, yanked: String) -> Self {
Self {
edits: vec![edit],
yanked: Some(yanked),
..Default::default()
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Action {
Submit,
HistoryPrev,
HistoryNext,
Cancel,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TextEdit {
Delete { start: usize, end: usize },
Insert { at: usize, text: String },
}
impl TextEdit {
pub fn apply(&self, s: &mut String) {
match self {
TextEdit::Delete { start, end } => {
s.replace_range(*start..*end, "");
}
TextEdit::Insert { at, text } => {
s.insert_str(*at, text);
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Key {
pub code: KeyCode,
pub ctrl: bool,
pub alt: bool,
pub shift: bool,
}
impl Key {
pub fn char(c: char) -> Self {
Self {
code: KeyCode::Char(c),
ctrl: false,
alt: false,
shift: false,
}
}
pub fn code(code: KeyCode) -> Self {
Self {
code,
ctrl: false,
alt: false,
shift: false,
}
}
pub fn ctrl(mut self) -> Self {
self.ctrl = true;
self
}
pub fn shift(mut self) -> Self {
self.shift = true;
self
}
pub fn alt(mut self) -> Self {
self.alt = true;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyCode {
Char(char),
Escape,
Backspace,
Delete,
Left,
Right,
Up,
Down,
Home,
End,
Tab,
Enter,
}