about summary refs log tree commit diff stats
path: root/shell
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-04-14 20:09:25 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-04-14 20:09:25 -0700
commit31b43680793efcd0c3d638a88d63793f1c4bdd5d (patch)
tree324949c668d70abc38c3ce40d4fd9342d842c47b /shell
parent76fb62a16d4db597cc6a5aad5c99759b0b8fdc0e (diff)
downloadmu-31b43680793efcd0c3d638a88d63793f1c4bdd5d.tar.gz
shell: word/line navigation
Diffstat (limited to 'shell')
-rw-r--r--shell/gap-buffer.mu222
-rw-r--r--shell/sandbox.mu8
2 files changed, 228 insertions, 2 deletions
diff --git a/shell/gap-buffer.mu b/shell/gap-buffer.mu
index 25f4c9b8..53f3bd54 100644
--- a/shell/gap-buffer.mu
+++ b/shell/gap-buffer.mu
@@ -906,15 +906,39 @@ fn edit-gap-buffer self: (addr gap-buffer), key: grapheme {
     return
   }
   {
+    compare g, 6/ctrl-f
+    break-if-!=
+    gap-to-start-of-next-word self
+    return
+  }
+  {
+    compare g, 2/ctrl-b
+    break-if-!=
+    gap-to-end-of-previous-word self
+    return
+  }
+  {
     compare g, 1/ctrl-a
     break-if-!=
-    gap-to-start self
+    gap-to-previous-start-of-line self
     return
   }
   {
     compare g, 5/ctrl-e
     break-if-!=
-    gap-to-end self
+    gap-to-next-end-of-line self
+    return
+  }
+  {
+    compare g, 0x81/down-arrow
+    break-if-!=
+    gap-down self
+    return
+  }
+  {
+    compare g, 0x82/up-arrow
+    break-if-!=
+    gap-up self
     return
   }
   {
@@ -926,3 +950,197 @@ fn edit-gap-buffer self: (addr gap-buffer), key: grapheme {
   # default: insert character
   add-grapheme-at-gap self, g
 }
+
+fn gap-to-start-of-next-word self: (addr gap-buffer) {
+  var curr/eax: grapheme <- copy 0
+  # skip to next space
+  {
+    curr <- gap-right self
+    compare curr, -1
+    break-if-=
+    compare curr, 0x20/space
+    break-if-=
+    compare curr, 0xa/newline
+    break-if-=
+    loop
+  }
+  # skip past spaces
+  {
+    curr <- gap-right self
+    compare curr, -1
+    break-if-=
+    compare curr, 0x20/space
+    loop-if-=
+    compare curr, 0xa/space
+    loop-if-=
+    curr <- gap-left self
+    break
+  }
+}
+
+fn gap-to-end-of-previous-word self: (addr gap-buffer) {
+  var curr/eax: grapheme <- copy 0
+  # skip to previous space
+  {
+    curr <- gap-left self
+    compare curr, -1
+    break-if-=
+    compare curr, 0x20/space
+    break-if-=
+    compare curr, 0xa/newline
+    break-if-=
+    loop
+  }
+  # skip past all spaces but one
+  {
+    curr <- gap-left self
+    compare curr, -1
+    break-if-=
+    compare curr, 0x20/space
+    loop-if-=
+    compare curr, 0xa/space
+    loop-if-=
+    curr <- gap-right self
+    break
+  }
+}
+
+fn gap-to-previous-start-of-line self: (addr gap-buffer) {
+  # skip past immediate newline
+  var dummy/eax: grapheme <- gap-left self
+  # skip to previous newline
+  {
+    dummy <- gap-left self
+    {
+      compare dummy, -1
+      break-if-!=
+      return
+    }
+    {
+      compare dummy, 0xa/newline
+      break-if-!=
+      dummy <- gap-right self
+      return
+    }
+    loop
+  }
+}
+
+fn gap-to-next-end-of-line self: (addr gap-buffer) {
+  # skip past immediate newline
+  var dummy/eax: grapheme <- gap-right self
+  # skip to next newline
+  {
+    dummy <- gap-right self
+    {
+      compare dummy, -1
+      break-if-!=
+      return
+    }
+    {
+      compare dummy, 0xa/newline
+      break-if-!=
+      dummy <- gap-left self
+      return
+    }
+    loop
+  }
+}
+
+fn gap-up self: (addr gap-buffer) {
+  # compute column
+  var col/edx: int <- count-columns-to-start-of-line self
+  #
+  gap-to-previous-start-of-line self
+  # skip ahead by up to col on previous line
+  var i/ecx: int <- copy 0
+  {
+    compare i, col
+    break-if->=
+    var curr/eax: grapheme <- gap-right self
+    {
+      compare curr, -1
+      break-if-!=
+      return
+    }
+    compare curr, 0xa/newline
+    {
+      break-if-!=
+      curr <- gap-left self
+      return
+    }
+    i <- increment
+    loop
+  }
+}
+
+fn gap-down self: (addr gap-buffer) {
+  # compute column
+  var col/edx: int <- count-columns-to-start-of-line self
+  # skip to start of next line
+  gap-to-end-of-line self
+  var dummy/eax: grapheme <- gap-right self
+  # skip ahead by up to col on previous line
+  var i/ecx: int <- copy 0
+  {
+    compare i, col
+    break-if->=
+    var curr/eax: grapheme <- gap-right self
+    {
+      compare curr, -1
+      break-if-!=
+      return
+    }
+    compare curr, 0xa/newline
+    {
+      break-if-!=
+      curr <- gap-left self
+      return
+    }
+    i <- increment
+    loop
+  }
+}
+
+fn count-columns-to-start-of-line self: (addr gap-buffer) -> _/edx: int {
+  var count/edx: int <- copy 0
+  var dummy/eax: grapheme <- copy 0
+  # skip to previous newline
+  {
+    dummy <- gap-left self
+    {
+      compare dummy, -1
+      break-if-!=
+      return count
+    }
+    {
+      compare dummy, 0xa/newline
+      break-if-!=
+      dummy <- gap-right self
+      return count
+    }
+    count <- increment
+    loop
+  }
+  return count
+}
+
+fn gap-to-end-of-line self: (addr gap-buffer) {
+  var dummy/eax: grapheme <- copy 0
+  # skip to next newline
+  {
+    dummy <- gap-right self
+    {
+      compare dummy, -1
+      break-if-!=
+      return
+    }
+    {
+      compare dummy, 0xa/newline
+      break-if-!=
+      dummy <- gap-left self
+      return
+    }
+    loop
+  }
+}
diff --git a/shell/sandbox.mu b/shell/sandbox.mu
index 68b04344..b9c5037c 100644
--- a/shell/sandbox.mu
+++ b/shell/sandbox.mu
@@ -464,6 +464,14 @@ fn render-sandbox-menu screen: (addr screen), _self: (addr sandbox) {
     draw-text-rightward-from-cursor screen, " tab ", width, 0/fg, 0x18/bg=keyboard
     draw-text-rightward-from-cursor screen, " move to keyboard  ", width, 7/fg, 0/bg
   }
+  draw-text-rightward-from-cursor screen, " ctrl-a ", width, 0/fg, 7/bg=grey
+  draw-text-rightward-from-cursor screen, " <<  ", width, 7/fg, 0/bg
+  draw-text-rightward-from-cursor screen, " ctrl-b ", width, 0/fg, 7/bg=grey
+  draw-text-rightward-from-cursor screen, " <word  ", width, 7/fg, 0/bg
+  draw-text-rightward-from-cursor screen, " ctrl-f ", width, 0/fg, 7/bg=grey
+  draw-text-rightward-from-cursor screen, " word>  ", width, 7/fg, 0/bg
+  draw-text-rightward-from-cursor screen, " ctrl-e ", width, 0/fg, 7/bg=grey
+  draw-text-rightward-from-cursor screen, " >>  ", width, 7/fg, 0/bg
 }
 
 fn render-keyboard-menu screen: (addr screen) {