From 2c53c3d0a921aec9825946be8dc37eff95b95485 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 12 Mar 2017 00:31:55 -0800 Subject: 3789 I accidentally got rid of git snapshotting of lessons back when I switched to testable file primitives last December (commit 3705). >:-( Bringing it back now, hopefully better. The improvement is that there's now at most one commit every time we hit F4. This change adds yet another reason that running `mu` from a different directory is just not supported. --- html/edit/005-sandbox.mu.html | 2056 +++++++++++++++++++++-------------------- 1 file changed, 1029 insertions(+), 1027 deletions(-) (limited to 'html/edit/005-sandbox.mu.html') diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html index 8a7b3986..066a08a3 100644 --- a/html/edit/005-sandbox.mu.html +++ b/html/edit/005-sandbox.mu.html @@ -74,7 +74,7 @@ if ('onhashchange' in window) { 11 local-scope 12 open-console 13 env:&:environment <- new-programming-environment 0/filesystem, 0/screen - 14 env <- restore-sandboxes env + 14 env <- restore-sandboxes env 15 render-all 0/screen, env, render 16 event-loop 0/screen, 0/console, env, 0/filesystem 17 # never gets here @@ -190,13 +190,13 @@ if ('onhashchange' in window) { 127 { 128 ¦ do-run?:bool <- equal k, 65532/F4 129 ¦ break-unless do-run? - 130 ¦ screen <- update-status screen, [running... ], 245/grey + 130 ¦ screen <- update-status screen, [running... ], 245/grey 131 ¦ error?:bool <- run-sandboxes env, resources, screen 132 ¦ # F4 might update warnings and results on both sides 133 ¦ screen <- render-all screen, env, render 134 ¦ { 135 ¦ ¦ break-if error? - 136 ¦ ¦ screen <- update-status screen, [ ], 245/grey + 136 ¦ ¦ screen <- update-status screen, [ ], 245/grey 137 ¦ } 138 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env 139 ¦ loop +next-event @@ -207,12 +207,12 @@ if ('onhashchange' in window) { 144 local-scope 145 load-ingredients 146 errors-found?:bool <- update-recipes env, resources, screen - 147 return-if errors-found? + 147 jump-if errors-found?, +return 148 # check contents of right editor (sandbox) 149 <run-sandboxes-begin> 150 current-sandbox:&:editor <- get *env, current-sandbox:offset 151 { - 152 ¦ sandbox-contents:text <- editor-contents current-sandbox + 152 ¦ sandbox-contents:text <- editor-contents current-sandbox 153 ¦ break-unless sandbox-contents 154 ¦ # if contents exist, first save them 155 ¦ # run them and turn them into a new sandbox @@ -232,7 +232,7 @@ if ('onhashchange' in window) { 169 ¦ *current-sandbox <- put *current-sandbox, top-of-screen:offset, init 170 } 171 # save all sandboxes before running, just in case we die when running - 172 save-sandboxes env, resources + 172 save-sandboxes env, resources 173 # run all sandboxes 174 curr:&:sandbox <- get *env, sandbox:offset 175 idx:num <- copy 0 @@ -244,1036 +244,1038 @@ if ('onhashchange' in window) { 181 ¦ loop 182 } 183 <run-sandboxes-end> - 184 ] - 185 - 186 # load code from disk - 187 # replaced in a later layer (whereupon errors-found? will actually be set) - 188 def update-recipes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [ - 189 local-scope - 190 load-ingredients - 191 recipes:&:editor <- get *env, recipes:offset - 192 in:text <- editor-contents recipes - 193 resources <- dump resources, [lesson/recipes.mu], in - 194 reload in - 195 errors-found? <- copy 0/false - 196 ] - 197 - 198 # replaced in a later layer - 199 def update-sandbox sandbox:&:sandbox, env:&:environment, idx:num -> sandbox:&:sandbox, env:&:environment [ - 200 local-scope - 201 load-ingredients - 202 data:text <- get *sandbox, data:offset - 203 response:text, _, fake-screen:&:screen <- run-sandboxed data - 204 *sandbox <- put *sandbox, response:offset, response - 205 *sandbox <- put *sandbox, screen:offset, fake-screen - 206 ] - 207 - 208 def update-status screen:&:screen, msg:text, color:num -> screen:&:screen [ - 209 local-scope - 210 load-ingredients - 211 screen <- move-cursor screen, 0, 2 - 212 screen <- print screen, msg, color, 238/grey/background - 213 ] - 214 - 215 def save-sandboxes env:&:environment, resources:&:resources -> resources:&:resources [ - 216 local-scope - 217 load-ingredients - 218 current-sandbox:&:editor <- get *env, current-sandbox:offset - 219 # first clear previous versions, in case we deleted some sandbox - 220 $system [rm lesson/[0-9]* >/dev/null 2>/dev/null] # some shells can't handle '>&' - 221 curr:&:sandbox <- get *env, sandbox:offset - 222 idx:num <- copy 0 - 223 { - 224 ¦ break-unless curr - 225 ¦ data:text <- get *curr, data:offset - 226 ¦ filename:text <- append [lesson/], idx - 227 ¦ resources <- dump resources, filename, data - 228 ¦ <end-save-sandbox> - 229 ¦ idx <- add idx, 1 - 230 ¦ curr <- get *curr, next-sandbox:offset - 231 ¦ loop - 232 } - 233 ] - 234 - 235 def! render-sandbox-side screen:&:screen, env:&:environment, {render-editor: (recipe (address screen) (address editor) -> number number (address screen) (address editor))} -> screen:&:screen, env:&:environment [ - 236 local-scope - 237 load-ingredients - 238 trace 11, [app], [render sandbox side] - 239 current-sandbox:&:editor <- get *env, current-sandbox:offset - 240 row:num, column:num <- copy 1, 0 - 241 left:num <- get *current-sandbox, left:offset - 242 right:num <- get *current-sandbox, right:offset - 243 # render sandbox editor - 244 render-from:num <- get *env, render-from:offset - 245 { - 246 ¦ render-current-sandbox?:bool <- equal render-from, -1 - 247 ¦ break-unless render-current-sandbox? - 248 ¦ row, column, screen, current-sandbox <- call render-editor, screen, current-sandbox - 249 ¦ clear-screen-from screen, row, column, left, right - 250 ¦ row <- add row, 1 - 251 } - 252 # render sandboxes - 253 draw-horizontal screen, row, left, right - 254 sandbox:&:sandbox <- get *env, sandbox:offset - 255 row, screen <- render-sandboxes screen, sandbox, left, right, row, render-from - 256 clear-rest-of-screen screen, row, left, right - 257 ] - 258 - 259 def render-sandboxes screen:&:screen, sandbox:&:sandbox, left:num, right:num, row:num, render-from:num, idx:num -> row:num, screen:&:screen, sandbox:&:sandbox [ - 260 local-scope - 261 load-ingredients - 262 return-unless sandbox - 263 screen-height:num <- screen-height screen - 264 at-bottom?:bool <- greater-or-equal row, screen-height - 265 return-if at-bottom?:bool - 266 hidden?:bool <- lesser-than idx, render-from - 267 { - 268 ¦ break-if hidden? - 269 ¦ # render sandbox menu - 270 ¦ row <- add row, 1 - 271 ¦ screen <- move-cursor screen, row, left - 272 ¦ screen <- render-sandbox-menu screen, idx, left, right - 273 ¦ # save menu row so we can detect clicks to it later - 274 ¦ *sandbox <- put *sandbox, starting-row-on-screen:offset, row - 275 ¦ # render sandbox contents - 276 ¦ row <- add row, 1 - 277 ¦ screen <- move-cursor screen, row, left - 278 ¦ sandbox-data:text <- get *sandbox, data:offset - 279 ¦ row, screen <- render-code screen, sandbox-data, left, right, row - 280 ¦ *sandbox <- put *sandbox, code-ending-row-on-screen:offset, row - 281 ¦ # render sandbox warnings, screen or response, in that order - 282 ¦ sandbox-response:text <- get *sandbox, response:offset - 283 ¦ <render-sandbox-results> - 284 ¦ { - 285 ¦ ¦ sandbox-screen:&:screen <- get *sandbox, screen:offset - 286 ¦ ¦ empty-screen?:bool <- fake-screen-is-empty? sandbox-screen - 287 ¦ ¦ break-if empty-screen? - 288 ¦ ¦ row, screen <- render-screen screen, sandbox-screen, left, right, row - 289 ¦ } - 290 ¦ { - 291 ¦ ¦ break-unless empty-screen? - 292 ¦ ¦ <render-sandbox-response> - 293 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 245/grey, row - 294 ¦ } - 295 ¦ +render-sandbox-end - 296 ¦ at-bottom?:bool <- greater-or-equal row, screen-height - 297 ¦ return-if at-bottom? - 298 ¦ # draw solid line after sandbox - 299 ¦ draw-horizontal screen, row, left, right - 300 } - 301 # if hidden, reset row attributes - 302 { - 303 ¦ break-unless hidden? - 304 ¦ *sandbox <- put *sandbox, starting-row-on-screen:offset, 0 - 305 ¦ *sandbox <- put *sandbox, code-ending-row-on-screen:offset, 0 - 306 ¦ <end-render-sandbox-reset-hidden> - 307 } - 308 # draw next sandbox - 309 next-sandbox:&:sandbox <- get *sandbox, next-sandbox:offset - 310 next-idx:num <- add idx, 1 - 311 row, screen <- render-sandboxes screen, next-sandbox, left, right, row, render-from, next-idx - 312 ] - 313 - 314 def render-sandbox-menu screen:&:screen, sandbox-index:num, left:num, right:num -> screen:&:screen [ - 315 local-scope - 316 load-ingredients - 317 move-cursor-to-column screen, left - 318 edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num <- sandbox-menu-columns left, right - 319 print screen, sandbox-index, 232/dark-grey, 245/grey - 320 start-buttons:num <- subtract edit-button-left, 1 - 321 clear-line-until screen, start-buttons, 245/grey - 322 print screen, [edit], 232/black, 94/background-orange - 323 clear-line-until screen, edit-button-right, 94/background-orange - 324 _, col:num <- cursor-position screen - 325 at-start-of-copy-button?:bool <- equal col, copy-button-left - 326 assert at-start-of-copy-button?, [aaa] - 327 print screen, [copy], 232/black, 58/background-green - 328 clear-line-until screen, copy-button-right, 58/background-green - 329 _, col:num <- cursor-position screen - 330 at-start-of-delete-button?:bool <- equal col, delete-button-left - 331 assert at-start-of-delete-button?, [bbb] - 332 print screen, [delete], 232/black, 52/background-red - 333 clear-line-until screen, right, 52/background-red - 334 ] - 335 - 336 # divide up the menu bar for a sandbox into 3 segments, for edit/copy/delete buttons - 337 # delete-button-right == right - 338 # all left/right pairs are inclusive - 339 def sandbox-menu-columns left:num, right:num -> edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num [ - 340 local-scope - 341 load-ingredients - 342 start-buttons:num <- add left, 4/space-for-sandbox-index - 343 buttons-space:num <- subtract right, start-buttons - 344 button-width:num <- divide-with-remainder buttons-space, 3 # integer division - 345 buttons-wide-enough?:bool <- greater-or-equal button-width, 8 - 346 assert buttons-wide-enough?, [sandbox must be at least 30 or so characters wide] - 347 edit-button-left:num <- copy start-buttons - 348 copy-button-left:num <- add start-buttons, button-width - 349 edit-button-right:num <- subtract copy-button-left, 1 - 350 delete-button-left:num <- subtract right, button-width - 351 copy-button-right:num <- subtract delete-button-left, 1 - 352 ] - 353 - 354 # print a text 's' to 'editor' in 'color' starting at 'row' - 355 # clear rest of last line, move cursor to next line - 356 def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num -> row:num, screen:&:screen [ - 357 local-scope - 358 load-ingredients - 359 return-unless s - 360 column:num <- copy left - 361 screen <- move-cursor screen, row, column - 362 screen-height:num <- screen-height screen - 363 i:num <- copy 0 - 364 len:num <- length *s - 365 { - 366 ¦ +next-character - 367 ¦ done?:bool <- greater-or-equal i, len - 368 ¦ break-if done? - 369 ¦ done? <- greater-or-equal row, screen-height + 184 +return + 185 $system [./snapshot_lesson] + 186 ] + 187 + 188 # load code from disk + 189 # replaced in a later layer (whereupon errors-found? will actually be set) + 190 def update-recipes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [ + 191 local-scope + 192 load-ingredients + 193 recipes:&:editor <- get *env, recipes:offset + 194 in:text <- editor-contents recipes + 195 resources <- dump resources, [lesson/recipes.mu], in + 196 reload in + 197 errors-found? <- copy 0/false + 198 ] + 199 + 200 # replaced in a later layer + 201 def update-sandbox sandbox:&:sandbox, env:&:environment, idx:num -> sandbox:&:sandbox, env:&:environment [ + 202 local-scope + 203 load-ingredients + 204 data:text <- get *sandbox, data:offset + 205 response:text, _, fake-screen:&:screen <- run-sandboxed data + 206 *sandbox <- put *sandbox, response:offset, response + 207 *sandbox <- put *sandbox, screen:offset, fake-screen + 208 ] + 209 + 210 def update-status screen:&:screen, msg:text, color:num -> screen:&:screen [ + 211 local-scope + 212 load-ingredients + 213 screen <- move-cursor screen, 0, 2 + 214 screen <- print screen, msg, color, 238/grey/background + 215 ] + 216 + 217 def save-sandboxes env:&:environment, resources:&:resources -> resources:&:resources [ + 218 local-scope + 219 load-ingredients + 220 current-sandbox:&:editor <- get *env, current-sandbox:offset + 221 # first clear previous versions, in case we deleted some sandbox + 222 $system [rm lesson/[0-9]* >/dev/null 2>/dev/null] # some shells can't handle '>&' + 223 curr:&:sandbox <- get *env, sandbox:offset + 224 idx:num <- copy 0 + 225 { + 226 ¦ break-unless curr + 227 ¦ data:text <- get *curr, data:offset + 228 ¦ filename:text <- append [lesson/], idx + 229 ¦ resources <- dump resources, filename, data + 230 ¦ <end-save-sandbox> + 231 ¦ idx <- add idx, 1 + 232 ¦ curr <- get *curr, next-sandbox:offset + 233 ¦ loop + 234 } + 235 ] + 236 + 237 def! render-sandbox-side screen:&:screen, env:&:environment, {render-editor: (recipe (address screen) (address editor) -> number number (address screen) (address editor))} -> screen:&:screen, env:&:environment [ + 238 local-scope + 239 load-ingredients + 240 trace 11, [app], [render sandbox side] + 241 current-sandbox:&:editor <- get *env, current-sandbox:offset + 242 row:num, column:num <- copy 1, 0 + 243 left:num <- get *current-sandbox, left:offset + 244 right:num <- get *current-sandbox, right:offset + 245 # render sandbox editor + 246 render-from:num <- get *env, render-from:offset + 247 { + 248 ¦ render-current-sandbox?:bool <- equal render-from, -1 + 249 ¦ break-unless render-current-sandbox? + 250 ¦ row, column, screen, current-sandbox <- call render-editor, screen, current-sandbox + 251 ¦ clear-screen-from screen, row, column, left, right + 252 ¦ row <- add row, 1 + 253 } + 254 # render sandboxes + 255 draw-horizontal screen, row, left, right + 256 sandbox:&:sandbox <- get *env, sandbox:offset + 257 row, screen <- render-sandboxes screen, sandbox, left, right, row, render-from + 258 clear-rest-of-screen screen, row, left, right + 259 ] + 260 + 261 def render-sandboxes screen:&:screen, sandbox:&:sandbox, left:num, right:num, row:num, render-from:num, idx:num -> row:num, screen:&:screen, sandbox:&:sandbox [ + 262 local-scope + 263 load-ingredients + 264 return-unless sandbox + 265 screen-height:num <- screen-height screen + 266 at-bottom?:bool <- greater-or-equal row, screen-height + 267 return-if at-bottom?:bool + 268 hidden?:bool <- lesser-than idx, render-from + 269 { + 270 ¦ break-if hidden? + 271 ¦ # render sandbox menu + 272 ¦ row <- add row, 1 + 273 ¦ screen <- move-cursor screen, row, left + 274 ¦ screen <- render-sandbox-menu screen, idx, left, right + 275 ¦ # save menu row so we can detect clicks to it later + 276 ¦ *sandbox <- put *sandbox, starting-row-on-screen:offset, row + 277 ¦ # render sandbox contents + 278 ¦ row <- add row, 1 + 279 ¦ screen <- move-cursor screen, row, left + 280 ¦ sandbox-data:text <- get *sandbox, data:offset + 281 ¦ row, screen <- render-code screen, sandbox-data, left, right, row + 282 ¦ *sandbox <- put *sandbox, code-ending-row-on-screen:offset, row + 283 ¦ # render sandbox warnings, screen or response, in that order + 284 ¦ sandbox-response:text <- get *sandbox, response:offset + 285 ¦ <render-sandbox-results> + 286 ¦ { + 287 ¦ ¦ sandbox-screen:&:screen <- get *sandbox, screen:offset + 288 ¦ ¦ empty-screen?:bool <- fake-screen-is-empty? sandbox-screen + 289 ¦ ¦ break-if empty-screen? + 290 ¦ ¦ row, screen <- render-screen screen, sandbox-screen, left, right, row + 291 ¦ } + 292 ¦ { + 293 ¦ ¦ break-unless empty-screen? + 294 ¦ ¦ <render-sandbox-response> + 295 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 245/grey, row + 296 ¦ } + 297 ¦ +render-sandbox-end + 298 ¦ at-bottom?:bool <- greater-or-equal row, screen-height + 299 ¦ return-if at-bottom? + 300 ¦ # draw solid line after sandbox + 301 ¦ draw-horizontal screen, row, left, right + 302 } + 303 # if hidden, reset row attributes + 304 { + 305 ¦ break-unless hidden? + 306 ¦ *sandbox <- put *sandbox, starting-row-on-screen:offset, 0 + 307 ¦ *sandbox <- put *sandbox, code-ending-row-on-screen:offset, 0 + 308 ¦ <end-render-sandbox-reset-hidden> + 309 } + 310 # draw next sandbox + 311 next-sandbox:&:sandbox <- get *sandbox, next-sandbox:offset + 312 next-idx:num <- add idx, 1 + 313 row, screen <- render-sandboxes screen, next-sandbox, left, right, row, render-from, next-idx + 314 ] + 315 + 316 def render-sandbox-menu screen:&:screen, sandbox-index:num, left:num, right:num -> screen:&:screen [ + 317 local-scope + 318 load-ingredients + 319 move-cursor-to-column screen, left + 320 edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num <- sandbox-menu-columns left, right + 321 print screen, sandbox-index, 232/dark-grey, 245/grey + 322 start-buttons:num <- subtract edit-button-left, 1 + 323 clear-line-until screen, start-buttons, 245/grey + 324 print screen, [edit], 232/black, 94/background-orange + 325 clear-line-until screen, edit-button-right, 94/background-orange + 326 _, col:num <- cursor-position screen + 327 at-start-of-copy-button?:bool <- equal col, copy-button-left + 328 assert at-start-of-copy-button?, [aaa] + 329 print screen, [copy], 232/black, 58/background-green + 330 clear-line-until screen, copy-button-right, 58/background-green + 331 _, col:num <- cursor-position screen + 332 at-start-of-delete-button?:bool <- equal col, delete-button-left + 333 assert at-start-of-delete-button?, [bbb] + 334 print screen, [delete], 232/black, 52/background-red + 335 clear-line-until screen, right, 52/background-red + 336 ] + 337 + 338 # divide up the menu bar for a sandbox into 3 segments, for edit/copy/delete buttons + 339 # delete-button-right == right + 340 # all left/right pairs are inclusive + 341 def sandbox-menu-columns left:num, right:num -> edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num [ + 342 local-scope + 343 load-ingredients + 344 start-buttons:num <- add left, 4/space-for-sandbox-index + 345 buttons-space:num <- subtract right, start-buttons + 346 button-width:num <- divide-with-remainder buttons-space, 3 # integer division + 347 buttons-wide-enough?:bool <- greater-or-equal button-width, 8 + 348 assert buttons-wide-enough?, [sandbox must be at least 30 or so characters wide] + 349 edit-button-left:num <- copy start-buttons + 350 copy-button-left:num <- add start-buttons, button-width + 351 edit-button-right:num <- subtract copy-button-left, 1 + 352 delete-button-left:num <- subtract right, button-width + 353 copy-button-right:num <- subtract delete-button-left, 1 + 354 ] + 355 + 356 # print a text 's' to 'editor' in 'color' starting at 'row' + 357 # clear rest of last line, move cursor to next line + 358 def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num -> row:num, screen:&:screen [ + 359 local-scope + 360 load-ingredients + 361 return-unless s + 362 column:num <- copy left + 363 screen <- move-cursor screen, row, column + 364 screen-height:num <- screen-height screen + 365 i:num <- copy 0 + 366 len:num <- length *s + 367 { + 368 ¦ +next-character + 369 ¦ done?:bool <- greater-or-equal i, len 370 ¦ break-if done? - 371 ¦ c:char <- index *s, i - 372 ¦ { - 373 ¦ ¦ # at right? wrap. - 374 ¦ ¦ at-right?:bool <- equal column, right - 375 ¦ ¦ break-unless at-right? - 376 ¦ ¦ # print wrap icon - 377 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left - 378 ¦ ¦ print screen, wrap-icon, 245/grey - 379 ¦ ¦ column <- copy left - 380 ¦ ¦ row <- add row, 1 - 381 ¦ ¦ screen <- move-cursor screen, row, column - 382 ¦ ¦ loop +next-character # retry i - 383 ¦ } - 384 ¦ i <- add i, 1 - 385 ¦ { - 386 ¦ ¦ # newline? move to left rather than 0 - 387 ¦ ¦ newline?:bool <- equal c, 10/newline - 388 ¦ ¦ break-unless newline? - 389 ¦ ¦ # clear rest of line in this window - 390 ¦ ¦ { - 391 ¦ ¦ ¦ done?:bool <- greater-than column, right - 392 ¦ ¦ ¦ break-if done? - 393 ¦ ¦ ¦ space:char <- copy 32/space - 394 ¦ ¦ ¦ print screen, space - 395 ¦ ¦ ¦ column <- add column, 1 - 396 ¦ ¦ ¦ loop - 397 ¦ ¦ } - 398 ¦ ¦ row <- add row, 1 - 399 ¦ ¦ column <- copy left - 400 ¦ ¦ screen <- move-cursor screen, row, column - 401 ¦ ¦ loop +next-character - 402 ¦ } - 403 ¦ print screen, c, color - 404 ¦ column <- add column, 1 - 405 ¦ loop - 406 } - 407 was-at-left?:bool <- equal column, left - 408 clear-line-until screen, right - 409 { - 410 ¦ break-if was-at-left? - 411 ¦ row <- add row, 1 - 412 } - 413 move-cursor screen, row, left - 414 ] - 415 - 416 # assumes programming environment has no sandboxes; restores them from previous session - 417 def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environment [ - 418 local-scope - 419 load-ingredients - 420 # read all scenarios, pushing them to end of a list of scenarios - 421 idx:num <- copy 0 - 422 curr:&:sandbox <- copy 0 - 423 prev:&:sandbox <- copy 0 - 424 { - 425 ¦ filename:text <- append [lesson/], idx - 426 ¦ contents:text <- slurp resources, filename - 427 ¦ break-unless contents # stop at first error; assuming file didn't exist - 428 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ # todo: handle empty sandbox - 429 ¦ # create new sandbox for file - 430 ¦ curr <- new sandbox:type - 431 ¦ *curr <- put *curr, data:offset, contents - 432 ¦ <end-restore-sandbox> - 433 ¦ { - 434 ¦ ¦ break-if idx - 435 ¦ ¦ *env <- put *env, sandbox:offset, curr - 436 ¦ } - 437 ¦ { - 438 ¦ ¦ break-unless idx - 439 ¦ ¦ *prev <- put *prev, next-sandbox:offset, curr - 440 ¦ } - 441 ¦ idx <- add idx, 1 - 442 ¦ prev <- copy curr - 443 ¦ loop - 444 } - 445 # update sandbox count - 446 *env <- put *env, number-of-sandboxes:offset, idx - 447 ] - 448 - 449 # print the fake sandbox screen to 'screen' with appropriate delimiters - 450 # leave cursor at start of next line - 451 def render-screen screen:&:screen, sandbox-screen:&:screen, left:num, right:num, row:num -> row:num, screen:&:screen [ - 452 local-scope - 453 load-ingredients - 454 return-unless sandbox-screen - 455 # print 'screen:' - 456 row <- render-text screen, [screen:], left, right, 245/grey, row - 457 screen <- move-cursor screen, row, left - 458 # start printing sandbox-screen - 459 column:num <- copy left - 460 s-width:num <- screen-width sandbox-screen - 461 s-height:num <- screen-height sandbox-screen - 462 buf:&:@:screen-cell <- get *sandbox-screen, data:offset - 463 stop-printing:num <- add left, s-width, 3 - 464 max-column:num <- min stop-printing, right - 465 i:num <- copy 0 - 466 len:num <- length *buf - 467 screen-height:num <- screen-height screen - 468 { - 469 ¦ done?:bool <- greater-or-equal i, len - 470 ¦ break-if done? - 471 ¦ done? <- greater-or-equal row, screen-height + 371 ¦ done? <- greater-or-equal row, screen-height + 372 ¦ break-if done? + 373 ¦ c:char <- index *s, i + 374 ¦ { + 375 ¦ ¦ # at right? wrap. + 376 ¦ ¦ at-right?:bool <- equal column, right + 377 ¦ ¦ break-unless at-right? + 378 ¦ ¦ # print wrap icon + 379 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left + 380 ¦ ¦ print screen, wrap-icon, 245/grey + 381 ¦ ¦ column <- copy left + 382 ¦ ¦ row <- add row, 1 + 383 ¦ ¦ screen <- move-cursor screen, row, column + 384 ¦ ¦ loop +next-character # retry i + 385 ¦ } + 386 ¦ i <- add i, 1 + 387 ¦ { + 388 ¦ ¦ # newline? move to left rather than 0 + 389 ¦ ¦ newline?:bool <- equal c, 10/newline + 390 ¦ ¦ break-unless newline? + 391 ¦ ¦ # clear rest of line in this window + 392 ¦ ¦ { + 393 ¦ ¦ ¦ done?:bool <- greater-than column, right + 394 ¦ ¦ ¦ break-if done? + 395 ¦ ¦ ¦ space:char <- copy 32/space + 396 ¦ ¦ ¦ print screen, space + 397 ¦ ¦ ¦ column <- add column, 1 + 398 ¦ ¦ ¦ loop + 399 ¦ ¦ } + 400 ¦ ¦ row <- add row, 1 + 401 ¦ ¦ column <- copy left + 402 ¦ ¦ screen <- move-cursor screen, row, column + 403 ¦ ¦ loop +next-character + 404 ¦ } + 405 ¦ print screen, c, color + 406 ¦ column <- add column, 1 + 407 ¦ loop + 408 } + 409 was-at-left?:bool <- equal column, left + 410 clear-line-until screen, right + 411 { + 412 ¦ break-if was-at-left? + 413 ¦ row <- add row, 1 + 414 } + 415 move-cursor screen, row, left + 416 ] + 417 + 418 # assumes programming environment has no sandboxes; restores them from previous session + 419 def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environment [ + 420 local-scope + 421 load-ingredients + 422 # read all scenarios, pushing them to end of a list of scenarios + 423 idx:num <- copy 0 + 424 curr:&:sandbox <- copy 0 + 425 prev:&:sandbox <- copy 0 + 426 { + 427 ¦ filename:text <- append [lesson/], idx + 428 ¦ contents:text <- slurp resources, filename + 429 ¦ break-unless contents # stop at first error; assuming file didn't exist + 430 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ # todo: handle empty sandbox + 431 ¦ # create new sandbox for file + 432 ¦ curr <- new sandbox:type + 433 ¦ *curr <- put *curr, data:offset, contents + 434 ¦ <end-restore-sandbox> + 435 ¦ { + 436 ¦ ¦ break-if idx + 437 ¦ ¦ *env <- put *env, sandbox:offset, curr + 438 ¦ } + 439 ¦ { + 440 ¦ ¦ break-unless idx + 441 ¦ ¦ *prev <- put *prev, next-sandbox:offset, curr + 442 ¦ } + 443 ¦ idx <- add idx, 1 + 444 ¦ prev <- copy curr + 445 ¦ loop + 446 } + 447 # update sandbox count + 448 *env <- put *env, number-of-sandboxes:offset, idx + 449 ] + 450 + 451 # print the fake sandbox screen to 'screen' with appropriate delimiters + 452 # leave cursor at start of next line + 453 def render-screen screen:&:screen, sandbox-screen:&:screen, left:num, right:num, row:num -> row:num, screen:&:screen [ + 454 local-scope + 455 load-ingredients + 456 return-unless sandbox-screen + 457 # print 'screen:' + 458 row <- render-text screen, [screen:], left, right, 245/grey, row + 459 screen <- move-cursor screen, row, left + 460 # start printing sandbox-screen + 461 column:num <- copy left + 462 s-width:num <- screen-width sandbox-screen + 463 s-height:num <- screen-height sandbox-screen + 464 buf:&:@:screen-cell <- get *sandbox-screen, data:offset + 465 stop-printing:num <- add left, s-width, 3 + 466 max-column:num <- min stop-printing, right + 467 i:num <- copy 0 + 468 len:num <- length *buf + 469 screen-height:num <- screen-height screen + 470 { + 471 ¦ done?:bool <- greater-or-equal i, len 472 ¦ break-if done? - 473 ¦ column <- copy left - 474 ¦ screen <- move-cursor screen, row, column - 475 ¦ # initial leader for each row: two spaces and a '.' - 476 ¦ space:char <- copy 32/space - 477 ¦ print screen, space, 245/grey - 478 ¦ print screen, space, 245/grey - 479 ¦ full-stop:char <- copy 46/period - 480 ¦ print screen, full-stop, 245/grey - 481 ¦ column <- add left, 3 - 482 ¦ { - 483 ¦ ¦ # print row - 484 ¦ ¦ row-done?:bool <- greater-or-equal column, max-column - 485 ¦ ¦ break-if row-done? - 486 ¦ ¦ curr:screen-cell <- index *buf, i - 487 ¦ ¦ c:char <- get curr, contents:offset - 488 ¦ ¦ color:num <- get curr, color:offset - 489 ¦ ¦ { - 490 ¦ ¦ ¦ # damp whites down to grey - 491 ¦ ¦ ¦ white?:bool <- equal color, 7/white - 492 ¦ ¦ ¦ break-unless white? - 493 ¦ ¦ ¦ color <- copy 245/grey - 494 ¦ ¦ } - 495 ¦ ¦ print screen, c, color - 496 ¦ ¦ column <- add column, 1 - 497 ¦ ¦ i <- add i, 1 - 498 ¦ ¦ loop - 499 ¦ } - 500 ¦ # print final '.' - 501 ¦ print screen, full-stop, 245/grey - 502 ¦ column <- add column, 1 - 503 ¦ { - 504 ¦ ¦ # clear rest of current line - 505 ¦ ¦ line-done?:bool <- greater-than column, right - 506 ¦ ¦ break-if line-done? - 507 ¦ ¦ print screen, space - 508 ¦ ¦ column <- add column, 1 - 509 ¦ ¦ loop - 510 ¦ } - 511 ¦ row <- add row, 1 - 512 ¦ loop - 513 } - 514 ] - 515 - 516 scenario run-updates-results [ - 517 local-scope - 518 trace-until 100/app # trace too long - 519 assume-screen 100/width, 12/height - 520 # define a recipe (no indent for the 'add' line below so column numbers are more obvious) - 521 assume-resources [ - 522 ¦ [lesson/recipes.mu] <- [ - 523 ¦ ¦ || - 524 ¦ ¦ |recipe foo [| - 525 ¦ ¦ | local-scope| - 526 ¦ ¦ | z:num <- add 2, 2| - 527 ¦ ¦ | reply z| - 528 ¦ ¦ |]| - 529 ¦ ] - 530 ] - 531 # sandbox editor contains an instruction without storing outputs - 532 env:&:environment <- new-programming-environment resources, screen, [foo] # contents of sandbox editor - 533 # run the code in the editors - 534 assume-console [ - 535 ¦ press F4 - 536 ] - 537 event-loop screen, console, env, resources - 538 screen-should-contain [ - 539 ¦ . run (F4) . - 540 ¦ . ╎ . - 541 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. - 542 ¦ . local-scope ╎0 edit copy delete . - 543 ¦ . z:num <- add 2, 2 ╎foo . - 544 ¦ . reply z ╎4 . - 545 ¦ .] ╎─────────────────────────────────────────────────. - 546 ¦ . ╎ . - 547 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 473 ¦ done? <- greater-or-equal row, screen-height + 474 ¦ break-if done? + 475 ¦ column <- copy left + 476 ¦ screen <- move-cursor screen, row, column + 477 ¦ # initial leader for each row: two spaces and a '.' + 478 ¦ space:char <- copy 32/space + 479 ¦ print screen, space, 245/grey + 480 ¦ print screen, space, 245/grey + 481 ¦ full-stop:char <- copy 46/period + 482 ¦ print screen, full-stop, 245/grey + 483 ¦ column <- add left, 3 + 484 ¦ { + 485 ¦ ¦ # print row + 486 ¦ ¦ row-done?:bool <- greater-or-equal column, max-column + 487 ¦ ¦ break-if row-done? + 488 ¦ ¦ curr:screen-cell <- index *buf, i + 489 ¦ ¦ c:char <- get curr, contents:offset + 490 ¦ ¦ color:num <- get curr, color:offset + 491 ¦ ¦ { + 492 ¦ ¦ ¦ # damp whites down to grey + 493 ¦ ¦ ¦ white?:bool <- equal color, 7/white + 494 ¦ ¦ ¦ break-unless white? + 495 ¦ ¦ ¦ color <- copy 245/grey + 496 ¦ ¦ } + 497 ¦ ¦ print screen, c, color + 498 ¦ ¦ column <- add column, 1 + 499 ¦ ¦ i <- add i, 1 + 500 ¦ ¦ loop + 501 ¦ } + 502 ¦ # print final '.' + 503 ¦ print screen, full-stop, 245/grey + 504 ¦ column <- add column, 1 + 505 ¦ { + 506 ¦ ¦ # clear rest of current line + 507 ¦ ¦ line-done?:bool <- greater-than column, right + 508 ¦ ¦ break-if line-done? + 509 ¦ ¦ print screen, space + 510 ¦ ¦ column <- add column, 1 + 511 ¦ ¦ loop + 512 ¦ } + 513 ¦ row <- add row, 1 + 514 ¦ loop + 515 } + 516 ] + 517 + 518 scenario run-updates-results [ + 519 local-scope + 520 trace-until 100/app # trace too long + 521 assume-screen 100/width, 12/height + 522 # define a recipe (no indent for the 'add' line below so column numbers are more obvious) + 523 assume-resources [ + 524 ¦ [lesson/recipes.mu] <- [ + 525 ¦ ¦ || + 526 ¦ ¦ |recipe foo [| + 527 ¦ ¦ | local-scope| + 528 ¦ ¦ | z:num <- add 2, 2| + 529 ¦ ¦ | reply z| + 530 ¦ ¦ |]| + 531 ¦ ] + 532 ] + 533 # sandbox editor contains an instruction without storing outputs + 534 env:&:environment <- new-programming-environment resources, screen, [foo] # contents of sandbox editor + 535 # run the code in the editors + 536 assume-console [ + 537 ¦ press F4 + 538 ] + 539 event-loop screen, console, env, resources + 540 screen-should-contain [ + 541 ¦ . run (F4) . + 542 ¦ . ╎ . + 543 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. + 544 ¦ . local-scope ╎0 edit copy delete . + 545 ¦ . z:num <- add 2, 2 ╎foo . + 546 ¦ . reply z ╎4 . + 547 ¦ .] ╎─────────────────────────────────────────────────. 548 ¦ . ╎ . - 549 ] - 550 # make a change (incrementing one of the args to 'add'), then rerun - 551 assume-console [ - 552 ¦ left-click 4, 28 # one past the value of the second arg - 553 ¦ press backspace - 554 ¦ type [3] - 555 ¦ press F4 - 556 ] - 557 run [ - 558 ¦ event-loop screen, console, env, resources - 559 ] - 560 # check that screen updates the result on the right - 561 screen-should-contain [ - 562 ¦ . run (F4) . - 563 ¦ . ╎ . - 564 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. - 565 ¦ . local-scope ╎0 edit copy delete . - 566 ¦ . z:num <- add 2, 3 ╎foo . - 567 ¦ . reply z ╎5 . - 568 ¦ .] ╎─────────────────────────────────────────────────. - 569 ¦ . ╎ . - 570 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 549 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 550 ¦ . ╎ . + 551 ] + 552 # make a change (incrementing one of the args to 'add'), then rerun + 553 assume-console [ + 554 ¦ left-click 4, 28 # one past the value of the second arg + 555 ¦ press backspace + 556 ¦ type [3] + 557 ¦ press F4 + 558 ] + 559 run [ + 560 ¦ event-loop screen, console, env, resources + 561 ] + 562 # check that screen updates the result on the right + 563 screen-should-contain [ + 564 ¦ . run (F4) . + 565 ¦ . ╎ . + 566 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. + 567 ¦ . local-scope ╎0 edit copy delete . + 568 ¦ . z:num <- add 2, 3 ╎foo . + 569 ¦ . reply z ╎5 . + 570 ¦ .] ╎─────────────────────────────────────────────────. 571 ¦ . ╎ . - 572 ] - 573 ] - 574 - 575 scenario run-instruction-manages-screen-per-sandbox [ - 576 local-scope - 577 trace-until 100/app # trace too long - 578 assume-screen 100/width, 20/height - 579 # empty recipes - 580 assume-resources [ - 581 ] - 582 # sandbox editor contains an instruction - 583 env:&:environment <- new-programming-environment resources, screen, [print screen, 4] # contents of sandbox editor - 584 # run the code in the editor - 585 assume-console [ - 586 ¦ press F4 - 587 ] - 588 run [ - 589 ¦ event-loop screen, console, env, resources - 590 ] - 591 # check that it prints a little toy screen - 592 screen-should-contain [ - 593 ¦ . run (F4) . - 594 ¦ . ╎ . - 595 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 596 ¦ . ╎0 edit copy delete . - 597 ¦ . ╎print screen, 4 . - 598 ¦ . ╎screen: . - 599 ¦ . ╎ .4 . . - 600 ¦ . ╎ . . . - 601 ¦ . ╎ . . . + 572 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 573 ¦ . ╎ . + 574 ] + 575 ] + 576 + 577 scenario run-instruction-manages-screen-per-sandbox [ + 578 local-scope + 579 trace-until 100/app # trace too long + 580 assume-screen 100/width, 20/height + 581 # empty recipes + 582 assume-resources [ + 583 ] + 584 # sandbox editor contains an instruction + 585 env:&:environment <- new-programming-environment resources, screen, [print screen, 4] # contents of sandbox editor + 586 # run the code in the editor + 587 assume-console [ + 588 ¦ press F4 + 589 ] + 590 run [ + 591 ¦ event-loop screen, console, env, resources + 592 ] + 593 # check that it prints a little toy screen + 594 screen-should-contain [ + 595 ¦ . run (F4) . + 596 ¦ . ╎ . + 597 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 598 ¦ . ╎0 edit copy delete . + 599 ¦ . ╎print screen, 4 . + 600 ¦ . ╎screen: . + 601 ¦ . ╎ .4 . . 602 ¦ . ╎ . . . 603 ¦ . ╎ . . . - 604 ¦ . ╎─────────────────────────────────────────────────. - 605 ¦ . ╎ . - 606 ] - 607 ] - 608 - 609 def editor-contents editor:&:editor -> result:text [ - 610 local-scope - 611 load-ingredients - 612 buf:&:buffer <- new-buffer 80 - 613 curr:&:duplex-list:char <- get *editor, data:offset - 614 # skip § sentinel - 615 assert curr, [editor without data is illegal; must have at least a sentinel] - 616 curr <- next curr - 617 return-unless curr, 0 - 618 { - 619 ¦ break-unless curr - 620 ¦ c:char <- get *curr, value:offset - 621 ¦ buf <- append buf, c - 622 ¦ curr <- next curr - 623 ¦ loop - 624 } - 625 result <- buffer-to-array buf - 626 ] - 627 - 628 scenario editor-provides-edited-contents [ - 629 local-scope - 630 assume-screen 10/width, 5/height - 631 e:&:editor <- new-editor [abc], 0/left, 10/right - 632 assume-console [ - 633 ¦ left-click 1, 2 - 634 ¦ type [def] - 635 ] - 636 run [ - 637 ¦ editor-event-loop screen, console, e - 638 ¦ s:text <- editor-contents e - 639 ¦ 1:@:char/raw <- copy *s - 640 ] - 641 memory-should-contain [ - 642 ¦ 1:array:character <- [abdefc] - 643 ] - 644 ] - 645 - 646 # keep the bottom of recipes from scrolling off the screen + 604 ¦ . ╎ . . . + 605 ¦ . ╎ . . . + 606 ¦ . ╎─────────────────────────────────────────────────. + 607 ¦ . ╎ . + 608 ] + 609 ] + 610 + 611 def editor-contents editor:&:editor -> result:text [ + 612 local-scope + 613 load-ingredients + 614 buf:&:buffer <- new-buffer 80 + 615 curr:&:duplex-list:char <- get *editor, data:offset + 616 # skip § sentinel + 617 assert curr, [editor without data is illegal; must have at least a sentinel] + 618 curr <- next curr + 619 return-unless curr, 0 + 620 { + 621 ¦ break-unless curr + 622 ¦ c:char <- get *curr, value:offset + 623 ¦ buf <- append buf, c + 624 ¦ curr <- next curr + 625 ¦ loop + 626 } + 627 result <- buffer-to-array buf + 628 ] + 629 + 630 scenario editor-provides-edited-contents [ + 631 local-scope + 632 assume-screen 10/width, 5/height + 633 e:&:editor <- new-editor [abc], 0/left, 10/right + 634 assume-console [ + 635 ¦ left-click 1, 2 + 636 ¦ type [def] + 637 ] + 638 run [ + 639 ¦ editor-event-loop screen, console, e + 640 ¦ s:text <- editor-contents e + 641 ¦ 1:@:char/raw <- copy *s + 642 ] + 643 memory-should-contain [ + 644 ¦ 1:array:character <- [abdefc] + 645 ] + 646 ] 647 - 648 scenario scrolling-down-past-bottom-of-recipe-editor [ - 649 local-scope - 650 trace-until 100/app - 651 assume-screen 100/width, 10/height - 652 assume-resources [ - 653 ] - 654 env:&:environment <- new-programming-environment resources, screen, [] - 655 render-all screen, env, render - 656 assume-console [ - 657 ¦ press enter - 658 ¦ press down-arrow - 659 ] - 660 event-loop screen, console, env, resources - 661 # no scroll - 662 screen-should-contain [ - 663 ¦ . run (F4) . - 664 ¦ . ╎ . - 665 ¦ . ╎─────────────────────────────────────────────────. - 666 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 667 ¦ . ╎ . - 668 ] - 669 ] - 670 - 671 scenario cursor-down-in-recipe-editor [ - 672 local-scope - 673 trace-until 100/app - 674 assume-screen 100/width, 10/height - 675 assume-resources [ - 676 ] - 677 env:&:environment <- new-programming-environment resources, screen, [] - 678 render-all screen, env, render - 679 assume-console [ - 680 ¦ press enter - 681 ¦ press up-arrow - 682 ¦ press down-arrow # while cursor isn't at bottom - 683 ] - 684 event-loop screen, console, env, resources - 685 cursor:char <- copy 9251/␣ - 686 print screen, cursor - 687 # cursor moves back to bottom - 688 screen-should-contain [ - 689 ¦ . run (F4) . - 690 ¦ . ╎ . - 691 ¦ .␣ ╎─────────────────────────────────────────────────. - 692 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 693 ¦ . ╎ . - 694 ] - 695 ] - 696 - 697 # we'll not use the recipe-editor's 'bottom' element directly, because later - 698 # layers will add other stuff to the left side below the editor (error messages) - 699 - 700 container environment [ - 701 recipe-bottom:num - 702 ] - 703 - 704 after <render-recipe-components-end> [ - 705 *env <- put *env, recipe-bottom:offset, row - 706 ] - 707 - 708 after <global-keypress> [ - 709 { - 710 ¦ break-if sandbox-in-focus? - 711 ¦ down-arrow?:bool <- equal k, 65516/down-arrow - 712 ¦ break-unless down-arrow? - 713 ¦ recipe-editor:&:editor <- get *env, recipes:offset - 714 ¦ recipe-cursor-row:num <- get *recipe-editor, cursor-row:offset - 715 ¦ recipe-editor-bottom:num <- get *recipe-editor, bottom:offset - 716 ¦ at-bottom-of-editor?:bool <- greater-or-equal recipe-cursor-row, recipe-editor-bottom - 717 ¦ break-unless at-bottom-of-editor? - 718 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen - 719 ¦ break-if more-to-scroll? - 720 ¦ loop +next-event - 721 } - 722 { - 723 ¦ break-if sandbox-in-focus? - 724 ¦ page-down?:bool <- equal k, 65518/page-down - 725 ¦ break-unless page-down? - 726 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen - 727 ¦ break-if more-to-scroll? - 728 ¦ loop +next-event - 729 } - 730 ] - 731 - 732 after <global-type> [ - 733 { - 734 ¦ break-if sandbox-in-focus? - 735 ¦ page-down?:bool <- equal k, 6/ctrl-f - 736 ¦ break-unless page-down? - 737 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen - 738 ¦ break-if more-to-scroll? - 739 ¦ loop +next-event - 740 } - 741 ] - 742 - 743 def more-to-scroll? env:&:environment, screen:&:screen -> result:bool [ - 744 local-scope - 745 load-ingredients - 746 recipe-bottom:num <- get *env, recipe-bottom:offset - 747 height:num <- screen-height screen - 748 result <- greater-or-equal recipe-bottom, height - 749 ] - 750 - 751 scenario scrolling-down-past-bottom-of-recipe-editor-2 [ - 752 local-scope - 753 trace-until 100/app - 754 assume-screen 100/width, 10/height - 755 assume-resources [ - 756 ] - 757 env:&:environment <- new-programming-environment resources, screen, [] - 758 render-all screen, env, render - 759 assume-console [ - 760 ¦ # add a line - 761 ¦ press enter - 762 ¦ # cursor back to top line - 763 ¦ press up-arrow - 764 ¦ # try to scroll - 765 ¦ press page-down # or ctrl-f - 766 ] - 767 event-loop screen, console, env, resources - 768 # no scroll, and cursor remains at top line - 769 screen-should-contain [ - 770 ¦ . run (F4) . - 771 ¦ . ╎ . - 772 ¦ . ╎─────────────────────────────────────────────────. - 773 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 774 ¦ . ╎ . - 775 ] - 776 ] - 777 - 778 scenario scrolling-down-past-bottom-of-recipe-editor-3 [ - 779 local-scope - 780 trace-until 100/app - 781 assume-screen 100/width, 10/height - 782 assume-resources [ - 783 ] - 784 env:&:environment <- new-programming-environment resources, screen, [ab - 785 cd] - 786 render-all screen, env, render - 787 assume-console [ - 788 ¦ # add a line - 789 ¦ press enter - 790 ¦ # switch to sandbox - 791 ¦ press ctrl-n - 792 ¦ # move cursor - 793 ¦ press down-arrow - 794 ] - 795 event-loop screen, console, env, resources - 796 cursor:char <- copy 9251/␣ - 797 print screen, cursor - 798 # no scroll on recipe side, cursor moves on sandbox side - 799 screen-should-contain [ - 800 ¦ . run (F4) . - 801 ¦ . ╎ab . - 802 ¦ . ╎␣d . - 803 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 804 ¦ . ╎ . - 805 ] - 806 ] - 807 - 808 # scrolling through sandboxes + 648 # keep the bottom of recipes from scrolling off the screen + 649 + 650 scenario scrolling-down-past-bottom-of-recipe-editor [ + 651 local-scope + 652 trace-until 100/app + 653 assume-screen 100/width, 10/height + 654 assume-resources [ + 655 ] + 656 env:&:environment <- new-programming-environment resources, screen, [] + 657 render-all screen, env, render + 658 assume-console [ + 659 ¦ press enter + 660 ¦ press down-arrow + 661 ] + 662 event-loop screen, console, env, resources + 663 # no scroll + 664 screen-should-contain [ + 665 ¦ . run (F4) . + 666 ¦ . ╎ . + 667 ¦ . ╎─────────────────────────────────────────────────. + 668 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 669 ¦ . ╎ . + 670 ] + 671 ] + 672 + 673 scenario cursor-down-in-recipe-editor [ + 674 local-scope + 675 trace-until 100/app + 676 assume-screen 100/width, 10/height + 677 assume-resources [ + 678 ] + 679 env:&:environment <- new-programming-environment resources, screen, [] + 680 render-all screen, env, render + 681 assume-console [ + 682 ¦ press enter + 683 ¦ press up-arrow + 684 ¦ press down-arrow # while cursor isn't at bottom + 685 ] + 686 event-loop screen, console, env, resources + 687 cursor:char <- copy 9251/␣ + 688 print screen, cursor + 689 # cursor moves back to bottom + 690 screen-should-contain [ + 691 ¦ . run (F4) . + 692 ¦ . ╎ . + 693 ¦ .␣ ╎─────────────────────────────────────────────────. + 694 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 695 ¦ . ╎ . + 696 ] + 697 ] + 698 + 699 # we'll not use the recipe-editor's 'bottom' element directly, because later + 700 # layers will add other stuff to the left side below the editor (error messages) + 701 + 702 container environment [ + 703 recipe-bottom:num + 704 ] + 705 + 706 after <render-recipe-components-end> [ + 707 *env <- put *env, recipe-bottom:offset, row + 708 ] + 709 + 710 after <global-keypress> [ + 711 { + 712 ¦ break-if sandbox-in-focus? + 713 ¦ down-arrow?:bool <- equal k, 65516/down-arrow + 714 ¦ break-unless down-arrow? + 715 ¦ recipe-editor:&:editor <- get *env, recipes:offset + 716 ¦ recipe-cursor-row:num <- get *recipe-editor, cursor-row:offset + 717 ¦ recipe-editor-bottom:num <- get *recipe-editor, bottom:offset + 718 ¦ at-bottom-of-editor?:bool <- greater-or-equal recipe-cursor-row, recipe-editor-bottom + 719 ¦ break-unless at-bottom-of-editor? + 720 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen + 721 ¦ break-if more-to-scroll? + 722 ¦ loop +next-event + 723 } + 724 { + 725 ¦ break-if sandbox-in-focus? + 726 ¦ page-down?:bool <- equal k, 65518/page-down + 727 ¦ break-unless page-down? + 728 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen + 729 ¦ break-if more-to-scroll? + 730 ¦ loop +next-event + 731 } + 732 ] + 733 + 734 after <global-type> [ + 735 { + 736 ¦ break-if sandbox-in-focus? + 737 ¦ page-down?:bool <- equal k, 6/ctrl-f + 738 ¦ break-unless page-down? + 739 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen + 740 ¦ break-if more-to-scroll? + 741 ¦ loop +next-event + 742 } + 743 ] + 744 + 745 def more-to-scroll? env:&:environment, screen:&:screen -> result:bool [ + 746 local-scope + 747 load-ingredients + 748 recipe-bottom:num <- get *env, recipe-bottom:offset + 749 height:num <- screen-height screen + 750 result <- greater-or-equal recipe-bottom, height + 751 ] + 752 + 753 scenario scrolling-down-past-bottom-of-recipe-editor-2 [ + 754 local-scope + 755 trace-until 100/app + 756 assume-screen 100/width, 10/height + 757 assume-resources [ + 758 ] + 759 env:&:environment <- new-programming-environment resources, screen, [] + 760 render-all screen, env, render + 761 assume-console [ + 762 ¦ # add a line + 763 ¦ press enter + 764 ¦ # cursor back to top line + 765 ¦ press up-arrow + 766 ¦ # try to scroll + 767 ¦ press page-down # or ctrl-f + 768 ] + 769 event-loop screen, console, env, resources + 770 # no scroll, and cursor remains at top line + 771 screen-should-contain [ + 772 ¦ . run (F4) . + 773 ¦ . ╎ . + 774 ¦ . ╎─────────────────────────────────────────────────. + 775 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 776 ¦ . ╎ . + 777 ] + 778 ] + 779 + 780 scenario scrolling-down-past-bottom-of-recipe-editor-3 [ + 781 local-scope + 782 trace-until 100/app + 783 assume-screen 100/width, 10/height + 784 assume-resources [ + 785 ] + 786 env:&:environment <- new-programming-environment resources, screen, [ab + 787 cd] + 788 render-all screen, env, render + 789 assume-console [ + 790 ¦ # add a line + 791 ¦ press enter + 792 ¦ # switch to sandbox + 793 ¦ press ctrl-n + 794 ¦ # move cursor + 795 ¦ press down-arrow + 796 ] + 797 event-loop screen, console, env, resources + 798 cursor:char <- copy 9251/␣ + 799 print screen, cursor + 800 # no scroll on recipe side, cursor moves on sandbox side + 801 screen-should-contain [ + 802 ¦ . run (F4) . + 803 ¦ . ╎ab . + 804 ¦ . ╎␣d . + 805 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 806 ¦ . ╎ . + 807 ] + 808 ] 809 - 810 scenario scrolling-down-past-bottom-of-sandbox-editor [ - 811 local-scope - 812 trace-until 100/app # trace too long - 813 assume-screen 100/width, 10/height - 814 # initialize - 815 assume-resources [ - 816 ] - 817 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] - 818 render-all screen, env, render - 819 assume-console [ - 820 ¦ # create a sandbox - 821 ¦ press F4 - 822 ] - 823 event-loop screen, console, env, resources - 824 screen-should-contain [ - 825 ¦ . run (F4) . - 826 ¦ . ╎ . - 827 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 828 ¦ . ╎0 edit copy delete . - 829 ¦ . ╎add 2, 2 . - 830 ] - 831 # switch to sandbox window and hit 'page-down' - 832 assume-console [ - 833 ¦ press ctrl-n - 834 ¦ press page-down - 835 ] - 836 run [ - 837 ¦ event-loop screen, console, env, resources - 838 ¦ cursor:char <- copy 9251/␣ - 839 ¦ print screen, cursor - 840 ] - 841 # sandbox editor hidden; first sandbox displayed - 842 # cursor moves to first sandbox - 843 screen-should-contain [ - 844 ¦ . run (F4) . - 845 ¦ . ╎─────────────────────────────────────────────────. - 846 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete . - 847 ¦ . ╎add 2, 2 . - 848 ¦ . ╎4 . - 849 ] - 850 # hit 'page-up' - 851 assume-console [ - 852 ¦ press page-up - 853 ] - 854 run [ - 855 ¦ event-loop screen, console, env, resources - 856 ¦ cursor:char <- copy 9251/␣ - 857 ¦ print screen, cursor - 858 ] - 859 # sandbox editor displays again, cursor is in editor - 860 screen-should-contain [ - 861 ¦ . run (F4) . - 862 ¦ . ╎␣ . - 863 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 864 ¦ . ╎0 edit copy delete . - 865 ¦ . ╎add 2, 2 . - 866 ] - 867 ] - 868 - 869 # page-down on sandbox side updates render-from to scroll sandboxes - 870 after <global-keypress> [ - 871 { - 872 ¦ break-unless sandbox-in-focus? - 873 ¦ page-down?:bool <- equal k, 65518/page-down - 874 ¦ break-unless page-down? - 875 ¦ sandbox:&:sandbox <- get *env, sandbox:offset - 876 ¦ break-unless sandbox - 877 ¦ # slide down if possible - 878 ¦ { - 879 ¦ ¦ render-from:num <- get *env, render-from:offset - 880 ¦ ¦ number-of-sandboxes:num <- get *env, number-of-sandboxes:offset - 881 ¦ ¦ max:num <- subtract number-of-sandboxes, 1 - 882 ¦ ¦ at-end?:bool <- greater-or-equal render-from, max - 883 ¦ ¦ jump-if at-end?, +finish-event # render nothing - 884 ¦ ¦ render-from <- add render-from, 1 - 885 ¦ ¦ *env <- put *env, render-from:offset, render-from - 886 ¦ } - 887 ¦ hide-screen screen - 888 ¦ screen <- render-sandbox-side screen, env, render - 889 ¦ show-screen screen - 890 ¦ jump +finish-event - 891 } - 892 ] - 893 - 894 # update-cursor takes render-from into account - 895 after <update-cursor-special-cases> [ - 896 { - 897 ¦ break-unless sandbox-in-focus? - 898 ¦ render-from:num <- get *env, render-from:offset - 899 ¦ scrolling?:bool <- greater-or-equal render-from, 0 - 900 ¦ break-unless scrolling? - 901 ¦ cursor-column:num <- get *current-sandbox, left:offset - 902 ¦ screen <- move-cursor screen, 2/row, cursor-column # highlighted sandbox will always start at row 2 - 903 ¦ return - 904 } - 905 ] - 906 - 907 # 'page-up' on sandbox side is like 'page-down': updates render-from when necessary - 908 after <global-keypress> [ - 909 { - 910 ¦ break-unless sandbox-in-focus? - 911 ¦ page-up?:bool <- equal k, 65519/page-up - 912 ¦ break-unless page-up? - 913 ¦ render-from:num <- get *env, render-from:offset - 914 ¦ at-beginning?:bool <- equal render-from, -1 - 915 ¦ break-if at-beginning? - 916 ¦ render-from <- subtract render-from, 1 - 917 ¦ *env <- put *env, render-from:offset, render-from - 918 ¦ hide-screen screen - 919 ¦ screen <- render-sandbox-side screen, env, render - 920 ¦ show-screen screen - 921 ¦ jump +finish-event - 922 } - 923 ] - 924 - 925 # sandbox belonging to 'env' whose next-sandbox is 'in' - 926 # return 0 if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox - 927 def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [ - 928 local-scope - 929 load-ingredients - 930 curr:&:sandbox <- get *env, sandbox:offset - 931 return-unless curr, 0/nil - 932 next:&:sandbox <- get *curr, next-sandbox:offset - 933 { - 934 ¦ return-unless next, 0/nil - 935 ¦ found?:bool <- equal next, in - 936 ¦ break-if found? - 937 ¦ curr <- copy next - 938 ¦ next <- get *curr, next-sandbox:offset - 939 ¦ loop - 940 } - 941 return curr - 942 ] - 943 - 944 scenario scrolling-down-past-bottom-on-recipe-side [ - 945 local-scope - 946 trace-until 100/app # trace too long - 947 assume-screen 100/width, 10/height - 948 # initialize sandbox side and create a sandbox - 949 assume-resources [ - 950 ¦ [lesson/recipes.mu] <- [ - 951 ¦ ¦ || # file containing just a newline - 952 ¦ ] - 953 ] - 954 # create a sandbox - 955 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] - 956 render-all screen, env, render - 957 assume-console [ - 958 ¦ press F4 - 959 ] - 960 event-loop screen, console, env, resources - 961 # hit 'down' in recipe editor - 962 assume-console [ - 963 ¦ press page-down - 964 ] - 965 run [ - 966 ¦ event-loop screen, console, env, resources - 967 ¦ cursor:char <- copy 9251/␣ - 968 ¦ print screen, cursor - 969 ] - 970 # cursor doesn't move when the end is already on-screen - 971 screen-should-contain [ - 972 ¦ . run (F4) . - 973 ¦ .␣ ╎ . - 974 ¦ . ╎─────────────────────────────────────────────────. - 975 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . - 976 ¦ . ╎add 2, 2 . - 977 ] - 978 ] - 979 - 980 scenario scrolling-through-multiple-sandboxes [ - 981 local-scope - 982 trace-until 100/app # trace too long - 983 assume-screen 100/width, 10/height - 984 # initialize environment - 985 assume-resources [ - 986 ] - 987 env:&:environment <- new-programming-environment resources, screen, [] - 988 render-all screen, env, render - 989 # create 2 sandboxes - 990 assume-console [ - 991 ¦ press ctrl-n - 992 ¦ type [add 2, 2] - 993 ¦ press F4 - 994 ¦ type [add 1, 1] + 810 # scrolling through sandboxes + 811 + 812 scenario scrolling-down-past-bottom-of-sandbox-editor [ + 813 local-scope + 814 trace-until 100/app # trace too long + 815 assume-screen 100/width, 10/height + 816 # initialize + 817 assume-resources [ + 818 ] + 819 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] + 820 render-all screen, env, render + 821 assume-console [ + 822 ¦ # create a sandbox + 823 ¦ press F4 + 824 ] + 825 event-loop screen, console, env, resources + 826 screen-should-contain [ + 827 ¦ . run (F4) . + 828 ¦ . ╎ . + 829 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 830 ¦ . ╎0 edit copy delete . + 831 ¦ . ╎add 2, 2 . + 832 ] + 833 # switch to sandbox window and hit 'page-down' + 834 assume-console [ + 835 ¦ press ctrl-n + 836 ¦ press page-down + 837 ] + 838 run [ + 839 ¦ event-loop screen, console, env, resources + 840 ¦ cursor:char <- copy 9251/␣ + 841 ¦ print screen, cursor + 842 ] + 843 # sandbox editor hidden; first sandbox displayed + 844 # cursor moves to first sandbox + 845 screen-should-contain [ + 846 ¦ . run (F4) . + 847 ¦ . ╎─────────────────────────────────────────────────. + 848 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete . + 849 ¦ . ╎add 2, 2 . + 850 ¦ . ╎4 . + 851 ] + 852 # hit 'page-up' + 853 assume-console [ + 854 ¦ press page-up + 855 ] + 856 run [ + 857 ¦ event-loop screen, console, env, resources + 858 ¦ cursor:char <- copy 9251/␣ + 859 ¦ print screen, cursor + 860 ] + 861 # sandbox editor displays again, cursor is in editor + 862 screen-should-contain [ + 863 ¦ . run (F4) . + 864 ¦ . ╎␣ . + 865 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 866 ¦ . ╎0 edit copy delete . + 867 ¦ . ╎add 2, 2 . + 868 ] + 869 ] + 870 + 871 # page-down on sandbox side updates render-from to scroll sandboxes + 872 after <global-keypress> [ + 873 { + 874 ¦ break-unless sandbox-in-focus? + 875 ¦ page-down?:bool <- equal k, 65518/page-down + 876 ¦ break-unless page-down? + 877 ¦ sandbox:&:sandbox <- get *env, sandbox:offset + 878 ¦ break-unless sandbox + 879 ¦ # slide down if possible + 880 ¦ { + 881 ¦ ¦ render-from:num <- get *env, render-from:offset + 882 ¦ ¦ number-of-sandboxes:num <- get *env, number-of-sandboxes:offset + 883 ¦ ¦ max:num <- subtract number-of-sandboxes, 1 + 884 ¦ ¦ at-end?:bool <- greater-or-equal render-from, max + 885 ¦ ¦ jump-if at-end?, +finish-event # render nothing + 886 ¦ ¦ render-from <- add render-from, 1 + 887 ¦ ¦ *env <- put *env, render-from:offset, render-from + 888 ¦ } + 889 ¦ hide-screen screen + 890 ¦ screen <- render-sandbox-side screen, env, render + 891 ¦ show-screen screen + 892 ¦ jump +finish-event + 893 } + 894 ] + 895 + 896 # update-cursor takes render-from into account + 897 after <update-cursor-special-cases> [ + 898 { + 899 ¦ break-unless sandbox-in-focus? + 900 ¦ render-from:num <- get *env, render-from:offset + 901 ¦ scrolling?:bool <- greater-or-equal render-from, 0 + 902 ¦ break-unless scrolling? + 903 ¦ cursor-column:num <- get *current-sandbox, left:offset + 904 ¦ screen <- move-cursor screen, 2/row, cursor-column # highlighted sandbox will always start at row 2 + 905 ¦ return + 906 } + 907 ] + 908 + 909 # 'page-up' on sandbox side is like 'page-down': updates render-from when necessary + 910 after <global-keypress> [ + 911 { + 912 ¦ break-unless sandbox-in-focus? + 913 ¦ page-up?:bool <- equal k, 65519/page-up + 914 ¦ break-unless page-up? + 915 ¦ render-from:num <- get *env, render-from:offset + 916 ¦ at-beginning?:bool <- equal render-from, -1 + 917 ¦ break-if at-beginning? + 918 ¦ render-from <- subtract render-from, 1 + 919 ¦ *env <- put *env, render-from:offset, render-from + 920 ¦ hide-screen screen + 921 ¦ screen <- render-sandbox-side screen, env, render + 922 ¦ show-screen screen + 923 ¦ jump +finish-event + 924 } + 925 ] + 926 + 927 # sandbox belonging to 'env' whose next-sandbox is 'in' + 928 # return 0 if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox + 929 def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [ + 930 local-scope + 931 load-ingredients + 932 curr:&:sandbox <- get *env, sandbox:offset + 933 return-unless curr, 0/nil + 934 next:&:sandbox <- get *curr, next-sandbox:offset + 935 { + 936 ¦ return-unless next, 0/nil + 937 ¦ found?:bool <- equal next, in + 938 ¦ break-if found? + 939 ¦ curr <- copy next + 940 ¦ next <- get *curr, next-sandbox:offset + 941 ¦ loop + 942 } + 943 return curr + 944 ] + 945 + 946 scenario scrolling-down-past-bottom-on-recipe-side [ + 947 local-scope + 948 trace-until 100/app # trace too long + 949 assume-screen 100/width, 10/height + 950 # initialize sandbox side and create a sandbox + 951 assume-resources [ + 952 ¦ [lesson/recipes.mu] <- [ + 953 ¦ ¦ || # file containing just a newline + 954 ¦ ] + 955 ] + 956 # create a sandbox + 957 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] + 958 render-all screen, env, render + 959 assume-console [ + 960 ¦ press F4 + 961 ] + 962 event-loop screen, console, env, resources + 963 # hit 'down' in recipe editor + 964 assume-console [ + 965 ¦ press page-down + 966 ] + 967 run [ + 968 ¦ event-loop screen, console, env, resources + 969 ¦ cursor:char <- copy 9251/␣ + 970 ¦ print screen, cursor + 971 ] + 972 # cursor doesn't move when the end is already on-screen + 973 screen-should-contain [ + 974 ¦ . run (F4) . + 975 ¦ .␣ ╎ . + 976 ¦ . ╎─────────────────────────────────────────────────. + 977 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . + 978 ¦ . ╎add 2, 2 . + 979 ] + 980 ] + 981 + 982 scenario scrolling-through-multiple-sandboxes [ + 983 local-scope + 984 trace-until 100/app # trace too long + 985 assume-screen 100/width, 10/height + 986 # initialize environment + 987 assume-resources [ + 988 ] + 989 env:&:environment <- new-programming-environment resources, screen, [] + 990 render-all screen, env, render + 991 # create 2 sandboxes + 992 assume-console [ + 993 ¦ press ctrl-n + 994 ¦ type [add 2, 2] 995 ¦ press F4 - 996 ] - 997 event-loop screen, console, env, resources - 998 cursor:char <- copy 9251/␣ - 999 print screen, cursor -1000 screen-should-contain [ -1001 ¦ . run (F4) . -1002 ¦ . ╎␣ . -1003 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1004 ¦ . ╎0 edit copy delete . -1005 ¦ . ╎add 1, 1 . -1006 ¦ . ╎2 . -1007 ¦ . ╎─────────────────────────────────────────────────. -1008 ¦ . ╎1 edit copy delete . -1009 ¦ . ╎add 2, 2 . -1010 ¦ . ╎4 . -1011 ] -1012 # hit 'page-down' -1013 assume-console [ -1014 ¦ press page-down -1015 ] -1016 run [ -1017 ¦ event-loop screen, console, env, resources -1018 ¦ cursor:char <- copy 9251/␣ -1019 ¦ print screen, cursor -1020 ] -1021 # sandbox editor hidden; first sandbox displayed -1022 # cursor moves to first sandbox -1023 screen-should-contain [ -1024 ¦ . run (F4) . -1025 ¦ . ╎─────────────────────────────────────────────────. -1026 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete . -1027 ¦ . ╎add 1, 1 . -1028 ¦ . ╎2 . -1029 ¦ . ╎─────────────────────────────────────────────────. -1030 ¦ . ╎1 edit copy delete . -1031 ¦ . ╎add 2, 2 . -1032 ¦ . ╎4 . -1033 ] -1034 # hit 'page-down' again -1035 assume-console [ -1036 ¦ press page-down -1037 ] -1038 run [ -1039 ¦ event-loop screen, console, env, resources -1040 ] -1041 # just second sandbox displayed -1042 screen-should-contain [ -1043 ¦ . run (F4) . -1044 ¦ . ╎─────────────────────────────────────────────────. -1045 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . -1046 ¦ . ╎add 2, 2 . -1047 ¦ . ╎4 . -1048 ¦ . ╎─────────────────────────────────────────────────. -1049 ¦ . ╎ . -1050 ] -1051 # hit 'page-down' again -1052 assume-console [ -1053 ¦ press page-down -1054 ] -1055 run [ -1056 ¦ event-loop screen, console, env, resources -1057 ] -1058 # no change -1059 screen-should-contain [ -1060 ¦ . run (F4) . -1061 ¦ . ╎─────────────────────────────────────────────────. -1062 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . -1063 ¦ . ╎add 2, 2 . -1064 ¦ . ╎4 . -1065 ¦ . ╎─────────────────────────────────────────────────. -1066 ¦ . ╎ . -1067 ] -1068 # hit 'page-up' -1069 assume-console [ -1070 ¦ press page-up -1071 ] -1072 run [ -1073 ¦ event-loop screen, console, env, resources -1074 ] -1075 # back to displaying both sandboxes without editor -1076 screen-should-contain [ -1077 ¦ . run (F4) . -1078 ¦ . ╎─────────────────────────────────────────────────. -1079 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . -1080 ¦ . ╎add 1, 1 . -1081 ¦ . ╎2 . -1082 ¦ . ╎─────────────────────────────────────────────────. -1083 ¦ . ╎1 edit copy delete . -1084 ¦ . ╎add 2, 2 . -1085 ¦ . ╎4 . -1086 ] -1087 # hit 'page-up' again -1088 assume-console [ -1089 ¦ press page-up -1090 ] -1091 run [ -1092 ¦ event-loop screen, console, env, resources -1093 ¦ cursor:char <- copy 9251/␣ -1094 ¦ print screen, cursor -1095 ] -1096 # back to displaying both sandboxes as well as editor -1097 screen-should-contain [ -1098 ¦ . run (F4) . -1099 ¦ . ╎␣ . -1100 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1101 ¦ . ╎0 edit copy delete . -1102 ¦ . ╎add 1, 1 . -1103 ¦ . ╎2 . -1104 ¦ . ╎─────────────────────────────────────────────────. -1105 ¦ . ╎1 edit copy delete . -1106 ¦ . ╎add 2, 2 . -1107 ¦ . ╎4 . -1108 ] -1109 # hit 'page-up' again -1110 assume-console [ -1111 ¦ press page-up -1112 ] -1113 run [ -1114 ¦ event-loop screen, console, env, resources -1115 ¦ cursor:char <- copy 9251/␣ -1116 ¦ print screen, cursor -1117 ] -1118 # no change -1119 screen-should-contain [ -1120 ¦ . run (F4) . -1121 ¦ . ╎␣ . -1122 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1123 ¦ . ╎0 edit copy delete . -1124 ¦ . ╎add 1, 1 . -1125 ¦ . ╎2 . -1126 ¦ . ╎─────────────────────────────────────────────────. -1127 ¦ . ╎1 edit copy delete . -1128 ¦ . ╎add 2, 2 . -1129 ¦ . ╎4 . -1130 ] -1131 ] -1132 -1133 scenario scrolling-manages-sandbox-index-correctly [ -1134 local-scope -1135 trace-until 100/app # trace too long -1136 assume-screen 100/width, 10/height -1137 # initialize environment -1138 assume-resources [ -1139 ] -1140 env:&:environment <- new-programming-environment resources, screen, [] -1141 render-all screen, env, render -1142 # create a sandbox -1143 assume-console [ -1144 ¦ press ctrl-n -1145 ¦ type [add 1, 1] -1146 ¦ press F4 -1147 ] -1148 event-loop screen, console, env, resources -1149 screen-should-contain [ -1150 ¦ . run (F4) . -1151 ¦ . ╎ . -1152 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1153 ¦ . ╎0 edit copy delete . -1154 ¦ . ╎add 1, 1 . -1155 ¦ . ╎2 . -1156 ¦ . ╎─────────────────────────────────────────────────. -1157 ¦ . ╎ . -1158 ] -1159 # hit 'page-down' and 'page-up' a couple of times. sandbox index should be stable -1160 assume-console [ -1161 ¦ press page-down -1162 ] -1163 run [ -1164 ¦ event-loop screen, console, env, resources -1165 ] -1166 # sandbox editor hidden; first sandbox displayed -1167 # cursor moves to first sandbox -1168 screen-should-contain [ -1169 ¦ . run (F4) . -1170 ¦ . ╎─────────────────────────────────────────────────. -1171 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . -1172 ¦ . ╎add 1, 1 . -1173 ¦ . ╎2 . -1174 ¦ . ╎─────────────────────────────────────────────────. -1175 ¦ . ╎ . -1176 ] -1177 # hit 'page-up' again -1178 assume-console [ -1179 ¦ press page-up -1180 ] -1181 run [ -1182 ¦ event-loop screen, console, env, resources -1183 ] -1184 # back to displaying both sandboxes as well as editor -1185 screen-should-contain [ -1186 ¦ . run (F4) . -1187 ¦ . ╎ . -1188 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1189 ¦ . ╎0 edit copy delete . -1190 ¦ . ╎add 1, 1 . -1191 ¦ . ╎2 . -1192 ¦ . ╎─────────────────────────────────────────────────. -1193 ¦ . ╎ . -1194 ] -1195 # hit 'page-down' -1196 assume-console [ -1197 ¦ press page-down -1198 ] -1199 run [ -1200 ¦ event-loop screen, console, env, resources -1201 ] -1202 # sandbox editor hidden; first sandbox displayed -1203 # cursor moves to first sandbox -1204 screen-should-contain [ -1205 ¦ . run (F4) . -1206 ¦ . ╎─────────────────────────────────────────────────. -1207 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . -1208 ¦ . ╎add 1, 1 . -1209 ¦ . ╎2 . -1210 ¦ . ╎─────────────────────────────────────────────────. -1211 ¦ . ╎ . -1212 ] -1213 ] + 996 ¦ type [add 1, 1] + 997 ¦ press F4 + 998 ] + 999 event-loop screen, console, env, resources +1000 cursor:char <- copy 9251/␣ +1001 print screen, cursor +1002 screen-should-contain [ +1003 ¦ . run (F4) . +1004 ¦ . ╎␣ . +1005 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1006 ¦ . ╎0 edit copy delete . +1007 ¦ . ╎add 1, 1 . +1008 ¦ . ╎2 . +1009 ¦ . ╎─────────────────────────────────────────────────. +1010 ¦ . ╎1 edit copy delete . +1011 ¦ . ╎add 2, 2 . +1012 ¦ . ╎4 . +1013 ] +1014 # hit 'page-down' +1015 assume-console [ +1016 ¦ press page-down +1017 ] +1018 run [ +1019 ¦ event-loop screen, console, env, resources +1020 ¦ cursor:char <- copy 9251/␣ +1021 ¦ print screen, cursor +1022 ] +1023 # sandbox editor hidden; first sandbox displayed +1024 # cursor moves to first sandbox +1025 screen-should-contain [ +1026 ¦ . run (F4) . +1027 ¦ . ╎─────────────────────────────────────────────────. +1028 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete . +1029 ¦ . ╎add 1, 1 . +1030 ¦ . ╎2 . +1031 ¦ . ╎─────────────────────────────────────────────────. +1032 ¦ . ╎1 edit copy delete . +1033 ¦ . ╎add 2, 2 . +1034 ¦ . ╎4 . +1035 ] +1036 # hit 'page-down' again +1037 assume-console [ +1038 ¦ press page-down +1039 ] +1040 run [ +1041 ¦ event-loop screen, console, env, resources +1042 ] +1043 # just second sandbox displayed +1044 screen-should-contain [ +1045 ¦ . run (F4) . +1046 ¦ . ╎─────────────────────────────────────────────────. +1047 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . +1048 ¦ . ╎add 2, 2 . +1049 ¦ . ╎4 . +1050 ¦ . ╎─────────────────────────────────────────────────. +1051 ¦ . ╎ . +1052 ] +1053 # hit 'page-down' again +1054 assume-console [ +1055 ¦ press page-down +1056 ] +1057 run [ +1058 ¦ event-loop screen, console, env, resources +1059 ] +1060 # no change +1061 screen-should-contain [ +1062 ¦ . run (F4) . +1063 ¦ . ╎─────────────────────────────────────────────────. +1064 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . +1065 ¦ . ╎add 2, 2 . +1066 ¦ . ╎4 . +1067 ¦ . ╎─────────────────────────────────────────────────. +1068 ¦ . ╎ . +1069 ] +1070 # hit 'page-up' +1071 assume-console [ +1072 ¦ press page-up +1073 ] +1074 run [ +1075 ¦ event-loop screen, console, env, resources +1076 ] +1077 # back to displaying both sandboxes without editor +1078 screen-should-contain [ +1079 ¦ . run (F4) . +1080 ¦ . ╎─────────────────────────────────────────────────. +1081 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +1082 ¦ . ╎add 1, 1 . +1083 ¦ . ╎2 . +1084 ¦ . ╎─────────────────────────────────────────────────. +1085 ¦ . ╎1 edit copy delete . +1086 ¦ . ╎add 2, 2 . +1087 ¦ . ╎4 . +1088 ] +1089 # hit 'page-up' again +1090 assume-console [ +1091 ¦ press page-up +1092 ] +1093 run [ +1094 ¦ event-loop screen, console, env, resources +1095 ¦ cursor:char <- copy 9251/␣ +1096 ¦ print screen, cursor +1097 ] +1098 # back to displaying both sandboxes as well as editor +1099 screen-should-contain [ +1100 ¦ . run (F4) . +1101 ¦ . ╎␣ . +1102 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1103 ¦ . ╎0 edit copy delete . +1104 ¦ . ╎add 1, 1 . +1105 ¦ . ╎2 . +1106 ¦ . ╎─────────────────────────────────────────────────. +1107 ¦ . ╎1 edit copy delete . +1108 ¦ . ╎add 2, 2 . +1109 ¦ . ╎4 . +1110 ] +1111 # hit 'page-up' again +1112 assume-console [ +1113 ¦ press page-up +1114 ] +1115 run [ +1116 ¦ event-loop screen, console, env, resources +1117 ¦ cursor:char <- copy 9251/␣ +1118 ¦ print screen, cursor +1119 ] +1120 # no change +1121 screen-should-contain [ +1122 ¦ . run (F4) . +1123 ¦ . ╎␣ . +1124 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1125 ¦ . ╎0 edit copy delete . +1126 ¦ . ╎add 1, 1 . +1127 ¦ . ╎2 . +1128 ¦ . ╎─────────────────────────────────────────────────. +1129 ¦ . ╎1 edit copy delete . +1130 ¦ . ╎add 2, 2 . +1131 ¦ . ╎4 . +1132 ] +1133 ] +1134 +1135 scenario scrolling-manages-sandbox-index-correctly [ +1136 local-scope +1137 trace-until 100/app # trace too long +1138 assume-screen 100/width, 10/height +1139 # initialize environment +1140 assume-resources [ +1141 ] +1142 env:&:environment <- new-programming-environment resources, screen, [] +1143 render-all screen, env, render +1144 # create a sandbox +1145 assume-console [ +1146 ¦ press ctrl-n +1147 ¦ type [add 1, 1] +1148 ¦ press F4 +1149 ] +1150 event-loop screen, console, env, resources +1151 screen-should-contain [ +1152 ¦ . run (F4) . +1153 ¦ . ╎ . +1154 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1155 ¦ . ╎0 edit copy delete . +1156 ¦ . ╎add 1, 1 . +1157 ¦ . ╎2 . +1158 ¦ . ╎─────────────────────────────────────────────────. +1159 ¦ . ╎ . +1160 ] +1161 # hit 'page-down' and 'page-up' a couple of times. sandbox index should be stable +1162 assume-console [ +1163 ¦ press page-down +1164 ] +1165 run [ +1166 ¦ event-loop screen, console, env, resources +1167 ] +1168 # sandbox editor hidden; first sandbox displayed +1169 # cursor moves to first sandbox +1170 screen-should-contain [ +1171 ¦ . run (F4) . +1172 ¦ . ╎─────────────────────────────────────────────────. +1173 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +1174 ¦ . ╎add 1, 1 . +1175 ¦ . ╎2 . +1176 ¦ . ╎─────────────────────────────────────────────────. +1177 ¦ . ╎ . +1178 ] +1179 # hit 'page-up' again +1180 assume-console [ +1181 ¦ press page-up +1182 ] +1183 run [ +1184 ¦ event-loop screen, console, env, resources +1185 ] +1186 # back to displaying both sandboxes as well as editor +1187 screen-should-contain [ +1188 ¦ . run (F4) . +1189 ¦ . ╎ . +1190 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1191 ¦ . ╎0 edit copy delete . +1192 ¦ . ╎add 1, 1 . +1193 ¦ . ╎2 . +1194 ¦ . ╎─────────────────────────────────────────────────. +1195 ¦ . ╎ . +1196 ] +1197 # hit 'page-down' +1198 assume-console [ +1199 ¦ press page-down +1200 ] +1201 run [ +1202 ¦ event-loop screen, console, env, resources +1203 ] +1204 # sandbox editor hidden; first sandbox displayed +1205 # cursor moves to first sandbox +1206 screen-should-contain [ +1207 ¦ . run (F4) . +1208 ¦ . ╎─────────────────────────────────────────────────. +1209 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +1210 ¦ . ╎add 1, 1 . +1211 ¦ . ╎2 . +1212 ¦ . ╎─────────────────────────────────────────────────. +1213 ¦ . ╎ . +1214 ] +1215 ] -- cgit 1.4.1-2-gfad0