summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/terminal.rs109
-rw-r--r--src/terminal/decoding.rs1
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);
   }
 }