diff options
Diffstat (limited to 'rust/src/editor.rs')
-rw-r--r-- | rust/src/editor.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/rust/src/editor.rs b/rust/src/editor.rs new file mode 100644 index 0000000..7d83904 --- /dev/null +++ b/rust/src/editor.rs @@ -0,0 +1,81 @@ +use std::io::Write; +use termion::event::Key; + +#[derive(Debug, Default)] +pub struct Editor { + s: String, + left: usize, + cursor: usize, + wid: usize, +} + +impl Editor { + pub fn keypress(&mut self, key: Key) -> Option<String> { + let mut ret = None; + + match key { + Key::Char('\n') => { + ret = Some(String::new()); + std::mem::swap(ret.as_mut().unwrap(), &mut self.s); + self.cursor = 0; + } + + Key::Char(c) if !c.is_control() => { + self.s.insert(self.cursor, c); + self.cursor += 1; + } + + Key::Backspace if self.cursor > 0 => { + self.cursor -= 1; + self.s.remove(self.cursor); + } + + Key::Delete if self.s.len() > self.cursor => { + self.s.remove(self.cursor); + } + + Key::Home | Key::Ctrl('a') => { + self.cursor = 0; + } + + Key::End | Key::Ctrl('e') => { + self.cursor = self.s.len(); + } + + Key::Left | Key::Ctrl('b') if self.cursor > 0 => { + self.cursor -= 1; + } + + Key::Right | Key::Ctrl('f') if self.cursor < self.s.len() => { + self.cursor += 1; + } + + Key::Ctrl('u') => { + self.s.replace_range(0..self.cursor, ""); + self.cursor = 0; + } + + _ => { + print!("\x07"); + std::io::stdout().flush().unwrap(); + } + }; + + self.fix_left(); + ret + } + + pub fn set_wid(&mut self, wid: usize) { + self.wid = wid; + self.fix_left(); + } + + pub fn displayed(&self) -> (&str, usize) { + let endidx = (self.left + self.wid).min(self.s.len()); + (&self.s[self.left .. endidx], self.cursor - self.left) + } + + fn fix_left(&mut self) { + self.left = self.left.min(self.cursor).max(self.cursor + 1 - self.wid.min(self.cursor + 1)); + } +} |