about summary refs log tree commit diff stats
path: root/edit.mu
diff options
context:
space:
mode:
Diffstat (limited to 'edit.mu')
-rw-r--r--edit.mu163
1 files changed, 160 insertions, 3 deletions
diff --git a/edit.mu b/edit.mu
index 677fccfd..07bac50c 100644
--- a/edit.mu
+++ b/edit.mu
@@ -22,9 +22,9 @@ recipe main [
   draw-horizontal 0:literal/screen, 35:literal, column2:number, width:number, 9473:literal/horizontal-double
   # editor on the left
   left:address:array:character <- new [abcde]
-  left-editor:address:editor-data <- new-editor left:address:array:character, 0:literal/screen, 0:literal/top, 0:literal/left, divider:number/right
+  left-editor:address:editor-data <- new-editor left:address:array:character, 0:literal/screen, 0:literal/top, 0:literal/left, 5:literal/right  #divider:number/right
   # editor on the right
-  right:address:array:character <- new [def]
+  right:address:array:character <- new [defgh]
   new-left:number <- add divider:number, 1:literal
   new-right:number <- add new-left:number, 5:literal
   right-editor:address:editor-data <- new-editor right:address:array:character, 0:literal/screen, 4:literal/top, new-left:number, new-right:number #width:number
@@ -272,7 +272,7 @@ recipe render [
       next:character <- get next-node:address:duplex-list/deref, value:offset
       next-character-is-newline?:boolean <- equal next:character, 10:literal/newline
       break-if next-character-is-newline?:boolean
-      # wrap
+      # print wrap icon
       print-character screen:address, 8617:literal/loop-back-to-left, 245:literal/grey
       column:number <- copy left:number
       row:number <- add row:number, 1:literal
@@ -680,6 +680,7 @@ recipe insert-at-cursor [
   before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
   d:address:duplex-list <- get editor:address:editor-data/deref, data:offset
   insert-duplex c:character, before-cursor:address:address:duplex-list/deref
+  before-cursor:address:address:duplex-list/deref <- next-duplex before-cursor:address:address:duplex-list/deref
   screen:address <- get editor:address:editor-data/deref, screen:offset
   cursor-row:address:number <- get-address editor:address:editor-data/deref, cursor-row:offset
   cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
@@ -714,6 +715,43 @@ recipe insert-at-cursor [
 #? ] #? 1
     reply
   }
+  # was cursor wrapped?
+  {
+    at-left-margin?:boolean <- equal cursor-column:address:number/deref, left:number
+    break-unless at-left-margin?:boolean
+    $print [wrapped cursor check: 1
+]
+    previous:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/deref
+    at-start-of-text?:boolean <- not previous:address:duplex-list
+    after-newline?:boolean <- copy 0:literal/false
+    {
+      break-if at-start-of-text?:boolean
+      previous-character:character <- get before-cursor:address:address:duplex-list/deref/deref, value:offset
+      after-newline?:boolean <- equal previous-character:character, 10:literal/newline
+    }
+    at-start-of-line?:boolean <- or at-start-of-text?:boolean, after-newline?:boolean
+    break-if at-start-of-line?:boolean  # i.e. not at wrapped line
+    $print [wrapped cursor check: 2
+]
+    current:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/deref
+    at-end-of-text?:boolean <- not current:address:duplex-list
+    $print [at end of text? ], at-end-of-text?:boolean, [ 
+]
+    at-newline?:boolean <- copy 0:literal/false
+    {
+      break-if at-end-of-text?:boolean
+      current-character:character <- get current:address:duplex-list/deref, value:offset
+      $print [current character: ], current-character:character, [ 
+]
+      at-newline?:boolean <- equal current-character:character, 10:literal/newline
+    }
+    at-end-of-line?:boolean <- or at-end-of-text?:boolean, at-newline?:boolean
+    break-unless at-end-of-line?:boolean
+    $print [wrapped cursor check: 3
+]
+    cursor-column:address:number/deref <- copy 2:literal  # add 2 rather than 1 to account for wrap icon
+    reply
+  }
   # otherwise move cursor right
   cursor-column:address:number/deref <- add cursor-column:address:number/deref, 1:literal
 ]
@@ -1018,6 +1056,99 @@ scenario editor-inserts-characters-at-cursor-6 [
   ]
 ]
 
+scenario editor-inserts-character-at-wrapped-cursor [
+  assume-screen 10:literal/width, 5:literal/height
+  # text fills line
+  1:address:array:character <- new [abcde]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/top, 0:literal/left, 5:literal/right
+  # make cursor wrap at end of text
+  assume-console [
+    left-click 4, 3
+  ]
+  run [
+    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
+  ]
+  memory-should-contain [
+    3 <- 1
+    4 <- 0  # cursor wrapped
+  ]
+  # but line doesn't wrap
+  screen-should-contain [
+    .abcde     .
+    .          .
+  ]
+  # now insert a character
+  assume-console [
+    type [f]
+  ]
+  run [
+    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
+  ]
+  # line now wraps
+  screen-should-contain [
+    .abcd↩     .
+    .ef        .
+  ]
+  # and wrapped cursor remains at the same *logical* point
+  memory-should-contain [
+    3 <- 1
+    4 <- 2  # not 1
+  ]
+]
+
+scenario editor-inserts-character-at-wrapped-cursor-2 [
+  assume-screen 10:literal/width, 5:literal/height
+  # text fills line
+  1:address:array:character <- new [abcde
+z]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/top, 0:literal/left, 5:literal/right
+  # make cursor wrap at end of an internal line
+  assume-console [
+    left-click 0, 4
+    press 65514  # right arrow
+  ]
+  run [
+    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
+  ]
+  memory-should-contain [
+    3 <- 1
+    4 <- 0  # cursor wrapped
+  ]
+  # but line doesn't wrap
+  screen-should-contain [
+    .abcde     .
+    .z         .
+    .          .
+  ]
+  # now insert a character
+  assume-console [
+    type [f]
+  ]
+  run [
+    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
+  ]
+  # line now wraps
+  screen-should-contain [
+    .abcd↩     .
+    .ef        .
+    .z         .
+    .          .
+  ]
+  # and wrapped cursor remains at the same *logical* point
+  memory-should-contain [
+    3 <- 1
+    4 <- 2  # not 1
+  ]
+]
+
 scenario editor-wraps-line-on-insert [
   assume-screen 5:literal/width, 3:literal/height
   1:address:array:character <- new [abcd]
@@ -1428,6 +1559,32 @@ d]
   ]
 ]
 
+scenario editor-wraps-just-cursor-with-right-arrow [
+  assume-screen 10:literal/width, 5:literal/height
+  # first line occupies entire width
+  1:address:array:character <- new [abcde
+z]
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/top, 0:literal/left, 5:literal/right
+  assume-console [
+    left-click 0, 4
+    press 65514  # right arrow - next line
+  ]
+  run [
+    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
+  ]
+  screen-should-contain [
+    .abcde     .
+    .z         .
+    .          .
+  ]
+  memory-should-contain [
+    3 <- 1
+    4 <- 0
+  ]
+]
+
 scenario editor-moves-cursor-left-with-key [
   assume-screen 10:literal/width, 5:literal/height
   1:address:array:character <- new [abc]