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