summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs148
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(())
   }