summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-03-27 04:12:42 -0700
committerIrene Knapp <ireneista@irenes.space>2026-03-27 04:12:42 -0700
commit9a5e271ccfc8cc91377a58344045173add5a75d5 (patch)
treef36e31931db6c484587488f6b93a1a685b0b0c64
parent10327d770eb19764d1e272d2f32a4f0e3edd9062 (diff)
the hjkl commands are partly implemented
it's now possible to move the cursor around the screen, but it doesn't interact with the buffer in any way. in particular it isn't forced to stay within the buffer, it just moves wherever.

Force-Push: yes
Change-Id: If56d044b97c761a2070ffc2cc3f541b35ef9965f
-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
   }