recipe! main [
local-scope
open-console
initial-recipe:address:shared:array:character <- restore [recipes.mu]
initial-sandbox:address:shared:array:character <- new []
hide-screen 0/screen
env:address:shared:programming-environment-data <- new-programming-environment 0/screen, initial-recipe, initial-sandbox
env <- restore-sandboxes env
render-all 0/screen, env
event-loop 0/screen, 0/console, env
]
container programming-environment-data [
sandbox:address:shared:sandbox-data
render-from:number
number-of-sandboxes:number
]
after <programming-environment-initialization> [
render-from:address:number <- get-address *result, render-from:offset
*render-from <- copy -1
]
container sandbox-data [
data:address:shared:array:character
response:address:shared:array:character
expected-response:address:shared:array:character
starting-row-on-screen:number
code-ending-row-on-screen:number
response-starting-row-on-screen:number
screen:address:shared:screen
next-sandbox:address:shared:sandbox-data
]
scenario run-and-show-results [
trace-until 100/app
assume-screen 100/width, 15/height
1:address:shared:array:character <- new []
2:address:shared:array:character <- new [divide-with-remainder 11, 3]
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
assume-console [
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. run (F4) .
. ┊ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊0 x.
. ┊divide-with-remainder 11, 3 .
. ┊3 .
. ┊2 .
. ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ .
]
screen-should-contain-in-color 7/white, [
. .
. .
. .
. .
. divide-with-remainder 11, 3 .
. .
. .
. .
. .
]
screen-should-contain-in-color 245/grey, [
. .
. ┊ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ x.
. ┊ .
. ┊3 .
. ┊2 .
. ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ .
]
screen-should-contain-in-color 240/dark-grey, [
. .
. .
. .
. 0 .
]
assume-console [
left-click 1, 80
type [add 2, 2]
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. run (F4) .
. ┊ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊1 x.
. ┊divide-with-remainder 11, 3 .
. ┊3 .
. ┊2 .
. ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ .
]
]
after <global-keypress> [
{
do-run?:boolean <- equal *k, 65532/F4
break-unless do-run?
status:address:shared:array:character <- new [running... ]
screen <- update-status screen, status, 245/grey
error?:boolean, env, screen <- run-sandboxes env, screen
screen <- render-all screen, env
{
break-if error?
status:address:shared:array:character <- new [ ]
screen <- update-status screen, status, 245/grey
}
screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus?, env
loop +next-event:label
}
]
recipe run-sandboxes env:address:shared:programming-environment-data, screen:address:shared:screen -> errors-found?:boolean, env:address:shared:programming-environment-data, screen:address:shared:screen [
local-scope
load-ingredients
errors-found?:boolean, env, screen <- update-recipes env, screen
reply-if errors-found?
<run-sandboxes-begin>
current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset
{
sandbox-contents:address:shared:array:character <- editor-contents current-sandbox
break-unless sandbox-contents
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
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
sandbox-count:address:number <- get-address *env, number-of-sandboxes:offset
*sandbox-count <- add *sandbox-count, 1
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
}
save-sandboxes env
curr:address:shared:sandbox-data <- get *env, sandbox:offset
idx:number <- copy 0
{
break-unless curr
curr <- update-sandbox curr, env, idx
curr <- get *curr, next-sandbox:offset
idx <- add idx, 1
loop
}
<run-sandboxes-end>
]
recipe update-recipes env:address:shared:programming-environment-data, screen:address:shared:screen -> errors-found?:boolean, env:address:shared:programming-environment-data, screen:address:shared:screen [
local-scope
load-ingredients
recipes:address:shared:editor-data <- get *env, recipes:offset
in:address:shared:array:character <- editor-contents recipes
save [recipes.mu], in
reload in
errors-found? <- copy 0/false
]
recipe! update-sandbox sandbox:address:shared:sandbox-data, env:address:shared:programming-environment-data, idx:number -> sandbox:address:shared:sandbox-data, env:address:shared:programming-environment-data [
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
]
recipe update-status screen:address:shared:screen, msg:address:shared:array:character, color:number -> screen:address:shared:screen [
local-scope
load-ingredients
screen <- move-cursor screen, 0, 2
screen <- print screen, msg, color, 238/grey/background
]
recipe save-sandboxes env:address:shared:programming-environment-data [
local-scope
load-ingredients
current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset
$system [rm lesson/[0-9]* >/dev/null 2>/dev/null]
curr:address:shared:sandbox-data <- get *env, sandbox:offset
suffix:address:shared:array:character <- new [.out]
idx:number <- copy 0
{
break-unless curr
data:address:shared:array:character <- get *curr, data:offset
filename:address:shared:array:character <- to-text idx
save filename, data
{
expected-response:address:shared:array:character <- get *curr, expected-response:offset
break-unless expected-response
filename <- append filename, suffix
save filename, expected-response
}
idx <- add idx, 1
curr <- get *curr, next-sandbox:offset
loop
}
]
recipe! render-sandbox-side screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen [
local-scope
load-ingredients
trace 11, [app], [render sandbox side]
current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset
row:number, column:number <- copy 1, 0
left:number <- get *current-sandbox, left:offset
right:number <- get *current-sandbox, right:offset
render-from:number <- get *env, render-from:offset
{
render-current-sandbox?:boolean <- equal render-from, -1
break-unless render-current-sandbox?
row, column, screen, current-sandbox <- render screen, current-sandbox
clear-screen-from screen, row, column, left, right
row <- add row, 1
}
draw-horizontal screen, row, left, right, 9473/horizontal-double
sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
row, screen <- render-sandboxes screen, sandbox, left, right, row, render-from
clear-rest-of-screen screen, row, left, right
]
recipe render-sandboxes screen:address:shared:screen, sandbox:address:shared:sandbox-data, left:number, right:number, row:number, render-from:number, idx:number -> row:number, screen:address:shared:screen, sandbox:address:shared:sandbox-data [
local-scope
load-ingredients
reply-unless sandbox
screen-height:number <- screen-height screen
at-bottom?:boolean <- greater-or-equal row, screen-height
reply-if at-bottom?:boolean
hidden?:boolean <- lesser-than idx, render-from
{
break-if hidden?
row <- add row, 1
screen <- move-cursor screen, row, left
print screen, idx, 240/dark-grey
clear-line-delimited screen, left, right
delete-icon:character <- copy 120/x
print screen, delete-icon, 245/grey
starting-row:address:number <- get-address *sandbox, starting-row-on-screen:offset
*starting-row <- copy row
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
response-starting-row:address:number <- get-address *sandbox, response-starting-row-on-screen:offset
sandbox-response:address:shared:array:character <- get *sandbox, response:offset
<render-sandbox-results>
{
sandbox-screen:address:shared:screen <- get *sandbox, screen:offset
empty-screen?:boolean <- fake-screen-is-empty? sandbox-screen
break-if empty-screen?
row, screen <- render-screen screen, sandbox-screen, left, right, row
}
{
break-unless empty-screen?
*response-starting-row <- copy row
<render-sandbox-response>
row, screen <- render screen, sandbox-response, left, right, 245/grey, row
}
+render-sandbox-end
at-bottom?:boolean <- greater-or-equal row, screen-height
reply-if at-bottom?
draw-horizontal screen, row, left, right, 9473/horizontal-double
}
{
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
tmp:address:number <- get-address *sandbox, response-starting-row-on-screen:offset
*tmp <- copy 0
}
next-sandbox:address:shared:sandbox-data <- get *sandbox, next-sandbox:offset
next-idx:number <- add idx, 1
row, screen <- render-sandboxes screen, next-sandbox, left, right, row, render-from, next-idx
]
recipe restore-sandboxes env:address:shared:programming-environment-data -> env:address:shared:programming-environment-data [
local-scope
load-ingredients
suffix:address:shared:array:character <- new [.out]
idx:number <- copy 0
curr:address:address:shared:sandbox-data <- get-address *env, sandbox:offset
{
filename:address:shared:array:character <- to-text idx
contents:address:shared:array:character <- restore filename
break-unless contents
*curr <- new sandbox-data:type
data:address:address:shared:array:character <- get-address **curr, data:offset
*data <- copy contents
{
filename <- append filename, suffix
contents <- restore filename
break-unless contents
expected-response:address:address:shared:array:character <- get-address **curr, expected-response:offset
*expected-response <- copy contents
}
+continue
idx <- add idx, 1
curr <- get-address **curr, next-sandbox:offset
loop
}
number-of-sandboxes:address:number <- get-address *env, number-of-sandboxes:offset
*number-of-sandboxes <- copy idx
]
recipe render-screen screen:address:shared:screen, sandbox-screen:address:shared:screen, left:number, right:number, row:number -> row:number, screen:address:shared:screen [
local-scope
load-ingredients
reply-unless sandbox-screen
header:address:shared:array:character <- new [screen:]
row <- render screen, header, left, right, 245/grey, row
screen <- move-cursor screen, row, left
column:number <- copy left
s-width:number <- screen-width sandbox-screen
s-height:number <- screen-height sandbox-screen
buf:address:shared:array:screen-cell <- get *sandbox-screen, data:offset
stop-printing:number <- add left, s-width, 3
max-column:number <- min stop-printing, right
i:number <- copy 0
len:number <- length *buf
screen-height:number <- screen-height screen
{
done?:boolean <- greater-or-equal i, len
break-if done?
done? <- greater-or-equal row, screen-height
break-if done?
column <- copy left
screen <- move-cursor screen, row, column
space:character <- copy 32/space
print screen, space, 245/grey
print screen, space, 245/grey
full-stop:character <- copy 46/period
print screen, full-stop, 245/grey
column <- add left, 3
{
row-done?:boolean <- greater-or-equal column, max-column
break-if row-done?
curr:screen-cell <- index *buf, i
c:character <- get curr, contents:offset
color:number <- get curr, color:offset
{
white?:boolean <- equal color, 7/white
break-unless white?
color <- copy 245/grey
}
print screen, c, color
column <- add column, 1
i <- add i, 1
loop
}
print screen, full-stop, 245/grey
column <- add column, 1
{
line-done?:boolean <- greater-than column, right
break-if line-done?
print screen, space
column <- add column, 1
loop
}
row <- add row, 1
loop
}
]
scenario run-updates-results [
trace-until 100/app
assume-screen 100/width, 12/height
1:address:shared:array:character <- new [
recipe foo [
z:number <- add 2, 2
reply z
]]
2:address:shared:array:character <- new [foo]
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
assume-console [
press F4
]
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
screen-should-contain [
. run (F4) .
. ┊ .
.recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
.z:number <- add 2, 2 ┊0 x.
.reply z ┊foo .
.] ┊4 .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ .
]
assume-console [
left-click 3, 28
press backspace
type [3]
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. run (F4) .
. ┊ .
.recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
.z:number <- add 2, 3 ┊0 x.
.reply z ┊foo .
.] ┊5 .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ .
]
]
scenario run-instruction-manages-screen-per-sandbox [
trace-until 100/app
assume-screen 100/width, 20/height
1:address:shared:array:character <- new []
2:address:shared:array:character <- new [print-integer screen, 4]
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
assume-console [
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. run (F4) .
. ┊ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊0 x.
. ┊print-integer screen, 4 .
. ┊screen: .
. ┊ .4 . .
. ┊ . . .
. ┊ . . .
. ┊ . . .
. ┊ . . .
. ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
. ┊ .
]
]
recipe editor-contents editor:address:shared:editor-data -> result:address:shared:array:character [
local-scope
load-ingredients
buf:address:shared:buffer <- new-buffer 80
curr:address:shared:duplex-list:character <- get *editor, data:offset
assert curr, [editor without data is illegal; must have at least a sentinel]
curr <- next curr
reply-unless curr, 0
{
break-unless curr
c:character <- get *curr, value:offset
buf <- append buf, c
curr <- next curr
loop
}
result <- buffer-to-array buf
]
scenario editor-provides-edited-contents [
assume-screen 10/width, 5/height
1:address:shared:array:character <- new [abc]
2:address:shared:editor-data <- new-editor 1:address:shared:array:character, screen:address:shared:screen, 0/left, 10/right
assume-console [
left-click 1, 2
type [def]
]
run [
editor-event-loop screen:address:shared:screen, console:address:shared:console, 2:address:shared:editor-data
3:address:shared:array:character <- editor-contents 2:address:shared:editor-data
4:array:character <- copy *3:address:shared:array:character
]
memory-should-contain [
4:array:character <- [abdefc]
]
]
scenario scrolling-down-past-bottom-of-sandbox-editor [
trace-until 100/app
assume-screen 30/width, 10/height
1:address:shared:array:character <- new []
2:address:shared:array:character <- new [add 2, 2]
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
render-all screen, 3:address:shared:programming-environment-data
assume-console [
press F4
press ctrl-n
type [abc
]
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. . # minor: F4 clears menu tooltip in very narrow screens
. ┊abc .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊␣ .
. ┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 2, 2 .
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊␣ x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
]
assume-console [
press up-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. . # minor: F4 clears menu tooltip in very narrow screens
. ┊abc .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊␣ .
. ┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 2, 2 .
]
]
after <global-keypress> [
{
break-unless *sandbox-in-focus?
down?:boolean <- equal *k, 65516/down-arrow
break-unless down?
sandbox-bottom:number <- get *current-sandbox, bottom:offset
sandbox-cursor:number <- get *current-sandbox, cursor-row:offset
sandbox-cursor-on-last-line?:boolean <- equal sandbox-bottom, sandbox-cursor
break-unless sandbox-cursor-on-last-line?
sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless sandbox
{
render-from:address:number <- get-address *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
jump-if at-end?, +finish-event:label
*render-from <- add *render-from, 1
}
hide-screen screen
screen <- render-sandbox-side screen, env
show-screen screen
jump +finish-event:label
}
]
after <update-cursor-special-cases> [
{
break-unless sandbox-in-focus?
render-from:number <- get *env, render-from:offset
scrolling?:boolean <- greater-or-equal render-from, 0
break-unless scrolling?
cursor-column:number <- get *current-sandbox, left:offset
screen <- move-cursor screen, 2/row, cursor-column
reply
}
]
after <global-keypress> [
{
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
break-if at-beginning?
*render-from <- subtract *render-from, 1
hide-screen screen
screen <- render-sandbox-side screen, env
show-screen screen
jump +finish-event:label
}
]
recipe previous-sandbox env:address:shared:programming-environment-data, in:address:shared:sandbox-data -> out:address:shared:sandbox-data [
local-scope
load-ingredients
curr:address:shared:sandbox-data <- get *env, sandbox:offset
reply-unless curr, 0/nil
next:address:shared:sandbox-data <- get *curr, next-sandbox:offset
{
reply-unless next, 0/nil
found?:boolean <- equal next, in
break-if found?
curr <- copy next
next <- get *curr, next-sandbox:offset
loop
}
reply curr
]
scenario scrolling-down-on-recipe-side [
trace-until 100/app
assume-screen 30/width, 10/height
1:address:shared:array:character <- new [
]
2:address:shared:array:character <- new [add 2, 2]
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
render-all screen, 3:address:shared:programming-environment-data
assume-console [
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. .
. ┊ .
.␣ ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊0 x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
]
]
scenario scrolling-through-multiple-sandboxes [
trace-until 100/app
assume-screen 30/width, 10/height
1:address:shared:array:character <- new []
2:address:shared:array:character <- new []
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
render-all screen, 3:address:shared:programming-environment-data
assume-console [
press ctrl-n
type [add 2, 2]
press F4
type [add 1, 1]
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. .
. ┊␣ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊1 x.
. ┊add 2, 2 .
. ┊4 .
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊␣ x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊1 x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━.
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊1 x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
. ┊ .
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊1 x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
. ┊ .
]
assume-console [
press up-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊1 x.
. ┊add 2, 2 .
. ┊4 .
. ┊━━━━━━━━━━━━━━.
]
assume-console [
press up-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
4:character/cursor <- copy 9251/␣
print screen:address:shared:screen, 4:character/cursor
]
screen-should-contain [
. .
. ┊␣ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊1 x.
. ┊add 2, 2 .
. ┊4 .
]
assume-console [
press up-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊␣ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊1 x.
. ┊add 2, 2 .
. ┊4 .
]
]
scenario scrolling-manages-sandbox-index-correctly [
trace-until 100/app
assume-screen 30/width, 10/height
1:address:shared:array:character <- new []
2:address:shared:array:character <- new []
3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character
render-all screen, 3:address:shared:programming-environment-data
assume-console [
press ctrl-n
type [add 1, 1]
press F4
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
]
assume-console [
press up-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊ .
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.
. ┊0 x.
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
]
assume-console [
press down-arrow
]
run [
event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data
]
screen-should-contain [
. .
. ┊━━━━━━━━━━━━━━.
.┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊0 x. # no change
. ┊add 1, 1 .
. ┊2 .
. ┊━━━━━━━━━━━━━━.
. ┊ .
]
]