summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs88
-rw-r--r--src/terminal.rs4
2 files changed, 86 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs
index 1753688..0625ccc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,6 +16,7 @@ mod types;
 struct Ivy {
   terminal: RwLock<Terminal>,
   buffer: RwLock<Buffer>,
+  window: RwLock<Window>,
   argument_files: Vec<PathBuf>,
 }
 
@@ -26,6 +27,18 @@ struct Buffer {
   has_end_newline: RwLock<bool>,
 }
 
+struct Window {
+  /* The traditional order of writing "row, column" is the opposite of the
+   * traditional order of writing "x, y"; be mindful. An alternate approach
+   * would use "x" and "y" for all the names, which might arguably reduce
+   * confusion, but personally we find the ordering concern to be
+   * aesthetically pleasing, a quiet reminder of how much humans care about
+   * everything.
+   */
+  cursor_column: RwLock<usize>,
+  cursor_row: RwLock<usize>,
+}
+
 
 fn main() -> ExitCode {
   smol::block_on(async {
@@ -44,6 +57,7 @@ impl Ivy {
     Ivy {
       terminal: RwLock::new(Terminal::new().await),
       buffer: RwLock::new(Buffer::new().await),
+      window: RwLock::new(Window::new().await),
       argument_files: Vec::new(),
     }
   }
@@ -118,10 +132,61 @@ impl Ivy {
     self.draw().await?;
 
     loop {
-      let c = self.terminal.write().await.read_char().await;
-      println!("c {:?}", c);
-      smol::Timer::after(std::time::Duration::from_millis(1000)).await;
-      return Ok(());
+      let c = self.terminal.write().await.read_char().await?;
+
+      match c {
+        'h' => {
+          let window = self.window.write().await;
+          let mut column = window.cursor_column.write().await;
+          if *column > 0 {
+            *column -= 1;
+          }
+
+          let mut terminal = self.terminal.write().await;
+          terminal.do_cursor_position(
+              *column, *window.cursor_row.read().await).await?;
+          terminal.stdout.flush().await?;
+        },
+
+        'j' => {
+          let window = self.window.write().await;
+          let mut row = window.cursor_row.write().await;
+          *row += 1;
+
+          let mut terminal = self.terminal.write().await;
+          terminal.do_cursor_position(
+              *window.cursor_column.read().await, *row).await?;
+          terminal.stdout.flush().await?;
+        },
+
+        'k' => {
+          let window = self.window.write().await;
+          let mut row = window.cursor_row.write().await;
+          if *row > 0 {
+            *row -= 1;
+          }
+
+          let mut terminal = self.terminal.write().await;
+          terminal.do_cursor_position(
+              *window.cursor_column.read().await, *row).await?;
+          terminal.stdout.flush().await?;
+        },
+
+        'l' => {
+          let window = self.window.write().await;
+          let mut column = window.cursor_column.write().await;
+          *column += 1;
+
+          let mut terminal = self.terminal.write().await;
+          terminal.do_cursor_position(
+              *column, *window.cursor_row.read().await).await?;
+          terminal.stdout.flush().await?;
+        },
+
+        _ => {
+          return Ok(());
+        },
+      }
     }
   }
 
@@ -152,7 +217,9 @@ impl Ivy {
 
     terminal.stdout.write_all("\n        status goes here".as_bytes()).await?;
 
-    terminal.do_cursor_position(0, 0).await?;
+    let window = self.window.read().await;
+    terminal.do_cursor_position(*window.cursor_column.read().await,
+                                *window.cursor_row.read().await).await?;
     terminal.stdout.flush().await?;
 
     Ok(())
@@ -242,3 +309,14 @@ impl Buffer {
     }
   }
 }
+
+
+impl Window {
+  pub async fn new() -> Self {
+    Window {
+      cursor_column: RwLock::new(0),
+      cursor_row: RwLock::new(0),
+    }
+  }
+}
+
diff --git a/src/terminal.rs b/src/terminal.rs
index d812069..de3ca4f 100644
--- a/src/terminal.rs
+++ b/src/terminal.rs
@@ -213,7 +213,9 @@ impl Terminal {
   }
 
   // vt220? vt100?
-  pub async fn do_cursor_position(&mut self, x: u64, y: u64) -> Result<()> {
+  pub async fn do_cursor_position(&mut self, x: usize, y: usize)
+      -> Result<()>
+  {
     self.do_escape(EscapeType::CSI, "H", &[y + 1, x + 1]).await
   }