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