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