diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-07-01 13:28:09 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-07-01 13:32:07 -0700 |
commit | 61a42dc1c23f02e889eb6116d5a602dcefde7b24 (patch) | |
tree | 2a6565fdd4f1dc7f610574d9ab07716e472a73de | |
parent | 8529e532499027ac37318b001700fe5a9629d2e8 (diff) | |
download | mu-61a42dc1c23f02e889eb6116d5a602dcefde7b24.tar.gz |
1694
I started fixing scenario editor-inserts-character-at-wrapped-cursor, but as I work further I notice there's an irreconcilable ambiguity in the approach of letting the cursor wrap in a non-wrapped line: if a cursor is at column 0 and the previous line occupies the entire width, should the next character you insert go before (assuming a wrapped cursor) or after the newline (assuming you're at the start of the next line)? No way to distinguish the two cases. One approach would be to delete the newline and have the cursor replace it with whatever you type. Then you have to hit a newline again to separate. But the simpler way is to simply wrap the moment the line grows to width-1, always leaving room for the cursor. Yeah, let's switch to that approach.
-rw-r--r-- | edit.mu | 163 |
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] |