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