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