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