1
2
3
4
5
6
7
8
9
10 def! main [
11 local-scope
12 open-console
13 env:&:environment <- new-programming-environment 0/filesystem, 0/screen
14 env <- restore-sandboxes env
15 render-all 0/screen, env, render
16 event-loop 0/screen, 0/console, env, 0/filesystem
17
18 ]
19
20 container environment [
21 sandbox:&:sandbox
22 render-from:num
23 number-of-sandboxes:num
24 ]
25
26 after <programming-environment-initialization> [
27 *result <- put *result, render-from:offset, -1
28 ]
29
30 container sandbox [
31 data:text
32 response:text
33
34
35 starting-row-on-screen:num
36 code-ending-row-on-screen:num
37 screen:&:screen
38 next-sandbox:&:sandbox
39 ]
40
41 scenario run-and-show-results [
42 local-scope
43 trace-until 100/app
44 assume-screen 100/width, 15/height
45
46 assume-resources [
47 ]
48
49 env:&:environment <- new-programming-environment resources, screen, [divide-with-remainder 11, 3]
50
51 assume-console [
52 press F4
53 ]
54 run [
55 event-loop screen, console, env, resources
56 ]
57
58 screen-should-contain [
59 . run (F4) .
60 . ╎ .
61 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
62 . ╎0 edit copy delete .
63 . ╎divide-with-remainder 11, 3 .
64 . ╎3 .
65 . ╎2 .
66 . ╎─────────────────────────────────────────────────.
67 . ╎ .
68 ]
69 screen-should-contain-in-color 7/white, [
70 . .
71 . .
72 . .
73 . .
74 . divide-with-remainder 11, 3 .
75 . .
76 . .
77 . .
78 . .
79 ]
80 screen-should-contain-in-color 245/grey, [
81 . .
82 . ╎ .
83 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
84 . ╎ .
85 . ╎ .
86 . ╎3 .
87 . ╎2 .
88 . ╎─────────────────────────────────────────────────.
89 . ╎ .
90 ]
91
92 screen-should-contain-in-color 232/black, [
93 . .
94 . .
95 . .
96 . 0 edit copy delete .
97 ]
98
99 assume-console [
100 left-click 1, 80
101 type [add 2, 2]
102 press F4
103 ]
104 run [
105 event-loop screen, console, env, resources
106 ]
107
108 screen-should-contain [
109 . run (F4) .
110 . ╎ .
111 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
112 . ╎0 edit copy delete .
113 . ╎add 2, 2 .
114 . ╎4 .
115 . ╎─────────────────────────────────────────────────.
116 . ╎1 edit copy delete .
117 . ╎divide-with-remainder 11, 3 .
118 . ╎3 .
119 . ╎2 .
120 . ╎─────────────────────────────────────────────────.
121 . ╎ .
122 ]
123 ]
124
125 after <global-keypress> [
126
127 {
128 do-run?:bool <- equal k, 65532/F4
129 break-unless do-run?
130 screen <- update-status screen, [running... ], 245/grey
131 error?:bool <- run-sandboxes env, resources, screen
132
133 screen <- render-all screen, env, render
134 {
135 break-if error?
136 screen <- update-status screen, [ ], 245/grey
137 }
138 screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
139 loop +next-event
140 }
141 ]
142
143 def run-sandboxes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [
144 local-scope
145 load-ingredients
146 errors-found?:bool <- update-recipes env, resources, screen
147 return-if errors-found?
148
149 <run-sandboxes-begin>
150 current-sandbox:&:editor <- get *env, current-sandbox:offset
151 {
152 sandbox-contents:text <- editor-contents current-sandbox
153 break-unless sandbox-contents
154
155
156 new-sandbox:&:sandbox <- new sandbox:type
157 *new-sandbox <- put *new-sandbox, data:offset, sandbox-contents
158
159 dest:&:sandbox <- get *env, sandbox:offset
160 *new-sandbox <- put *new-sandbox, next-sandbox:offset, dest
161 *env <- put *env, sandbox:offset, new-sandbox
162
163 sandbox-count:num <- get *env, number-of-sandboxes:offset
164 sandbox-count <- add sandbox-count, 1
165 *env <- put *env, number-of-sandboxes:offset, sandbox-count
166
167 init:&:duplex-list:char <- push 167/§, 0/tail
168 *current-sandbox <- put *current-sandbox, data:offset, init
169 *current-sandbox <- put *current-sandbox, top-of-screen:offset, init
170 }
171
172 save-sandboxes env, resources
173
174 curr:&:sandbox <- get *env, sandbox:offset
175 idx:num <- copy 0
176 {
177 break-unless curr
178 curr <- update-sandbox curr, env, idx
179 curr <- get *curr, next-sandbox:offset
180 idx <- add idx, 1
181 loop
182 }
183 <run-sandboxes-end>
184 ]
185
186
187
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
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
220 $system [rm lesson/[0-9]* >/dev/null 2>/dev/null]
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
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
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
270 row <- add row, 1
271 screen <- move-cursor screen, row, left
272 screen <- render-sandbox-menu screen, idx, left, right
273
274 *sandbox <- put *sandbox, starting-row-on-screen:offset, row
275
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
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
299 draw-horizontal screen, row, left, right
300 }
301
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
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
337
338
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
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
355
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
370 break-if done?
371 c:char <- index *s, i
372 {
373
374 at-right?:bool <- equal column, right
375 break-unless at-right?
376
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
383 }
384 i <- add i, 1
385 {
386
387 newline?:bool <- equal c, 10/newline
388 break-unless newline?
389
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
417 def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environment [
418 local-scope
419 load-ingredients
420
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
428
429
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
446 *env <- put *env, number-of-sandboxes:offset, idx
447 ]
448
449
450
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
456 row <- render-text screen, [screen:], left, right, 245/grey, row
457 screen <- move-cursor screen, row, left
458
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
472 break-if done?
473 column <- copy left
474 screen <- move-cursor screen, row, column
475
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
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
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
501 print screen, full-stop, 245/grey
502 column <- add column, 1
503 {
504
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
519 assume-screen 100/width, 12/height
520
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
532 env:&:environment <- new-programming-environment resources, screen, [foo]
533
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 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
548 . ╎ .
549 ]
550
551 assume-console [
552 left-click 4, 28
553 press backspace
554 type [3]
555 press F4
556 ]
557 run [
558 event-loop screen, console, env, resources
559 ]
560
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 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
571 . ╎ .
572 ]
573 ]
574
575 scenario run-instruction-manages-screen-per-sandbox [
576 local-scope
577 trace-until 100/app
578 assume-screen 100/width, 20/height
579
580 assume-resources [
581 ]
582
583 env:&:environment <- new-programming-environment resources, screen, [print-integer screen, 4]
584
585 assume-console [
586 press F4
587 ]
588 run [
589 event-loop screen, console, env, resources
590 ]
591
592 screen-should-contain [
593 . run (F4) .
594 . ╎ .
595 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
596 . ╎0 edit copy delete .
597 . ╎print-integer screen, 4 .
598 . ╎screen: .
599 . ╎ .4 . .
600 . ╎ . . .
601 . ╎ . . .
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
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
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
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
683 ]
684 event-loop screen, console, env, resources
685 cursor:char <- copy 9251/␣
686 print screen, cursor
687
688 screen-should-contain [
689 . run (F4) .
690 . ╎ .
691 .␣ ╎─────────────────────────────────────────────────.
692 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .
693 . ╎ .
694 ]
695 ]
696
697
698
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
761 press enter
762
763 press up-arrow
764
765 press page-down
766 ]
767 event-loop screen, console, env, resources
768
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
789 press enter
790
791 press ctrl-n
792
793 press down-arrow
794 ]
795 event-loop screen, console, env, resources
796 cursor:char <- copy 9251/␣
797 print screen, cursor
798
799 screen-should-contain [
800 . run (F4) .
801 . ╎ab .
802 . ╎␣d .
803 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
804 . ╎ .
805 ]
806 ]
807
808
809
810 scenario scrolling-down-past-bottom-of-sandbox-editor [
811 local-scope
812 trace-until 100/app
813 assume-screen 100/width, 10/height
814
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
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
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
842
843 screen-should-contain [
844 . run (F4) .
845 . ╎─────────────────────────────────────────────────.
846 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete .
847 . ╎add 2, 2 .
848 . ╎4 .
849 ]
850
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
860 screen-should-contain [
861 . run (F4) .
862 . ╎␣ .
863 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
864 . ╎0 edit copy delete .
865 . ╎add 2, 2 .
866 ]
867 ]
868
869
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
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
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
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
903 return
904 }
905 ]
906
907
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
926
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
947 assume-screen 100/width, 10/height
948
949 assume-resources [
950 [lesson/recipes.mu] <- [
951 ||
952 ]
953 ]
954
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
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
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
983 assume-screen 100/width, 10/height
984
985 assume-resources [
986 ]
987 env:&:environment <- new-programming-environment resources, screen, []
988 render-all screen, env, render
989
990 assume-console [
991 press ctrl-n
992 type [add 2, 2]
993 press F4
994 type [add 1, 1]
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
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
1022
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
1035 assume-console [
1036 press page-down
1037 ]
1038 run [
1039 event-loop screen, console, env, resources
1040 ]
1041
1042 screen-should-contain [
1043 . run (F4) .
1044 . ╎─────────────────────────────────────────────────.
1045 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete .
1046 . ╎add 2, 2 .
1047 . ╎4 .
1048 . ╎─────────────────────────────────────────────────.
1049 . ╎ .
1050 ]
1051
1052 assume-console [
1053 press page-down
1054 ]
1055 run [
1056 event-loop screen, console, env, resources
1057 ]
1058
1059 screen-should-contain [
1060 . run (F4) .
1061 . ╎─────────────────────────────────────────────────.
1062 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete .
1063 . ╎add 2, 2 .
1064 . ╎4 .
1065 . ╎─────────────────────────────────────────────────.
1066 . ╎ .
1067 ]
1068
1069 assume-console [
1070 press page-up
1071 ]
1072 run [
1073 event-loop screen, console, env, resources
1074 ]
1075
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
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
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
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
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
1136 assume-screen 100/width, 10/height
1137
1138 assume-resources [
1139 ]
1140 env:&:environment <- new-programming-environment resources, screen, []
1141 render-all screen, env, render
1142
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
1160 assume-console [
1161 press page-down
1162 ]
1163 run [
1164 event-loop screen, console, env, resources
1165 ]
1166
1167
1168 screen-should-contain [
1169 . run (F4) .
1170 . ╎─────────────────────────────────────────────────.
1171 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete .
1172 . ╎add 1, 1 .
1173 . ╎2 .
1174 . ╎─────────────────────────────────────────────────.
1175 . ╎ .
1176 ]
1177
1178 assume-console [
1179 press page-up
1180 ]
1181 run [
1182 event-loop screen, console, env, resources
1183 ]
1184
1185 screen-should-contain [
1186 . run (F4) .
1187 . ╎ .
1188 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
1189 . ╎0 edit copy delete .
1190 . ╎add 1, 1 .
1191 . ╎2 .
1192 . ╎─────────────────────────────────────────────────.
1193 . ╎ .
1194 ]
1195
1196 assume-console [
1197 press page-down
1198 ]
1199 run [
1200 event-loop screen, console, env, resources
1201 ]
1202
1203
1204 screen-should-contain [
1205 . run (F4) .
1206 . ╎─────────────────────────────────────────────────.
1207 .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete .
1208 . ╎add 1, 1 .
1209 . ╎2 .
1210 . ╎─────────────────────────────────────────────────.
1211 . ╎ .
1212 ]
1213 ]