diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-04-22 18:35:10 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-04-22 21:49:29 -0700 |
commit | ea5e7fd4cb5757589cf3cb52439a3d432517bc7a (patch) | |
tree | 13aa8596e6caedc3e22543be659ff968eeee2890 | |
parent | 537e7812c998b468142b16bde8901d8405dbc690 (diff) | |
download | mu-ea5e7fd4cb5757589cf3cb52439a3d432517bc7a.tar.gz |
2853 - purge get-address from edit/ app
Phew!
-rw-r--r-- | edit/001-editor.mu | 69 | ||||
-rw-r--r-- | edit/002-typing.mu | 121 | ||||
-rw-r--r-- | edit/003-shortcuts.mu | 261 | ||||
-rw-r--r-- | edit/004-programming-environment.mu | 55 | ||||
-rw-r--r-- | edit/005-sandbox.mu | 81 | ||||
-rw-r--r-- | edit/006-sandbox-edit.mu | 55 | ||||
-rw-r--r-- | edit/007-sandbox-delete.mu | 53 | ||||
-rw-r--r-- | edit/008-sandbox-test.mu | 27 | ||||
-rw-r--r-- | edit/009-sandbox-trace.mu | 15 | ||||
-rw-r--r-- | edit/010-errors.mu | 41 | ||||
-rw-r--r-- | edit/011-editor-undo.mu | 255 |
11 files changed, 563 insertions, 470 deletions
diff --git a/edit/001-editor.mu b/edit/001-editor.mu index 818f3520..614608c2 100644 --- a/edit/001-editor.mu +++ b/edit/001-editor.mu @@ -55,25 +55,17 @@ def new-editor s:address:shared:array:character, screen:address:shared:screen, l right <- subtract right, 1 result <- new editor-data:type # initialize screen-related fields - x:address:number <- get-address *result, left:offset - *x <- copy left - x <- get-address *result, right:offset - *x <- copy right - # initialize cursor - x <- get-address *result, cursor-row:offset - *x <- copy 1/top - x <- get-address *result, cursor-column:offset - *x <- copy left - init:address:address:shared:duplex-list:character <- get-address *result, data:offset - *init <- push 167/§, 0/tail - top-of-screen:address:address:shared:duplex-list:character <- get-address *result, top-of-screen:offset - *top-of-screen <- copy *init - y:address:address:shared:duplex-list:character <- get-address *result, before-cursor:offset - *y <- copy *init + *result <- put *result, left:offset, left + *result <- put *result, right:offset, right + # initialize cursor coordinates + *result <- put *result, cursor-row:offset, 1/top + *result <- put *result, cursor-column:offset, left + # initialize empty contents + init:address:shared:duplex-list:character <- push 167/§, 0/tail + *result <- put *result, data:offset, init + *result <- put *result, top-of-screen:offset, init + *result <- put *result, before-cursor:offset, init result <- insert-text result, s - # initialize cursor to top of screen - y <- get-address *result, before-cursor:offset - *y <- copy *init # initial render to screen, just for some old tests _, _, screen, result <- render screen, result <editor-initialization> @@ -145,9 +137,9 @@ def render screen:address:shared:screen, editor:address:shared:editor-data -> la color:number <- copy 7/white row:number <- copy 1/top column:number <- copy left - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset screen <- move-cursor screen, row, column { +next-character @@ -158,11 +150,11 @@ def render screen:address:shared:screen, editor:address:shared:editor-data -> la # Doing so at the start of each iteration ensures it stays one step behind # the current character. { - at-cursor-row?:boolean <- equal row, *cursor-row + at-cursor-row?:boolean <- equal row, cursor-row break-unless at-cursor-row? - at-cursor?:boolean <- equal column, *cursor-column + at-cursor?:boolean <- equal column, cursor-column break-unless at-cursor? - *before-cursor <- copy prev + before-cursor <- copy prev } c:character <- get *curr, value:offset <character-c-received> @@ -172,12 +164,12 @@ def render screen:address:shared:screen, editor:address:shared:editor-data -> la break-unless newline? # adjust cursor if necessary { - at-cursor-row?:boolean <- equal row, *cursor-row + at-cursor-row?:boolean <- equal row, cursor-row break-unless at-cursor-row? - left-of-cursor?:boolean <- lesser-than column, *cursor-column + left-of-cursor?:boolean <- lesser-than column, cursor-column break-unless left-of-cursor? - *cursor-column <- copy column - *before-cursor <- prev curr + cursor-column <- copy column + before-cursor <- prev curr } # clear rest of line in this window clear-line-delimited screen, column, right @@ -210,22 +202,23 @@ def render screen:address:shared:screen, editor:address:shared:editor-data -> la loop } # save first character off-screen - bottom-of-screen:address:address:shared:duplex-list:character <- get-address *editor, bottom-of-screen:offset - *bottom-of-screen <- copy curr + *editor <- put *editor, bottom-of-screen:offset, curr # is cursor to the right of the last line? move to end { - at-cursor-row?:boolean <- equal row, *cursor-row - cursor-outside-line?:boolean <- lesser-or-equal column, *cursor-column + at-cursor-row?:boolean <- equal row, cursor-row + cursor-outside-line?:boolean <- lesser-or-equal column, cursor-column before-cursor-on-same-line?:boolean <- and at-cursor-row?, cursor-outside-line? - above-cursor-row?:boolean <- lesser-than row, *cursor-row + above-cursor-row?:boolean <- lesser-than row, cursor-row before-cursor?:boolean <- or before-cursor-on-same-line?, above-cursor-row? break-unless before-cursor? - *cursor-row <- copy row - *cursor-column <- copy column - *before-cursor <- copy prev + cursor-row <- copy row + cursor-column <- copy column + before-cursor <- copy prev } - bottom:address:number <- get-address *editor, bottom:offset - *bottom <- copy row + *editor <- put *editor, bottom:offset, row + *editor <- put *editor, cursor-row:offset, cursor-row + *editor <- put *editor, cursor-column:offset, cursor-column + *editor <- put *editor, before-cursor:offset, before-cursor return row, column, screen/same-as-ingredient:0, editor/same-as-ingredient:1 ] diff --git a/edit/002-typing.mu b/edit/002-typing.mu index 7a68bb64..1c27ce98 100644 --- a/edit/002-typing.mu +++ b/edit/002-typing.mu @@ -83,11 +83,11 @@ def snap-cursor screen:address:shared:screen, editor:address:shared:editor-data, curr <- next curr row:number <- copy 1/top column:number <- copy left - cursor-row:address:number <- get-address *editor, cursor-row:offset - *cursor-row <- copy target-row - cursor-column:address:number <- get-address *editor, cursor-column:offset - *cursor-column <- copy target-column - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + *editor <- put *editor, cursor-row:offset, target-row + cursor-row:number <- copy target-row + *editor <- put *editor, cursor-column:offset, target-column + cursor-column:number <- copy target-column + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset { +next-character break-unless curr @@ -97,11 +97,12 @@ def snap-cursor screen:address:shared:screen, editor:address:shared:editor-data, # Doing so at the start of each iteration ensures it stays one step behind # the current character. { - at-cursor-row?:boolean <- equal row, *cursor-row + at-cursor-row?:boolean <- equal row, cursor-row break-unless at-cursor-row? - at-cursor?:boolean <- equal column, *cursor-column + at-cursor?:boolean <- equal column, cursor-column break-unless at-cursor? - *before-cursor <- copy prev + before-cursor <- copy prev + *editor <- put *editor, before-cursor:offset, before-cursor } c:character <- get *curr, value:offset { @@ -110,12 +111,14 @@ def snap-cursor screen:address:shared:screen, editor:address:shared:editor-data, break-unless newline? # adjust cursor if necessary { - at-cursor-row?:boolean <- equal row, *cursor-row + at-cursor-row?:boolean <- equal row, cursor-row break-unless at-cursor-row? - left-of-cursor?:boolean <- lesser-than column, *cursor-column + left-of-cursor?:boolean <- lesser-than column, cursor-column break-unless left-of-cursor? - *cursor-column <- copy column - *before-cursor <- copy prev + cursor-column <- copy column + *editor <- put *editor, cursor-column:offset, cursor-column + before-cursor <- copy prev + *editor <- put *editor, before-cursor:offset, before-cursor } # skip to next line row <- add row, 1 @@ -141,15 +144,18 @@ def snap-cursor screen:address:shared:screen, editor:address:shared:editor-data, } # is cursor to the right of the last line? move to end { - at-cursor-row?:boolean <- equal row, *cursor-row - cursor-outside-line?:boolean <- lesser-or-equal column, *cursor-column + at-cursor-row?:boolean <- equal row, cursor-row + cursor-outside-line?:boolean <- lesser-or-equal column, cursor-column before-cursor-on-same-line?:boolean <- and at-cursor-row?, cursor-outside-line? - above-cursor-row?:boolean <- lesser-than row, *cursor-row + above-cursor-row?:boolean <- lesser-than row, cursor-row before-cursor?:boolean <- or before-cursor-on-same-line?, above-cursor-row? break-unless before-cursor? - *cursor-row <- copy row - *cursor-column <- copy column - *before-cursor <- copy prev + cursor-row <- copy row + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- copy column + *editor <- put *editor, cursor-column:offset, cursor-column + before-cursor <- copy prev + *editor <- put *editor, before-cursor:offset, before-cursor } ] @@ -164,11 +170,11 @@ def handle-keyboard-event screen:address:shared:screen, editor:address:shared:ed screen-height:number <- screen-height screen left:number <- get *editor, left:offset right:number <- get *editor, right:offset - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - save-row:number <- copy *cursor-row - save-column:number <- copy *cursor-column + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + save-row:number <- copy cursor-row + save-column:number <- copy cursor-column # character { c:address:character <- maybe-convert e, text:variant @@ -198,22 +204,24 @@ def handle-keyboard-event screen:address:shared:screen, editor:address:shared:ed def insert-at-cursor editor:address:shared:editor-data, c:character, screen:address:shared:screen -> editor:address:shared:editor-data, screen:address:shared:screen, go-render?:boolean [ local-scope load-ingredients - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset - insert c, *before-cursor - *before-cursor <- next *before-cursor - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + insert c, before-cursor + before-cursor <- next before-cursor + *editor <- put *editor, before-cursor:offset, before-cursor + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset left:number <- get *editor, left:offset right:number <- get *editor, right:offset - save-row:number <- copy *cursor-row - save-column:number <- copy *cursor-column + save-row:number <- copy cursor-row + save-column:number <- copy cursor-column screen-width:number <- screen-width screen screen-height:number <- screen-height screen # occasionally we'll need to mess with the cursor <insert-character-special-case> # but mostly we'll just move the cursor right - *cursor-column <- add *cursor-column, 1 - next:address:shared:duplex-list:character <- next *before-cursor + cursor-column <- add cursor-column, 1 + *editor <- put *editor, cursor-column:offset, cursor-column + next:address:shared:duplex-list:character <- next before-cursor { # at end of all text? no need to scroll? just print the character and leave at-end?:boolean <- equal next, 0/null @@ -231,9 +239,9 @@ def insert-at-cursor editor:address:shared:editor-data, c:character, screen:addr { # not at right margin? print the character and rest of line break-unless next - at-right?:boolean <- greater-or-equal *cursor-column, screen-width + at-right?:boolean <- greater-or-equal cursor-column, screen-width break-if at-right? - curr:address:shared:duplex-list:character <- copy *before-cursor + curr:address:shared:duplex-list:character <- copy before-cursor move-cursor screen, save-row, save-column curr-column:number <- copy save-column { @@ -685,14 +693,16 @@ after <insert-character-special-case> [ { # if we're at the column just before the wrap indicator wrap-column:number <- subtract right, 1 - at-wrap?:boolean <- greater-or-equal *cursor-column, wrap-column + at-wrap?:boolean <- greater-or-equal cursor-column, wrap-column break-unless at-wrap? - *cursor-column <- subtract *cursor-column, wrap-column - *cursor-column <- add *cursor-column, left - *cursor-row <- add *cursor-row, 1 + cursor-column <- subtract cursor-column, wrap-column + cursor-column <- add cursor-column, left + *editor <- put *editor, cursor-column:offset, cursor-column + cursor-row <- add cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row # if we're out of the screen, scroll down { - below-screen?:boolean <- greater-or-equal *cursor-row, screen-height + below-screen?:boolean <- greater-or-equal cursor-row, screen-height break-unless below-screen? <scroll-down> } @@ -786,8 +796,7 @@ container editor-data [ ] after <editor-initialization> [ - indent?:address:boolean <- get-address *result, indent?:offset - *indent? <- copy 1/true + *result <- put *result, indent?:offset, 1/true ] scenario editor-moves-cursor-down-after-inserting-newline [ @@ -825,30 +834,34 @@ after <handle-special-character> [ def insert-new-line-and-indent editor:address:shared:editor-data, screen:address:shared:screen -> editor:address:shared:editor-data, screen:address:shared:screen, go-render?:boolean [ local-scope load-ingredients - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset left:number <- get *editor, left:offset right:number <- get *editor, right:offset screen-height:number <- screen-height screen # insert newline - insert 10/newline, *before-cursor - *before-cursor <- next *before-cursor - *cursor-row <- add *cursor-row, 1 - *cursor-column <- copy left + insert 10/newline, before-cursor + before-cursor <- next before-cursor + *editor <- put *editor, before-cursor:offset, before-cursor + cursor-row <- add cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- copy left + *editor <- put *editor, cursor-column:offset, cursor-column # maybe scroll { - below-screen?:boolean <- greater-or-equal *cursor-row, screen-height # must be equal, never greater + below-screen?:boolean <- greater-or-equal cursor-row, screen-height # must be equal, never greater break-unless below-screen? <scroll-down> go-render? <- copy 1/true - *cursor-row <- subtract *cursor-row, 1 # bring back into screen range + cursor-row <- subtract cursor-row, 1 # bring back into screen range + *editor <- put *editor, cursor-row:offset, cursor-row } # indent if necessary indent?:boolean <- get *editor, indent?:offset return-unless indent? d:address:shared:duplex-list:character <- get *editor, data:offset - end-of-previous-line:address:shared:duplex-list:character <- prev *before-cursor + end-of-previous-line:address:shared:duplex-list:character <- prev before-cursor indent:number <- line-indent end-of-previous-line, d i:number <- copy 0 { @@ -992,8 +1005,7 @@ after <handle-special-key> [ { paste-start?:boolean <- equal *k, 65507/paste-start break-unless paste-start? - indent?:address:boolean <- get-address *editor, indent?:offset - *indent? <- copy 0/false + *editor <- put *editor, indent?:offset, 0/false go-render? <- copy 1/true return } @@ -1003,8 +1015,7 @@ after <handle-special-key> [ { paste-end?:boolean <- equal *k, 65506/paste-end break-unless paste-end? - indent?:address:boolean <- get-address *editor, indent?:offset - *indent? <- copy 1/true + *editor <- put *editor, indent?:offset, 1/true go-render? <- copy 1/true return } diff --git a/edit/003-shortcuts.mu b/edit/003-shortcuts.mu index c09c3441..f29773af 100644 --- a/edit/003-shortcuts.mu +++ b/edit/003-shortcuts.mu @@ -83,18 +83,19 @@ after <handle-special-character> [ def delete-before-cursor editor:address:shared:editor-data, screen:address:shared:screen -> editor:address:shared:editor-data, screen:address:shared:screen, go-render?:boolean, backspaced-cell:address:shared:duplex-list:character [ local-scope load-ingredients - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset data:address:shared:duplex-list:character <- get *editor, data:offset # if at start of text (before-cursor at § sentinel), return - prev:address:shared:duplex-list:character <- prev *before-cursor + prev:address:shared:duplex-list:character <- prev before-cursor go-render?, backspaced-cell <- copy 0/no-more-render, 0/nothing-deleted return-unless prev trace 10, [app], [delete-before-cursor] original-row:number <- get *editor, cursor-row:offset editor, scroll?:boolean <- move-cursor-coordinates-left editor - backspaced-cell:address:shared:duplex-list:character <- copy *before-cursor - data <- remove *before-cursor, data # will also neatly trim next/prev pointers in backspaced-cell/*before-cursor - *before-cursor <- copy prev + backspaced-cell:address:shared:duplex-list:character <- copy before-cursor + data <- remove before-cursor, data # will also neatly trim next/prev pointers in backspaced-cell/before-cursor + before-cursor <- copy prev + *editor <- put *editor, before-cursor:offset, before-cursor go-render? <- copy 1/true return-if scroll? screen-width:number <- screen-width screen @@ -106,7 +107,7 @@ def delete-before-cursor editor:address:shared:editor-data, screen:address:share return-unless same-row? left:number <- get *editor, left:offset right:number <- get *editor, right:offset - curr:address:shared:duplex-list:character <- next *before-cursor + curr:address:shared:duplex-list:character <- next before-cursor screen <- move-cursor screen, cursor-row, cursor-column curr-column:number <- copy cursor-column { @@ -134,24 +135,26 @@ def move-cursor-coordinates-left editor:address:shared:editor-data -> editor:add local-scope load-ingredients before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset left:number <- get *editor, left:offset # if not at left margin, move one character left { - at-left-margin?:boolean <- equal *cursor-column, left + at-left-margin?:boolean <- equal cursor-column, left break-if at-left-margin? trace 10, [app], [decrementing cursor column] - *cursor-column <- subtract *cursor-column, 1 + cursor-column <- subtract cursor-column, 1 + *editor <- put *editor, cursor-column:offset, cursor-column go-render? <- copy 0/false return } # if at left margin, we must move to previous row: - top-of-screen?:boolean <- equal *cursor-row, 1 # exclude menu bar + top-of-screen?:boolean <- equal cursor-row, 1 # exclude menu bar go-render?:boolean <- copy 0/false { break-if top-of-screen? - *cursor-row <- subtract *cursor-row, 1 + cursor-row <- subtract cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row } { break-unless top-of-screen? @@ -173,18 +176,21 @@ def move-cursor-coordinates-left editor:address:shared:editor-data -> editor:add { break-unless wrap? _, column-offset:number <- divide-with-remainder end-of-line, width - *cursor-column <- add left, column-offset + cursor-column <- add left, column-offset + *editor <- put *editor, cursor-column:offset, cursor-column } { break-if wrap? - *cursor-column <- add left, end-of-line + cursor-column <- add left, end-of-line + *editor <- put *editor, cursor-column:offset, cursor-column } return } # case 2: if previous-character was not newline, we're just at a wrapped line trace 10, [app], [wrapping to previous line] right:number <- get *editor, right:offset - *cursor-column <- subtract right, 1 # leave room for wrap icon + cursor-column <- subtract right, 1 # leave room for wrap icon + *editor <- put *editor, cursor-column:offset, cursor-column ] # takes a pointer 'curr' into the doubly-linked list and its sentinel, counts @@ -345,9 +351,9 @@ after <handle-special-key> [ def delete-at-cursor editor:address:shared:editor-data, screen:address:shared:screen -> editor:address:shared:editor-data, screen:address:shared:screen, go-render?:boolean, deleted-cell:address:shared:duplex-list:character [ local-scope load-ingredients - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset data:address:shared:duplex-list:character <- get *editor, data:offset - deleted-cell:address:shared:duplex-list:character <- next *before-cursor + deleted-cell:address:shared:duplex-list:character <- next before-cursor go-render? <- copy 0/false return-unless deleted-cell currc:character <- get *deleted-cell, value:offset @@ -356,11 +362,11 @@ def delete-at-cursor editor:address:shared:editor-data, screen:address:shared:sc go-render? <- copy 1/true return-if deleted-newline? # wasn't a newline? render rest of line - curr:address:shared:duplex-list:character <- next *before-cursor # refresh after remove above - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - screen <- move-cursor screen, *cursor-row, *cursor-column - curr-column:number <- copy *cursor-column + curr:address:shared:duplex-list:character <- next before-cursor # refresh after remove above + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + screen <- move-cursor screen, cursor-row, cursor-column + curr-column:number <- copy cursor-column screen-width:number <- screen-width screen { # hit right margin? give up and let caller render @@ -412,13 +418,14 @@ after <handle-special-key> [ move-to-next-character?:boolean <- equal *k, 65514/right-arrow break-unless move-to-next-character? # if not at end of text - next-cursor:address:shared:duplex-list:character <- next *before-cursor + next-cursor:address:shared:duplex-list:character <- next before-cursor break-unless next-cursor # scan to next character <move-cursor-begin> - *before-cursor <- copy next-cursor + before-cursor <- copy next-cursor + *editor <- put *editor, before-cursor:offset, before-cursor editor, go-render?:boolean <- move-cursor-coordinates-right editor, screen-height - screen <- move-cursor screen, *cursor-row, *cursor-column + screen <- move-cursor screen, cursor-row, cursor-column undo-coalesce-tag:number <- copy 2/right-arrow <move-cursor-end> return @@ -429,8 +436,8 @@ def move-cursor-coordinates-right editor:address:shared:editor-data, screen-heig local-scope load-ingredients before-cursor:address:shared:duplex-list:character <- get *editor before-cursor:offset - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset left:number <- get *editor, left:offset right:number <- get *editor, right:offset # if crossed a newline, move cursor to start of next row @@ -438,13 +445,16 @@ def move-cursor-coordinates-right editor:address:shared:editor-data, screen-heig old-cursor-character:character <- get *before-cursor, value:offset was-at-newline?:boolean <- equal old-cursor-character, 10/newline break-unless was-at-newline? - *cursor-row <- add *cursor-row, 1 - *cursor-column <- copy left - below-screen?:boolean <- greater-or-equal *cursor-row, screen-height # must be equal + cursor-row <- add cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- copy left + *editor <- put *editor, cursor-column:offset, cursor-column + below-screen?:boolean <- greater-or-equal cursor-row, screen-height # must be equal go-render? <- copy 0/false return-unless below-screen? <scroll-down> - *cursor-row <- subtract *cursor-row, 1 # bring back into screen range + cursor-row <- subtract cursor-row, 1 # bring back into screen range + *editor <- put *editor, cursor-row:offset, cursor-row go-render? <- copy 1/true return } @@ -452,7 +462,7 @@ def move-cursor-coordinates-right editor:address:shared:editor-data, screen-heig { # if we're at the column just before the wrap indicator wrap-column:number <- subtract right, 1 - at-wrap?:boolean <- equal *cursor-column, wrap-column + at-wrap?:boolean <- equal cursor-column, wrap-column break-unless at-wrap? # and if next character isn't newline next:address:shared:duplex-list:character <- next before-cursor @@ -460,17 +470,21 @@ def move-cursor-coordinates-right editor:address:shared:editor-data, screen-heig next-character:character <- get *next, value:offset newline?:boolean <- equal next-character, 10/newline break-if newline? - *cursor-row <- add *cursor-row, 1 - *cursor-column <- copy left - below-screen?:boolean <- greater-or-equal *cursor-row, screen-height # must be equal + cursor-row <- add cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- copy left + *editor <- put *editor, cursor-column:offset, cursor-column + below-screen?:boolean <- greater-or-equal cursor-row, screen-height # must be equal return-unless below-screen?, editor/same-as-ingredient:0, 0/no-more-render <scroll-down> - *cursor-row <- subtract *cursor-row, 1 # bring back into screen range + cursor-row <- subtract cursor-row, 1 # bring back into screen range + *editor <- put *editor, cursor-row:offset, cursor-row go-render? <- copy 1/true return } # otherwise move cursor one character right - *cursor-column <- add *cursor-column, 1 + cursor-column <- add cursor-column, 1 + *editor <- put *editor, cursor-column:offset, cursor-column go-render? <- copy 0/false ] @@ -689,12 +703,13 @@ after <handle-special-key> [ break-unless move-to-previous-character? trace 10, [app], [left arrow] # if not at start of text (before-cursor at § sentinel) - prev:address:shared:duplex-list:character <- prev *before-cursor + prev:address:shared:duplex-list:character <- prev before-cursor go-render? <- copy 0/false return-unless prev <move-cursor-begin> editor, go-render? <- move-cursor-coordinates-left editor - *before-cursor <- copy prev + before-cursor <- copy prev + *editor <- put *editor, before-cursor:offset, before-cursor undo-coalesce-tag:number <- copy 1/left-arrow <move-cursor-end> return @@ -961,19 +976,19 @@ after <handle-special-key> [ def move-to-previous-line editor:address:shared:editor-data -> editor:address:shared:editor-data, go-render?:boolean [ local-scope load-ingredients - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset left:number <- get *editor, left:offset right:number <- get *editor, right:offset - already-at-top?:boolean <- lesser-or-equal *cursor-row, 1/top + already-at-top?:boolean <- lesser-or-equal cursor-row, 1/top { # if cursor not at top, move it break-if already-at-top? # if not at newline, move to start of line (previous newline) # then scan back another line # if either step fails, give up without modifying cursor or coordinates - curr:address:shared:duplex-list:character <- copy *before-cursor + curr:address:shared:duplex-list:character <- copy before-cursor { old:address:shared:duplex-list:character <- copy curr c2:character <- get *curr, value:offset @@ -991,22 +1006,27 @@ def move-to-previous-line editor:address:shared:editor-data -> editor:address:sh go-render? <- copy 0/false return-if no-motion? } - *before-cursor <- copy curr - *cursor-row <- subtract *cursor-row, 1 + before-cursor <- copy curr + *editor <- put *editor, before-cursor:offset, before-cursor + cursor-row <- subtract cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row # scan ahead to right column or until end of line - target-column:number <- copy *cursor-column - *cursor-column <- copy left + target-column:number <- copy cursor-column + cursor-column <- copy left + *editor <- put *editor, cursor-column:offset, cursor-column { - done?:boolean <- greater-or-equal *cursor-column, target-column + done?:boolean <- greater-or-equal cursor-column, target-column break-if done? - curr:address:shared:duplex-list:character <- next *before-cursor + curr:address:shared:duplex-list:character <- next before-cursor break-unless curr currc:character <- get *curr, value:offset at-newline?:boolean <- equal currc, 10/newline break-if at-newline? # - *before-cursor <- copy curr - *cursor-column <- add *cursor-column, 1 + before-cursor <- copy curr + *editor <- put *editor, before-cursor:offset, before-cursor + cursor-column <- add cursor-column, 1 + *editor <- put *editor, cursor-column:offset, cursor-column loop } go-render? <- copy 0/false @@ -1186,44 +1206,49 @@ after <handle-special-key> [ def move-to-next-line editor:address:shared:editor-data, screen-height:number -> editor:address:shared:editor-data, go-render?:boolean [ local-scope load-ingredients - cursor-row:address:number <- get-address *editor, cursor-row:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset left:number <- get *editor, left:offset right:number <- get *editor, right:offset last-line:number <- subtract screen-height, 1 - already-at-bottom?:boolean <- greater-or-equal *cursor-row, last-line + already-at-bottom?:boolean <- greater-or-equal cursor-row, last-line { # if cursor not at bottom, move it break-if already-at-bottom? # scan to start of next line, then to right column or until end of line max:number <- subtract right, left - next-line:address:shared:duplex-list:character <- before-start-of-next-line *before-cursor, max + next-line:address:shared:duplex-list:character <- before-start-of-next-line before-cursor, max { # already at end of buffer? try to scroll up (so we can see more # warnings or sandboxes below) - no-motion?:boolean <- equal next-line, *before-cursor + no-motion?:boolean <- equal next-line, before-cursor break-unless no-motion? - scroll?:boolean <- greater-than *cursor-row, 1 + scroll?:boolean <- greater-than cursor-row, 1 break-if scroll?, +try-to-scroll:label go-render? <- copy 0/false return } - *cursor-row <- add *cursor-row, 1 - *before-cursor <- copy next-line - target-column:number <- copy *cursor-column - *cursor-column <- copy left + cursor-row <- add cursor-row, 1 + *editor <- put *editor, cursor-row:offset, cursor-row + before-cursor <- copy next-line + *editor <- put *editor, before-cursor:offset, before-cursor + target-column:number <- copy cursor-column + cursor-column <- copy left + *editor <- put *editor, cursor-column:offset, cursor-column { - done?:boolean <- greater-or-equal *cursor-column, target-column + done?:boolean <- greater-or-equal cursor-column, target-column break-if done? - curr:address:shared:duplex-list:character <- next *before-cursor + curr:address:shared:duplex-list:character <- next before-cursor break-unless curr currc:character <- get *curr, value:offset at-newline?:boolean <- equal currc, 10/newline break-if at-newline? # - *before-cursor <- copy curr - *cursor-column <- add *cursor-column, 1 + before-cursor <- copy curr + *editor <- put *editor, before-cursor:offset, before-cursor + cursor-column <- add cursor-column, 1 + *editor <- put *editor, cursor-column:offset, cursor-column loop } go-render? <- copy 0/false @@ -1328,20 +1353,21 @@ def move-to-start-of-line editor:address:shared:editor-data -> editor:address:sh load-ingredients # update cursor column left:number <- get *editor, left:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - *cursor-column <- copy left + cursor-column:number <- copy left + *editor <- put *editor, cursor-column:offset, cursor-column # update before-cursor - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset init:address:shared:duplex-list:character <- get *editor, data:offset # while not at start of line, move { - at-start-of-text?:boolean <- equal *before-cursor, init + at-start-of-text?:boolean <- equal before-cursor, init break-if at-start-of-text? - prev:character <- get **before-cursor, value:offset + prev:character <- get *before-cursor, value:offset at-start-of-line?:boolean <- equal prev, 10/newline break-if at-start-of-line? - *before-cursor <- prev *before-cursor - assert *before-cursor, [move-to-start-of-line tried to move before start of text] + before-cursor <- prev before-cursor + *editor <- put *editor, before-cursor:offset, before-cursor + assert before-cursor, [move-to-start-of-line tried to move before start of text] loop } ] @@ -1497,17 +1523,19 @@ after <handle-special-key> [ def move-to-end-of-line editor:address:shared:editor-data -> editor:address:shared:editor-data [ local-scope load-ingredients - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + cursor-column:number <- get *editor, cursor-column:offset # while not at start of line, move { - next:address:shared:duplex-list:character <- next *before-cursor + next:address:shared:duplex-list:character <- next before-cursor break-unless next # end of text nextc:character <- get *next, value:offset at-end-of-line?:boolean <- equal nextc, 10/newline break-if at-end-of-line? - *before-cursor <- copy next - *cursor-column <- add *cursor-column, 1 + before-cursor <- copy next + *editor <- put *editor, before-cursor:offset, before-cursor + cursor-column <- add cursor-column, 1 + *editor <- put *editor, cursor-column:offset, cursor-column loop } ] @@ -1629,9 +1657,9 @@ def delete-to-start-of-line editor:address:shared:editor-data -> result:address: load-ingredients # compute range to delete init:address:shared:duplex-list:character <- get *editor, data:offset - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset - start:address:shared:duplex-list:character <- copy *before-cursor - end:address:shared:duplex-list:character <- next *before-cursor + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + start:address:shared:duplex-list:character <- copy before-cursor + end:address:shared:duplex-list:character <- next before-cursor { at-start-of-text?:boolean <- equal start, init break-if at-start-of-text? @@ -1646,10 +1674,10 @@ def delete-to-start-of-line editor:address:shared:editor-data -> result:address: result:address:shared:duplex-list:character <- next start remove-between start, end # adjust cursor - *before-cursor <- copy start + before-cursor <- copy start + *editor <- put *editor, before-cursor:offset, before-cursor left:number <- get *editor, left:offset - cursor-column:address:number <- get-address *editor, cursor-column:offset - *cursor-column <- copy left + *editor <- put *editor, cursor-column:offset, left ] scenario editor-deletes-to-start-of-line-with-ctrl-u-2 [ @@ -1929,13 +1957,14 @@ d] after <scroll-down> [ trace 10, [app], [scroll down] - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset left:number <- get *editor, left:offset right:number <- get *editor, right:offset max:number <- subtract right, left - old-top:address:shared:duplex-list:character <- copy *top-of-screen - *top-of-screen <- before-start-of-next-line *top-of-screen, max - no-movement?:boolean <- equal old-top, *top-of-screen + old-top:address:shared:duplex-list:character <- copy top-of-screen + top-of-screen <- before-start-of-next-line top-of-screen, max + *editor <- put *editor, top-of-screen:offset, top-of-screen + no-movement?:boolean <- equal old-top, top-of-screen go-render? <- copy 0/false return-if no-movement? ] @@ -2299,10 +2328,11 @@ d] after <scroll-up> [ trace 10, [app], [scroll up] - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - old-top:address:shared:duplex-list:character <- copy *top-of-screen - *top-of-screen <- before-previous-line *top-of-screen, editor - no-movement?:boolean <- equal old-top, *top-of-screen + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + old-top:address:shared:duplex-list:character <- copy top-of-screen + top-of-screen <- before-previous-line top-of-screen, editor + *editor <- put *editor, top-of-screen:offset, top-of-screen + no-movement?:boolean <- equal old-top, top-of-screen go-render? <- copy 0/false return-if no-movement? ] @@ -2690,13 +2720,13 @@ after <handle-special-character> [ { page-down?:boolean <- equal *c, 6/ctrl-f break-unless page-down? - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - old-top:address:shared:duplex-list:character <- copy *top-of-screen + old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset <move-cursor-begin> page-down editor undo-coalesce-tag:number <- copy 0/never <move-cursor-end> - no-movement?:boolean <- equal *top-of-screen, old-top + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + no-movement?:boolean <- equal top-of-screen, old-top go-render? <- not no-movement? return } @@ -2706,13 +2736,13 @@ after <handle-special-key> [ { page-down?:boolean <- equal *k, 65518/page-down break-unless page-down? - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - old-top:address:shared:duplex-list:character <- copy *top-of-screen + old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset <move-cursor-begin> page-down editor undo-coalesce-tag:number <- copy 0/never <move-cursor-end> - no-movement?:boolean <- equal *top-of-screen, old-top + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + no-movement?:boolean <- equal top-of-screen, old-top go-render? <- not no-movement? return } @@ -2727,19 +2757,21 @@ def page-down editor:address:shared:editor-data -> editor:address:shared:editor- bottom-of-screen:address:shared:duplex-list:character <- get *editor, bottom-of-screen:offset return-unless bottom-of-screen # if not, position cursor at final character - before-cursor:address:address:shared:duplex-list:character <- get-address *editor, before-cursor:offset - *before-cursor <- prev bottom-of-screen + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + before-cursor:address:shared:duplex-list:character <- prev bottom-of-screen + *editor <- put *editor, before-cursor:offset, before-cursor # keep one line in common with previous page { - last:character <- get **before-cursor, value:offset + last:character <- get *before-cursor, value:offset newline?:boolean <- equal last, 10/newline break-unless newline?:boolean - *before-cursor <- prev *before-cursor + before-cursor <- prev before-cursor + *editor <- put *editor, before-cursor:offset, before-cursor } # move cursor and top-of-screen to start of that line move-to-start-of-line editor - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top-of-screen <- copy *before-cursor + before-cursor <- get *editor, before-cursor:offset + *editor <- put *editor, top-of-screen:offset, before-cursor ] scenario editor-does-not-scroll-past-end [ @@ -2882,13 +2914,13 @@ after <handle-special-character> [ { page-up?:boolean <- equal *c, 2/ctrl-b break-unless page-up? - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - old-top:address:shared:duplex-list:character <- copy *top-of-screen + old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset <move-cursor-begin> editor <- page-up editor, screen-height undo-coalesce-tag:number <- copy 0/never <move-cursor-end> - no-movement?:boolean <- equal *top-of-screen, old-top + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + no-movement?:boolean <- equal top-of-screen, old-top go-render? <- not no-movement? return } @@ -2898,13 +2930,13 @@ after <handle-special-key> [ { page-up?:boolean <- equal *k, 65519/page-up break-unless page-up? - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - old-top:address:shared:duplex-list:character <- copy *top-of-screen + old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset <move-cursor-begin> editor <- page-up editor, screen-height undo-coalesce-tag:number <- copy 0/never <move-cursor-end> - no-movement?:boolean <- equal *top-of-screen, old-top + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + no-movement?:boolean <- equal top-of-screen, old-top # don't bother re-rendering if nothing changed. todo: test this go-render? <- not no-movement? return @@ -2916,13 +2948,14 @@ def page-up editor:address:shared:editor-data, screen-height:number -> editor:ad load-ingredients max:number <- subtract screen-height, 1/menu-bar, 1/overlapping-line count:number <- copy 0 - top-of-screen:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset + top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset { done?:boolean <- greater-or-equal count, max break-if done? - prev:address:shared:duplex-list:character <- before-previous-line *top-of-screen, editor + prev:address:shared:duplex-list:character <- before-previous-line top-of-screen, editor break-unless prev - *top-of-screen <- copy prev + top-of-screen <- copy prev + *editor <- put *editor, top-of-screen:offset, top-of-screen count <- add count, 1 loop } diff --git a/edit/004-programming-environment.mu b/edit/004-programming-environment.mu index f43a44a7..86ad3f5a 100644 --- a/edit/004-programming-environment.mu +++ b/edit/004-programming-environment.mu @@ -38,12 +38,13 @@ def new-programming-environment screen:address:shared:screen, initial-recipe-con divider:number, _ <- divide-with-remainder width, 2 draw-vertical screen, divider, 1/top, height, 9482/vertical-dotted # recipe editor on the left - recipes:address:address:shared:editor-data <- get-address *result, recipes:offset - *recipes <- new-editor initial-recipe-contents, screen, 0/left, divider/right + recipes:address:shared:editor-data <- new-editor initial-recipe-contents, screen, 0/left, divider/right # sandbox editor on the right - new-left:number <- add divider, 1 - current-sandbox:address:address:shared:editor-data <- get-address *result, current-sandbox:offset - *current-sandbox <- new-editor initial-sandbox-contents, screen, new-left, width/right + sandbox-left:number <- add divider, 1 + current-sandbox:address:shared:editor-data <- new-editor initial-sandbox-contents, screen, sandbox-left, width/right + *result <- put *result, recipes:offset, recipes + *result <- put *result, current-sandbox:offset, current-sandbox + *result <- put *result, sandbox-in-focus?:offset, 0/false <programming-environment-initialization> ] @@ -52,7 +53,7 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env load-ingredients recipes:address:shared:editor-data <- get *env, recipes:offset current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset - sandbox-in-focus?:address:boolean <- get-address *env, sandbox-in-focus?:offset + sandbox-in-focus?:boolean <- get *env, sandbox-in-focus?:offset # if we fall behind we'll stop updating the screen, but then we have to # render the entire screen when we catch up. # todo: test this @@ -89,8 +90,9 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env <global-touch> # send to both editors _ <- move-cursor-in-editor screen, recipes, *t - *sandbox-in-focus? <- move-cursor-in-editor screen, current-sandbox, *t - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + sandbox-in-focus?:boolean <- move-cursor-in-editor screen, current-sandbox, *t + *env <- put *env, sandbox-in-focus?:offset, sandbox-in-focus? + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env loop +next-event:label } # 'resize' event - redraw editor @@ -115,8 +117,9 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env # if it's not global and not a touch event, send to appropriate editor { hide-screen screen + sandbox-in-focus?:boolean <- get *env, sandbox-in-focus?:offset { - break-if *sandbox-in-focus? + break-if sandbox-in-focus? screen, recipes, render?:boolean <- handle-keyboard-event screen, recipes, e:event # refresh screen only if no more events # if there are more events to process, wait for them to clear up, then make sure you render-all afterward. @@ -144,7 +147,7 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env } } { - break-unless *sandbox-in-focus? + break-unless sandbox-in-focus? screen, current-sandbox, render?:boolean <- handle-keyboard-event screen, current-sandbox, e:event # refresh screen only if no more events # if there are more events to process, wait for them to clear up, then make sure you render-all afterward. @@ -172,7 +175,7 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env } } +finish-event - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env show-screen screen } loop @@ -187,24 +190,20 @@ def resize screen:address:shared:screen, env:address:shared:programming-environm divider:number, _ <- divide-with-remainder width, 2 # update recipe editor recipes:address:shared:editor-data <- get *env, recipes:offset - right:address:number <- get-address *recipes, right:offset - *right <- subtract divider, 1 + right:number <- subtract divider, 1 + *recipes <- put *recipes, right:offset, right # reset cursor (later we'll try to preserve its position) - cursor-row:address:number <- get-address *recipes, cursor-row:offset - *cursor-row <- copy 1 - cursor-column:address:number <- get-address *recipes, cursor-column:offset - *cursor-column <- copy 0 + *recipes <- put *recipes, cursor-row:offset, 1 + *recipes <- put *recipes, cursor-column:offset, 0 # update sandbox editor current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset - left:address:number <- get-address *current-sandbox, left:offset - right:address:number <- get-address *current-sandbox, right:offset - *left <- add divider, 1 - *right <- subtract width, 1 + left:number <- add divider, 1 + *current-sandbox <- put *current-sandbox, left:offset, left + right:number <- subtract width, 1 + *current-sandbox <- put *current-sandbox, right:offset, right # reset cursor (later we'll try to preserve its position) - cursor-row:address:number <- get-address *current-sandbox, cursor-row:offset - *cursor-row <- copy 1 - cursor-column:address:number <- get-address *current-sandbox, cursor-column:offset - *cursor-column <- copy *left + *current-sandbox <- put *current-sandbox, cursor-row:offset, 1 + *current-sandbox <- put *current-sandbox, cursor-column:offset, left ] scenario point-at-multiple-editors [ @@ -598,8 +597,10 @@ after <global-type> [ { switch-side?:boolean <- equal *c, 14/ctrl-n break-unless switch-side? - *sandbox-in-focus? <- not *sandbox-in-focus? - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + sandbox-in-focus?:boolean <- get *env, sandbox-in-focus?:offset + sandbox-in-focus? <- not sandbox-in-focus? + *env <- put *env, sandbox-in-focus?:offset, sandbox-in-focus? + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env loop +next-event:label } ] diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu index 95cc53b8..0bbd7f85 100644 --- a/edit/005-sandbox.mu +++ b/edit/005-sandbox.mu @@ -24,8 +24,7 @@ container programming-environment-data [ ] after <programming-environment-initialization> [ - render-from:address:number <- get-address *result, render-from:offset - *render-from <- copy -1 + *result <- put *result, render-from:offset, -1 ] container sandbox-data [ @@ -135,7 +134,7 @@ after <global-keypress> [ break-if error? screen <- update-status screen, [ ], 245/grey } - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env loop +next-event:label } ] @@ -154,21 +153,19 @@ def run-sandboxes env:address:shared:programming-environment-data, screen:addres # if contents exist, first save them # run them and turn them into a new sandbox-data new-sandbox:address:shared:sandbox-data <- new sandbox-data:type - data:address:address:shared:array:character <- get-address *new-sandbox, data:offset - *data <- copy sandbox-contents + *new-sandbox <- put *new-sandbox, data:offset, sandbox-contents # push to head of sandbox list - dest:address:address:shared:sandbox-data <- get-address *env, sandbox:offset - next:address:address:shared:sandbox-data <- get-address *new-sandbox, next-sandbox:offset - *next <- copy *dest - *dest <- copy new-sandbox + dest:address:shared:sandbox-data <- get *env, sandbox:offset + *new-sandbox <- put *new-sandbox, next-sandbox:offset, dest + *env <- put *env, sandbox:offset, new-sandbox # update sandbox count - sandbox-count:address:number <- get-address *env, number-of-sandboxes:offset - *sandbox-count <- add *sandbox-count, 1 + sandbox-count:number <- get *env, number-of-sandboxes:offset + sandbox-count <- add sandbox-count, 1 + *env <- put *env, number-of-sandboxes:offset, sandbox-count # clear sandbox editor - init:address:address:shared:duplex-list:character <- get-address *current-sandbox, data:offset - *init <- push 167/§, 0/tail - top-of-screen:address:address:shared:duplex-list:character <- get-address *current-sandbox, top-of-screen:offset - *top-of-screen <- copy *init + init:address:shared:duplex-list:character <- push 167/§, 0/tail + *current-sandbox <- put *current-sandbox, data:offset, init + *current-sandbox <- put *current-sandbox, top-of-screen:offset, init } # save all sandboxes before running, just in case we die when running save-sandboxes env @@ -202,9 +199,9 @@ def! update-sandbox sandbox:address:shared:sandbox-data, env:address:shared:prog local-scope load-ingredients data:address:shared:array:character <- get *sandbox, data:offset - response:address:address:shared:array:character <- get-address *sandbox, response:offset - fake-screen:address:address:shared:screen <- get-address *sandbox, screen:offset - *response, _, *fake-screen <- run-interactive data + response:address:shared:array:character, _, fake-screen:address:shared:screen <- run-interactive data + *sandbox <- put *sandbox, response:offset, response + *sandbox <- put *sandbox, screen:offset, fake-screen ] def update-status screen:address:shared:screen, msg:address:shared:array:character, color:number -> screen:address:shared:screen [ @@ -276,15 +273,13 @@ def render-sandboxes screen:address:shared:screen, sandbox:address:shared:sandbo delete-icon:character <- copy 120/x print screen, delete-icon, 245/grey # save menu row so we can detect clicks to it later - starting-row:address:number <- get-address *sandbox, starting-row-on-screen:offset - *starting-row <- copy row + *sandbox <- put *sandbox, starting-row-on-screen:offset, row # render sandbox contents row <- add row, 1 screen <- move-cursor screen, row, left sandbox-data:address:shared:array:character <- get *sandbox, data:offset row, screen <- render-code screen, sandbox-data, left, right, row - code-ending-row:address:number <- get-address *sandbox, code-ending-row-on-screen:offset - *code-ending-row <- copy row + *sandbox <- put *sandbox, code-ending-row-on-screen:offset, row # render sandbox warnings, screen or response, in that order sandbox-response:address:shared:array:character <- get *sandbox, response:offset <render-sandbox-results> @@ -308,10 +303,8 @@ def render-sandboxes screen:address:shared:screen, sandbox:address:shared:sandbo # if hidden, reset row attributes { break-unless hidden? - tmp:address:number <- get-address *sandbox, starting-row-on-screen:offset - *tmp <- copy 0 - tmp:address:number <- get-address *sandbox, code-ending-row-on-screen:offset - *tmp <- copy 0 + *sandbox <- put *sandbox, starting-row-on-screen:offset, 0 + *sandbox <- put *sandbox, code-ending-row-on-screen:offset, 0 <end-render-sandbox-reset-hidden> } # draw next sandbox @@ -326,15 +319,15 @@ def restore-sandboxes env:address:shared:programming-environment-data -> env:add load-ingredients # read all scenarios, pushing them to end of a list of scenarios idx:number <- copy 0 - curr:address:address:shared:sandbox-data <- get-address *env, sandbox:offset + curr:address:shared:sandbox-data <- copy 0 + prev:address:shared:sandbox-data <- copy 0 { filename:address:shared:array:character <- to-text idx contents:address:shared:array:character <- restore filename break-unless contents # stop at first error; assuming file didn't exist # create new sandbox for file - *curr <- new sandbox-data:type - data:address:address:shared:array:character <- get-address **curr, data:offset - *data <- copy contents + curr <- new sandbox-data:type + *curr <- put *curr, data:offset, contents # restore expected output for sandbox if it exists { filename <- append filename, [.out] @@ -344,12 +337,16 @@ def restore-sandboxes env:address:shared:programming-environment-data -> env:add } +continue idx <- add idx, 1 - curr <- get-address **curr, next-sandbox:offset + { + break-unless prev + *prev <- put *prev, next-sandbox:offset, curr + } + prev <- copy curr loop } + *env <- put *env, sandbox:offset, curr # update sandbox count - number-of-sandboxes:address:number <- get-address *env, number-of-sandboxes:offset - *number-of-sandboxes <- copy idx + *env <- put *env, number-of-sandboxes:offset, idx ] # print the fake sandbox screen to 'screen' with appropriate delimiters @@ -616,7 +613,7 @@ scenario scrolling-down-past-bottom-of-sandbox-editor [ # down on sandbox side updates render-from when sandbox editor has cursor at bottom after <global-keypress> [ { - break-unless *sandbox-in-focus? + break-unless sandbox-in-focus? down?:boolean <- equal *k, 65516/down-arrow break-unless down? sandbox-bottom:number <- get *current-sandbox, bottom:offset @@ -627,12 +624,13 @@ after <global-keypress> [ break-unless sandbox # slide down if possible { - render-from:address:number <- get-address *env, render-from:offset + render-from:number <- get *env, render-from:offset number-of-sandboxes:number <- get *env, number-of-sandboxes:offset max:number <- subtract number-of-sandboxes, 1 - at-end?:boolean <- greater-or-equal *render-from, max + at-end?:boolean <- greater-or-equal render-from, max jump-if at-end?, +finish-event:label # render nothing - *render-from <- add *render-from, 1 + render-from <- add render-from, 1 + *env <- put *env, render-from:offset, render-from } hide-screen screen screen <- render-sandbox-side screen, env @@ -657,13 +655,14 @@ after <update-cursor-special-cases> [ # 'up' on sandbox side is like 'down': updates render-from when necessary after <global-keypress> [ { - break-unless *sandbox-in-focus? + break-unless sandbox-in-focus? up?:boolean <- equal *k, 65517/up-arrow break-unless up? - render-from:address:number <- get-address *env, render-from:offset - at-beginning?:boolean <- equal *render-from, -1 + render-from:number <- get *env, render-from:offset + at-beginning?:boolean <- equal render-from, -1 break-if at-beginning? - *render-from <- subtract *render-from, 1 + render-from <- subtract render-from, 1 + *env <- put *env, render-from:offset, render-from hide-screen screen screen <- render-sandbox-side screen, env show-screen screen diff --git a/edit/006-sandbox-edit.mu b/edit/006-sandbox-edit.mu index 7354d60b..c5537851 100644 --- a/edit/006-sandbox-edit.mu +++ b/edit/006-sandbox-edit.mu @@ -25,7 +25,7 @@ recipe foo [ . ┊━━━━━━━━━━━━━━━━━━━. . ┊ . ] - # click somewhere on the sandbox + # click somewhere in the first row of the sandbox assume-console [ left-click 3, 30 ] @@ -82,11 +82,10 @@ after <global-touch> [ break-unless sandbox text:address:shared:array:character <- get *sandbox, data:offset current-sandbox <- insert-text current-sandbox, text - render-from:address:number <- get-address *env, render-from:offset - *render-from <- copy -1 + *env <- put *env, render-from:offset, -1 hide-screen screen screen <- render-sandbox-side screen, env - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env show-screen screen loop +next-event:label } @@ -103,29 +102,43 @@ def empty-editor? editor:address:shared:editor-data -> result:boolean [ def extract-sandbox env:address:shared:programming-environment-data, click-row:number -> result:address:shared:sandbox-data, env:address:shared:programming-environment-data [ local-scope load-ingredients - sandbox:address:address:shared:sandbox-data <- get-address *env, sandbox:offset - start:number <- get **sandbox, starting-row-on-screen:offset + curr-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset + start:number <- get *curr-sandbox, starting-row-on-screen:offset in-editor?:boolean <- lesser-than click-row, start return-if in-editor?, 0 + first-sandbox?:boolean <- equal click-row, start { - next-sandbox:address:shared:sandbox-data <- get **sandbox, next-sandbox:offset - break-unless next-sandbox - # if click-row < sandbox.next-sandbox.starting-row-on-screen, break - next-start:number <- get *next-sandbox, starting-row-on-screen:offset - found?:boolean <- lesser-than click-row, next-start - break-if found? - sandbox <- get-address **sandbox, next-sandbox:offset - loop + # first sandbox? pop + break-unless first-sandbox? + next-sandbox:address:shared:sandbox-data <- get *curr-sandbox, next-sandbox:offset + *env <- put *env, sandbox:offset, next-sandbox } - # snip sandbox out of its list - result <- copy *sandbox - *sandbox <- copy next-sandbox + { + # not first sandbox? + break-if first-sandbox? + prev-sandbox:address:shared:sandbox-data <- copy curr-sandbox + curr-sandbox <- get *curr-sandbox, next-sandbox:offset + { + next-sandbox:address:shared:sandbox-data <- get *curr-sandbox, next-sandbox:offset + break-unless next-sandbox + # if click-row < sandbox.next-sandbox.starting-row-on-screen, break + next-start:number <- get *next-sandbox, starting-row-on-screen:offset + found?:boolean <- lesser-than click-row, next-start + break-if found? + prev-sandbox <- copy curr-sandbox + curr-sandbox <- copy next-sandbox + loop + } + # snip sandbox out of its list + *prev-sandbox <- put *prev-sandbox, next-sandbox:offset, next-sandbox + } + result <- copy curr-sandbox # update sandbox count - sandbox-count:address:number <- get-address *env, number-of-sandboxes:offset - *sandbox-count <- subtract *sandbox-count, 1 + sandbox-count:number <- get *env, number-of-sandboxes:offset + sandbox-count <- subtract sandbox-count, 1 + *env <- put *env, number-of-sandboxes:offset, sandbox-count # position cursor in sandbox editor - sandbox-in-focus?:address:boolean <- get-address *env, sandbox-in-focus?:offset - *sandbox-in-focus? <- copy 1/true + *env <- put *env, sandbox-in-focus?:offset, 1/true ] scenario sandbox-with-print-can-be-edited [ diff --git a/edit/007-sandbox-delete.mu b/edit/007-sandbox-delete.mu index 567e3cd6..e59d333e 100644 --- a/edit/007-sandbox-delete.mu +++ b/edit/007-sandbox-delete.mu @@ -71,7 +71,7 @@ after <global-touch> [ break-unless was-delete? hide-screen screen screen <- render-sandbox-side screen, env - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env show-screen screen loop +next-event:label } @@ -86,8 +86,20 @@ def delete-sandbox t:touch-event, env:address:shared:programming-environment-dat at-right?:boolean <- equal click-column, right return-unless at-right?, 0/false click-row:number <- get t, row:offset - prev:address:address:shared:sandbox-data <- get-address *env, sandbox:offset - curr:address:shared:sandbox-data <- get *env, sandbox:offset + { + first:address:shared:sandbox-data <- get *env, sandbox:offset + reply-unless first, 0/false + target-row:number <- get *first, starting-row-on-screen:offset + delete-first?:boolean <- equal target-row, click-row + break-unless delete-first? + new-first:address:shared:sandbox-data <- get *first, next-sandbox:offset + *env <- put *env, sandbox:offset, new-first + env <- fixup-delete env, new-first + return 1/true # force rerender + } + prev:address:shared:sandbox-data <- get *env, sandbox:offset + assert prev, [failed to find any sandboxes!] + curr:address:shared:sandbox-data <- get *prev, next-sandbox:offset { break-unless curr # more sandboxes to check @@ -96,27 +108,36 @@ def delete-sandbox t:touch-event, env:address:shared:programming-environment-dat delete-curr?:boolean <- equal target-row, click-row break-unless delete-curr? # delete this sandbox - *prev <- get *curr, next-sandbox:offset - # update sandbox count - sandbox-count:address:number <- get-address *env, number-of-sandboxes:offset - *sandbox-count <- subtract *sandbox-count, 1 - # if it's the last sandbox and if it was the only sandbox rendered, reset scroll - { - break-if *prev - render-from:address:number <- get-address *env, render-from:offset - reset-scroll?:boolean <- equal *render-from, *sandbox-count - break-unless reset-scroll? - *render-from <- copy -1 - } + next:address:shared:sandbox-data <- get *curr, next-sandbox:offset + *prev <- put *prev, next-sandbox:offset, next + env <- fixup-delete env, next return 1/true # force rerender } - prev <- get-address *curr, next-sandbox:offset + prev <- copy curr curr <- get *curr, next-sandbox:offset loop } return 0/false ] +def fixup-delete env:address:shared:programming-environment-data, next:address:shared:sandbox-data -> env:address:shared:programming-environment-data [ + local-scope + load-ingredients + # update sandbox count + sandbox-count:number <- get *env, number-of-sandboxes:offset + sandbox-count <- subtract sandbox-count, 1 + *env <- put *env, number-of-sandboxes:offset, sandbox-count + { + break-if next + # deleted sandbox was last + render-from:number <- get *env, render-from:offset + reset-scroll?:boolean <- equal render-from, sandbox-count + break-unless reset-scroll? + # deleted sandbox was only sandbox rendered, so reset scroll + *env <- put *env, render-from:offset, -1 + } +] + scenario deleting-sandbox-after-scroll [ trace-until 100/app # trace too long assume-screen 30/width, 10/height diff --git a/edit/008-sandbox-test.mu b/edit/008-sandbox-test.mu index 7d479375..c81099f9 100644 --- a/edit/008-sandbox-test.mu +++ b/edit/008-sandbox-test.mu @@ -99,8 +99,7 @@ before <end-save-sandbox> [ ] before <end-restore-sandbox> [ - expected-response:address:address:shared:array:character <- get-address **curr, expected-response:offset - *expected-response <- copy contents + *curr <- put *curr, expected-response:offset, contents ] # clicks on sandbox responses save it as 'expected' @@ -125,7 +124,7 @@ after <global-touch> [ save-sandboxes env hide-screen screen screen <- render-sandbox-side screen, env, 1/clear - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env # no change in cursor show-screen screen loop +next-event:label @@ -161,24 +160,25 @@ def find-click-in-sandbox-output env:address:shared:programming-environment-data def toggle-expected-response sandbox:address:shared:sandbox-data -> sandbox:address:shared:sandbox-data [ local-scope load-ingredients - expected-response:address:address:shared:array:character <- get-address *sandbox, expected-response:offset + expected-response:address:shared:array:character <- get *sandbox, expected-response:offset { # if expected-response is set, reset - break-unless *expected-response - *expected-response <- copy 0 - return sandbox/same-as-ingredient:0 + break-unless expected-response + *sandbox <- put *sandbox, expected-response:offset, 0 + } + { + # if not, set expected response to the current response + break-if expected-response + response:address:shared:array:character <- get *sandbox, response:offset + *sandbox <- put *sandbox, expected-response:offset, response } - # if not, current response is the expected response - response:address:shared:array:character <- get *sandbox, response:offset - *expected-response <- copy response ] # when rendering a sandbox, color it in red/green if expected response exists after <render-sandbox-response> [ { break-unless sandbox-response - response-starting-row:address:number <- get-address *sandbox, response-starting-row-on-screen:offset - *response-starting-row <- copy row + *sandbox <- put *sandbox, response-starting-row-on-screen:offset, row expected-response:address:shared:array:character <- get *sandbox, expected-response:offset break-unless expected-response # fall-through to print in grey response-is-expected?:boolean <- equal expected-response, sandbox-response @@ -195,6 +195,5 @@ after <render-sandbox-response> [ ] before <end-render-sandbox-reset-hidden> [ - tmp:address:number <- get-address *sandbox, response-starting-row-on-screen:offset - *tmp <- copy 0 + *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0 ] diff --git a/edit/009-sandbox-trace.mu b/edit/009-sandbox-trace.mu index 0ac17120..f7476ca8 100644 --- a/edit/009-sandbox-trace.mu +++ b/edit/009-sandbox-trace.mu @@ -131,10 +131,10 @@ def! update-sandbox sandbox:address:shared:sandbox-data, env:address:shared:prog local-scope load-ingredients data:address:shared:array:character <- get *sandbox, data:offset - response:address:address:shared:array:character <- get-address *sandbox, response:offset - trace:address:address:shared:array:character <- get-address *sandbox, trace:offset - fake-screen:address:address:shared:screen <- get-address *sandbox, screen:offset - *response, _, *fake-screen, *trace <- run-interactive data + response:address:shared:array:character, _, fake-screen:address:shared:screen, trace:address:shared:array:character <- run-interactive data + *sandbox <- put *sandbox, response:offset, response + *sandbox <- put *sandbox, screen:offset, fake-screen + *sandbox <- put *sandbox, trace:offset, trace ] # clicks on sandbox code toggle its display-trace? flag @@ -155,11 +155,12 @@ after <global-touch> [ sandbox:address:shared:sandbox-data <- find-click-in-sandbox-code env, click-row break-unless sandbox # toggle its display-trace? property - x:address:boolean <- get-address *sandbox, display-trace?:offset - *x <- not *x + x:boolean <- get *sandbox, display-trace?:offset + x <- not x + *sandbox <- put *sandbox, display-trace?:offset, x hide-screen screen screen <- render-sandbox-side screen, env, 1/clear - screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env # no change in cursor show-screen screen loop +next-event:label diff --git a/edit/010-errors.mu b/edit/010-errors.mu index 10ec43bd..494871e5 100644 --- a/edit/010-errors.mu +++ b/edit/010-errors.mu @@ -11,11 +11,11 @@ def! update-recipes env:address:shared:programming-environment-data, screen:addr recipes:address:shared:editor-data <- get *env, recipes:offset in:address:shared:array:character <- editor-contents recipes save [recipes.mu], in - recipe-errors:address:address:shared:array:character <- get-address *env, recipe-errors:offset - *recipe-errors <- reload in + recipe-errors:address:shared:array:character <- reload in + *env <- put *env, recipe-errors:offset, recipe-errors # if recipe editor has errors, stop { - break-unless *recipe-errors + break-unless recipe-errors update-status screen, [errors found ], 1/red errors-found? <- copy 1/true return @@ -45,18 +45,17 @@ container programming-environment-data [ ] after <programming-environment-initialization> [ - error-index:address:number <- get-address *result, error-index:offset - *error-index <- copy -1 + *result <- put *result, error-index:offset, -1 ] after <run-sandboxes-begin> [ - error-index:address:number <- get-address *env, error-index:offset - *error-index <- copy -1 + *env <- put *env, error-index:offset, -1 ] before <run-sandboxes-end> [ { - sandboxes-completed-successfully?:boolean <- equal *error-index, -1 + error-index:number <- get *env, error-index:offset + sandboxes-completed-successfully?:boolean <- equal error-index, -1 break-if sandboxes-completed-successfully? errors-found? <- copy 1/true } @@ -82,23 +81,24 @@ def! update-sandbox sandbox:address:shared:sandbox-data, env:address:shared:prog local-scope load-ingredients data:address:shared:array:character <- get *sandbox, data:offset - response:address:address:shared:array:character <- get-address *sandbox, response:offset - errors:address:address:shared:array:character <- get-address *sandbox, errors:offset - trace:address:address:shared:array:character <- get-address *sandbox, trace:offset - fake-screen:address:address:shared:screen <- get-address *sandbox, screen:offset - *response, *errors, *fake-screen, *trace, completed?:boolean <- run-interactive data + response:address:shared:array:character, errors:address:shared:array:character, fake-screen:address:shared:screen, trace:address:shared:array:character, completed?:boolean <- run-interactive data + *sandbox <- put *sandbox, response:offset, response + *sandbox <- put *sandbox, errors:offset, errors + *sandbox <- put *sandbox, screen:offset, fake-screen + *sandbox <- put *sandbox, trace:offset, trace { - break-if *errors + break-if errors break-if completed?:boolean - *errors <- new [took too long! + errors <- new [took too long! ] + *sandbox <- put *sandbox, errors:offset, errors } { - break-unless *errors - error-index:address:number <- get-address *env, error-index:offset - error-not-set?:boolean <- equal *error-index, -1 + break-unless errors + error-index:number <- get *env, error-index:offset + error-not-set?:boolean <- equal error-index, -1 break-unless error-not-set? - *error-index <- copy idx + *env <- put *env, error-index:offset, idx } ] @@ -107,8 +107,7 @@ after <render-sandbox-trace-done> [ { sandbox-errors:address:shared:array:character <- get *sandbox, errors:offset break-unless sandbox-errors - response-starting-row:address:number <- get-address *sandbox, response-starting-row-on-screen:offset - *response-starting-row <- copy 0 # no response + *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0 # no response row, screen <- render screen, sandbox-errors, left, right, 1/red, row # don't try to print anything more for this sandbox jump +render-sandbox-end:label diff --git a/edit/011-editor-undo.mu b/edit/011-editor-undo.mu index 3524840a..07ecb14f 100644 --- a/edit/011-editor-undo.mu +++ b/edit/011-editor-undo.mu @@ -65,12 +65,14 @@ after <handle-special-character> [ { undo?:boolean <- equal *c, 26/ctrl-z break-unless undo? - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset - break-unless *undo - op:address:shared:operation <- first *undo - *undo <- rest *undo - redo:address:address:shared:list:address:shared:operation <- get-address *editor, redo:offset - *redo <- push op, *redo + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset + break-unless undo + op:address:shared:operation <- first undo + undo <- rest undo + *editor <- put *editor, undo:offset, undo + redo:address:shared:list:address:shared:operation <- get *editor, redo:offset + redo <- push op, redo + *editor <- put *editor, redo:offset, redo <handle-undo> return screen/same-as-ingredient:0, editor/same-as-ingredient:1, 1/go-render } @@ -81,12 +83,14 @@ after <handle-special-character> [ { redo?:boolean <- equal *c, 25/ctrl-y break-unless redo? - redo:address:address:shared:list:address:shared:operation <- get-address *editor, redo:offset - break-unless *redo - op:address:shared:operation <- first *redo - *redo <- rest *redo - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset - *undo <- push op, *undo + redo:address:shared:list:address:shared:operation <- get *editor, redo:offset + break-unless redo + op:address:shared:operation <- first redo + redo <- rest redo + *editor <- put *editor, redo:offset, redo + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset + undo <- push op, undo + *editor <- put *editor, undo:offset, undo <handle-redo> return screen/same-as-ingredient:0, editor/same-as-ingredient:1, 1/go-render } @@ -136,52 +140,55 @@ scenario editor-can-undo-typing [ # save operation to undo after <insert-character-begin> [ top-before:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - cursor-before:address:shared:duplex-list:character <- copy *before-cursor + cursor-before:address:shared:duplex-list:character <- get *editor, before-cursor:offset ] before <insert-character-end> [ top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset { # if previous operation was an insert, coalesce this operation with it - break-unless *undo - op:address:shared:operation <- first *undo + break-unless undo + op:address:shared:operation <- first undo typing:address:insert-operation <- maybe-convert *op, typing:variant break-unless typing previous-coalesce-tag:number <- get *typing, tag:offset break-unless previous-coalesce-tag - insert-until:address:address:shared:duplex-list:character <- get-address *typing, insert-until:offset - *insert-until <- next *before-cursor - after-row:address:number <- get-address *typing, after-row:offset - *after-row <- copy *cursor-row - after-column:address:number <- get-address *typing, after-column:offset - *after-column <- copy *cursor-column - after-top:address:address:shared:duplex-list:character <- get-address *typing, after-top-of-screen:offset - *after-top <- get *editor, top-of-screen:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + insert-until:address:shared:duplex-list:character <- next before-cursor + *typing <- put *typing, insert-until:offset, insert-until + *typing <- put *typing, after-row:offset, cursor-row + *typing <- put *typing, after-column:offset, cursor-column + *typing <- put *typing, after-top-of-screen:offset, top-after break +done-adding-insert-operation:label } # if not, create a new operation insert-from:address:shared:duplex-list:character <- next cursor-before insert-to:address:shared:duplex-list:character <- next insert-from op:address:shared:operation <- new operation:type - *op <- merge 0/insert-operation, save-row/before, save-column/before, top-before, *cursor-row/after, *cursor-column/after, top-after, insert-from, insert-to, 1/coalesce + *op <- merge 0/insert-operation, save-row/before, save-column/before, top-before, cursor-row/after, cursor-column/after, top-after, insert-from, insert-to, 1/coalesce editor <- add-operation editor, op +done-adding-insert-operation ] # enter operations never coalesce with typing before or after after <insert-enter-begin> [ - cursor-row-before:number <- copy *cursor-row - cursor-column-before:number <- copy *cursor-column + cursor-row-before:number <- copy cursor-row + cursor-column-before:number <- copy cursor-column top-before:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - cursor-before:address:shared:duplex-list:character <- copy *before-cursor + cursor-before:address:shared:duplex-list:character <- get *editor, before-cursor:offset ] before <insert-enter-end> [ top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-row:offset # never coalesce insert-from:address:shared:duplex-list:character <- next cursor-before - insert-to:address:shared:duplex-list:character <- next *before-cursor + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + insert-to:address:shared:duplex-list:character <- next before-cursor op:address:shared:operation <- new operation:type - *op <- merge 0/insert-operation, cursor-row-before, cursor-column-before, top-before, *cursor-row/after, *cursor-column/after, top-after, insert-from, insert-to, 0/never-coalesce + *op <- merge 0/insert-operation, cursor-row-before, cursor-column-before, top-before, cursor-row/after, cursor-column/after, top-after, insert-from, insert-to, 0/never-coalesce editor <- add-operation editor, op ] @@ -192,10 +199,12 @@ before <insert-enter-end> [ def add-operation editor:address:shared:editor-data, op:address:shared:operation -> editor:address:shared:editor-data [ local-scope load-ingredients - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset - *undo <- push op *undo - redo:address:address:shared:list:address:shared:operation <- get-address *editor, redo:offset - *redo <- copy 0 + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset + undo <- push op undo + *editor <- put *editor, undo:offset, undo + redo:address:shared:list:address:shared:operation <- get *editor, redo:offset + redo <- copy 0 + *editor <- put *editor, redo:offset, redo return editor/same-as-ingredient:0 ] @@ -206,12 +215,15 @@ after <handle-undo> [ start:address:shared:duplex-list:character <- get *typing, insert-from:offset end:address:shared:duplex-list:character <- get *typing, insert-until:offset # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen - *before-cursor <- prev start - remove-between *before-cursor, end - *cursor-row <- get *typing, before-row:offset - *cursor-column <- get *typing, before-column:offset - top:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top <- get *typing, before-top-of-screen:offset + before-cursor:address:shared:duplex-list:character <- prev start + *editor <- put *editor, before-cursor:offset, before-cursor + remove-between before-cursor, end + cursor-row <- get *typing, before-row:offset + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- get *typing, before-column:offset + *editor <- put *editor, cursor-column:offset, cursor-column + top:address:shared:duplex-list:character <- get *typing, before-top-of-screen:offset + *editor <- put *editor, top-of-screen:offset, top } ] @@ -400,14 +412,17 @@ after <handle-redo> [ { typing:address:insert-operation <- maybe-convert *op, typing:variant break-unless typing + before-cursor <- get *editor, before-cursor:offset insert-from:address:shared:duplex-list:character <- get *typing, insert-from:offset # ignore insert-to because it's already been spliced away - # assert insert-to matches next(*before-cursor) - insert-range *before-cursor, insert-from + # assert insert-to matches next(before-cursor) + insert-range before-cursor, insert-from # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen - *cursor-row <- get *typing, after-row:offset - *cursor-column <- get *typing, after-column:offset - top:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top <- get *typing, after-top-of-screen:offset + cursor-row <- get *typing, after-row:offset + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- get *typing, after-column:offset + *editor <- put *editor, cursor-column:offset, cursor-column + top:address:shared:duplex-list:character <- get *typing, after-top-of-screen:offset + *editor <- put *editor, top-of-screen:offset, top } ] @@ -700,36 +715,33 @@ ghi] ] after <move-cursor-begin> [ - before-cursor-row:number <- get *editor, cursor-row:offset - before-cursor-column:number <- get *editor, cursor-column:offset - before-top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + cursor-row-before:number <- get *editor, cursor-row:offset + cursor-column-before:number <- get *editor, cursor-column:offset + top-before:address:shared:duplex-list:character <- get *editor, top-of-screen:offset ] before <move-cursor-end> [ - after-cursor-row:number <- get *editor, cursor-row:offset - after-cursor-column:number <- get *editor, cursor-column:offset - after-top-of-screen:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset { break-unless undo-coalesce-tag # if previous operation was also a move, and also had the same coalesce # tag, coalesce with it - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset - break-unless *undo - op:address:shared:operation <- first *undo + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset + break-unless undo + op:address:shared:operation <- first undo move:address:move-operation <- maybe-convert *op, move:variant break-unless move previous-coalesce-tag:number <- get *move, tag:offset coalesce?:boolean <- equal undo-coalesce-tag, previous-coalesce-tag break-unless coalesce? - after-row:address:number <- get-address *move, after-row:offset - *after-row <- copy after-cursor-row - after-column:address:number <- get-address *move, after-column:offset - *after-column <- copy after-cursor-column - after-top:address:address:shared:duplex-list:character <- get-address *move, after-top-of-screen:offset - *after-top <- get *editor, top-of-screen:offset + *move <- put *move, after-row:offset, cursor-row + *move <- put *move, after-column:offset, cursor-column + *move <- put *move, after-top-of-screen:offset, top-after break +done-adding-move-operation:label } op:address:shared:operation <- new operation:type - *op <- merge 1/move-operation, before-cursor-row, before-cursor-column, before-top-of-screen, after-cursor-row, after-cursor-column, after-top-of-screen, undo-coalesce-tag + *op <- merge 1/move-operation, cursor-row-before, cursor-column-before, top-before, cursor-row/after, cursor-column/after, top-after, undo-coalesce-tag editor <- add-operation editor, op +done-adding-move-operation ] @@ -739,10 +751,12 @@ after <handle-undo> [ move:address:move-operation <- maybe-convert *op, move:variant break-unless move # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen - *cursor-row <- get *move, before-row:offset - *cursor-column <- get *move, before-column:offset - top:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top <- get *move, before-top-of-screen:offset + cursor-row <- get *move, before-row:offset + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- get *move, before-column:offset + *editor <- put *editor, cursor-column:offset, cursor-column + top:address:shared:duplex-list:character <- get *move, before-top-of-screen:offset + *editor <- put *editor, top-of-screen:offset, top } ] @@ -1367,10 +1381,12 @@ after <handle-redo> [ move:address:move-operation <- maybe-convert *op, move:variant break-unless move # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen - *cursor-row <- get *move, after-row:offset - *cursor-column <- get *move, after-column:offset - top:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top <- get *move, after-top-of-screen:offset + cursor-row <- get *move, after-row:offset + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- get *move, after-column:offset + *editor <- put *editor, cursor-column:offset, cursor-column + top:address:shared:duplex-list:character <- get *move, after-top-of-screen:offset + *editor <- put *editor, top-of-screen:offset, top } ] @@ -1596,33 +1612,32 @@ before <backspace-character-end> [ { break-unless backspaced-cell # backspace failed; don't add an undo operation top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-row:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset { # if previous operation was an insert, coalesce this operation with it break-unless *undo - op:address:shared:operation <- first *undo + op:address:shared:operation <- first undo deletion:address:delete-operation <- maybe-convert *op, delete:variant break-unless deletion previous-coalesce-tag:number <- get *deletion, tag:offset coalesce?:boolean <- equal previous-coalesce-tag, 1/coalesce-backspace break-unless coalesce? - delete-from:address:address:shared:duplex-list:character <- get-address *deletion, delete-from:offset - *delete-from <- copy *before-cursor - backspaced-so-far:address:address:shared:duplex-list:character <- get-address *deletion, deleted-text:offset - insert-range backspaced-cell, *backspaced-so-far - *backspaced-so-far <- copy backspaced-cell - after-row:address:number <- get-address *deletion, after-row:offset - *after-row <- copy *cursor-row - after-column:address:number <- get-address *deletion, after-column:offset - *after-column <- copy *cursor-column - after-top:address:address:shared:duplex-list:character <- get-address *deletion, after-top-of-screen:offset - *after-top <- get *editor, top-of-screen:offset + *deletion <- put *deletion, delete-from:offset, before-cursor + backspaced-so-far:address:shared:duplex-list:character <- get *deletion, deleted-text:offset + insert-range backspaced-cell, backspaced-so-far + *deletion <- put *deletion, deleted-text:offset, backspaced-cell + *deletion <- put *deletion, after-row:offset, cursor-row + *deletion <- put *deletion, after-column:offset, cursor-column + *deletion <- put *deletion, after-top-of-screen:offset, top-after break +done-adding-backspace-operation:label } # if not, create a new operation op:address:shared:operation <- new operation:type - deleted-until:address:shared:duplex-list:character <- next *before-cursor - *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, *cursor-row/after, *cursor-column/after, top-after, backspaced-cell/deleted, *before-cursor/delete-from, deleted-until, 1/coalesce-backspace + deleted-until:address:shared:duplex-list:character <- next before-cursor + *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, cursor-row/after, cursor-column/after, top-after, backspaced-cell/deleted, before-cursor/delete-from, deleted-until, 1/coalesce-backspace editor <- add-operation editor, op +done-adding-backspace-operation } @@ -1632,18 +1647,19 @@ after <handle-undo> [ { deletion:address:delete-operation <- maybe-convert *op, delete:variant break-unless deletion - start2:address:address:shared:duplex-list:character <- get-address *editor, data:offset anchor:address:shared:duplex-list:character <- get *deletion, delete-from:offset break-unless anchor deleted:address:shared:duplex-list:character <- get *deletion, deleted-text:offset old-cursor:address:shared:duplex-list:character <- last deleted insert-range anchor, deleted # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen - *before-cursor <- copy old-cursor - *cursor-row <- get *deletion, before-row:offset - *cursor-column <- get *deletion, before-column:offset - top:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top <- get *deletion, before-top-of-screen:offset + before-cursor <- copy old-cursor + cursor-row <- get *deletion, before-row:offset + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- get *deletion, before-column:offset + *editor <- put *editor, cursor-column:offset, cursor-column + top:address:shared:duplex-list:character <- get *deletion, before-top-of-screen:offset + *editor <- put *editor, top-of-screen:offset, top } ] @@ -1653,12 +1669,15 @@ after <handle-redo> [ break-unless deletion start:address:shared:duplex-list:character <- get *deletion, delete-from:offset end:address:shared:duplex-list:character <- get *deletion, delete-until:offset + data:address:shared:duplex-list:character <- get *editor, data:offset remove-between start, end # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen - *cursor-row <- get *deletion, after-row:offset - *cursor-column <- get *deletion, after-column:offset - top:address:address:shared:duplex-list:character <- get-address *editor, top-of-screen:offset - *top <- get *deletion, after-top-of-screen:offset + cursor-row <- get *deletion, after-row:offset + *editor <- put *editor, cursor-row:offset, cursor-row + cursor-column <- get *deletion, after-column:offset + *editor <- put *editor, cursor-column:offset, cursor-column + top:address:shared:duplex-list:character <- get *deletion, before-top-of-screen:offset + *editor <- put *editor, top-of-screen:offset, top } ] @@ -1818,32 +1837,33 @@ before <delete-character-end> [ { break-unless deleted-cell # delete failed; don't add an undo operation top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + undo:address:shared:list:address:shared:operation <- get *editor, undo:offset { # if previous operation was an insert, coalesce this operation with it - break-unless *undo - op:address:shared:operation <- first *undo + break-unless undo + op:address:shared:operation <- first undo deletion:address:delete-operation <- maybe-convert *op, delete:variant break-unless deletion previous-coalesce-tag:number <- get *deletion, tag:offset coalesce?:boolean <- equal previous-coalesce-tag, 2/coalesce-delete break-unless coalesce? - delete-until:address:address:shared:duplex-list:character <- get-address *deletion, delete-until:offset - *delete-until <- next *before-cursor - deleted-so-far:address:address:shared:duplex-list:character <- get-address *deletion, deleted-text:offset - *deleted-so-far <- append *deleted-so-far, deleted-cell - after-row:address:number <- get-address *deletion, after-row:offset - *after-row <- copy *cursor-row - after-column:address:number <- get-address *deletion, after-column:offset - *after-column <- copy *cursor-column - after-top:address:address:shared:duplex-list:character <- get-address *deletion, after-top-of-screen:offset - *after-top <- get *editor, top-of-screen:offset + delete-until:address:shared:duplex-list:character <- next before-cursor + *deletion <- put *deletion, delete-until:offset, delete-until + deleted-so-far:address:shared:duplex-list:character <- get *deletion, deleted-text:offset + deleted-so-far <- append deleted-so-far, deleted-cell + *deletion <- put *deletion, deleted-text:offset, deleted-so-far + *deletion <- put *deletion, after-row:offset, cursor-row + *deletion <- put *deletion, after-column:offset, cursor-column + *deletion <- put *deletion, after-top-of-screen:offset, top-after break +done-adding-delete-operation:label } # if not, create a new operation op:address:shared:operation <- new operation:type - deleted-until:address:shared:duplex-list:character <- next *before-cursor - *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, *cursor-row/after, *cursor-column/after, top-after, deleted-cell/deleted, *before-cursor/delete-from, deleted-until, 2/coalesce-delete + deleted-until:address:shared:duplex-list:character <- next before-cursor + *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, cursor-row/after, cursor-column/after, top-after, deleted-cell/deleted, before-cursor/delete-from, deleted-until, 2/coalesce-delete editor <- add-operation editor, op +done-adding-delete-operation } @@ -1941,10 +1961,11 @@ before <delete-to-end-of-line-end> [ { break-unless deleted-cells # delete failed; don't add an undo operation top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + deleted-until:address:shared:duplex-list:character <- next before-cursor op:address:shared:operation <- new operation:type - deleted-until:address:shared:duplex-list:character <- next *before-cursor - *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, *cursor-row/after, *cursor-column/after, top-after, deleted-cells/deleted, *before-cursor/delete-from, deleted-until, 0/never-coalesce + *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, cursor-row/after, cursor-column/after, top-after, deleted-cells/deleted, before-cursor/delete-from, deleted-until, 0/never-coalesce editor <- add-operation editor, op +done-adding-delete-operation } @@ -2042,10 +2063,12 @@ before <delete-to-start-of-line-end> [ { break-unless deleted-cells # delete failed; don't add an undo operation top-after:address:shared:duplex-list:character <- get *editor, top-of-screen:offset - undo:address:address:shared:list:address:shared:operation <- get-address *editor, undo:offset op:address:shared:operation <- new operation:type - deleted-until:address:shared:duplex-list:character <- next *before-cursor - *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, *cursor-row/after, *cursor-column/after, top-after, deleted-cells/deleted, *before-cursor/delete-from, deleted-until, 0/never-coalesce + before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset + deleted-until:address:shared:duplex-list:character <- next before-cursor + cursor-row:number <- get *editor, cursor-row:offset + cursor-column:number <- get *editor, cursor-column:offset + *op <- merge 2/delete-operation, save-row/before, save-column/before, top-before, cursor-row/after, cursor-column/after, top-after, deleted-cells/deleted, before-cursor/delete-from, deleted-until, 0/never-coalesce editor <- add-operation editor, op +done-adding-delete-operation } |