diff options
author | Irene Knapp <ireneista@gmail.com> | 2021-01-16 20:33:14 -0800 |
---|---|---|
committer | Irene Knapp <ireneista@gmail.com> | 2021-01-16 20:33:14 -0800 |
commit | 90854643432c0941f22972d55559d8c2be818b32 (patch) | |
tree | e5eeee06a4a25047cfe288ca7bacc98cba1db2c7 /src | |
parent | ceabb18d9529940985abb5bb13312f76482e584a (diff) |
more edit loop stuff
Diffstat (limited to 'src')
-rw-r--r-- | src/terminal.rs | 109 | ||||
-rw-r--r-- | src/terminal/decoding.rs | 1 |
2 files changed, 105 insertions, 5 deletions
diff --git a/src/terminal.rs b/src/terminal.rs index 041a884..298cc8c 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -9,6 +9,67 @@ pub mod decoding; pub mod error; +#[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)] +struct Point { + x: usize, + y: usize, +} + +impl Point { + pub fn new(x: usize, y: usize) -> Point { + Point { + x: x, + y: y, + } + } +} + + +#[derive(Debug,Eq,PartialEq)] +struct LineBuffer { + lines: Vec<String>, + cursor: Point, +} + +impl LineBuffer { + pub fn new() -> LineBuffer { + LineBuffer { + lines: vec![String::new()], + cursor: Point::new(0, 0), + } + } + + pub fn insert(&mut self, input: &str) { + let line = &mut self.lines[self.cursor.y]; + line.replace_range(self.cursor.x .. self.cursor.x, input); + self.cursor.x += input.len(); + } + + pub fn backspace(&mut self) { + if self.cursor.x > 0 { + let line = &mut self.lines[self.cursor.y]; + line.replace_range(self.cursor.x - 1 .. self.cursor.x, ""); + self.cursor.x -= 1; + } else if self.cursor.y > 0 { + let second_line = self.lines.remove(self.cursor.y); + let first_line = &mut self.lines[self.cursor.y - 1]; + + self.cursor.x = first_line.len(); + self.cursor.y -= 1; + + first_line.push_str(&second_line); + } + } +} + + +#[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)] +enum InputAction { + Backspace, + Execute, +} + + pub fn handle_input_terminal(input_stream: impl Read + AsRawFd) -> std::result::Result<(), TerminalError> { @@ -31,12 +92,52 @@ pub fn handle_input(input_stream: impl Read) -> std::result::Result<(), TerminalError> { let mut reader = CharBufReader::new(input_stream); + let mut line_buffer = LineBuffer::new(); + + loop { + let mut action: Option<InputAction> = None; - let string = reader.fill_buf().map_err(error::input)?; - println!("top level {:?}", string); + let string = reader.fill_buf().map_err(error::input)?; + + let mut chars = string.char_indices(); + + for (_, c) in &mut chars { + match c { + '\n' => { + action = Some(InputAction::Execute); + } + '\u{7f}' => { + action = Some(InputAction::Backspace); + } + _ => { + line_buffer.insert(&c.to_string()); + } + } + + if action.is_some() { + break; + } + } + + let n_to_consume = match chars.next() { + Some((offset, _)) => offset, + None => string.len(), + }; + + reader.consume(n_to_consume); + + match action { + Some(InputAction::Execute) => { + break; + } + Some(InputAction::Backspace) => { + line_buffer.backspace(); + } + None => { } + } + } - let n_to_consume = string.len(); - reader.consume(n_to_consume); + println!("line buffer {:?}", line_buffer); Ok(()) } diff --git a/src/terminal/decoding.rs b/src/terminal/decoding.rs index 249b257..e2654fb 100644 --- a/src/terminal/decoding.rs +++ b/src/terminal/decoding.rs @@ -62,7 +62,6 @@ impl<R: Read> CharBufReader<R> { pub fn consume(&mut self, amount: usize) { self.char_buffer.replace_range(..amount, ""); - println!("consume {:?}", self.char_buffer); } } |