diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-03-27 04:27:16 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-03-27 04:27:16 -0700 |
| commit | 7b2d4b4724cb9458ceed8d88ed58a4bfe0ea4092 (patch) | |
| tree | 1d2eb8766e0db664034405024d548dc3d5ed2f3f /src | |
| parent | 9a5e271ccfc8cc91377a58344045173add5a75d5 (diff) | |
added a handle_movement() abstraction
right now, the main thing it takes care of is checking whether it's actually necessary to move the cursor, and doing it. the hope is to be very parsimonious of bandwidth, like to 1980s standards, and to also be deliberate about making sure the portions of the screen that are redrawn follow logically from the user's actions. this is meant to help in high-latency situations as well as with screen readers. also, it just feels right. Force-Push: yes Change-Id: Ib26ae484a34e0aaa0e8382f5ad4966226bada223
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 148 |
1 files changed, 89 insertions, 59 deletions
diff --git a/src/main.rs b/src/main.rs index 0625ccc..ea151c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -128,6 +128,41 @@ impl Ivy { Ok(()) } + async fn draw(&mut self) -> Result<()> { + let mut terminal = self.terminal.write().await; + let buffer = self.buffer.read().await; + + let height = *terminal.height.read().await; + + let mut screen_y = 0; + for logical_y in 0 .. height - 1 { + if let Some(span) = buffer.line_span(logical_y).await { + if logical_y > 0 { + terminal.stdout.write_all("\n".as_bytes()).await?; + } + + terminal.stdout.write_all(&buffer.contents.read().await[span]).await?; + + screen_y = logical_y + 1; + } else { + break; + } + } + + for _ in screen_y .. height - 1 { + terminal.stdout.write_all("\n~".as_bytes()).await?; + } + + terminal.stdout.write_all("\n status goes here".as_bytes()).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(()) + } + async fn interact(&mut self) -> Result<()> { self.draw().await?; @@ -136,51 +171,51 @@ impl Ivy { match c { 'h' => { - let window = self.window.write().await; - let mut column = window.cursor_column.write().await; - if *column > 0 { - *column -= 1; - } + self.handle_movement(async |ivy: &mut Ivy| { + let window = ivy.window.write().await; - let mut terminal = self.terminal.write().await; - terminal.do_cursor_position( - *column, *window.cursor_row.read().await).await?; - terminal.stdout.flush().await?; + let mut column = window.cursor_column.write().await; + if *column > 0 { + *column -= 1; + } + + Ok(()) + }).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?; + self.handle_movement(async |ivy: &mut Ivy| { + let window = ivy.window.write().await; + + let mut row = window.cursor_row.write().await; + *row += 1; + + Ok(()) + }).await?; }, 'k' => { - let window = self.window.write().await; - let mut row = window.cursor_row.write().await; - if *row > 0 { - *row -= 1; - } + self.handle_movement(async |ivy: &mut Ivy| { + let window = ivy.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?; + Ok(()) + }).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?; + self.handle_movement(async |ivy: &mut Ivy| { + let window = ivy.window.write().await; + + let mut column = window.cursor_column.write().await; + *column += 1; + + Ok(()) + }).await?; }, _ => { @@ -190,37 +225,32 @@ impl Ivy { } } - async fn draw(&mut self) -> Result<()> { - let mut terminal = self.terminal.write().await; - let buffer = self.buffer.read().await; - - let height = *terminal.height.read().await; + async fn handle_movement(&mut self, + movement: impl AsyncFn(&mut Ivy) -> Result<()>) + -> Result<()> + { + let (old_row, old_column) = { + let window = self.window.read().await; - let mut screen_y = 0; - for logical_y in 0 .. height - 1 { - if let Some(span) = buffer.line_span(logical_y).await { - if logical_y > 0 { - terminal.stdout.write_all("\n".as_bytes()).await?; - } + (*window.cursor_row.read().await, + *window.cursor_column.read().await) + }; - terminal.stdout.write_all(&buffer.contents.read().await[span]).await?; + movement(self).await?; - screen_y = logical_y + 1; - } else { - break; - } - } + let (new_row, new_column) = { + let window = self.window.read().await; - for _ in screen_y .. height - 1 { - terminal.stdout.write_all("\n~".as_bytes()).await?; - } + (*window.cursor_row.read().await, + *window.cursor_column.read().await) + }; - terminal.stdout.write_all("\n status goes here".as_bytes()).await?; + if old_row != new_row || old_column != new_column { + let mut terminal = self.terminal.write().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?; + terminal.do_cursor_position(new_column, new_row).await?; + terminal.stdout.flush().await?; + } Ok(()) } |