about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-07-15 19:25:56 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-07-15 20:45:46 -0700
commitb3ae8194404c0e91279a64a2b4026162a44c9e9e (patch)
tree4f921b3e640e4054a9702c41bf126dacce3cb3d2
parent44babc860a59b2838515ac83d80ee94946012444 (diff)
downloadmu-b3ae8194404c0e91279a64a2b4026162a44c9e9e.tar.gz
1789 - move to start of line with home/ctrl-a
-rw-r--r--edit.mu135
1 files changed, 133 insertions, 2 deletions
diff --git a/edit.mu b/edit.mu
index 4c3e76ab..dfc9a67b 100644
--- a/edit.mu
+++ b/edit.mu
@@ -596,10 +596,11 @@ recipe handle-event [
   editor:address:editor-data <- next-ingredient
   e:event <- next-ingredient
   reply-unless editor:address:editor-data
-  # typing a character
+  # character
   {
     c:address:character <- maybe-convert e:event, text:variant
     break-unless c:address:character
+    # check for special characters
     # unless it's a backspace
     {
       backspace?:boolean <- equal c:address:character/deref, 8:literal/backspace
@@ -607,10 +608,18 @@ recipe handle-event [
       delete-before-cursor editor:address:editor-data
       reply
     }
+    # ctrl-a
+    {
+      ctrl-a?:boolean <- equal c:address:character/deref, 1:literal/ctrl-a
+      break-unless ctrl-a?:boolean
+      move-to-start-of-line editor:address:editor-data
+      reply
+    }
+    # otherwise type it in
     insert-at-cursor editor:address:editor-data, c:address:character/deref, screen:address
     reply
   }
-  # otherwise it's a special key to control the editor
+  # otherwise it's a special key
   k:address:number <- maybe-convert e:event, keycode:variant
   assert k:address:number, [event was of unknown type; neither keyboard nor mouse]
   d:address:duplex-list <- get editor:address:editor-data/deref, data:offset
@@ -724,6 +733,13 @@ recipe handle-event [
     cursor-row:address:number/deref <- subtract cursor-row:address:number/deref, 1:literal
     # that's it; render will adjust cursor-column as necessary
   }
+  # home
+  {
+    home?:boolean <- equal k:address:number/deref, 65521:literal/home
+    break-unless home?:boolean
+    move-to-start-of-line editor:address:editor-data
+    reply
+  }
 ]
 
 # process click, return if it was on current editor
@@ -841,6 +857,29 @@ recipe previous-line-length [
   reply result:number
 ]
 
+recipe move-to-start-of-line [
+  local-scope
+  editor:address:editor-data <- next-ingredient
+  # update cursor column
+  left:number <- get editor:address:editor-data/deref, left:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
+  cursor-column:address:number/deref <- copy left:number
+  # update before-cursor
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
+  init:address:duplex-list <- get editor:address:editor-data/deref, data:offset
+  # while not at start of line, move 
+  {
+    at-start-of-text?:boolean <- equal before-cursor:address:address:duplex-list/deref, init:address:duplex-list
+    break-if at-start-of-text?:boolean
+    prev:character <- get before-cursor:address:address:duplex-list/deref/deref, value:offset
+    at-start-of-line?:boolean <- equal prev:character, 10:literal/newline
+    break-if at-start-of-line?:boolean
+    before-cursor:address:address:duplex-list/deref <- prev-duplex before-cursor:address:address:duplex-list/deref
+    assert before-cursor:address:address:duplex-list/deref, [move-to-start-of-line tried to move before start of text]
+    loop
+  }
+]
+
 recipe render-all [
   local-scope
   screen:address <- next-ingredient
@@ -1823,6 +1862,98 @@ de]
   ]
 ]
 
+scenario editor-moves-to-start-of-line-with-ctrl-a [
+  assume-screen 10:literal/width, 5:literal/height
+  1:address:array:character <- new [123
+456]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right
+  # start on second line, press ctrl-a
+  assume-console [
+    left-click 2, 3
+    type [a]  # ctrl-a
+  ]
+  3:event/ctrl-a <- merge 0:literal/text, 1:literal/ctrl-a, 0:literal/dummy, 0:literal/dummy
+  replace-in-console 97:literal/a, 3:event/ctrl-a
+  run [
+    editor-event-loop screen:address, console:address, 2:address:editor-data
+    4:number <- get 2:address:editor-data/deref, cursor-row:offset
+    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+  ]
+  # cursor moves to start of line
+  memory-should-contain [
+    4 <- 2
+    5 <- 0
+  ]
+]
+
+scenario editor-moves-to-start-of-line-with-ctrl-a-2 [
+  assume-screen 10:literal/width, 5:literal/height
+  1:address:array:character <- new [123
+456]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right
+  # start on first line (no newline before), press ctrl-a
+  assume-console [
+    left-click 1, 3
+    type [a]  # ctrl-a
+  ]
+  3:event/ctrl-a <- merge 0:literal/text, 1:literal/ctrl-a, 0:literal/dummy, 0:literal/dummy
+  replace-in-console 97:literal/a, 3:event/ctrl-a
+  run [
+    editor-event-loop screen:address, console:address, 2:address:editor-data
+    4:number <- get 2:address:editor-data/deref, cursor-row:offset
+    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+  ]
+  # cursor moves to start of line
+  memory-should-contain [
+    4 <- 1
+    5 <- 0
+  ]
+]
+
+scenario editor-moves-to-start-of-line-with-home [
+  assume-screen 10:literal/width, 5:literal/height
+  1:address:array:character <- new [123
+456]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right
+  # start on second line, press 'home'
+  assume-console [
+    left-click 2, 3
+    press 65521  # 'home'
+  ]
+  run [
+    editor-event-loop screen:address, console:address, 2:address:editor-data
+    3:number <- get 2:address:editor-data/deref, cursor-row:offset
+    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+  ]
+  # cursor moves to start of line
+  memory-should-contain [
+    3 <- 2
+    4 <- 0
+  ]
+]
+
+scenario editor-moves-to-start-of-line-with-home-2 [
+  assume-screen 10:literal/width, 5:literal/height
+  1:address:array:character <- new [123
+456]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right
+  # start on first line (no newline before), press 'home'
+  assume-console [
+    left-click 1, 3
+    press 65521  # 'home'
+  ]
+  run [
+    editor-event-loop screen:address, console:address, 2:address:editor-data
+    3:number <- get 2:address:editor-data/deref, cursor-row:offset
+    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+  ]
+  # cursor moves to start of line
+  memory-should-contain [
+    3 <- 1
+    4 <- 0
+  ]
+]
+
 scenario point-at-multiple-editors [
   assume-screen 30:literal/width, 5:literal/height
   # initialize both halves of screen