1
2
3
4
5
6
7 scenario editor-inserts-two-spaces-on-tab [
8 local-scope
9 assume-screen 10/width, 5/height
10
11 s:text <- new [ab
12 cd]
13 e:&:editor <- new-editor s, 0/left, 5/right
14 assume-console [
15 ¦ press tab
16 ]
17 run [
18 ¦ editor-event-loop screen, console, e
19 ]
20 screen-should-contain [
21 ¦ . .
22 ¦ . ab .
23 ¦ .cd .
24 ]
25 ]
26
27 after <handle-special-character> [
28 {
29 ¦ tab?:bool <- equal c, 9/tab
30 ¦ break-unless tab?
31 ¦ <insert-character-begin>
32 ¦ insert-at-cursor editor, 32/space, screen
33 ¦ insert-at-cursor editor, 32/space, screen
34 ¦ <insert-character-end>
35 ¦ return 1/go-render
36 }
37 ]
38
39
40
41 scenario editor-handles-backspace-key [
42 local-scope
43 assume-screen 10/width, 5/height
44 e:&:editor <- new-editor [abc], 0/left, 10/right
45 editor-render screen, e
46 $clear-trace
47 assume-console [
48 ¦ left-click 1, 1
49 ¦ press backspace
50 ]
51 run [
52 ¦ editor-event-loop screen, console, e
53 ¦ 4:num/raw <- get *e, cursor-row:offset
54 ¦ 5:num/raw <- get *e, cursor-column:offset
55 ]
56 screen-should-contain [
57 ¦ . .
58 ¦ .bc .
59 ¦ .╌╌╌╌╌╌╌╌╌╌.
60 ¦ . .
61 ]
62 memory-should-contain [
63 ¦ 4 <- 1
64 ¦ 5 <- 0
65 ]
66 check-trace-count-for-label 3, [print-character]
67 ]
68
69 after <handle-special-character> [
70 {
71 ¦ delete-previous-character?:bool <- equal c, 8/backspace
72 ¦ break-unless delete-previous-character?
73 ¦ <backspace-character-begin>
74 ¦ go-render?:bool, backspaced-cell:&:duplex-list:char <- delete-before-cursor editor, screen
75 ¦ <backspace-character-end>
76 ¦ return
77 }
78 ]
79
80
81
82
83 def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, backspaced-cell:&:duplex-list:char, editor:&:editor, screen:&:screen [
84 local-scope
85 load-ingredients
86 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
87 data:&:duplex-list:char <- get *editor, data:offset
88
89 prev:&:duplex-list:char <- prev before-cursor
90 return-unless prev, 0/no-more-render, 0/nothing-deleted
91 trace 10, [app], [delete-before-cursor]
92 original-row:num <- get *editor, cursor-row:offset
93 scroll?:bool <- move-cursor-coordinates-left editor
94 backspaced-cell:&:duplex-list:char <- copy before-cursor
95 data <- remove before-cursor, data
96 before-cursor <- copy prev
97 *editor <- put *editor, before-cursor:offset, before-cursor
98 return-if scroll?, 1/go-render
99 screen-width:num <- screen-width screen
100 cursor-row:num <- get *editor, cursor-row:offset
101 cursor-column:num <- get *editor, cursor-column:offset
102
103 same-row?:bool <- equal cursor-row, original-row
104 return-unless same-row?, 1/go-render
105 left:num <- get *editor, left:offset
106 right:num <- get *editor, right:offset
107 curr:&:duplex-list:char <- next before-cursor
108 screen <- move-cursor screen, cursor-row, cursor-column
109 curr-column:num <- copy cursor-column
110 {
111 ¦
112 ¦ at-right?:bool <- greater-or-equal curr-column, right
113 ¦ return-if at-right?, 1/go-render
114 ¦ break-unless curr
115 ¦
116 ¦ currc:char <- get *curr, value:offset
117 ¦ at-newline?:bool <- equal currc, 10/newline
118 ¦ break-if at-newline?
119 ¦ screen <- print screen, currc
120 ¦ curr-column <- add curr-column, 1
121 ¦ curr <- next curr
122 ¦ loop
123 }
124
125 space:char <- copy 32/space
126 screen <- print screen, space
127 go-render? <- copy 0/false
128 ]
129
130 def move-cursor-coordinates-left editor:&:editor -> go-render?:bool, editor:&:editor [
131 local-scope
132 load-ingredients
133 go-render?:bool <- copy 0/false
134 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
135 cursor-row:num <- get *editor, cursor-row:offset
136 cursor-column:num <- get *editor, cursor-column:offset
137 left:num <- get *editor, left:offset
138
139 {
140 ¦ at-left-margin?:bool <- equal cursor-column, left
141 ¦ break-if at-left-margin?
142 ¦ trace 10, [app], [decrementing cursor column]
143 ¦ cursor-column <- subtract cursor-column, 1
144 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
145 ¦ return
146 }
147
148 top-of-screen?:bool <- equal cursor-row, 1
149 {
150 ¦ break-if top-of-screen?
151 ¦ cursor-row <- subtract cursor-row, 1
152 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
153 }
154 {
155 ¦ break-unless top-of-screen?
156 ¦ <scroll-up>
157 ¦ go-render? <- copy 1/true
158 }
159 {
160 ¦
161 ¦ previous-character:char <- get *before-cursor, value:offset
162 ¦ previous-character-is-newline?:bool <- equal previous-character, 10/newline
163 ¦ break-unless previous-character-is-newline?
164 ¦
165 ¦ trace 10, [app], [switching to previous line]
166 ¦ d:&:duplex-list:char <- get *editor, data:offset
167 ¦ end-of-line:num <- previous-line-length before-cursor, d
168 ¦ right:num <- get *editor, right:offset
169 ¦ width:num <- subtract right, left
170 ¦ wrap?:bool <- greater-than end-of-line, width
171 ¦ {
172 ¦ ¦ break-unless wrap?
173 ¦ ¦ _, column-offset:num <- divide-with-remainder end-of-line, width
174 ¦ ¦ cursor-column <- add left, column-offset
175 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
176 ¦ }
177 ¦ {
178 ¦ ¦ break-if wrap?
179 ¦ ¦ cursor-column <- add left, end-of-line
180 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
181 ¦ }
182 ¦ return
183 }
184
185 trace 10, [app], [wrapping to previous line]
186 right:num <- get *editor, right:offset
187 cursor-column <- subtract right, 1
188 *editor <- put *editor, cursor-column:offset, cursor-column
189 ]
190
191
192
193 def previous-line-length curr:&:duplex-list:char, start:&:duplex-list:char -> result:num [
194 local-scope
195 load-ingredients
196 result:num <- copy 0
197 return-unless curr
198 at-start?:bool <- equal curr, start
199 return-if at-start?
200 {
201 ¦ curr <- prev curr
202 ¦ break-unless curr
203 ¦ at-start?:bool <- equal curr, start
204 ¦ break-if at-start?
205 ¦ c:char <- get *curr, value:offset
206 ¦ at-newline?:bool <- equal c, 10/newline
207 ¦ break-if at-newline?
208 ¦ result <- add result, 1
209 ¦ loop
210 }
211 ]
212
213 scenario editor-clears-last-line-on-backspace [
214 local-scope
215 assume-screen 10/width, 5/height
216
217 s:text <- new [ab
218 cd]
219 e:&:editor <- new-editor s, 0/left, 10/right
220 assume-console [
221 ¦ left-click 2, 0
222 ¦ press backspace
223 ]
224 run [
225 ¦ editor-event-loop screen, console, e
226 ¦ 4:num/raw <- get *e, cursor-row:offset
227 ¦ 5:num/raw <- get *e, cursor-column:offset
228 ]
229 screen-should-contain [
230 ¦ . .
231 ¦ .abcd .
232 ¦ .╌╌╌╌╌╌╌╌╌╌.
233 ¦ . .
234 ]
235 memory-should-contain [
236 ¦ 4 <- 1
237 ¦ 5 <- 2
238 ]
239 ]
240
241 scenario editor-joins-and-wraps-lines-on-backspace [
242 local-scope
243 assume-screen 10/width, 5/height
244
245 s:text <- new [abc def
246 ghi jkl]
247 e:&:editor <- new-editor s, 0/left, 10/right
248 editor-render screen, e
249 $clear-trace
250
251 assume-console [
252 ¦ left-click 2, 0
253 ¦ press backspace
254 ]
255 run [
256 ¦ editor-event-loop screen, console, e
257 ]
258
259 screen-should-contain [
260 ¦ . .
261 ¦ .abc defgh↩.
262 ¦ .i jkl .
263 ¦ .╌╌╌╌╌╌╌╌╌╌.
264 ¦ . .
265 ]
266 ]
267
268 scenario editor-wraps-long-lines-on-backspace [
269 local-scope
270 assume-screen 10/width, 5/height
271
272 e:&:editor <- new-editor [abc def ghij], 0/left, 8/right
273 editor-render screen, e
274
275 screen-should-contain [
276 ¦ . .
277 ¦ .abc def↩ .
278 ¦ . ghij .
279 ¦ .╌╌╌╌╌╌╌╌ .
280 ]
281 $clear-trace
282
283 assume-console [
284 ¦ left-click 1, 4
285 ¦ press backspace
286 ]
287 run [
288 ¦ editor-event-loop screen, console, e
289 ]
290
291 screen-should-contain [
292 ¦ . .
293 ¦ .abcdef ↩ .
294 ¦ .ghij .
295 ¦ .╌╌╌╌╌╌╌╌ .
296 ¦ . .
297 ]
298 ]
299
300
301
302 scenario editor-handles-delete-key [
303 local-scope
304 assume-screen 10/width, 5/height
305 e:&:editor <- new-editor [abc], 0/left, 10/right
306 editor-render screen, e
307 $clear-trace
308 assume-console [
309 ¦ press delete
310 ]
311 run [
312 ¦ editor-event-loop screen, console, e
313 ]
314 screen-should-contain [
315 ¦ . .
316 ¦ .bc .
317 ¦ .╌╌╌╌╌╌╌╌╌╌.
318 ¦ . .
319 ]
320 check-trace-count-for-label 3, [print-character]
321 $clear-trace
322 assume-console [
323 ¦ press delete
324 ]
325 run [
326 ¦ editor-event-loop screen, console, e
327 ]
328 screen-should-contain [
329 ¦ . .
330 ¦ .c .
331 ¦ .╌╌╌╌╌╌╌╌╌╌.
332 ¦ . .
333 ]
334 check-trace-count-for-label 2, [print-character]
335 ]
336
337 after <handle-special-key> [
338 {
339 ¦ delete-next-character?:bool <- equal k, 65522/delete
340 ¦ break-unless delete-next-character?
341 ¦ <delete-character-begin>
342 ¦ go-render?:bool, deleted-cell:&:duplex-list:char <- delete-at-cursor editor, screen
343 ¦ <delete-character-end>
344 ¦ return
345 }
346 ]
347
348 def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, deleted-cell:&:duplex-list:char, editor:&:editor, screen:&:screen [
349 local-scope
350 load-ingredients
351 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
352 data:&:duplex-list:char <- get *editor, data:offset
353 deleted-cell:&:duplex-list:char <- next before-cursor
354 return-unless deleted-cell, 0/don't-render
355 currc:char <- get *deleted-cell, value:offset
356 data <- remove deleted-cell, data
357 deleted-newline?:bool <- equal currc, 10/newline
358 return-if deleted-newline?, 1/go-render
359
360 curr:&:duplex-list:char <- next before-cursor
361 cursor-row:num <- get *editor, cursor-row:offset
362 cursor-column:num <- get *editor, cursor-column:offset
363 screen <- move-cursor screen, cursor-row, cursor-column
364 curr-column:num <- copy cursor-column
365 screen-width:num <- screen-width screen
366 {
367 ¦
368 ¦ at-right?:bool <- greater-or-equal curr-column, screen-width
369 ¦ return-if at-right?, 1/go-render
370 ¦ break-unless curr
371 ¦
372 ¦ currc:char <- get *curr, value:offset
373 ¦ at-newline?:bool <- equal currc, 10/newline
374 ¦ break-if at-newline?
375 ¦ screen <- print screen, currc
376 ¦ curr-column <- add curr-column, 1
377 ¦ curr <- next curr
378 ¦ loop
379 }
380
381 space:char <- copy 32/space
382 screen <- print screen, space
383 go-render? <- copy 0/false
384 ]
385
386
387
388 scenario editor-moves-cursor-right-with-key [
389 local-scope
390 assume-screen 10/width, 5/height
391 e:&:editor <- new-editor [abc], 0/left, 10/right
392 editor-render screen, e
393 $clear-trace
394 assume-console [
395 ¦ press right-arrow
396 ¦ type [0]
397 ]
398 run [
399 ¦ editor-event-loop screen, console, e
400 ]
401 screen-should-contain [
402 ¦ . .
403 ¦ .a0bc .
404 ¦ .╌╌╌╌╌╌╌╌╌╌.
405 ¦ . .
406 ]
407 check-trace-count-for-label 3, [print-character]
408 ]
409
410 after <handle-special-key> [
411 {
412 ¦ move-to-next-character?:bool <- equal k, 65514/right-arrow
413 ¦ break-unless move-to-next-character?
414 ¦
415 ¦ next-cursor:&:duplex-list:char <- next before-cursor
416 ¦ break-unless next-cursor
417 ¦
418 ¦ <move-cursor-begin>
419 ¦ before-cursor <- copy next-cursor
420 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
421 ¦ go-render?:bool <- move-cursor-coordinates-right editor, screen-height
422 ¦ screen <- move-cursor screen, cursor-row, cursor-column
423 ¦ undo-coalesce-tag:num <- copy 2/right-arrow
424 ¦ <move-cursor-end>
425 ¦ return
426 }
427 ]
428
429 def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
430 local-scope
431 load-ingredients
432 before-cursor:&:duplex-list:char <- get *editor before-cursor:offset
433 cursor-row:num <- get *editor, cursor-row:offset
434 cursor-column:num <- get *editor, cursor-column:offset
435 left:num <- get *editor, left:offset
436 right:num <- get *editor, right:offset
437
438 {
439 ¦ old-cursor-character:char <- get *before-cursor, value:offset
440 ¦ was-at-newline?:bool <- equal old-cursor-character, 10/newline
441 ¦ break-unless was-at-newline?
442 ¦ cursor-row <- add cursor-row, 1
443 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
444 ¦ cursor-column <- copy left
445 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
446 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height
447 ¦ return-unless below-screen?, 0/don't-render
448 ¦ <scroll-down>
449 ¦ cursor-row <- subtract cursor-row, 1
450 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
451 ¦ return 1/go-render
452 }
453
454 {
455 ¦
456 ¦ wrap-column:num <- subtract right, 1
457 ¦ at-wrap?:bool <- equal cursor-column, wrap-column
458 ¦ break-unless at-wrap?
459 ¦
460 ¦ next:&:duplex-list:char <- next before-cursor
461 ¦ break-unless next
462 ¦ next-character:char <- get *next, value:offset
463 ¦ newline?:bool <- equal next-character, 10/newline
464 ¦ break-if newline?
465 ¦ cursor-row <- add cursor-row, 1
466 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
467 ¦ cursor-column <- copy left
468 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
469 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height
470 ¦ return-unless below-screen?, 0/no-more-render
471 ¦ <scroll-down>
472 ¦ cursor-row <- subtract cursor-row, 1
473 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
474 ¦ return 1/go-render
475 }
476
477 cursor-column <- add cursor-column, 1
478 *editor <- put *editor, cursor-column:offset, cursor-column
479 go-render? <- copy 0/false
480 ]
481
482 scenario editor-moves-cursor-to-next-line-with-right-arrow [
483 local-scope
484 assume-screen 10/width, 5/height
485 s:text <- new [abc
486 d]
487 e:&:editor <- new-editor s, 0/left, 10/right
488 editor-render screen, e
489 $clear-trace
490
491 assume-console [
492 ¦ press right-arrow
493 ¦ press right-arrow
494 ¦ press right-arrow
495 ¦ press right-arrow
496 ]
497 run [
498 ¦ editor-event-loop screen, console, e
499 ]
500 check-trace-count-for-label 0, [print-character]
501
502 assume-console [
503 ¦ type [0]
504 ]
505 run [
506 ¦ editor-event-loop screen, console, e
507 ]
508 screen-should-contain [
509 ¦ . .
510 ¦ .abc .
511 ¦ .0d .
512 ¦ .╌╌╌╌╌╌╌╌╌╌.
513 ¦ . .
514 ]
515 check-trace-count-for-label 2, [print-character]
516 ]
517
518 scenario editor-moves-cursor-to-next-line-with-right-arrow-2 [
519 local-scope
520 assume-screen 10/width, 5/height
521 s:text <- new [abc
522 d]
523 e:&:editor <- new-editor s, 1/left, 10/right
524 editor-render screen, e
525 assume-console [
526 ¦ press right-arrow
527 ¦ press right-arrow
528 ¦ press right-arrow
529 ¦ press right-arrow
530 ¦ type [0]
531 ]
532 run [
533 ¦ editor-event-loop screen, console, e
534 ]
535 screen-should-contain [
536 ¦ . .
537 ¦ . abc .
538 ¦ . 0d .
539 ¦ . ╌╌╌╌╌╌╌╌╌.
540 ¦ . .
541 ]
542 ]
543
544 scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow [
545 local-scope
546 assume-screen 10/width, 5/height
547 e:&:editor <- new-editor [abcdef], 0/left, 5/right
548 editor-render screen, e
549 $clear-trace
550 assume-console [
551 ¦ left-click 1, 3
552 ¦ press right-arrow
553 ]
554 run [
555 ¦ editor-event-loop screen, console, e
556 ¦ 3:num/raw <- get *e, cursor-row:offset
557 ¦ 4:num/raw <- get *e, cursor-column:offset
558 ]
559 screen-should-contain [
560 ¦ . .
561 ¦ .abcd↩ .
562 ¦ .ef .
563 ¦ .╌╌╌╌╌ .
564 ¦ . .
565 ]
566 memory-should-contain [
567 ¦ 3 <- 2
568 ¦ 4 <- 0
569 ]
570 check-trace-count-for-label 0, [print-character]
571 ]
572
573 scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [
574 local-scope
575 assume-screen 10/width, 5/height
576
577 e:&:editor <- new-editor [abcde], 0/left, 5/right
578 editor-render screen, e
579 $clear-trace
580
581 assume-console [
582 ¦ left-click 1, 3
583 ¦ press right-arrow
584 ]
585 run [
586 ¦ editor-event-loop screen, console, e
587 ¦ 3:num/raw <- get *e, cursor-row:offset
588 ¦ 4:num/raw <- get *e, cursor-column:offset
589 ]
590 memory-should-contain [
591 ¦ 3 <- 2
592 ¦ 4 <- 0
593 ]
594
595 assume-console [
596 ¦ press right-arrow
597 ]
598 run [
599 ¦ editor-event-loop screen, console, e
600 ¦ 3:num/raw <- get *e, cursor-row:offset
601 ¦ 4:num/raw <- get *e, cursor-column:offset
602 ]
603 memory-should-contain [
604 ¦ 3 <- 2
605 ¦ 4 <- 1
606 ]
607 check-trace-count-for-label 0, [print-character]
608 ]
609
610 scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-3 [
611 local-scope
612 assume-screen 10/width, 5/height
613 e:&:editor <- new-editor [abcdef], 1/left, 6/right
614 editor-render screen, e
615 $clear-trace
616 assume-console [
617 ¦ left-click 1, 4
618 ¦ press right-arrow
619 ]
620 run [
621 ¦ editor-event-loop screen, console, e
622 ¦ 3:num/raw <- get *e, cursor-row:offset
623 ¦ 4:num/raw <- get *e, cursor-column:offset
624 ]
625 screen-should-contain [
626 ¦ . .
627 ¦ . abcd↩ .
628 ¦ . ef .
629 ¦ . ╌╌╌╌╌ .
630 ¦ . .
631 ]
632 memory-should-contain [
633 ¦ 3 <- 2
634 ¦ 4 <- 1
635 ]
636 check-trace-count-for-label 0, [print-character]
637 ]
638
639 scenario editor-moves-cursor-to-next-line-with-right-arrow-at-end-of-line [
640 local-scope
641 assume-screen 10/width, 5/height
642 s:text <- new [abc
643 d]
644 e:&:editor <- new-editor s, 0/left, 10/right
645 editor-render screen, e
646 $clear-trace
647
648 assume-console [
649 ¦ left-click 1, 3
650 ¦ press right-arrow
651 ¦ type [0]
652 ]
653 run [
654 ¦ editor-event-loop screen, console, e
655 ]
656
657 screen-should-contain [
658 ¦ . .
659 ¦ .abc .
660 ¦ .0d .
661 ¦ .╌╌╌╌╌╌╌╌╌╌.
662 ¦ . .
663 ]
664 check-trace-count-for-label 2, [print-character]
665 ]
666
667
668
669
670
671 scenario editor-moves-cursor-left-with-key [
672 local-scope
673 assume-screen 10/width, 5/height
674 e:&:editor <- new-editor [abc], 0/left, 10/right
675 editor-render screen, e
676 $clear-trace
677 assume-console [
678 ¦ left-click 1, 2
679 ¦ press left-arrow
680 ¦ type [0]
681 ]
682 run [
683 ¦ editor-event-loop screen, console, e
684 ]
685 screen-should-contain [
686 ¦ . .
687 ¦ .a0bc .
688 ¦ .╌╌╌╌╌╌╌╌╌╌.
689 ¦ . .
690 ]
691 check-trace-count-for-label 3, [print-character]
692 ]
693
694 after <handle-special-key> [
695 {
696 ¦ move-to-previous-character?:bool <- equal k, 65515/left-arrow
697 ¦ break-unless move-to-previous-character?
698 ¦ trace 10, [app], [left arrow]
699 ¦
700 ¦ prev:&:duplex-list:char <- prev before-cursor
701 ¦ return-unless prev, 0/don't-render
702 ¦ <move-cursor-begin>
703 ¦ go-render? <- move-cursor-coordinates-left editor
704 ¦ before-cursor <- copy prev
705 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
706 ¦ undo-coalesce-tag:num <- copy 1/left-arrow
707 ¦ <move-cursor-end>
708 ¦ return
709 }
710 ]
711
712 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line [
713 local-scope
714 assume-screen 10/width, 5/height
715
716 s:text <- new [abc
717 d]
718 e:&:editor <- new-editor s, 0/left, 10/right
719 editor-render screen, e
720 $clear-trace
721
722 assume-console [
723 ¦ left-click 2, 0
724 ¦ press left-arrow
725 ]
726 run [
727 ¦ editor-event-loop screen, console, e
728 ¦ 3:num/raw <- get *e, cursor-row:offset
729 ¦ 4:num/raw <- get *e, cursor-column:offset
730 ]
731 memory-should-contain [
732 ¦ 3 <- 1
733 ¦ 4 <- 3
734 ]
735 check-trace-count-for-label 0, [print-character]
736 ]
737
738 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-2 [
739 local-scope
740 assume-screen 10/width, 5/height
741
742 s:text <- new [abc
743 def
744 g]
745 e:&:editor <- new-editor s:text, 0/left, 10/right
746 editor-render screen, e
747 $clear-trace
748
749
750 assume-console [
751 ¦ left-click 3, 0
752 ¦ press left-arrow
753 ¦ type [0]
754 ]
755 run [
756 ¦ editor-event-loop screen, console, e
757 ]
758 screen-should-contain [
759 ¦ . .
760 ¦ .abc .
761 ¦ .def0 .
762 ¦ .g .
763 ¦ .╌╌╌╌╌╌╌╌╌╌.
764 ]
765 check-trace-count-for-label 1, [print-character]
766 ]
767
768 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-3 [
769 local-scope
770 assume-screen 10/width, 5/height
771 s:text <- new [abc
772 def
773 g]
774 e:&:editor <- new-editor s, 0/left, 10/right
775 editor-render screen, e
776 $clear-trace
777
778 assume-console [
779 ¦ left-click 1, 0
780 ¦ press left-arrow
781 ¦ type [0]
782 ]
783 run [
784 ¦ editor-event-loop screen, console, e
785 ]
786
787 screen-should-contain [
788 ¦ . .
789 ¦ .0abc .
790 ¦ .def .
791 ¦ .g .
792 ¦ .╌╌╌╌╌╌╌╌╌╌.
793 ]
794 check-trace-count-for-label 4, [print-character]
795 ]
796
797 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-4 [
798 local-scope
799 assume-screen 10/width, 5/height
800
801 s:text <- new [abc
802
803 d]
804 e:&:editor <- new-editor s, 0/left, 10/right
805 editor-render screen, e:&:editor
806 $clear-trace
807
808 assume-console [
809 ¦ left-click 3, 0
810 ¦ press left-arrow
811 ¦ type [0]
812 ]
813 run [
814 ¦ editor-event-loop screen, console, e
815 ]
816 screen-should-contain [
817 ¦ . .
818 ¦ .abc .
819 ¦ .0 .
820 ¦ .d .
821 ¦ .╌╌╌╌╌╌╌╌╌╌.
822 ]
823 check-trace-count-for-label 1, [print-character]
824 ]
825
826 scenario editor-moves-across-screen-lines-across-wrap-with-left-arrow [
827 local-scope
828 assume-screen 10/width, 5/height
829
830 e:&:editor <- new-editor [abcdef], 0/left, 5/right
831 editor-render screen, e
832 $clear-trace
833 screen-should-contain [
834 ¦ . .
835 ¦ .abcd↩ .
836 ¦ .ef .
837 ¦ .╌╌╌╌╌ .
838 ¦ . .
839 ]
840
841 assume-console [
842 ¦ left-click 2, 0
843 ¦ press left-arrow
844 ]
845 run [
846 ¦ editor-event-loop screen, console, e
847 ¦ 3:num/raw <- get *e, cursor-row:offset
848 ¦ 4:num/raw <- get *e, cursor-column:offset
849 ]
850 memory-should-contain [
851 ¦ 3 <- 1
852 ¦ 4 <- 3
853 ]
854 check-trace-count-for-label 0, [print-character]
855 ]
856
857 scenario editor-moves-across-screen-lines-to-wrapping-line-with-left-arrow [
858 local-scope
859 assume-screen 10/width, 5/height
860
861 s:text <- new [abcdef
862 g]
863 e:&:editor <- new-editor s, 0/left, 5/right
864 editor-render screen, e
865 $clear-trace
866 screen-should-contain [
867 ¦ . .
868 ¦ .abcd↩ .
869 ¦ .ef .
870 ¦ .g .
871 ¦ .╌╌╌╌╌ .
872 ]
873
874 assume-console [
875 ¦ left-click 3, 0
876 ¦ press left-arrow
877 ]
878 run [
879 ¦ editor-event-loop screen, console, e
880 ¦ 3:num/raw <- get *e, cursor-row:offset
881 ¦ 4:num/raw <- get *e, cursor-column:offset
882 ]
883 memory-should-contain [
884 ¦ 3 <- 2
885 ¦ 4 <- 2
886 ]
887 check-trace-count-for-label 0, [print-character]
888 ]
889
890 scenario editor-moves-across-screen-lines-to-non-wrapping-line-with-left-arrow [
891 local-scope
892 assume-screen 10/width, 5/height
893
894 s:text <- new [abcd
895 e]
896 e:&:editor <- new-editor s, 0/left, 5/right
897 editor-render screen, e
898 $clear-trace
899 screen-should-contain [
900 ¦ . .
901 ¦ .abcd .
902 ¦ .e .
903 ¦ .╌╌╌╌╌ .
904 ¦ . .
905 ]
906
907 assume-console [
908 ¦ left-click 2, 0
909 ¦ press left-arrow
910 ]
911 run [
912 ¦ editor-event-loop screen, console, e
913 ¦ 3:num/raw <- get *e, cursor-row:offset
914 ¦ 4:num/raw <- get *e, cursor-column:offset
915 ]
916 memory-should-contain [
917 ¦ 3 <- 1
918 ¦ 4 <- 4
919 ]
920 check-trace-count-for-label 0, [print-character]
921 ]
922
923
924
925
926
927 scenario editor-moves-to-previous-line-with-up-arrow [
928 local-scope
929 assume-screen 10/width, 5/height
930 s:text <- new [abc
931 def]
932 e:&:editor <- new-editor s, 0/left, 10/right
933 editor-render screen, e
934 $clear-trace
935 assume-console [
936 ¦ left-click 2, 1
937 ¦ press up-arrow
938 ]
939 run [
940 ¦ editor-event-loop screen, console, e
941 ¦ 3:num/raw <- get *e, cursor-row:offset
942 ¦ 4:num/raw <- get *e, cursor-column:offset
943 ]
944 memory-should-contain [
945 ¦ 3 <- 1
946 ¦ 4 <- 1
947 ]
948 check-trace-count-for-label 0, [print-character]
949 assume-console [
950 ¦ type [0]
951 ]
952 run [
953 ¦ editor-event-loop screen, console, e
954 ]
955 screen-should-contain [
956 ¦ . .
957 ¦ .a0bc .
958 ¦ .def .
959 ¦ .╌╌╌╌╌╌╌╌╌╌.
960 ¦ . .
961 ]
962 ]
963
964 after <handle-special-key> [
965 {
966 ¦ move-to-previous-line?:bool <- equal k, 65517/up-arrow
967 ¦ break-unless move-to-previous-line?
968 ¦ <move-cursor-begin>
969 ¦ go-render? <- move-to-previous-line editor
970 ¦ undo-coalesce-tag:num <- copy 3/up-arrow
971 ¦ <move-cursor-end>
972 ¦ return
973 }
974 ]
975
976 def move-to-previous-line editor:&:editor -> go-render?:bool, editor:&:editor [
977 local-scope
978 load-ingredients
979 go-render?:bool <- copy 0/false
980 cursor-row:num <- get *editor, cursor-row:offset
981 cursor-column:num <- get *editor, cursor-column:offset
982 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
983 left:num <- get *editor, left:offset
984 right:num <- get *editor, right:offset
985 already-at-top?:bool <- lesser-or-equal cursor-row, 1/top
986 {
987 ¦
988 ¦ break-if already-at-top?
989 ¦
990 ¦
991 ¦
992 ¦ curr:&:duplex-list:char <- copy before-cursor
993 ¦ {
994 ¦ ¦ old:&:duplex-list:char <- copy curr
995 ¦ ¦ c2:char <- get *curr, value:offset
996 ¦ ¦ at-newline?:bool <- equal c2, 10/newline
997 ¦ ¦ break-if at-newline?
998 ¦ ¦ curr:&:duplex-list:char <- before-previous-line curr, editor
999 ¦ ¦ no-motion?:bool <- equal curr, old
1000 ¦ ¦ return-if no-motion?
1001 ¦ }
1002 ¦ {
1003 ¦ ¦ old <- copy curr
1004 ¦ ¦ curr <- before-previous-line curr, editor
1005 ¦ ¦ no-motion?:bool <- equal curr, old
1006 ¦ ¦ return-if no-motion?
1007 ¦ }
1008 ¦ before-cursor <- copy curr
1009 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1010 ¦ cursor-row <- subtract cursor-row, 1
1011 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
1012 ¦
1013 ¦ target-column:num <- copy cursor-column
1014 ¦ cursor-column <- copy left
1015 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1016 ¦ {
1017 ¦ ¦ done?:bool <- greater-or-equal cursor-column, target-column
1018 ¦ ¦ break-if done?
1019 ¦ ¦ curr:&:duplex-list:char <- next before-cursor
1020 ¦ ¦ break-unless curr
1021 ¦ ¦ currc:char <- get *curr, value:offset
1022 ¦ ¦ at-newline?:bool <- equal currc, 10/newline
1023 ¦ ¦ break-if at-newline?
1024 ¦ ¦
1025 ¦ ¦ before-cursor <- copy curr
1026 ¦ ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1027 ¦ ¦ cursor-column <- add cursor-column, 1
1028 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1029 ¦ ¦ loop
1030 ¦ }
1031 ¦ return
1032 }
1033 {
1034 ¦
1035 ¦ break-unless already-at-top?
1036 ¦ <scroll-up>
1037 ¦ return 1/go-render
1038 }
1039 ]
1040
1041 scenario editor-adjusts-column-at-previous-line [
1042 local-scope
1043 assume-screen 10/width, 5/height
1044 s:text <- new [ab
1045 def]
1046 e:&:editor <- new-editor s, 0/left, 10/right
1047 editor-render screen, e
1048 $clear-trace
1049 assume-console [
1050 ¦ left-click 2, 3
1051 ¦ press up-arrow
1052 ]
1053 run [
1054 ¦ editor-event-loop screen, console, e
1055 ¦ 3:num/raw <- get *e, cursor-row:offset
1056 ¦ 4:num/raw <- get *e, cursor-column:offset
1057 ]
1058 memory-should-contain [
1059 ¦ 3 <- 1
1060 ¦ 4 <- 2
1061 ]
1062 check-trace-count-for-label 0, [print-character]
1063 assume-console [
1064 ¦ type [0]
1065 ]
1066 run [
1067 ¦ editor-event-loop screen, console, e
1068 ]
1069 screen-should-contain [
1070 ¦ . .
1071 ¦ .ab0 .
1072 ¦ .def .
1073 ¦ .╌╌╌╌╌╌╌╌╌╌.
1074 ¦ . .
1075 ]
1076 ]
1077
1078 scenario editor-adjusts-column-at-empty-line [
1079 local-scope
1080 assume-screen 10/width, 5/height
1081 s:text <- new [
1082 def]
1083 e:&:editor <- new-editor s, 0/left, 10/right
1084 editor-render screen, e
1085 $clear-trace
1086 assume-console [
1087 ¦ left-click 2, 3
1088 ¦ press up-arrow
1089 ]
1090 run [
1091 ¦ editor-event-loop screen, console, e
1092 ¦ 3:num/raw <- get *e, cursor-row:offset
1093 ¦ 4:num/raw <- get *e, cursor-column:offset
1094 ]
1095 memory-should-contain [
1096 ¦ 3 <- 1
1097 ¦ 4 <- 0
1098 ]
1099 check-trace-count-for-label 0, [print-character]
1100 assume-console [
1101 ¦ type [0]
1102 ]
1103 run [
1104 ¦ editor-event-loop screen, console, e
1105 ]
1106 screen-should-contain [
1107 ¦ . .
1108 ¦ .0 .
1109 ¦ .def .
1110 ¦ .╌╌╌╌╌╌╌╌╌╌.
1111 ¦ . .
1112 ]
1113 ]
1114
1115 scenario editor-moves-to-previous-line-from-left-margin [
1116 local-scope
1117 assume-screen 10/width, 5/height
1118
1119 s:text <- new [abc
1120 def
1121 ghi]
1122 e:&:editor <- new-editor s, 0/left, 10/right
1123 editor-render screen, e
1124 $clear-trace
1125
1126 assume-console [
1127 ¦ left-click 3, 0
1128 ¦ press up-arrow
1129 ]
1130 run [
1131 ¦ editor-event-loop screen, console, e
1132 ¦ 3:num/raw <- get *e, cursor-row:offset
1133 ¦ 4:num/raw <- get *e, cursor-column:offset
1134 ]
1135 memory-should-contain [
1136 ¦ 3 <- 2
1137 ¦ 4 <- 0
1138 ]
1139 check-trace-count-for-label 0, [print-character]
1140 assume-console [
1141 ¦ type [0]
1142 ]
1143 run [
1144 ¦ editor-event-loop screen, console, e
1145 ]
1146 screen-should-contain [
1147 ¦ . .
1148 ¦ .abc .
1149 ¦ .0def .
1150 ¦ .ghi .
1151 ¦ .╌╌╌╌╌╌╌╌╌╌.
1152 ]
1153 ]
1154
1155
1156
1157 scenario editor-moves-to-next-line-with-down-arrow [
1158 local-scope
1159 assume-screen 10/width, 5/height
1160 s:text <- new [abc
1161 def]
1162 e:&:editor <- new-editor s, 0/left, 10/right
1163 editor-render screen, e
1164 $clear-trace
1165
1166 assume-console [
1167 ¦ press down-arrow
1168 ]
1169 run [
1170 ¦ editor-event-loop screen, console, e
1171 ¦ 3:num/raw <- get *e, cursor-row:offset
1172 ¦ 4:num/raw <- get *e, cursor-column:offset
1173 ]
1174
1175 memory-should-contain [
1176 ¦ 3 <- 2
1177 ¦ 4 <- 0
1178 ]
1179 check-trace-count-for-label 0, [print-character]
1180 assume-console [
1181 ¦ type [0]
1182 ]
1183 run [
1184 ¦ editor-event-loop screen, console, e
1185 ]
1186 screen-should-contain [
1187 ¦ . .
1188 ¦ .abc .
1189 ¦ .0def .
1190 ¦ .╌╌╌╌╌╌╌╌╌╌.
1191 ¦ . .
1192 ]
1193 ]
1194
1195 after <handle-special-key> [
1196 {
1197 ¦ move-to-next-line?:bool <- equal k, 65516/down-arrow
1198 ¦ break-unless move-to-next-line?
1199 ¦ <move-cursor-begin>
1200 ¦ go-render? <- move-to-next-line editor, screen-height
1201 ¦ undo-coalesce-tag:num <- copy 4/down-arrow
1202 ¦ <move-cursor-end>
1203 ¦ return
1204 }
1205 ]
1206
1207 def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
1208 local-scope
1209 load-ingredients
1210 cursor-row:num <- get *editor, cursor-row:offset
1211 cursor-column:num <- get *editor, cursor-column:offset
1212 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1213 left:num <- get *editor, left:offset
1214 right:num <- get *editor, right:offset
1215 last-line:num <- subtract screen-height, 1
1216 already-at-bottom?:bool <- greater-or-equal cursor-row, last-line
1217 {
1218 ¦
1219 ¦ break-if already-at-bottom?
1220 ¦
1221 ¦ max:num <- subtract right, left
1222 ¦ next-line:&:duplex-list:char <- before-start-of-next-line before-cursor, max
1223 ¦ {
1224 ¦ ¦
1225 ¦ ¦
1226 ¦ ¦ no-motion?:bool <- equal next-line, before-cursor
1227 ¦ ¦ break-unless no-motion?
1228 ¦ ¦ scroll?:bool <- greater-than cursor-row, 1
1229 ¦ ¦ break-if scroll?, +try-to-scroll
1230 ¦ ¦ return 0/don't-render
1231 ¦ }
1232 ¦ cursor-row <- add cursor-row, 1
1233 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
1234 ¦ before-cursor <- copy next-line
1235 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1236 ¦ target-column:num <- copy cursor-column
1237 ¦ cursor-column <- copy left
1238 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1239 ¦ {
1240 ¦ ¦ done?:bool <- greater-or-equal cursor-column, target-column
1241 ¦ ¦ break-if done?
1242 ¦ ¦ curr:&:duplex-list:char <- next before-cursor
1243 ¦ ¦ break-unless curr
1244 ¦ ¦ currc:char <- get *curr, value:offset
1245 ¦ ¦ at-newline?:bool <- equal currc, 10/newline
1246 ¦ ¦ break-if at-newline?
1247 ¦ ¦
1248 ¦ ¦ before-cursor <- copy curr
1249 ¦ ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1250 ¦ ¦ cursor-column <- add cursor-column, 1
1251 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1252 ¦ ¦ loop
1253 ¦ }
1254 ¦ return 0/don't-render
1255 }
1256 +try-to-scroll
1257 <scroll-down>
1258 go-render? <- copy 1/true
1259 ]
1260
1261 scenario editor-adjusts-column-at-next-line [
1262 local-scope
1263 assume-screen 10/width, 5/height
1264 s:text <- new [abc
1265 de]
1266 e:&:editor <- new-editor s, 0/left, 10/right
1267 editor-render screen, e
1268 $clear-trace
1269 assume-console [
1270 ¦ left-click 1, 3
1271 ¦ press down-arrow
1272 ]
1273 run [
1274 ¦ editor-event-loop screen, console, e
1275 ¦ 3:num/raw <- get *e, cursor-row:offset
1276 ¦ 4:num/raw <- get *e, cursor-column:offset
1277 ]
1278 memory-should-contain [
1279 ¦ 3 <- 2
1280 ¦ 4 <- 2
1281 ]
1282 check-trace-count-for-label 0, [print-character]
1283 assume-console [
1284 ¦ type [0]
1285 ]
1286 run [
1287 ¦ editor-event-loop screen, console, e
1288 ]
1289 screen-should-contain [
1290 ¦ . .
1291 ¦ .abc .
1292 ¦ .de0 .
1293 ¦ .╌╌╌╌╌╌╌╌╌╌.
1294 ¦ . .
1295 ]
1296 ]
1297
1298
1299
1300 scenario editor-moves-to-start-of-line-with-ctrl-a [
1301 local-scope
1302 assume-screen 10/width, 5/height
1303 s:text <- new [123
1304 456]
1305 e:&:editor <- new-editor s, 0/left, 10/right
1306 editor-render screen, e
1307 $clear-trace
1308
1309 assume-console [
1310 ¦ left-click 2, 3
1311 ¦ press ctrl-a
1312 ]
1313 run [
1314 ¦ editor-event-loop screen, console, e
1315 ¦ 4:num/raw <- get *e, cursor-row:offset
1316 ¦ 5:num/raw <- get *e, cursor-column:offset
1317 ]
1318
1319 memory-should-contain [
1320 ¦ 4 <- 2
1321 ¦ 5 <- 0
1322 ]
1323 check-trace-count-for-label 0, [print-character]
1324 ]
1325
1326 after <handle-special-character> [
1327 {
1328 ¦ move-to-start-of-line?:bool <- equal c, 1/ctrl-a
1329 ¦ break-unless move-to-start-of-line?
1330 ¦ <move-cursor-begin>
1331 ¦ move-to-start-of-line editor
1332 ¦ undo-coalesce-tag:num <- copy 0/never
1333 ¦ <move-cursor-end>
1334 ¦ return 0/don't-render
1335 }
1336 ]
1337
1338 after <handle-special-key> [
1339 {
1340 ¦ move-to-start-of-line?:bool <- equal k, 65521/home
1341 ¦ break-unless move-to-start-of-line?
1342 ¦ <move-cursor-begin>
1343 ¦ move-to-start-of-line editor
1344 ¦ undo-coalesce-tag:num <- copy 0/never
1345 ¦ <move-cursor-end>
1346 ¦ return 0/don't-render
1347 }
1348 ]
1349
1350 def move-to-start-of-line editor:&:editor -> editor:&:editor [
1351 local-scope
1352 load-ingredients
1353
1354 left:num <- get *editor, left:offset
1355 cursor-column:num <- copy left
1356 *editor <- put *editor, cursor-column:offset, cursor-column
1357
1358 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1359 init:&:duplex-list:char <- get *editor, data:offset
1360
1361 {
1362 ¦ at-start-of-text?:bool <- equal before-cursor, init
1363 ¦ break-if at-start-of-text?
1364 ¦ prev:char <- get *before-cursor, value:offset
1365 ¦ at-start-of-line?:bool <- equal prev, 10/newline
1366 ¦ break-if at-start-of-line?
1367 ¦ before-cursor <- prev before-cursor
1368 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1369 ¦ assert before-cursor, [move-to-start-of-line tried to move before start of text]
1370 ¦ loop
1371 }
1372 ]
1373
1374 scenario editor-moves-to-start-of-line-with-ctrl-a-2 [
1375 local-scope
1376 assume-screen 10/width, 5/height
1377 s:text <- new [123
1378 456]
1379 e:&:editor <- new-editor s, 0/left, 10/right
1380 editor-render screen, e
1381 $clear-trace
1382
1383 assume-console [
1384 ¦ left-click 1, 3
1385 ¦ press ctrl-a
1386 ]
1387 run [
1388 ¦ editor-event-loop screen, console, e
1389 ¦ 4:num/raw <- get *e, cursor-row:offset
1390 ¦ 5:num/raw <- get *e, cursor-column:offset
1391 ]
1392
1393 memory-should-contain [
1394 ¦ 4 <- 1
1395 ¦ 5 <- 0
1396 ]
1397 check-trace-count-for-label 0, [print-character]
1398 ]
1399
1400 scenario editor-moves-to-start-of-line-with-home [
1401 local-scope
1402 assume-screen 10/width, 5/height
1403 s:text <- new [123
1404 456]
1405 e:&:editor <- new-editor s, 0/left, 10/right
1406 $clear-trace
1407
1408 assume-console [
1409 ¦ left-click 2, 3
1410 ¦ press home
1411 ]
1412 run [
1413 ¦ editor-event-loop screen, console, e
1414 ¦ 3:num/raw <- get *e, cursor-row:offset
1415 ¦ 4:num/raw <- get *e, cursor-column:offset
1416 ]
1417
1418 memory-should-contain [
1419 ¦ 3 <- 2
1420 ¦ 4 <- 0
1421 ]
1422 check-trace-count-for-label 0, [print-character]
1423 ]
1424
1425 scenario editor-moves-to-start-of-line-with-home-2 [
1426 local-scope
1427 assume-screen 10/width, 5/height
1428 s:text <- new [123
1429 456]
1430 e:&:editor <- new-editor s, 0/left, 10/right
1431 editor-render screen, e
1432 $clear-trace
1433
1434 assume-console [
1435 ¦ left-click 1, 3
1436 ¦ press home
1437 ]
1438 run [
1439 ¦ editor-event-loop screen, console, e
1440 ¦ 3:num/raw <- get *e, cursor-row:offset
1441 ¦ 4:num/raw <- get *e, cursor-column:offset
1442 ]
1443
1444 memory-should-contain [
1445 ¦ 3 <- 1
1446 ¦ 4 <- 0
1447 ]
1448 check-trace-count-for-label 0, [print-character]
1449 ]
1450
1451
1452
1453 scenario editor-moves-to-end-of-line-with-ctrl-e [
1454 local-scope
1455 assume-screen 10/width, 5/height
1456 s:text <- new [123
1457 456]
1458 e:&:editor <- new-editor s, 0/left, 10/right
1459 editor-render screen, e
1460 $clear-trace
1461
1462 assume-console [
1463 ¦ left-click 1, 1
1464 ¦ press ctrl-e
1465 ]
1466 run [
1467 ¦ editor-event-loop screen, console, e
1468 ¦ 4:num/raw <- get *e, cursor-row:offset
1469 ¦ 5:num/raw <- get *e, cursor-column:offset
1470 ]
1471
1472 memory-should-contain [
1473 ¦ 4 <- 1
1474 ¦ 5 <- 3
1475 ]
1476 check-trace-count-for-label 0, [print-character]
1477
1478 assume-console [
1479 ¦ type [z]
1480 ]
1481 run [
1482 ¦ editor-event-loop screen, console, e
1483 ¦ 4:num/raw <- get *e, cursor-row:offset
1484 ¦ 5:num/raw <- get *e, cursor-column:offset
1485 ]
1486 memory-should-contain [
1487 ¦ 4 <- 1
1488 ¦ 5 <- 4
1489 ]
1490 screen-should-contain [
1491 ¦ . .
1492 ¦ .123z .
1493 ¦ .456 .
1494 ¦ .╌╌╌╌╌╌╌╌╌╌.
1495 ¦ . .
1496 ]
1497 check-trace-count-for-label 1, [print-character]
1498 ]
1499
1500 after <handle-special-character> [
1501 {
1502 ¦ move-to-end-of-line?:bool <- equal c, 5/ctrl-e
1503 ¦ break-unless move-to-end-of-line?
1504 ¦ <move-cursor-begin>
1505 ¦ move-to-end-of-line editor
1506 ¦ undo-coalesce-tag:num <- copy 0/never
1507 ¦ <move-cursor-end>
1508 ¦ return 0/don't-render
1509 }
1510 ]
1511
1512 after <handle-special-key> [
1513 {
1514 ¦ move-to-end-of-line?:bool <- equal k, 65520/end
1515 ¦ break-unless move-to-end-of-line?
1516 ¦ <move-cursor-begin>
1517 ¦ move-to-end-of-line editor
1518 ¦ undo-coalesce-tag:num <- copy 0/never
1519 ¦ <move-cursor-end>
1520 ¦ return 0/don't-render
1521 }
1522 ]
1523
1524 def move-to-end-of-line editor:&:editor -> editor:&:editor [
1525 local-scope
1526 load-ingredients
1527 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1528 cursor-column:num <- get *editor, cursor-column:offset
1529
1530 {
1531 ¦ next:&:duplex-list:char <- next before-cursor
1532 ¦ break-unless next
1533 ¦ nextc:char <- get *next, value:offset
1534 ¦ at-end-of-line?:bool <- equal nextc, 10/newline
1535 ¦ break-if at-end-of-line?
1536 ¦ before-cursor <- copy next
1537 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1538 ¦ cursor-column <- add cursor-column, 1
1539 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1540 ¦ loop
1541 }
1542 ]
1543
1544 scenario editor-moves-to-end-of-line-with-ctrl-e-2 [
1545 local-scope
1546 assume-screen 10/width, 5/height
1547 s:text <- new [123
1548 456]
1549 e:&:editor <- new-editor s, 0/left, 10/right
1550 editor-render screen, e
1551 $clear-trace
1552
1553 assume-console [
1554 ¦ left-click 2, 1
1555 ¦ press ctrl-e
1556 ]
1557 run [
1558 ¦ editor-event-loop screen, console, e
1559 ¦ 4:num/raw <- get *e, cursor-row:offset
1560 ¦ 5:num/raw <- get *e, cursor-column:offset
1561 ]
1562
1563 memory-should-contain [
1564 ¦ 4 <- 2
1565 ¦ 5 <- 3
1566 ]
1567 check-trace-count-for-label 0, [print-character]
1568 ]
1569
1570 scenario editor-moves-to-end-of-line-with-end [
1571 local-scope
1572 assume-screen 10/width, 5/height
1573 s:text <- new [123
1574 456]
1575 e:&:editor <- new-editor s, 0/left, 10/right
1576 editor-render screen, e
1577 $clear-trace
1578
1579 assume-console [
1580 ¦ left-click 1, 1
1581 ¦ press end
1582 ]
1583 run [
1584 ¦ editor-event-loop screen, console, e
1585 ¦ 3:num/raw <- get *e, cursor-row:offset
1586 ¦ 4:num/raw <- get *e, cursor-column:offset
1587 ]
1588
1589 memory-should-contain [
1590 ¦ 3 <- 1
1591 ¦ 4 <- 3
1592 ]
1593 check-trace-count-for-label 0, [print-character]
1594 ]
1595
1596 scenario editor-moves-to-end-of-line-with-end-2 [
1597 local-scope
1598 assume-screen 10/width, 5/height
1599 s:text <- new [123
1600 456]
1601 e:&:editor <- new-editor s, 0/left, 10/right
1602 editor-render screen, e
1603 $clear-trace
1604
1605 assume-console [
1606 ¦ left-click 2, 1
1607 ¦ press end
1608 ]
1609 run [
1610 ¦ editor-event-loop screen, console, e
1611 ¦ 3:num/raw <- get *e, cursor-row:offset
1612 ¦ 4:num/raw <- get *e, cursor-column:offset
1613 ]
1614
1615 memory-should-contain [
1616 ¦ 3 <- 2
1617 ¦ 4 <- 3
1618 ]
1619 check-trace-count-for-label 0, [print-character]
1620 ]
1621
1622
1623
1624 scenario editor-deletes-to-start-of-line-with-ctrl-u [
1625 local-scope
1626 assume-screen 10/width, 5/height
1627 s:text <- new [123
1628 456]
1629 e:&:editor <- new-editor s, 0/left, 10/right
1630
1631 assume-console [
1632 ¦ left-click 2, 2
1633 ¦ press ctrl-u
1634 ]
1635 run [
1636 ¦ editor-event-loop screen, console, e
1637 ]
1638
1639 screen-should-contain [
1640 ¦ . .
1641 ¦ .123 .
1642 ¦ .6 .
1643 ¦ .╌╌╌╌╌╌╌╌╌╌.
1644 ¦ . .
1645 ]
1646 ]
1647
1648 after <handle-special-character> [
1649 {
1650 ¦ delete-to-start-of-line?:bool <- equal c, 21/ctrl-u
1651 ¦ break-unless delete-to-start-of-line?
1652 ¦ <delete-to-start-of-line-begin>
1653 ¦ deleted-cells:&:duplex-list:char <- delete-to-start-of-line editor
1654 ¦ <delete-to-start-of-line-end>
1655 ¦ return 1/go-render
1656 }
1657 ]
1658
1659 def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
1660 local-scope
1661 load-ingredients
1662
1663 init:&:duplex-list:char <- get *editor, data:offset
1664 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1665 start:&:duplex-list:char <- copy before-cursor
1666 end:&:duplex-list:char <- next before-cursor
1667 {
1668 ¦ at-start-of-text?:bool <- equal start, init
1669 ¦ break-if at-start-of-text?
1670 ¦ curr:char <- get *start, value:offset
1671 ¦ at-start-of-line?:bool <- equal curr, 10/newline
1672 ¦ break-if at-start-of-line?
1673 ¦ start <- prev start
1674 ¦ assert start, [delete-to-start-of-line tried to move before start of text]
1675 ¦ loop
1676 }
1677
1678 result:&:duplex-list:char <- next start
1679 remove-between start, end
1680
1681 before-cursor <- copy start
1682 *editor <- put *editor, before-cursor:offset, before-cursor
1683 left:num <- get *editor, left:offset
1684 *editor <- put *editor, cursor-column:offset, left
1685 ]
1686
1687 scenario editor-deletes-to-start-of-line-with-ctrl-u-2 [
1688 local-scope
1689 assume-screen 10/width, 5/height
1690 s:text <- new [123
1691 456]
1692 e:&:editor <- new-editor s, 0/left, 10/right
1693
1694 assume-console [
1695 ¦ left-click 1, 2
1696 ¦ press ctrl-u
1697 ]
1698 run [
1699 ¦ editor-event-loop screen, console, e
1700 ]
1701
1702 screen-should-contain [
1703 ¦ . .
1704 ¦ .3 .
1705 ¦ .456 .
1706 ¦ .╌╌╌╌╌╌╌╌╌╌.
1707 ¦ . .
1708 ]
1709 ]
1710
1711 scenario editor-deletes-to-start-of-line-with-ctrl-u-3 [
1712 local-scope
1713 assume-screen 10/width, 5/height
1714 s:text <- new [123
1715 456]
1716 e:&:editor <- new-editor s, 0/left, 10/right
1717
1718 assume-console [
1719 ¦ left-click 1, 3
1720 ¦ press ctrl-u
1721 ]
1722 run [
1723 ¦ editor-event-loop screen, console, e
1724 ]
1725
1726 screen-should-contain [
1727 ¦ . .
1728 ¦ . .
1729 ¦ .456 .
1730 ¦ .╌╌╌╌╌╌╌╌╌╌.
1731 ¦ . .
1732 ]
1733 ]
1734
1735 scenario editor-deletes-to-start-of-final-line-with-ctrl-u [
1736 local-scope
1737 assume-screen 10/width, 5/height
1738 s:text <- new [123
1739 456]
1740 e:&:editor <- new-editor s, 0/left, 10/right
1741
1742 assume-console [
1743 ¦ left-click 2, 3
1744 ¦ press ctrl-u
1745 ]
1746 run [
1747 ¦ editor-event-loop screen, console, e
1748 ]
1749
1750 screen-should-contain [
1751 ¦ . .
1752 ¦ .123 .
1753 ¦ . .
1754 ¦ .╌╌╌╌╌╌╌╌╌╌.
1755 ¦ . .
1756 ]
1757 ]
1758
1759
1760
1761 scenario editor-deletes-to-end-of-line-with-ctrl-k [
1762 local-scope
1763 assume-screen 10/width, 5/height
1764 s:text <- new [123
1765 456]
1766 e:&:editor <- new-editor s, 0/left, 10/right
1767
1768 assume-console [
1769 ¦ left-click 1, 1
1770 ¦ press ctrl-k
1771 ]
1772 run [
1773 ¦ editor-event-loop screen, console, e
1774 ]
1775
1776 screen-should-contain [
1777 ¦ . .
1778 ¦ .1 .
1779 ¦ .456 .
1780 ¦ .╌╌╌╌╌╌╌╌╌╌.
1781 ¦ . .
1782 ]
1783 ]
1784
1785 after <handle-special-character> [
1786 {
1787 ¦ delete-to-end-of-line?:bool <- equal c, 11/ctrl-k
1788 ¦ break-unless delete-to-end-of-line?
1789 ¦ <delete-to-end-of-line-begin>
1790 ¦ deleted-cells:&:duplex-list:char <- delete-to-end-of-line editor
1791 ¦ <delete-to-end-of-line-end>
1792 ¦ return 1/go-render
1793 }
1794 ]
1795
1796 def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
1797 local-scope
1798 load-ingredients
1799
1800 start:&:duplex-list:char <- get *editor, before-cursor:offset
1801 end:&:duplex-list:char <- next start
1802 {
1803 ¦ at-end-of-text?:bool <- equal end, 0/null
1804 ¦ break-if at-end-of-text?
1805 ¦ curr:char <- get *end, value:offset
1806 ¦ at-end-of-line?:bool <- equal curr, 10/newline
1807 ¦ break-if at-end-of-line?
1808 ¦ end <- next end
1809 ¦ loop
1810 }
1811
1812 result <- next start
1813 remove-between start, end
1814 ]
1815
1816 scenario editor-deletes-to-end-of-line-with-ctrl-k-2 [
1817 local-scope
1818 assume-screen 10/width, 5/height
1819 s:text <- new [123
1820 456]
1821 e:&:editor <- new-editor s, 0/left, 10/right
1822
1823 assume-console [
1824 ¦ left-click 2, 1
1825 ¦ press ctrl-k
1826 ]
1827 run [
1828 ¦ editor-event-loop screen, console, e
1829 ]
1830
1831 screen-should-contain [
1832 ¦ . .
1833 ¦ .123 .
1834 ¦ .4 .
1835 ¦ .╌╌╌╌╌╌╌╌╌╌.
1836 ¦ . .
1837 ]
1838 ]
1839
1840 scenario editor-deletes-to-end-of-line-with-ctrl-k-3 [
1841 local-scope
1842 assume-screen 10/width, 5/height
1843 s:text <- new [123
1844 456]
1845 e:&:editor <- new-editor s, 0/left, 10/right
1846
1847 assume-console [
1848 ¦ left-click 1, 2
1849 ¦ press ctrl-k
1850 ]
1851 run [
1852 ¦ editor-event-loop screen, console, e
1853 ]
1854
1855 screen-should-contain [
1856 ¦ . .
1857 ¦ .12 .
1858 ¦ .456 .
1859 ¦ .╌╌╌╌╌╌╌╌╌╌.
1860 ¦ . .
1861 ]
1862 ]
1863
1864 scenario editor-deletes-to-end-of-line-with-ctrl-k-4 [
1865 local-scope
1866 assume-screen 10/width, 5/height
1867 s:text <- new [123
1868 456]
1869 e:&:editor <- new-editor s, 0/left, 10/right
1870
1871 assume-console [
1872 ¦ left-click 1, 3
1873 ¦ press ctrl-k
1874 ]
1875 run [
1876 ¦ editor-event-loop screen, console, e
1877 ]
1878
1879 screen-should-contain [
1880 ¦ . .
1881 ¦ .123 .
1882 ¦ .456 .
1883 ¦ .╌╌╌╌╌╌╌╌╌╌.
1884 ¦ . .
1885 ]
1886 ]
1887
1888 scenario editor-deletes-to-end-of-line-with-ctrl-k-5 [
1889 local-scope
1890 assume-screen 10/width, 5/height
1891 s:text <- new [123
1892 456]
1893 e:&:editor <- new-editor s, 0/left, 10/right
1894
1895 assume-console [
1896 ¦ left-click 2, 2
1897 ¦ press ctrl-k
1898 ]
1899 run [
1900 ¦ editor-event-loop screen, console, e
1901 ]
1902
1903 screen-should-contain [
1904 ¦ . .
1905 ¦ .123 .
1906 ¦ .45 .
1907 ¦ .╌╌╌╌╌╌╌╌╌╌.
1908 ¦ . .
1909 ]
1910 ]
1911
1912 scenario editor-deletes-to-end-of-line-with-ctrl-k-6 [
1913 local-scope
1914 assume-screen 10/width, 5/height
1915 s:text <- new [123
1916 456]
1917 e:&:editor <- new-editor s, 0/left, 10/right
1918
1919 assume-console [
1920 ¦ left-click 2, 3
1921 ¦ press ctrl-k
1922 ]
1923 run [
1924 ¦ editor-event-loop screen, console, e
1925 ]
1926
1927 screen-should-contain [
1928 ¦ . .
1929 ¦ .123 .
1930 ¦ .456 .
1931 ¦ .╌╌╌╌╌╌╌╌╌╌.
1932 ¦ . .
1933 ]
1934 ]
1935
1936
1937
1938 scenario editor-can-scroll-down-using-arrow-keys [
1939 local-scope
1940
1941 assume-screen 10/width, 4/height
1942
1943 s:text <- new [a
1944 b
1945 c
1946 d]
1947 e:&:editor <- new-editor s, 0/left, 10/right
1948 editor-render screen, e
1949 screen-should-contain [
1950 ¦ . .
1951 ¦ .a .
1952 ¦ .b .
1953 ¦ .c .
1954 ]
1955
1956 assume-console [
1957 ¦ left-click 3, 0
1958 ¦ press down-arrow
1959 ]
1960 run [
1961 ¦ editor-event-loop screen, console, e
1962 ]
1963
1964 screen-should-contain [
1965 ¦ . .
1966 ¦ .b .
1967 ¦ .c .
1968 ¦ .d .
1969 ]
1970 ]
1971
1972 after <scroll-down> [
1973 trace 10, [app], [scroll down]
1974 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
1975 left:num <- get *editor, left:offset
1976 right:num <- get *editor, right:offset
1977 max:num <- subtract right, left
1978 old-top:&:duplex-list:char <- copy top-of-screen
1979 top-of-screen <- before-start-of-next-line top-of-screen, max
1980 *editor <- put *editor, top-of-screen:offset, top-of-screen
1981 no-movement?:bool <- equal old-top, top-of-screen
1982 return-if no-movement?, 0/don't-render
1983 ]
1984
1985
1986
1987
1988 def before-start-of-next-line original:&:duplex-list:char, max:num -> curr:&:duplex-list:char [
1989 local-scope
1990 load-ingredients
1991 count:num <- copy 0
1992 curr:&:duplex-list:char <- copy original
1993
1994 {
1995 ¦ c:char <- get *curr, value:offset
1996 ¦ at-newline?:bool <- equal c, 10/newline
1997 ¦ break-unless at-newline?
1998 ¦ curr <- next curr
1999 ¦ count <- add count, 1
2000 }
2001 {
2002 ¦ return-unless curr, original
2003 ¦ done?:bool <- greater-or-equal count, max
2004 ¦ break-if done?
2005 ¦ c:char <- get *curr, value:offset
2006 ¦ at-newline?:bool <- equal c, 10/newline
2007 ¦ break-if at-newline?
2008 ¦ curr <- next curr
2009 ¦ count <- add count, 1
2010 ¦ loop
2011 }
2012 return-unless curr, original
2013 return curr
2014 ]
2015
2016 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys [
2017 local-scope
2018
2019 assume-screen 10/width, 4/height
2020
2021
2022 s:text <- new [abcdef
2023 g
2024 h
2025 i]
2026 e:&:editor <- new-editor s, 0/left, 5/right
2027 editor-render screen, e
2028 screen-should-contain [
2029 ¦ . .
2030 ¦ .abcd↩ .
2031 ¦ .ef .
2032 ¦ .g .
2033 ]
2034
2035 assume-console [
2036 ¦ left-click 3, 0
2037 ¦ press down-arrow
2038 ]
2039 run [
2040 ¦ editor-event-loop screen, console, e
2041 ]
2042
2043 screen-should-contain [
2044 ¦ . .
2045 ¦ .ef .
2046 ¦ .g .
2047 ¦ .h .
2048 ]
2049 ]
2050
2051 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys-2 [
2052 local-scope
2053
2054 assume-screen 10/width, 4/height
2055
2056 s:text <- new [abcdefghij
2057 k
2058 l
2059 m]
2060 e:&:editor <- new-editor s, 0/left, 5/right
2061
2062 assume-console [
2063 ¦ left-click 3, 0
2064 ¦ press down-arrow
2065 ]
2066 run [
2067 ¦ editor-event-loop screen, console, e
2068 ]
2069
2070 screen-should-contain [
2071 ¦ . .
2072 ¦ .efgh↩ .
2073 ¦ .ij .
2074 ¦ .k .
2075 ]
2076
2077 assume-console [
2078 ¦ press down-arrow
2079 ]
2080 run [
2081 ¦ editor-event-loop screen, console, e
2082 ]
2083
2084 screen-should-contain [
2085 ¦ . .
2086 ¦ .ij .
2087 ¦ .k .
2088 ¦ .l .
2089 ]
2090 ]
2091
2092 scenario editor-scrolls-down-when-line-wraps [
2093 local-scope
2094
2095 assume-screen 5/width, 4/height
2096
2097 s:text <- new [a
2098 b
2099 cdef]
2100 e:&:editor <- new-editor s, 0/left, 5/right
2101
2102 assume-console [
2103 ¦ left-click 3, 4
2104 ¦ type [g]
2105 ]
2106 run [
2107 ¦ editor-event-loop screen, console, e
2108 ¦ 3:num/raw <- get *e, cursor-row:offset
2109 ¦ 4:num/raw <- get *e, cursor-column:offset
2110 ]
2111
2112 screen-should-contain [
2113 ¦ . .
2114 ¦ .b .
2115 ¦ .cdef↩.
2116 ¦ .g .
2117 ]
2118 memory-should-contain [
2119 ¦ 3 <- 3
2120 ¦ 4 <- 1
2121 ]
2122 ]
2123
2124 scenario editor-scrolls-down-on-newline [
2125 local-scope
2126 assume-screen 5/width, 4/height
2127
2128 s:text <- new [a
2129 b
2130 c]
2131 e:&:editor <- new-editor s, 0/left, 5/right
2132 assume-console [
2133 ¦ left-click 3, 4
2134 ¦ type [
2135 ]
2136 ]
2137 run [
2138 ¦ editor-event-loop screen, console, e
2139 ¦ 3:num/raw <- get *e, cursor-row:offset
2140 ¦ 4:num/raw <- get *e, cursor-column:offset
2141 ]
2142
2143 screen-should-contain [
2144 ¦ . .
2145 ¦ .b .
2146 ¦ .c .
2147 ¦ . .
2148 ]
2149 memory-should-contain [
2150 ¦ 3 <- 3
2151 ¦ 4 <- 0
2152 ]
2153 ]
2154
2155 scenario editor-scrolls-down-on-right-arrow [
2156 local-scope
2157
2158 assume-screen 5/width, 4/height
2159
2160 s:text <- new [a
2161 b
2162 cdefgh]
2163 e:&:editor <- new-editor s, 0/left, 5/right
2164
2165 assume-console [
2166 ¦ left-click 3, 3
2167 ¦ press right-arrow
2168 ]
2169 run [
2170 ¦ editor-event-loop screen, console, e
2171 ¦ 3:num/raw <- get *e, cursor-row:offset
2172 ¦ 4:num/raw <- get *e, cursor-column:offset
2173 ]
2174
2175 screen-should-contain [
2176 ¦ . .
2177 ¦ .b .
2178 ¦ .cdef↩.
2179 ¦ .gh .
2180 ]
2181 memory-should-contain [
2182 ¦ 3 <- 3
2183 ¦ 4 <- 0
2184 ]
2185 ]
2186
2187 scenario editor-scrolls-down-on-right-arrow-2 [
2188 local-scope
2189
2190 assume-screen 5/width, 4/height
2191
2192 s:text <- new [a
2193 b
2194 c
2195 d]
2196 e:&:editor <- new-editor s, 0/left, 5/right
2197
2198 assume-console [
2199 ¦ left-click 3, 3
2200 ¦ press right-arrow
2201 ]
2202 run [
2203 ¦ editor-event-loop screen, console, e
2204 ¦ 3:num/raw <- get *e, cursor-row:offset
2205 ¦ 4:num/raw <- get *e, cursor-column:offset
2206 ]
2207
2208 screen-should-contain [
2209 ¦ . .
2210 ¦ .b .
2211 ¦ .c .
2212 ¦ .d .
2213 ]
2214 memory-should-contain [
2215 ¦ 3 <- 3
2216 ¦ 4 <- 0
2217 ]
2218 ]
2219
2220 scenario editor-scrolls-at-end-on-down-arrow [
2221 local-scope
2222 assume-screen 10/width, 5/height
2223 s:text <- new [abc
2224 de]
2225 e:&:editor <- new-editor s, 0/left, 10/right
2226 editor-render screen, e
2227 $clear-trace
2228
2229 assume-console [
2230 ¦ left-click 2, 0
2231 ¦ press down-arrow
2232 ]
2233 run [
2234 ¦ editor-event-loop screen, console, e
2235 ¦ 3:num/raw <- get *e, cursor-row:offset
2236 ¦ 4:num/raw <- get *e, cursor-column:offset
2237 ]
2238
2239 memory-should-contain [
2240 ¦ 3 <- 1
2241 ¦ 4 <- 2
2242 ]
2243 assume-console [
2244 ¦ type [0]
2245 ]
2246 run [
2247 ¦ editor-event-loop screen, console, e
2248 ]
2249 screen-should-contain [
2250 ¦ . .
2251 ¦ .de0 .
2252 ¦ .╌╌╌╌╌╌╌╌╌╌.
2253 ¦ . .
2254 ]
2255
2256 $clear-trace
2257 assume-console [
2258 ¦ left-click 2, 0
2259 ¦ press down-arrow
2260 ]
2261 run [
2262 ¦ editor-event-loop screen, console, e
2263 ¦ 3:num/raw <- get *e, cursor-row:offset
2264 ¦ 4:num/raw <- get *e, cursor-column:offset
2265 ]
2266
2267 memory-should-contain [
2268 ¦ 3 <- 1
2269 ¦ 4 <- 3
2270 ]
2271 check-trace-count-for-label 0, [print-character]
2272 assume-console [
2273 ¦ type [1]
2274 ]
2275 run [
2276 ¦ editor-event-loop screen, console, e
2277 ]
2278 screen-should-contain [
2279 ¦ . .
2280 ¦ .de01 .
2281 ¦ .╌╌╌╌╌╌╌╌╌╌.
2282 ¦ . .
2283 ]
2284 ]
2285
2286 scenario editor-combines-page-and-line-scroll [
2287 local-scope
2288
2289 assume-screen 10/width, 4/height
2290
2291 s:text <- new [a
2292 b
2293 c
2294 d
2295 e
2296 f
2297 g]
2298 e:&:editor <- new-editor s, 0/left, 5/right
2299 editor-render screen, e
2300
2301 assume-console [
2302 ¦ press page-down
2303 ¦ left-click 3, 0
2304 ¦ press down-arrow
2305 ]
2306 run [
2307 ¦ editor-event-loop screen, console, e
2308 ]
2309
2310 screen-should-contain [
2311 ¦ . .
2312 ¦ .d .
2313 ¦ .e .
2314 ¦ .f .
2315 ]
2316 ]
2317
2318
2319
2320 scenario editor-can-scroll-up-using-arrow-keys [
2321 local-scope
2322
2323 assume-screen 10/width, 4/height
2324
2325 s:text <- new [a
2326 b
2327 c
2328 d]
2329 e:&:editor <- new-editor s, 0/left, 10/right
2330 editor-render screen, e
2331 screen-should-contain [
2332 ¦ . .
2333 ¦ .a .
2334 ¦ .b .
2335 ¦ .c .
2336 ]
2337
2338 assume-console [
2339 ¦ press page-down
2340 ¦ press up-arrow
2341 ]
2342 run [
2343 ¦ editor-event-loop screen, console, e
2344 ]
2345
2346 screen-should-contain [
2347 ¦ . .
2348 ¦ .b .
2349 ¦ .c .
2350 ¦ .d .
2351 ]
2352 ]
2353
2354 after <scroll-up> [
2355 trace 10, [app], [scroll up]
2356 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2357 old-top:&:duplex-list:char <- copy top-of-screen
2358 top-of-screen <- before-previous-line top-of-screen, editor
2359 *editor <- put *editor, top-of-screen:offset, top-of-screen
2360 no-movement?:bool <- equal old-top, top-of-screen
2361 return-if no-movement?, 0/don't-render
2362 ]
2363
2364
2365
2366
2367 def before-previous-line in:&:duplex-list:char, editor:&:editor -> out:&:duplex-list:char [
2368 local-scope
2369 load-ingredients
2370 curr:&:duplex-list:char <- copy in
2371 c:char <- get *curr, value:offset
2372
2373
2374
2375 left:num <- get *editor, left:offset
2376 right:num <- get *editor, right:offset
2377 max-line-length:num <- subtract right, left, -1/exclusive-right, 1/wrap-icon
2378 sentinel:&:duplex-list:char <- get *editor, data:offset
2379 len:num <- previous-line-length curr, sentinel
2380 {
2381 ¦ break-if len
2382 ¦
2383 ¦ prev:&:duplex-list:char <- prev curr
2384 ¦ return-unless prev, curr
2385 ¦ return prev
2386 }
2387 _, max:num <- divide-with-remainder len, max-line-length
2388
2389 {
2390 ¦ break-if max
2391 ¦ max <- copy max-line-length
2392 }
2393 max <- add max, 1
2394 count:num <- copy 0
2395
2396 {
2397 ¦ done?:bool <- greater-or-equal count, max
2398 ¦ break-if done?
2399 ¦ prev:&:duplex-list:char <- prev curr
2400 ¦ break-unless prev
2401 ¦ curr <- copy prev
2402 ¦ count <- add count, 1
2403 ¦ loop
2404 }
2405 return curr
2406 ]
2407
2408 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys [
2409 local-scope
2410
2411 assume-screen 10/width, 4/height
2412
2413
2414 s:text <- new [abcdef
2415 g
2416 h
2417 i]
2418 e:&:editor <- new-editor s, 0/left, 5/right
2419 editor-render screen, e
2420 screen-should-contain [
2421 ¦ . .
2422 ¦ .abcd↩ .
2423 ¦ .ef .
2424 ¦ .g .
2425 ]
2426
2427 assume-console [
2428 ¦ press page-down
2429 ]
2430 run [
2431 ¦ editor-event-loop screen, console, e
2432 ]
2433 screen-should-contain [
2434 ¦ . .
2435 ¦ .g .
2436 ¦ .h .
2437 ¦ .i .
2438 ]
2439
2440 assume-console [
2441 ¦ press up-arrow
2442 ]
2443 run [
2444 ¦ editor-event-loop screen, console, e
2445 ]
2446
2447 screen-should-contain [
2448 ¦ . .
2449 ¦ .ef .
2450 ¦ .g .
2451 ¦ .h .
2452 ]
2453 ]
2454
2455 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-2 [
2456 local-scope
2457
2458 assume-screen 10/width, 5/height
2459
2460 s:text <- new [abcdefghij
2461 k
2462 l
2463 m]
2464 e:&:editor <- new-editor s, 0/left, 5/right
2465 editor-render screen, e
2466
2467 assume-console [
2468 ¦ press page-down
2469 ]
2470 run [
2471 ¦ editor-event-loop screen, console, e
2472 ]
2473 screen-should-contain [
2474 ¦ . .
2475 ¦ .k .
2476 ¦ .l .
2477 ¦ .m .
2478 ¦ .╌╌╌╌╌ .
2479 ]
2480
2481 assume-console [
2482 ¦ press up-arrow
2483 ]
2484 run [
2485 ¦ editor-event-loop screen, console, e
2486 ]
2487
2488 screen-should-contain [
2489 ¦ . .
2490 ¦ .ij .
2491 ¦ .k .
2492 ¦ .l .
2493 ¦ .m .
2494 ]
2495
2496 assume-console [
2497 ¦ press up-arrow
2498 ]
2499 run [
2500 ¦ editor-event-loop screen, console, e
2501 ]
2502
2503 screen-should-contain [
2504 ¦ . .
2505 ¦ .efgh↩ .
2506 ¦ .ij .
2507 ¦ .k .
2508 ¦ .l .
2509 ]
2510
2511 assume-console [
2512 ¦ press up-arrow
2513 ]
2514 run [
2515 ¦ editor-event-loop screen, console, e
2516 ]
2517
2518 screen-should-contain [
2519 ¦ . .
2520 ¦ .abcd↩ .
2521 ¦ .efgh↩ .
2522 ¦ .ij .
2523 ¦ .k .
2524 ]
2525 ]
2526
2527
2528
2529 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-3 [
2530 local-scope
2531
2532 assume-screen 10/width, 4/height
2533
2534
2535 s:text <- new [abcdef
2536 g
2537 h
2538 i]
2539 e:&:editor <- new-editor s, 0/left, 6/right
2540 editor-render screen, e
2541 screen-should-contain [
2542 ¦ . .
2543 ¦ .abcde↩ .
2544 ¦ .f .
2545 ¦ .g .
2546 ]
2547
2548 assume-console [
2549 ¦ press page-down
2550 ]
2551 run [
2552 ¦ editor-event-loop screen, console, e
2553 ]
2554 screen-should-contain [
2555 ¦ . .
2556 ¦ .g .
2557 ¦ .h .
2558 ¦ .i .
2559 ]
2560
2561 assume-console [
2562 ¦ press up-arrow
2563 ]
2564 run [
2565 ¦ editor-event-loop screen, console, e
2566 ]
2567
2568 screen-should-contain [
2569 ¦ . .
2570 ¦ .f .
2571 ¦ .g .
2572 ¦ .h .
2573 ]
2574 ]
2575
2576
2577 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-4 [
2578 local-scope
2579 assume-screen 10/width, 4/height
2580
2581 s:text <- new [a
2582 b
2583
2584 c
2585 d
2586 e]
2587 e:&:editor <- new-editor s, 0/left, 6/right
2588 editor-render screen, e
2589 assume-console [
2590 ¦ press page-down
2591 ]
2592 run [
2593 ¦ editor-event-loop screen, console, e
2594 ]
2595 screen-should-contain [
2596 ¦ . .
2597 ¦ . .
2598 ¦ .c .
2599 ¦ .d .
2600 ]
2601 assume-console [
2602 ¦ press page-down
2603 ]
2604 run [
2605 ¦ editor-event-loop screen, console, e
2606 ]
2607 screen-should-contain [
2608 ¦ . .
2609 ¦ .d .
2610 ¦ .e .
2611 ¦ .╌╌╌╌╌╌ .
2612 ]
2613 assume-console [
2614 ¦ press page-up
2615 ]
2616 run [
2617 ¦ editor-event-loop screen, console, e
2618 ]
2619 screen-should-contain [
2620 ¦ . .
2621 ¦ . .
2622 ¦ .c .
2623 ¦ .d .
2624 ]
2625 ]
2626
2627 scenario editor-scrolls-up-on-left-arrow [
2628 local-scope
2629
2630 assume-screen 5/width, 4/height
2631
2632 s:text <- new [a
2633 b
2634 c
2635 d
2636 e]
2637 e:&:editor <- new-editor s, 0/left, 5/right
2638 editor-render screen, e
2639
2640 assume-console [
2641 ¦ press page-down
2642 ]
2643 run [
2644 ¦ editor-event-loop screen, console, e
2645 ]
2646 screen-should-contain [
2647 ¦ . .
2648 ¦ .c .
2649 ¦ .d .
2650 ¦ .e .
2651 ]
2652
2653 assume-console [
2654 ¦ press left-arrow
2655 ]
2656 run [
2657 ¦ editor-event-loop screen, console, e
2658 ¦ 3:num/raw <- get *e, cursor-row:offset
2659 ¦ 4:num/raw <- get *e, cursor-column:offset
2660 ]
2661
2662 screen-should-contain [
2663 ¦ . .
2664 ¦ .b .
2665 ¦ .c .
2666 ¦ .d .
2667 ]
2668 memory-should-contain [
2669 ¦ 3 <- 1
2670 ¦ 4 <- 1
2671 ]
2672 ]
2673
2674 scenario editor-can-scroll-up-to-start-of-file [
2675 local-scope
2676
2677 assume-screen 10/width, 4/height
2678
2679 s:text <- new [a
2680 b
2681 c
2682 d]
2683 e:&:editor <- new-editor s, 0/left, 10/right
2684 editor-render screen, e
2685 screen-should-contain [
2686 ¦ . .
2687 ¦ .a .
2688 ¦ .b .
2689 ¦ .c .
2690 ]
2691
2692
2693 assume-console [
2694 ¦ press page-down
2695 ¦ press up-arrow
2696 ¦ press up-arrow
2697 ]
2698 run [
2699 ¦ editor-event-loop screen, console, e
2700 ]
2701
2702 screen-should-contain [
2703 ¦ . .
2704 ¦ .a .
2705 ¦ .b .
2706 ¦ .c .
2707 ]
2708
2709 assume-console [
2710 ¦ press up-arrow
2711 ]
2712 run [
2713 ¦ editor-event-loop screen, console, e
2714 ]
2715
2716 screen-should-contain [
2717 ¦ . .
2718 ¦ .a .
2719 ¦ .b .
2720 ¦ .c .
2721 ]
2722 ]
2723
2724
2725
2726 scenario editor-can-scroll [
2727 local-scope
2728 assume-screen 10/width, 4/height
2729 s:text <- new [a
2730 b
2731 c
2732 d]
2733 e:&:editor <- new-editor s, 0/left, 10/right
2734 editor-render screen, e
2735 screen-should-contain [
2736 ¦ . .
2737 ¦ .a .
2738 ¦ .b .
2739 ¦ .c .
2740 ]
2741
2742 assume-console [
2743 ¦ press page-down
2744 ]
2745 run [
2746 ¦ editor-event-loop screen, console, e
2747 ]
2748
2749 screen-should-contain [
2750 ¦ . .
2751 ¦ .c .
2752 ¦ .d .
2753 ¦ .╌╌╌╌╌╌╌╌╌╌.
2754 ]
2755 ]
2756
2757 after <handle-special-character> [
2758 {
2759 ¦ page-down?:bool <- equal c, 6/ctrl-f
2760 ¦ break-unless page-down?
2761 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
2762 ¦ <move-cursor-begin>
2763 ¦ page-down editor
2764 ¦ undo-coalesce-tag:num <- copy 0/never
2765 ¦ <move-cursor-end>
2766 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2767 ¦ movement?:bool <- not-equal top-of-screen, old-top
2768 ¦ return movement?/go-render
2769 }
2770 ]
2771
2772 after <handle-special-key> [
2773 {
2774 ¦ page-down?:bool <- equal k, 65518/page-down
2775 ¦ break-unless page-down?
2776 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
2777 ¦ <move-cursor-begin>
2778 ¦ page-down editor
2779 ¦ undo-coalesce-tag:num <- copy 0/never
2780 ¦ <move-cursor-end>
2781 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2782 ¦ movement?:bool <- not-equal top-of-screen, old-top
2783 ¦ return movement?/go-render
2784 }
2785 ]
2786
2787
2788
2789 def page-down editor:&:editor -> editor:&:editor [
2790 local-scope
2791 load-ingredients
2792
2793 bottom-of-screen:&:duplex-list:char <- get *editor, bottom-of-screen:offset
2794 return-unless bottom-of-screen
2795
2796 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
2797 before-cursor:&:duplex-list:char <- prev bottom-of-screen
2798 *editor <- put *editor, before-cursor:offset, before-cursor
2799
2800 {
2801 ¦ last:char <- get *before-cursor, value:offset
2802 ¦ newline?:bool <- equal last, 10/newline
2803 ¦ break-unless newline?:bool
2804 ¦ before-cursor <- prev before-cursor
2805 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
2806 }
2807
2808 move-to-start-of-line editor
2809 before-cursor <- get *editor, before-cursor:offset
2810 *editor <- put *editor, top-of-screen:offset, before-cursor
2811 ]
2812
2813 scenario editor-does-not-scroll-past-end [
2814 local-scope
2815 assume-screen 10/width, 4/height
2816 s:text <- new [a
2817 b]
2818 e:&:editor <- new-editor s, 0/left, 10/right
2819 editor-render screen, e
2820 screen-should-contain [
2821 ¦ . .
2822 ¦ .a .
2823 ¦ .b .
2824 ¦ .╌╌╌╌╌╌╌╌╌╌.
2825 ]
2826
2827 assume-console [
2828 ¦ press page-down
2829 ]
2830 run [
2831 ¦ editor-event-loop screen, console, e
2832 ]
2833
2834 screen-should-contain [
2835 ¦ . .
2836 ¦ .a .
2837 ¦ .b .
2838 ¦ .╌╌╌╌╌╌╌╌╌╌.
2839 ]
2840 ]
2841
2842 scenario editor-starts-next-page-at-start-of-wrapped-line [
2843 local-scope
2844
2845 assume-screen 10/width, 4/height
2846
2847 s:text <- new [a
2848 b
2849 cdefgh]
2850
2851 e:&:editor <- new-editor s, 0/left, 4/right
2852 editor-render screen, e
2853
2854 screen-should-contain [
2855 ¦ . .
2856 ¦ .a .
2857 ¦ .b .
2858 ¦ .cde↩ .
2859 ]
2860
2861 assume-console [
2862 ¦ press page-down
2863 ]
2864 run [
2865 ¦ editor-event-loop screen, console, e
2866 ]
2867
2868 screen-should-contain [
2869 ¦ . .
2870 ¦ .cde↩ .
2871 ¦ .fgh .
2872 ¦ .╌╌╌╌ .
2873 ]
2874 ]
2875
2876 scenario editor-starts-next-page-at-start-of-wrapped-line-2 [
2877 local-scope
2878
2879 assume-screen 10/width, 4/height
2880
2881
2882 s:text <- new [a
2883 bcdefgh]
2884 e:&:editor <- new-editor s, 0/left, 4/right
2885 editor-render screen, e
2886
2887 screen-should-contain [
2888 ¦ . .
2889 ¦ .a .
2890 ¦ .bcd↩ .
2891 ¦ .efg↩ .
2892 ]
2893
2894 assume-console [
2895 ¦ press page-down
2896 ]
2897 run [
2898 ¦ editor-event-loop screen, console, e
2899 ]
2900
2901 screen-should-contain [
2902 ¦ . .
2903 ¦ .bcd↩ .
2904 ¦ .efg↩ .
2905 ¦ .h .
2906 ]
2907 ]
2908
2909
2910
2911 scenario editor-can-scroll-up [
2912 local-scope
2913 assume-screen 10/width, 4/height
2914 s:text <- new [a
2915 b
2916 c
2917 d]
2918 e:&:editor <- new-editor s, 0/left, 10/right
2919 editor-render screen, e
2920 screen-should-contain [
2921 ¦ . .
2922 ¦ .a .
2923 ¦ .b .
2924 ¦ .c .
2925 ]
2926
2927 assume-console [
2928 ¦ press page-down
2929 ]
2930 run [
2931 ¦ editor-event-loop screen, console, e
2932 ]
2933
2934 screen-should-contain [
2935 ¦ . .
2936 ¦ .c .
2937 ¦ .d .
2938 ¦ .╌╌╌╌╌╌╌╌╌╌.
2939 ]
2940
2941 assume-console [
2942 ¦ press page-up
2943 ]
2944 run [
2945 ¦ editor-event-loop screen, console, e
2946 ]
2947
2948 screen-should-contain [
2949 ¦ . .
2950 ¦ .a .
2951 ¦ .b .
2952 ¦ .c .
2953 ]
2954 ]
2955
2956 after <handle-special-character> [
2957 {
2958 ¦ page-up?:bool <- equal c, 2/ctrl-b
2959 ¦ break-unless page-up?
2960 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
2961 ¦ <move-cursor-begin>
2962 ¦ editor <- page-up editor, screen-height
2963 ¦ undo-coalesce-tag:num <- copy 0/never
2964 ¦ <move-cursor-end>
2965 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2966 ¦ movement?:bool <- not-equal top-of-screen, old-top
2967 ¦ return movement?/go-render
2968 }
2969 ]
2970
2971 after <handle-special-key> [
2972 {
2973 ¦ page-up?:bool <- equal k, 65519/page-up
2974 ¦ break-unless page-up?
2975 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
2976 ¦ <move-cursor-begin>
2977 ¦ editor <- page-up editor, screen-height
2978 ¦ undo-coalesce-tag:num <- copy 0/never
2979 ¦ <move-cursor-end>
2980 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2981 ¦ movement?:bool <- not-equal top-of-screen, old-top
2982 ¦
2983 ¦ return movement?/go-render
2984 }
2985 ]
2986
2987 def page-up editor:&:editor, screen-height:num -> editor:&:editor [
2988 local-scope
2989 load-ingredients
2990 max:num <- subtract screen-height, 1/menu-bar, 1/overlapping-line
2991 count:num <- copy 0
2992 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2993 {
2994 ¦ done?:bool <- greater-or-equal count, max
2995 ¦ break-if done?
2996 ¦ prev:&:duplex-list:char <- before-previous-line top-of-screen, editor
2997 ¦ break-unless prev
2998 ¦ top-of-screen <- copy prev
2999 ¦ *editor <- put *editor, top-of-screen:offset, top-of-screen
3000 ¦ count <- add count, 1
3001 ¦ loop
3002 }
3003 ]
3004
3005 scenario editor-can-scroll-up-multiple-pages [
3006 local-scope
3007
3008 assume-screen 10/width, 4/height
3009
3010 s:text <- new [a
3011 b
3012 c
3013 d
3014 e
3015 f
3016 g
3017 h]
3018 e:&:editor <- new-editor s, 0/left, 10/right
3019 editor-render screen, e
3020 screen-should-contain [
3021 ¦ . .
3022 ¦ .a .
3023 ¦ .b .
3024 ¦ .c .
3025 ]
3026
3027 assume-console [
3028 ¦ press page-down
3029 ¦ press page-down
3030 ]
3031 run [
3032 ¦ editor-event-loop screen, console, e
3033 ]
3034
3035 screen-should-contain [
3036 ¦ . .
3037 ¦ .e .
3038 ¦ .f .
3039 ¦ .g .
3040 ]
3041
3042 assume-console [
3043 ¦ press page-up
3044 ]
3045 run [
3046 ¦ editor-event-loop screen, console, e
3047 ]
3048
3049 screen-should-contain [
3050 ¦ . .
3051 ¦ .c .
3052 ¦ .d .
3053 ¦ .e .
3054 ]
3055
3056 assume-console [
3057 ¦ press page-up
3058 ]
3059 run [
3060 ¦ editor-event-loop screen, console, e
3061 ]
3062
3063 screen-should-contain [
3064 ¦ . .
3065 ¦ .a .
3066 ¦ .b .
3067 ¦ .c .
3068 ]
3069 ]
3070
3071 scenario editor-can-scroll-up-wrapped-lines [
3072 local-scope
3073
3074 assume-screen 10/width, 6/height
3075
3076 s:text <- new [a
3077 b
3078 cdefgh
3079 i
3080 j
3081 k
3082 l
3083 m
3084 n
3085 o]
3086
3087 e:&:editor <- new-editor s, 0/left, 4/right
3088 editor-render screen, e
3089
3090 screen-should-contain [
3091 ¦ . .
3092 ¦ .a .
3093 ¦ .b .
3094 ¦ .cde↩ .
3095 ¦ .fgh .
3096 ¦ .i .
3097 ]
3098
3099 assume-console [
3100 ¦ press page-down
3101 ¦ left-click 5, 0
3102 ¦ press down-arrow
3103 ]
3104 run [
3105 ¦ editor-event-loop screen, console, e
3106 ]
3107
3108 screen-should-contain [
3109 ¦ . .
3110 ¦ .j .
3111 ¦ .k .
3112 ¦ .l .
3113 ¦ .m .
3114 ¦ .n .
3115 ]
3116
3117 assume-console [
3118 ¦ press page-up
3119 ]
3120 run [
3121 ¦ editor-event-loop screen, console, e
3122 ]
3123
3124 screen-should-contain [
3125 ¦ . .
3126 ¦ .b .
3127 ¦ .cde↩ .
3128 ¦ .fgh .
3129 ¦ .i .
3130 ¦ .j .
3131 ]
3132 ]
3133
3134 scenario editor-can-scroll-up-wrapped-lines-2 [
3135 local-scope
3136
3137 assume-screen 10/width, 4/height
3138
3139
3140 s:text <- new [a
3141 bcdefgh]
3142 e:&:editor <- new-editor s, 0/left, 4/right
3143 editor-render screen, e
3144
3145 screen-should-contain [
3146 ¦ . .
3147 ¦ .a .
3148 ¦ .bcd↩ .
3149 ¦ .efg↩ .
3150 ]
3151
3152 assume-console [
3153 ¦ press page-down
3154 ]
3155 run [
3156 ¦ editor-event-loop screen, console, e
3157 ]
3158
3159 screen-should-contain [
3160 ¦ . .
3161 ¦ .bcd↩ .
3162 ¦ .efg↩ .
3163 ¦ .h .
3164 ]
3165
3166 assume-console [
3167 ¦ press page-up
3168 ]
3169 run [
3170 ¦ editor-event-loop screen, console, e
3171 ]
3172
3173 screen-should-contain [
3174 ¦ . .
3175 ¦ .a .
3176 ¦ .bcd↩ .
3177 ¦ .efg↩ .
3178 ]
3179 ]
3180
3181 scenario editor-can-scroll-up-past-nonempty-lines [
3182 local-scope
3183 assume-screen 10/width, 4/height
3184
3185 s:text <- new [axx
3186 bxx
3187 cxx
3188 dxx
3189 exx
3190 fxx
3191 gxx
3192 hxx
3193 ]
3194 e:&:editor <- new-editor s, 0/left, 4/right
3195 editor-render screen, e
3196 screen-should-contain [
3197 ¦ . .
3198 ¦ .axx .
3199 ¦ .bxx .
3200 ¦ .cxx .
3201 ]
3202 assume-console [
3203 ¦ press page-down
3204 ]
3205 run [
3206 ¦ editor-event-loop screen, console, e
3207 ]
3208 screen-should-contain [
3209 ¦ . .
3210 ¦ .cxx .
3211 ¦ .dxx .
3212 ¦ .exx .
3213 ]
3214 assume-console [
3215 ¦ press page-down
3216 ]
3217 run [
3218 ¦ editor-event-loop screen, console, e
3219 ]
3220 screen-should-contain [
3221 ¦ . .
3222 ¦ .exx .
3223 ¦ .fxx .
3224 ¦ .gxx .
3225 ]
3226
3227 assume-console [
3228 ¦ press page-up
3229 ]
3230 run [
3231 ¦ editor-event-loop screen, console, e
3232 ]
3233 screen-should-contain [
3234 ¦ . .
3235 ¦ .cxx .
3236 ¦ .dxx .
3237 ¦ .exx .
3238 ]
3239 ]
3240
3241 scenario editor-can-scroll-up-past-empty-lines [
3242 local-scope
3243 assume-screen 10/width, 4/height
3244
3245 s:text <- new [axy
3246 bxy
3247 cxy
3248
3249 dxy
3250 exy
3251 fxy
3252 gxy
3253 ]
3254 e:&:editor <- new-editor s, 0/left, 4/right
3255 editor-render screen, e
3256 screen-should-contain [
3257 ¦ . .
3258 ¦ .axy .
3259 ¦ .bxy .
3260 ¦ .cxy .
3261 ]
3262 assume-console [
3263 ¦ press page-down
3264 ]
3265 run [
3266 ¦ editor-event-loop screen, console, e
3267 ]
3268 screen-should-contain [
3269 ¦ . .
3270 ¦ .cxy .
3271 ¦ . .
3272 ¦ .dxy .
3273 ]
3274 assume-console [
3275 ¦ press page-down
3276 ]
3277 run [
3278 ¦ editor-event-loop screen, console, e
3279 ]
3280 screen-should-contain [
3281 ¦ . .
3282 ¦ .dxy .
3283 ¦ .exy .
3284 ¦ .fxy .
3285 ]
3286
3287 assume-console [
3288 ¦ press page-up
3289 ]
3290 run [
3291 ¦ editor-event-loop screen, console, e
3292 ]
3293 screen-should-contain [
3294 ¦ . .
3295 ¦ .cxy .
3296 ¦ . .
3297 ¦ .dxy .
3298 ]
3299 ]