about summary refs log tree commit diff stats
path: root/edit.mu
diff options
context:
space:
mode:
Diffstat (limited to 'edit.mu')
-rw-r--r--edit.mu355
1 files changed, 147 insertions, 208 deletions
diff --git a/edit.mu b/edit.mu
index 5828ebdc..4bbf47b5 100644
--- a/edit.mu
+++ b/edit.mu
@@ -3,52 +3,13 @@
 recipe main [
   local-scope
   open-console
-  initial-recipe:address:array:character <- new [ 
-# return true if a list of numbers contains the pattern 1, 5, 3
-recipe check [
-  default-space:address:array:location <- new location:type, 30:literal
-  state:number <- copy 0:literal
-  {
-    +next-number
-    curr:number, found?:boolean <- next-ingredient
-    break-unless found?:boolean
-    # if curr is 1, state = 1
-    {
-      state1:boolean <- equal curr:number, 1:literal
-      break-unless state1:boolean
-      state:number <- copy 1:literal
-      loop +next-number:label
-    }
-    # if state is 1 and curr is 5, state = 2
-    {
-      state-is-1?:boolean <- equal state:number, 1:literal
-      break-unless state-is-1?:boolean
-      state2:boolean <- equal curr:number, 5:literal
-      break-unless state2:boolean
-      state:number <- copy 2:literal
-      loop +next-number:label
-    }
-    # if state is 2 and curr is 3, return true
-    {
-      state-is-2?:boolean <- equal state:number, 2:literal
-      break-unless state-is-2?:boolean
-      state3:boolean <- equal curr:number, 3:literal
-      break-unless state3:boolean
-      reply 1:literal/found
-    }
-    # otherwise reset state
-    #state:number <- copy 0:literal
-    loop
-  }
-  reply 0:literal/not-found
+  initial-recipe:address:array:character <- new [recipe new-add [
+  x:number <- next-ingredient
+  y:number <- next-ingredient
+  z:number <- add x:number, y:number
+  reply z:number
 ]]
-#?   initial-recipe:address:array:character <- new [recipe new-add [
-#?   x:number <- next-ingredient
-#?   y:number <- next-ingredient
-#?   z:number <- add x:number, y:number
-#?   reply z:number
-#? ]]
-  initial-sandbox:address:array:character <- new []
+  initial-sandbox:address:array:character <- new [print-character screen:address, 97]
   env:address:programming-environment-data <- new-programming-environment 0:literal/screen, initial-recipe:address:array:character, initial-sandbox:address:array:character
   event-loop 0:literal/screen, 0:literal/console, env:address:programming-environment-data
 ]
@@ -302,6 +263,7 @@ recipe render [
 ]
 
 # row:number, screen:address <- render-string screen:address, s:address:array:character, left:number, right:number, color:number, row:number
+# move cursor at start of next line
 # print a string 's' to 'editor' in 'color' starting at 'row'
 # leave cursor at start of next line
 recipe render-string [
@@ -370,6 +332,76 @@ recipe render-string [
   reply row:number/same-as-ingredient:5, screen:address/same-as-ingredient:0
 ]
 
+# row:number, screen:address <- render-screen screen:address, sandbox-screen:address:screen, left:number, right:number, row:number
+# print the fake sandbox screen to 'screen' with appropriate delimiters
+# leave cursor at start of next line
+recipe render-screen [
+  local-scope
+  screen:address <- next-ingredient
+  s:address:screen <- next-ingredient
+  left:number <- next-ingredient
+  right:number <- next-ingredient
+  row:number <- next-ingredient
+  row:number <- add row:number, 1:literal
+  reply-unless s:address:screen, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0
+#?   $start-tracing #? 1
+  # print 'screen:'
+  column:number <- copy left:number
+  move-cursor screen:address, row:number, column:number
+  screen-height:number <- screen-height screen:address
+  header:address:array:character <- new [screen:]
+  row:number <- subtract row:number, 1:literal  # compensate for render-string below
+  row:number <- render-string screen:address, header:address:array:character, left:number, right:number, 245:literal/grey, row:number
+  # start printing s
+  column:number <- copy left:number
+  move-cursor screen:address, row:number, column:number
+  s-width:number <- screen-width s:address:screen
+  s-height:number <- screen-height s:address:screen
+  buf:address:array:screen-cell <- get s:address:screen/deref, data:offset
+  stop-printing:number <- add s-width:number, 3:literal
+#?   stop-printing:number <- add left:number, s-width:number, 3:literal
+  max-column:number <- min stop-printing:number, right:number
+  i:number <- copy 0:literal
+  len:number <- length buf:address:array:screen-cell/deref
+  {
+    done?:boolean <- greater-or-equal i:number, len:number
+    break-if done?:boolean
+    done?:boolean <- greater-or-equal row:number, screen-height:number
+    break-if done?:boolean
+    column:number <- copy left:number
+    move-cursor screen:address, row:number, column:number
+    # initial leader for each row: two spaces and a '.'
+    print-character screen:address, 32:literal/space, 245:literal/grey
+    print-character screen:address, 32:literal/space, 245:literal/grey
+    print-character screen:address, 46:literal/full-stop, 245:literal/grey
+    column:number <- add left:number, 3:literal
+    {
+      # print row
+      row-done?:boolean <- greater-than column:number, max-column:number
+      break-if row-done?:boolean
+      curr:screen-cell <- index buf:address:array:screen-cell/deref, i:number
+      print-character screen:address, 32:literal/space
+      column:number <- add column:number, 1:literal
+      i:number <- add i:number, 1:literal
+      loop
+    }
+    # print final '.'
+    print-character screen:address, 46:literal/full-stop, 245:literal/grey
+    column:number <- add column:number, 1:literal
+    {
+      # clear rest of current line
+      line-done?:boolean <- greater-than column:number, right:number
+      break-if line-done?:boolean
+      print-character screen:address, 32:literal/space
+      column:number <- add column:number, 1:literal
+      loop
+    }
+    row:number <- add row:number, 1:literal
+    loop
+  }
+  reply row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0
+]
+
 recipe clear-line-delimited [
   local-scope
   screen:address <- next-ingredient
@@ -522,19 +554,10 @@ recipe event-loop [
         loop +next-event:label
       }
     }
-    # 'touch' event
+    # 'touch' event - send to both editors
     {
       t:address:touch-event <- maybe-convert e:event, touch:variant
       break-unless t:address:touch-event
-      # on a sandbox delete icon? process delete
-      {
-        was-delete?:boolean <- delete-sandbox t:address:touch-event/deref, env:address:programming-environment-data
-        break-unless was-delete?:boolean
-        screen:address <- render-sandbox-side screen:address, env:address:programming-environment-data, 1:literal/clear
-        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/deref
-        loop +next-event:label
-      }
-      # if not, send to both editors
       _ <- move-cursor-in-editor screen:address, recipes:address:editor-data, t:address:touch-event/deref
       sandbox-in-focus?:address:boolean/deref <- move-cursor-in-editor screen:address, current-sandbox:address:editor-data, t:address:touch-event/deref
       jump +continue:label
@@ -1063,7 +1086,6 @@ recipe render-sandbox-side [
   local-scope
   screen:address <- next-ingredient
   env:address:programming-environment-data <- next-ingredient
-  clear:boolean <- next-ingredient
   current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
   left:number <- get current-sandbox:address:editor-data/deref, left:offset
   right:number <- get current-sandbox:address:editor-data/deref, right:offset
@@ -1076,62 +1098,61 @@ recipe render-sandbox-side [
   row:number <- add row:number, 1:literal
   move-cursor screen:address, row:number, left:number
   clear-line-delimited screen:address, left:number, right:number
-  reply-unless clear:boolean, screen:address/same-as-ingredient:0
-  screen-height:number <- screen-height screen:address
-  {
-    at-bottom-of-screen?:boolean <- greater-or-equal row:number, screen-height:number
-    break-if at-bottom-of-screen?:boolean
-    move-cursor screen:address, row:number, left:number
-    clear-line-delimited screen:address, left:number, right:number
-    row:number <- add row:number, 1:literal
-    loop
-  }
   reply screen:address/same-as-ingredient:0
 ]
 
 recipe render-sandboxes [
   local-scope
-  screen:address <- next-ingredient
+  screen:address:screen <- next-ingredient
   sandbox:address:sandbox-data <- next-ingredient
   left:number <- next-ingredient
   right:number <- next-ingredient
   row:number <- next-ingredient
-  reply-unless sandbox:address:sandbox-data, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0
-  screen-height:number <- screen-width screen:address
+  reply-unless sandbox:address:sandbox-data, row:number/same-as-ingredient:4, screen:address:screen/same-as-ingredient:0
+  screen-height:number <- screen-height screen:address:screen
   at-bottom?:boolean <- greater-or-equal row:number screen-height:number
-  reply-if at-bottom?:boolean, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0
-#?   $print [rendering sandbox ], sandbox:address:sandbox-data, [ 
-#? ] #? 1
-  # render sandbox menu
-  row:number <- add row:number, 1:literal
-  move-cursor screen:address, row:number, left:number
-  clear-line-delimited screen:address, left:number, right:number
-  print-character screen:address, 120:literal/x, 245:literal/grey
-  # save menu row so we can detect clicks to it later
-  starting-row:address:number <- get-address sandbox:address:sandbox-data/deref, starting-row-on-screen:offset
-  starting-row:address:number/deref <- copy row:number
+  reply-if at-bottom?:boolean, row:number/same-as-ingredient:4, screen:address:screen/same-as-ingredient:0
   # render sandbox contents
   sandbox-data:address:array:character <- get sandbox:address:sandbox-data/deref, data:offset
-  row:number, screen:address <- render-string screen:address, sandbox-data:address:array:character, left:number, right:number, 7:literal/white, row:number
+  row:number, screen:address:screen <- render-string screen:address:screen, sandbox-data:address:array:character, left:number, right:number, 7:literal/white, row:number
   # render sandbox warnings or response, in that order
   sandbox-response:address:array:character <- get sandbox:address:sandbox-data/deref, response:offset
   sandbox-warnings:address:array:character <- get sandbox:address:sandbox-data/deref, warnings:offset
+  sandbox-screen:address:screen <- get sandbox:address:sandbox-data/deref, screen:offset
   {
     break-unless sandbox-warnings:address:array:character
-    row:number, screen:address <- render-string screen:address, sandbox-warnings:address:array:character, left:number, right:number, 1:literal/red, row:number
+    row:number, screen:address:screen <- render-string screen:address:screen, sandbox-warnings:address:array:character, left:number, right:number, 1:literal/red, row:number
   }
   {
     break-if sandbox-warnings:address:array:character
-    row:number, screen:address <- render-string screen:address, sandbox-response:address:array:character, left:number, right:number, 245:literal/grey, row:number
+    row:number, screen:address:screen <- render-string screen:address:screen, sandbox-response:address:array:character, left:number, right:number, 245:literal/grey, row:number
   }
+  # render sandbox screen if necessary
+  at-bottom?:boolean <- greater-or-equal row:number screen-height:number
+  reply-if at-bottom?:boolean, row:number/same-as-ingredient:4, screen:address:screen/same-as-ingredient:0
+  {
+    empty-screen?:boolean <- fake-screen-is-clear? sandbox-screen:address:screen
+    break-if empty-screen?:boolean
+    row:number, screen:address:screen <- render-screen screen:address:screen, sandbox-screen:address:screen, left:number, right:number, row:number
+  }
+  at-bottom?:boolean <- greater-or-equal row:number screen-height:number
+  reply-if at-bottom?:boolean, row:number/same-as-ingredient:4, screen:address:screen/same-as-ingredient:0
   # draw solid line after sandbox
-  draw-horizontal screen:address, row:number, left:number, right:number, 9473:literal/horizontal-double
+#?   $print [aaa ]
+#?   $dump screen:address:screen
+#?   $dump right:number
+#?   $foo screen:address:screen
+#?   xxx:address:array:screen-cell <- get screen:address:screen/deref, data:offset
+#?   $dump xxx:address:array:screen-cell
+#?   yyy:number <- length xxx:address:array:screen-cell/deref
+#?   $dump yyy:number
+  draw-horizontal screen:address:screen, row:number, left:number, right:number, 9473:literal/horizontal-double
+#?   $print [zzz ]
+#?   $dump screen:address:screen
   # draw next sandbox
   next-sandbox:address:sandbox-data <- get sandbox:address:sandbox-data/deref, next-sandbox:offset
-#?   $print [next sandbox is ], next-sandbox:address:sandbox-data, [ 
-#? ] #? 1
-  row:number, screen:address <- render-sandboxes screen:address, next-sandbox:address:sandbox-data, left:number, right:number, row:number
-  reply row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0
+  row:number, screen:address:screen <- render-sandboxes screen:address:screen, next-sandbox:address:sandbox-data, left:number, right:number, row:number
+  reply row:number/same-as-ingredient:4, screen:address:screen/same-as-ingredient:0
 ]
 
 recipe update-cursor [
@@ -2542,13 +2563,13 @@ container sandbox-data [
   data:address:array:character
   response:address:array:character
   warnings:address:array:character
-  starting-row-on-screen:number  # to track clicks on delete
+  screen:address:screen
   next-sandbox:address:sandbox-data
 ]
 
 scenario run-and-show-results [
   $close-trace  # trace too long for github
-  assume-screen 100:literal/width, 15:literal/height
+  assume-screen 100:literal/width, 12:literal/height
   # recipe editor is empty
   1:address:array:character <- new []
   # sandbox editor contains an instruction without storing outputs
@@ -2566,7 +2587,6 @@ scenario run-and-show-results [
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊divide-with-remainder 11:literal, 3:literal      .
     .                                                  ┊3                                                .
     .                                                  ┊2                                                .
@@ -2577,7 +2597,6 @@ scenario run-and-show-results [
     .                                                                                                    .
     .                                                                                                    .
     .                                                                                                    .
-    .                                                                                                    .
     .                                                   divide-with-remainder 11:literal, 3:literal      .
     .                                                                                                    .
     .                                                                                                    .
@@ -2588,7 +2607,6 @@ scenario run-and-show-results [
     .                                                                                                    .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊                                                 .
     .                                                  ┊3                                                .
     .                                                  ┊2                                                .
@@ -2609,11 +2627,9 @@ scenario run-and-show-results [
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊add 2:literal, 2:literal                         .
     .                                                  ┊4                                                .
     .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊divide-with-remainder 11:literal, 3:literal      .
     .                                                  ┊3                                                .
     .                                                  ┊2                                                .
@@ -2648,14 +2664,15 @@ recipe run-sandboxes [
     init:address:address:duplex-list <- get-address current-sandbox:address:editor-data/deref, data:offset
     init:address:address:duplex-list/deref <- push-duplex 167:literal/§, 0:literal/tail
   }
-  # rerun other sandboxes
+  # run all sandboxes
   curr:address:sandbox-data <- get env:address:programming-environment-data/deref, sandbox:offset
   {
     break-unless curr:address:sandbox-data
     data:address:address:array:character <- get-address curr:address:sandbox-data/deref, data:offset
     response:address:address:array:character <- get-address curr:address:sandbox-data/deref, response:offset
     warnings:address:address:array:character <- get-address curr:address:sandbox-data/deref, warnings:offset
-    response:address:address:array:character/deref, warnings:address:address:array:character/deref <- run-interactive data:address:address:array:character/deref
+    fake-screen:address:address:screen <- get-address curr:address:sandbox-data/deref, screen:offset
+    response:address:address:array:character/deref, warnings:address:address:array:character/deref, fake-screen:address:address:screen/deref <- run-interactive data:address:address:array:character/deref
 #?     $print warnings:address:address:array:character/deref, [ ], warnings:address:address:array:character/deref/deref, [ 
 #? ] #? 1
     curr:address:sandbox-data <- get curr:address:sandbox-data/deref, next-sandbox:offset
@@ -2663,55 +2680,6 @@ recipe run-sandboxes [
   }
 ]
 
-# was-deleted?:boolean <- delete-sandbox t:touch-event, env:address:programming-environment-data
-recipe delete-sandbox [
-  local-scope
-  t:touch-event <- next-ingredient
-  env:address:programming-environment-data <- next-ingredient
-  click-column:number <- get t:touch-event, column:offset
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
-  right:number <- get current-sandbox:address:editor-data/deref, right:offset
-#?   $print [comparing column ], click-column:number, [ vs ], right:number, [ 
-#? ] #? 1
-  at-right?:boolean <- equal click-column:number, right:number
-  reply-unless at-right?:boolean, 0:literal/false
-#?   $print [trying to delete
-#? ] #? 1
-  click-row:number <- get t:touch-event, row:offset
-  prev:address:address:sandbox-data <- get-address env:address:programming-environment-data/deref, sandbox:offset
-#?   $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, [ 
-#? ] #? 1
-  curr:address:sandbox-data <- get env:address:programming-environment-data/deref, sandbox:offset
-  {
-#?     $print [next sandbox
-#? ] #? 1
-    break-unless curr:address:sandbox-data
-    # more sandboxes to check
-    {
-#?       $print [checking
-#? ] #? 1
-      target-row:number <- get curr:address:sandbox-data/deref, starting-row-on-screen:offset
-#?       $print [comparing row ], target-row:number, [ vs ], click-row:number, [ 
-#? ] #? 1
-      delete-curr?:boolean <- equal target-row:number, click-row:number
-      break-unless delete-curr?:boolean
-#?       $print [found!
-#? ] #? 1
-      # delete this sandbox, rerender and stop
-      prev:address:address:sandbox-data/deref <- get curr:address:sandbox-data/deref, next-sandbox:offset
-#?       $print [setting prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, [ 
-#? ] #? 1
-      reply 1:literal/true
-    }
-    prev:address:address:sandbox-data <- get-address curr:address:sandbox-data/deref, next-sandbox:offset
-#?     $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, [ 
-#? ] #? 1
-    curr:address:sandbox-data <- get curr:address:sandbox-data/deref, next-sandbox:offset
-    loop
-  }
-  reply 0:literal/false
-]
-
 scenario run-updates-results [
   $close-trace  # trace too long for github
   assume-screen 100:literal/width, 12:literal/height
@@ -2735,10 +2703,9 @@ z:number <- add 2:literal, 2:literal
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .recipe foo [                                      ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .z:number <- add 2:literal, 2:literal              ┊                                                x.
-    .]                                                 ┊foo                                              .
-    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4                                                .
-    .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
+    .z:number <- add 2:literal, 2:literal              ┊foo                                              .
+    .]                                                 ┊4                                                .
+    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
     .                                                  ┊                                                 .
   ]
   # make a change (incrementing one of the args to 'add'), then rerun
@@ -2757,10 +2724,9 @@ z:number <- add 2:literal, 2:literal
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .recipe foo [                                      ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .z:number <- add 2:literal, 3:literal              ┊                                                x.
-    .]                                                 ┊foo                                              .
-    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊5                                                .
-    .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
+    .z:number <- add 2:literal, 3:literal              ┊foo                                              .
+    .]                                                 ┊5                                                .
+    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
     .                                                  ┊                                                 .
   ]
 ]
@@ -2785,7 +2751,6 @@ scenario run-instruction-and-print-warnings [
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊get 1234:number, foo:offset                      .
     .                                                  ┊unknown element foo in container number          .
     .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
@@ -2795,7 +2760,6 @@ scenario run-instruction-and-print-warnings [
     .                                                                                                    .
     .                                                                                                    .
     .                                                                                                    .
-    .                                                                                                    .
     .                                                   get 1234:number, foo:offset                      .
     .                                                                                                    .
     .                                                                                                    .
@@ -2806,7 +2770,6 @@ scenario run-instruction-and-print-warnings [
     .                                                                                                    .
     .                                                                                                    .
     .                                                                                                    .
-    .                                                                                                    .
     .                                                   unknown element foo in container number          .
     .                                                                                                    .
   ]
@@ -2814,7 +2777,6 @@ scenario run-instruction-and-print-warnings [
     .                                                                                                    .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊                                                 .
     .                                                  ┊                                                 .
     .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
@@ -2843,7 +2805,6 @@ scenario run-instruction-and-print-warnings-only-once [
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
     .                                                  ┊get 1234:number, foo:offset                      .
     .                                                  ┊unknown element foo in container number          .
     .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
@@ -2851,69 +2812,37 @@ scenario run-instruction-and-print-warnings-only-once [
   ]
 ]
 
-scenario deleting-sandboxes [
-  $close-trace  # trace too long for github
-  assume-screen 100:literal/width, 15:literal/height
+scenario run-instruction-manages-screen-per-sandbox [
+  $close-trace  # trace too long for github #? 1
+  assume-screen 100:literal/width, 20:literal/height
+  # left editor is empty
   1:address:array:character <- new []
-  2:address:array:character <- new []
+  # right editor contains an illegal instruction
+  2:address:array:character <- new [print-integer screen:address, 4]
   3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character
-  # run a few commands
+  # run the code in the editor
   assume-console [
-    left-click 1, 80
-    type [divide-with-remainder 11:literal, 3:literal]
-    press 65526  # F10
-    type [add 2:literal, 2:literal]
     press 65526  # F10
   ]
   run [
     event-loop screen:address, console:address, 3:address:programming-environment-data
   ]
+  # check that it prints a little 5x5 toy screen
+  # hack: screen address is brittle
   screen-should-contain [
     .                                                                                 run (F10)          .
     .                                                  ┊                                                 .
     .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
-    .                                                  ┊add 2:literal, 2:literal                         .
-    .                                                  ┊4                                                .
-    .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
-    .                                                  ┊divide-with-remainder 11:literal, 3:literal      .
-    .                                                  ┊3                                                .
-    .                                                  ┊2                                                .
-    .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                 .
-  ]
-  # delete second sandbox
-  assume-console [
-    left-click 7, 99
-  ]
-  run [
-    event-loop screen:address, console:address, 3:address:programming-environment-data
-  ]
-  screen-should-contain [
-    .                                                                                 run (F10)          .
-    .                                                  ┊                                                 .
-    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                x.
-    .                                                  ┊add 2:literal, 2:literal                         .
-    .                                                  ┊4                                                .
+    .                                                  ┊print-integer screen:address, 4                  .
+    .                                                  ┊5557                                             .
+    .                                                  ┊screen:                                          .
+    .                                                  ┊  .4    .                                        .
+    .                                                  ┊  .     .                                        .
+    .                                                  ┊  .     .                                        .
+    .                                                  ┊  .     .                                        .
+    .                                                  ┊  .     .                                        .
     .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
     .                                                  ┊                                                 .
-    .                                                  ┊                                                 .
-  ]
-  # delete first sandbox
-  assume-console [
-    left-click 3, 99
-  ]
-  run [
-    event-loop screen:address, console:address, 3:address:programming-environment-data
-  ]
-  screen-should-contain [
-    .                                                                                 run (F10)          .
-    .                                                  ┊                                                 .
-    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
-    .                                                  ┊                                                 .
-    .                                                  ┊                                                 .
   ]
 ]
 
@@ -3007,12 +2936,22 @@ recipe draw-horizontal [
     break-if bg-color-found?:boolean
     bg-color:number <- copy 0:literal/black
   }
+#?   $print [bbb ], 5155:number/raw, [  #? 1
+#? ] #? 1
   move-cursor screen:address, row:number, x:number
   {
+#?   $print [ccc ], 5155:number/raw, [  #? 1
+#? ] #? 1
     continue?:boolean <- lesser-or-equal x:number, right:number  # right is inclusive, to match editor-data semantics
     break-unless continue?:boolean
+#?   $print [ddd ], 5155:number/raw, [  #? 1
+#? ] #? 1
     print-character screen:address, style:character, color:number, bg-color:number
+#?   $print [xxx ], 5155:number/raw, [  #? 1
+#? ] #? 1
     x:number <- add x:number, 1:literal
+#?   $print [yyy ], 5155:number/raw, [  #? 1
+#? ] #? 1
     loop
   }
 ]