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