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