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 editor-render screen, e
1631 $clear-trace
1632
1633 assume-console [
1634 ¦ left-click 2, 2
1635 ¦ press ctrl-u
1636 ]
1637 run [
1638 ¦ editor-event-loop screen, console, e
1639 ]
1640
1641 screen-should-contain [
1642 ¦ . .
1643 ¦ .123 .
1644 ¦ .6 .
1645 ¦ .╌╌╌╌╌╌╌╌╌╌.
1646 ¦ . .
1647 ]
1648 check-trace-count-for-label 10, [print-character]
1649 ]
1650
1651 after <handle-special-character> [
1652 {
1653 ¦ delete-to-start-of-line?:bool <- equal c, 21/ctrl-u
1654 ¦ break-unless delete-to-start-of-line?
1655 ¦ <delete-to-start-of-line-begin>
1656 ¦ deleted-cells:&:duplex-list:char <- delete-to-start-of-line editor
1657 ¦ <delete-to-start-of-line-end>
1658 ¦ go-render?:bool <- minimal-render-for-ctrl-u editor, screen
1659 ¦ return
1660 }
1661 ]
1662
1663 def minimal-render-for-ctrl-u editor:&:editor, screen:&:screen -> go-render?:bool, screen:&:screen [
1664 local-scope
1665 load-ingredients
1666 curr-row:num <- get *editor, cursor-row:offset
1667 curr-column:num <- get *editor, cursor-column:offset
1668 left:num <- get *editor, left:offset
1669 right:num <- get *editor, right:offset
1670 end:num <- subtract left, right
1671
1672 buf:&:buffer:char <- new-buffer 30
1673 curr:&:duplex-list:char <- get *editor, before-cursor:offset
1674 i:num <- copy 0
1675 {
1676 ¦ i <- add i, 1
1677 ¦
1678 ¦ wrap?:bool <- equal i, end
1679 ¦ return-if wrap?, 1/do-render
1680 ¦ curr <- next curr
1681 ¦ break-unless curr
1682 ¦ c:char <- get *curr, value:offset
1683 ¦ b:bool <- equal c, 10
1684 ¦ break-if b
1685 ¦ buf <- append buf, c
1686 ¦ loop
1687 }
1688 curr-line:text <- buffer-to-array buf
1689 render-code screen, curr-line, curr-column, right, curr-row
1690 return 0/dont-render
1691 ]
1692
1693 def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
1694 local-scope
1695 load-ingredients
1696
1697 init:&:duplex-list:char <- get *editor, data:offset
1698 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1699 start:&:duplex-list:char <- copy before-cursor
1700 end:&:duplex-list:char <- next before-cursor
1701 {
1702 ¦ at-start-of-text?:bool <- equal start, init
1703 ¦ break-if at-start-of-text?
1704 ¦ curr:char <- get *start, value:offset
1705 ¦ at-start-of-line?:bool <- equal curr, 10/newline
1706 ¦ break-if at-start-of-line?
1707 ¦ start <- prev start
1708 ¦ assert start, [delete-to-start-of-line tried to move before start of text]
1709 ¦ loop
1710 }
1711
1712 result:&:duplex-list:char <- next start
1713 remove-between start, end
1714
1715 before-cursor <- copy start
1716 *editor <- put *editor, before-cursor:offset, before-cursor
1717 left:num <- get *editor, left:offset
1718 *editor <- put *editor, cursor-column:offset, left
1719 ]
1720
1721 def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num, screen:&:screen [
1722 local-scope
1723 load-ingredients
1724 return-unless s
1725 color:num <- copy 7/white
1726 column:num <- copy left
1727 screen <- move-cursor screen, row, column
1728 screen-height:num <- screen-height screen
1729 i:num <- copy 0
1730 len:num <- length *s
1731 {
1732 ¦ +next-character
1733 ¦ done?:bool <- greater-or-equal i, len
1734 ¦ break-if done?
1735 ¦ done? <- greater-or-equal row, screen-height
1736 ¦ break-if done?
1737 ¦ c:char <- index *s, i
1738 ¦ <character-c-received>
1739 ¦ {
1740 ¦ ¦
1741 ¦ ¦ newline?:bool <- equal c, 10/newline
1742 ¦ ¦ break-unless newline?
1743 ¦ ¦
1744 ¦ ¦ {
1745 ¦ ¦ ¦ done?:bool <- greater-than column, right
1746 ¦ ¦ ¦ break-if done?
1747 ¦ ¦ ¦ space:char <- copy 32/space
1748 ¦ ¦ ¦ print screen, space
1749 ¦ ¦ ¦ column <- add column, 1
1750 ¦ ¦ ¦ loop
1751 ¦ ¦ }
1752 ¦ ¦ row <- add row, 1
1753 ¦ ¦ column <- copy left
1754 ¦ ¦ screen <- move-cursor screen, row, column
1755 ¦ ¦ i <- add i, 1
1756 ¦ ¦ loop +next-character
1757 ¦ }
1758 ¦ {
1759 ¦ ¦
1760 ¦ ¦ at-right?:bool <- equal column, right
1761 ¦ ¦ break-unless at-right?
1762 ¦ ¦
1763 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left
1764 ¦ ¦ print screen, wrap-icon, 245/grey
1765 ¦ ¦ column <- copy left
1766 ¦ ¦ row <- add row, 1
1767 ¦ ¦ screen <- move-cursor screen, row, column
1768 ¦ ¦
1769 ¦ ¦ loop +next-character
1770 ¦ }
1771 ¦ i <- add i, 1
1772 ¦ print screen, c, color
1773 ¦ column <- add column, 1
1774 ¦ loop
1775 }
1776 was-at-left?:bool <- equal column, left
1777 clear-line-until screen, right
1778 {
1779 ¦ break-if was-at-left?
1780 ¦ row <- add row, 1
1781 }
1782 move-cursor screen, row, left
1783 ]
1784
1785 scenario editor-deletes-to-start-of-line-with-ctrl-u-2 [
1786 local-scope
1787 assume-screen 10/width, 5/height
1788 s:text <- new [123
1789 456]
1790 e:&:editor <- new-editor s, 0/left, 10/right
1791 editor-render screen, e
1792 $clear-trace
1793
1794 assume-console [
1795 ¦ left-click 1, 2
1796 ¦ press ctrl-u
1797 ]
1798 run [
1799 ¦ editor-event-loop screen, console, e
1800 ]
1801
1802 screen-should-contain [
1803 ¦ . .
1804 ¦ .3 .
1805 ¦ .456 .
1806 ¦ .╌╌╌╌╌╌╌╌╌╌.
1807 ¦ . .
1808 ]
1809 check-trace-count-for-label 10, [print-character]
1810 ]
1811
1812 scenario editor-deletes-to-start-of-line-with-ctrl-u-3 [
1813 local-scope
1814 assume-screen 10/width, 5/height
1815 s:text <- new [123
1816 456]
1817 e:&:editor <- new-editor s, 0/left, 10/right
1818 editor-render screen, e
1819 $clear-trace
1820
1821 assume-console [
1822 ¦ left-click 1, 3
1823 ¦ press ctrl-u
1824 ]
1825 run [
1826 ¦ editor-event-loop screen, console, e
1827 ]
1828
1829 screen-should-contain [
1830 ¦ . .
1831 ¦ . .
1832 ¦ .456 .
1833 ¦ .╌╌╌╌╌╌╌╌╌╌.
1834 ¦ . .
1835 ]
1836 check-trace-count-for-label 10, [print-character]
1837 ]
1838
1839 scenario editor-deletes-to-start-of-final-line-with-ctrl-u [
1840 local-scope
1841 assume-screen 10/width, 5/height
1842 s:text <- new [123
1843 456]
1844 e:&:editor <- new-editor s, 0/left, 10/right
1845 editor-render screen, e
1846 $clear-trace
1847
1848 assume-console [
1849 ¦ left-click 2, 3
1850 ¦ press ctrl-u
1851 ]
1852 run [
1853 ¦ editor-event-loop screen, console, e
1854 ]
1855
1856 screen-should-contain [
1857 ¦ . .
1858 ¦ .123 .
1859 ¦ . .
1860 ¦ .╌╌╌╌╌╌╌╌╌╌.
1861 ¦ . .
1862 ]
1863 check-trace-count-for-label 10, [print-character]
1864 ]
1865
1866
1867
1868 scenario editor-deletes-to-end-of-line-with-ctrl-k [
1869 local-scope
1870 assume-screen 10/width, 5/height
1871 s:text <- new [123
1872 456]
1873 e:&:editor <- new-editor s, 0/left, 10/right
1874 editor-render screen, e
1875 $clear-trace
1876
1877 assume-console [
1878 ¦ left-click 1, 1
1879 ¦ press ctrl-k
1880 ]
1881 run [
1882 ¦ editor-event-loop screen, console, e
1883 ]
1884
1885 screen-should-contain [
1886 ¦ . .
1887 ¦ .1 .
1888 ¦ .456 .
1889 ¦ .╌╌╌╌╌╌╌╌╌╌.
1890 ¦ . .
1891 ]
1892 check-trace-count-for-label 9, [print-character]
1893 ]
1894
1895 after <handle-special-character> [
1896 {
1897 ¦ delete-to-end-of-line?:bool <- equal c, 11/ctrl-k
1898 ¦ break-unless delete-to-end-of-line?
1899 ¦ <delete-to-end-of-line-begin>
1900 ¦ deleted-cells:&:duplex-list:char <- delete-to-end-of-line editor
1901 ¦ <delete-to-end-of-line-end>
1902 ¦
1903 ¦ go-render?:bool <- minimal-render-for-ctrl-k editor, screen, deleted-cells
1904 ¦ return
1905 }
1906 ]
1907
1908 def minimal-render-for-ctrl-k editor:&:editor, screen:&:screen, deleted-cells:&:duplex-list:char -> go-render?:bool, screen:&:screen [
1909 local-scope
1910 load-ingredients
1911
1912 return-unless deleted-cells, 0/dont-render
1913
1914 curr-column:num <- get *editor, cursor-column:offset
1915 num-deleted-cells:num <- length, deleted-cells
1916 old-row-len:num <- add curr-column, num-deleted-cells
1917 left:num <- get *editor, left:offset
1918 right:num <- get *editor, right:offset
1919 end:num <- subtract right, left
1920 wrap?:bool <- greater-or-equal old-row-len, end
1921 return-if wrap?, 1/do-render
1922
1923 buf:&:buffer:char <- new-buffer 30
1924 curr:&:duplex-list:char <- get *editor, before-cursor:offset
1925 i:num <- copy 0
1926 {
1927 ¦ i <- add i, 1
1928 ¦
1929 ¦ curr <- next curr
1930 ¦ break-unless curr
1931 ¦ c:char <- get *curr, value:offset
1932 ¦
1933 ¦ b:bool <- equal c, 10
1934 ¦ break-if b
1935 ¦ buf <- append buf, c
1936 ¦ loop
1937 }
1938 curr-line:text <- buffer-to-array buf
1939 curr-row:num <- get *editor, cursor-row:offset
1940 render-code screen, curr-line, curr-column, right, curr-row
1941 return 0/dont-render
1942 ]
1943
1944 def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
1945 local-scope
1946 load-ingredients
1947
1948 start:&:duplex-list:char <- get *editor, before-cursor:offset
1949 end:&:duplex-list:char <- next start
1950 {
1951 ¦ at-end-of-text?:bool <- equal end, 0/null
1952 ¦ break-if at-end-of-text?
1953 ¦ curr:char <- get *end, value:offset
1954 ¦ at-end-of-line?:bool <- equal curr, 10/newline
1955 ¦ break-if at-end-of-line?
1956 ¦ end <- next end
1957 ¦ loop
1958 }
1959
1960 result <- next start
1961 remove-between start, end
1962 ]
1963
1964 scenario editor-deletes-to-end-of-line-with-ctrl-k-2 [
1965 local-scope
1966 assume-screen 10/width, 5/height
1967 s:text <- new [123
1968 456]
1969 e:&:editor <- new-editor s, 0/left, 10/right
1970 editor-render screen, e
1971 $clear-trace
1972
1973 assume-console [
1974 ¦ left-click 2, 1
1975 ¦ press ctrl-k
1976 ]
1977 run [
1978 ¦ editor-event-loop screen, console, e
1979 ]
1980
1981 screen-should-contain [
1982 ¦ . .
1983 ¦ .123 .
1984 ¦ .4 .
1985 ¦ .╌╌╌╌╌╌╌╌╌╌.
1986 ¦ . .
1987 ]
1988 check-trace-count-for-label 9, [print-character]
1989 ]
1990
1991 scenario editor-deletes-to-end-of-line-with-ctrl-k-3 [
1992 local-scope
1993 assume-screen 10/width, 5/height
1994 s:text <- new [123
1995 456]
1996 e:&:editor <- new-editor s, 0/left, 10/right
1997 editor-render screen, e
1998 $clear-trace
1999
2000 assume-console [
2001 ¦ left-click 1, 2
2002 ¦ press ctrl-k
2003 ]
2004 run [
2005 ¦ editor-event-loop screen, console, e
2006 ]
2007
2008 screen-should-contain [
2009 ¦ . .
2010 ¦ .12 .
2011 ¦ .456 .
2012 ¦ .╌╌╌╌╌╌╌╌╌╌.
2013 ¦ . .
2014 ]
2015 check-trace-count-for-label 8, [print-character]
2016 ]
2017
2018 scenario editor-deletes-to-end-of-line-with-ctrl-k-4 [
2019 local-scope
2020 assume-screen 10/width, 5/height
2021 s:text <- new [123
2022 456]
2023 e:&:editor <- new-editor s, 0/left, 10/right
2024 editor-render screen, e
2025 $clear-trace
2026
2027 assume-console [
2028 ¦ left-click 1, 3
2029 ¦ press ctrl-k
2030 ]
2031 run [
2032 ¦ editor-event-loop screen, console, e
2033 ]
2034
2035 screen-should-contain [
2036 ¦ . .
2037 ¦ .123 .
2038 ¦ .456 .
2039 ¦ .╌╌╌╌╌╌╌╌╌╌.
2040 ¦ . .
2041 ]
2042 check-trace-count-for-label 7, [print-character]
2043 ]
2044
2045 scenario editor-deletes-to-end-of-line-with-ctrl-k-5 [
2046 local-scope
2047 assume-screen 10/width, 5/height
2048 s:text <- new [123
2049 456]
2050 e:&:editor <- new-editor s, 0/left, 10/right
2051 editor-render screen, e
2052 $clear-trace
2053
2054 assume-console [
2055 ¦ left-click 2, 2
2056 ¦ press ctrl-k
2057 ]
2058 run [
2059 ¦ editor-event-loop screen, console, e
2060 ]
2061
2062 screen-should-contain [
2063 ¦ . .
2064 ¦ .123 .
2065 ¦ .45 .
2066 ¦ .╌╌╌╌╌╌╌╌╌╌.
2067 ¦ . .
2068 ]
2069 check-trace-count-for-label 8, [print-character]
2070 ]
2071
2072 scenario editor-deletes-to-end-of-line-with-ctrl-k-6 [
2073 local-scope
2074 assume-screen 10/width, 5/height
2075 s:text <- new [123
2076 456]
2077 e:&:editor <- new-editor s, 0/left, 10/right
2078 editor-render screen, e
2079 $clear-trace
2080
2081 assume-console [
2082 ¦ left-click 2, 3
2083 ¦ press ctrl-k
2084 ]
2085 run [
2086 ¦ editor-event-loop screen, console, e
2087 ]
2088
2089 screen-should-contain [
2090 ¦ . .
2091 ¦ .123 .
2092 ¦ .456 .
2093 ¦ .╌╌╌╌╌╌╌╌╌╌.
2094 ¦ . .
2095 ]
2096
2097 check-trace-count-for-label 0, [print-character]
2098 ]
2099
2100 scenario editor-deletes-to-end-of-wrapped-line-with-ctrl-k [
2101 local-scope
2102 assume-screen 10/width, 5/height
2103
2104 s:text <- new [1234
2105 567]
2106 e:&:editor <- new-editor s, 0/left, 4/right
2107 editor-render screen, e
2108 $clear-trace
2109
2110 assume-console [
2111 ¦ press ctrl-k
2112 ]
2113 run [
2114 ¦ editor-event-loop screen, console, e
2115 ]
2116
2117 screen-should-contain [
2118 ¦ . .
2119 ¦ . .
2120 ¦ .567 .
2121 ¦ .╌╌╌╌ .
2122 ¦ . .
2123 ]
2124
2125 check-trace-count-for-label 16, [print-character]
2126 ]
2127
2128
2129
2130 scenario editor-can-scroll-down-using-arrow-keys [
2131 local-scope
2132
2133 assume-screen 10/width, 4/height
2134
2135 s:text <- new [a
2136 b
2137 c
2138 d]
2139 e:&:editor <- new-editor s, 0/left, 10/right
2140 editor-render screen, e
2141 screen-should-contain [
2142 ¦ . .
2143 ¦ .a .
2144 ¦ .b .
2145 ¦ .c .
2146 ]
2147
2148 assume-console [
2149 ¦ left-click 3, 0
2150 ¦ press down-arrow
2151 ]
2152 run [
2153 ¦ editor-event-loop screen, console, e
2154 ]
2155
2156 screen-should-contain [
2157 ¦ . .
2158 ¦ .b .
2159 ¦ .c .
2160 ¦ .d .
2161 ]
2162 ]
2163
2164 after <scroll-down> [
2165 trace 10, [app], [scroll down]
2166 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2167 left:num <- get *editor, left:offset
2168 right:num <- get *editor, right:offset
2169 max:num <- subtract right, left
2170 old-top:&:duplex-list:char <- copy top-of-screen
2171 top-of-screen <- before-start-of-next-line top-of-screen, max
2172 *editor <- put *editor, top-of-screen:offset, top-of-screen
2173 no-movement?:bool <- equal old-top, top-of-screen
2174 return-if no-movement?, 0/don't-render
2175 ]
2176
2177
2178
2179
2180 def before-start-of-next-line original:&:duplex-list:char, max:num -> curr:&:duplex-list:char [
2181 local-scope
2182 load-ingredients
2183 count:num <- copy 0
2184 curr:&:duplex-list:char <- copy original
2185
2186 {
2187 ¦ c:char <- get *curr, value:offset
2188 ¦ at-newline?:bool <- equal c, 10/newline
2189 ¦ break-unless at-newline?
2190 ¦ curr <- next curr
2191 ¦ count <- add count, 1
2192 }
2193 {
2194 ¦ return-unless curr, original
2195 ¦ done?:bool <- greater-or-equal count, max
2196 ¦ break-if done?
2197 ¦ c:char <- get *curr, value:offset
2198 ¦ at-newline?:bool <- equal c, 10/newline
2199 ¦ break-if at-newline?
2200 ¦ curr <- next curr
2201 ¦ count <- add count, 1
2202 ¦ loop
2203 }
2204 return-unless curr, original
2205 return curr
2206 ]
2207
2208 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys [
2209 local-scope
2210
2211 assume-screen 10/width, 4/height
2212
2213
2214 s:text <- new [abcdef
2215 g
2216 h
2217 i]
2218 e:&:editor <- new-editor s, 0/left, 5/right
2219 editor-render screen, e
2220 screen-should-contain [
2221 ¦ . .
2222 ¦ .abcd↩ .
2223 ¦ .ef .
2224 ¦ .g .
2225 ]
2226
2227 assume-console [
2228 ¦ left-click 3, 0
2229 ¦ press down-arrow
2230 ]
2231 run [
2232 ¦ editor-event-loop screen, console, e
2233 ]
2234
2235 screen-should-contain [
2236 ¦ . .
2237 ¦ .ef .
2238 ¦ .g .
2239 ¦ .h .
2240 ]
2241 ]
2242
2243 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys-2 [
2244 local-scope
2245
2246 assume-screen 10/width, 4/height
2247
2248 s:text <- new [abcdefghij
2249 k
2250 l
2251 m]
2252 e:&:editor <- new-editor s, 0/left, 5/right
2253
2254 assume-console [
2255 ¦ left-click 3, 0
2256 ¦ press down-arrow
2257 ]
2258 run [
2259 ¦ editor-event-loop screen, console, e
2260 ]
2261
2262 screen-should-contain [
2263 ¦ . .
2264 ¦ .efgh↩ .
2265 ¦ .ij .
2266 ¦ .k .
2267 ]
2268
2269 assume-console [
2270 ¦ press down-arrow
2271 ]
2272 run [
2273 ¦ editor-event-loop screen, console, e
2274 ]
2275
2276 screen-should-contain [
2277 ¦ . .
2278 ¦ .ij .
2279 ¦ .k .
2280 ¦ .l .
2281 ]
2282 ]
2283
2284 scenario editor-scrolls-down-when-line-wraps [
2285 local-scope
2286
2287 assume-screen 5/width, 4/height
2288
2289 s:text <- new [a
2290 b
2291 cdef]
2292 e:&:editor <- new-editor s, 0/left, 5/right
2293
2294 assume-console [
2295 ¦ left-click 3, 4
2296 ¦ type [g]
2297 ]
2298 run [
2299 ¦ editor-event-loop screen, console, e
2300 ¦ 3:num/raw <- get *e, cursor-row:offset
2301 ¦ 4:num/raw <- get *e, cursor-column:offset
2302 ]
2303
2304 screen-should-contain [
2305 ¦ . .
2306 ¦ .b .
2307 ¦ .cdef↩.
2308 ¦ .g .
2309 ]
2310 memory-should-contain [
2311 ¦ 3 <- 3
2312 ¦ 4 <- 1
2313 ]
2314 ]
2315
2316 scenario editor-scrolls-down-on-newline [
2317 local-scope
2318 assume-screen 5/width, 4/height
2319
2320 s:text <- new [a
2321 b
2322 c]
2323 e:&:editor <- new-editor s, 0/left, 5/right
2324 assume-console [
2325 ¦ left-click 3, 4
2326 ¦ type [
2327 ]
2328 ]
2329 run [
2330 ¦ editor-event-loop screen, console, e
2331 ¦ 3:num/raw <- get *e, cursor-row:offset
2332 ¦ 4:num/raw <- get *e, cursor-column:offset
2333 ]
2334
2335 screen-should-contain [
2336 ¦ . .
2337 ¦ .b .
2338 ¦ .c .
2339 ¦ . .
2340 ]
2341 memory-should-contain [
2342 ¦ 3 <- 3
2343 ¦ 4 <- 0
2344 ]
2345 ]
2346
2347 scenario editor-scrolls-down-on-right-arrow [
2348 local-scope
2349
2350 assume-screen 5/width, 4/height
2351
2352 s:text <- new [a
2353 b
2354 cdefgh]
2355 e:&:editor <- new-editor s, 0/left, 5/right
2356
2357 assume-console [
2358 ¦ left-click 3, 3
2359 ¦ press right-arrow
2360 ]
2361 run [
2362 ¦ editor-event-loop screen, console, e
2363 ¦ 3:num/raw <- get *e, cursor-row:offset
2364 ¦ 4:num/raw <- get *e, cursor-column:offset
2365 ]
2366
2367 screen-should-contain [
2368 ¦ . .
2369 ¦ .b .
2370 ¦ .cdef↩.
2371 ¦ .gh .
2372 ]
2373 memory-should-contain [
2374 ¦ 3 <- 3
2375 ¦ 4 <- 0
2376 ]
2377 ]
2378
2379 scenario editor-scrolls-down-on-right-arrow-2 [
2380 local-scope
2381
2382 assume-screen 5/width, 4/height
2383
2384 s:text <- new [a
2385 b
2386 c
2387 d]
2388 e:&:editor <- new-editor s, 0/left, 5/right
2389
2390 assume-console [
2391 ¦ left-click 3, 3
2392 ¦ press right-arrow
2393 ]
2394 run [
2395 ¦ editor-event-loop screen, console, e
2396 ¦ 3:num/raw <- get *e, cursor-row:offset
2397 ¦ 4:num/raw <- get *e, cursor-column:offset
2398 ]
2399
2400 screen-should-contain [
2401 ¦ . .
2402 ¦ .b .
2403 ¦ .c .
2404 ¦ .d .
2405 ]
2406 memory-should-contain [
2407 ¦ 3 <- 3
2408 ¦ 4 <- 0
2409 ]
2410 ]
2411
2412 scenario editor-scrolls-at-end-on-down-arrow [
2413 local-scope
2414 assume-screen 10/width, 5/height
2415 s:text <- new [abc
2416 de]
2417 e:&:editor <- new-editor s, 0/left, 10/right
2418 editor-render screen, e
2419 $clear-trace
2420
2421 assume-console [
2422 ¦ left-click 2, 0
2423 ¦ press down-arrow
2424 ]
2425 run [
2426 ¦ editor-event-loop screen, console, e
2427 ¦ 3:num/raw <- get *e, cursor-row:offset
2428 ¦ 4:num/raw <- get *e, cursor-column:offset
2429 ]
2430
2431 memory-should-contain [
2432 ¦ 3 <- 1
2433 ¦ 4 <- 2
2434 ]
2435 assume-console [
2436 ¦ type [0]
2437 ]
2438 run [
2439 ¦ editor-event-loop screen, console, e
2440 ]
2441 screen-should-contain [
2442 ¦ . .
2443 ¦ .de0 .
2444 ¦ .╌╌╌╌╌╌╌╌╌╌.
2445 ¦ . .
2446 ]
2447
2448 $clear-trace
2449 assume-console [
2450 ¦ left-click 2, 0
2451 ¦ press down-arrow
2452 ]
2453 run [
2454 ¦ editor-event-loop screen, console, e
2455 ¦ 3:num/raw <- get *e, cursor-row:offset
2456 ¦ 4:num/raw <- get *e, cursor-column:offset
2457 ]
2458
2459 memory-should-contain [
2460 ¦ 3 <- 1
2461 ¦ 4 <- 3
2462 ]
2463 check-trace-count-for-label 0, [print-character]
2464 assume-console [
2465 ¦ type [1]
2466 ]
2467 run [
2468 ¦ editor-event-loop screen, console, e
2469 ]
2470 screen-should-contain [
2471 ¦ . .
2472 ¦ .de01 .
2473 ¦ .╌╌╌╌╌╌╌╌╌╌.
2474 ¦ . .
2475 ]
2476 ]
2477
2478 scenario editor-combines-page-and-line-scroll [
2479 local-scope
2480
2481 assume-screen 10/width, 4/height
2482
2483 s:text <- new [a
2484 b
2485 c
2486 d
2487 e
2488 f
2489 g]
2490 e:&:editor <- new-editor s, 0/left, 5/right
2491 editor-render screen, e
2492
2493 assume-console [
2494 ¦ press page-down
2495 ¦ left-click 3, 0
2496 ¦ press down-arrow
2497 ]
2498 run [
2499 ¦ editor-event-loop screen, console, e
2500 ]
2501
2502 screen-should-contain [
2503 ¦ . .
2504 ¦ .d .
2505 ¦ .e .
2506 ¦ .f .
2507 ]
2508 ]
2509
2510
2511
2512 scenario editor-can-scroll-up-using-arrow-keys [
2513 local-scope
2514
2515 assume-screen 10/width, 4/height
2516
2517 s:text <- new [a
2518 b
2519 c
2520 d]
2521 e:&:editor <- new-editor s, 0/left, 10/right
2522 editor-render screen, e
2523 screen-should-contain [
2524 ¦ . .
2525 ¦ .a .
2526 ¦ .b .
2527 ¦ .c .
2528 ]
2529
2530 assume-console [
2531 ¦ press page-down
2532 ¦ press up-arrow
2533 ]
2534 run [
2535 ¦ editor-event-loop screen, console, e
2536 ]
2537
2538 screen-should-contain [
2539 ¦ . .
2540 ¦ .b .
2541 ¦ .c .
2542 ¦ .d .
2543 ]
2544 ]
2545
2546 after <scroll-up> [
2547 trace 10, [app], [scroll up]
2548 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2549 old-top:&:duplex-list:char <- copy top-of-screen
2550 top-of-screen <- before-previous-line top-of-screen, editor
2551 *editor <- put *editor, top-of-screen:offset, top-of-screen
2552 no-movement?:bool <- equal old-top, top-of-screen
2553 return-if no-movement?, 0/don't-render
2554 ]
2555
2556
2557
2558
2559 def before-previous-line in:&:duplex-list:char, editor:&:editor -> out:&:duplex-list:char [
2560 local-scope
2561 load-ingredients
2562 curr:&:duplex-list:char <- copy in
2563 c:char <- get *curr, value:offset
2564
2565
2566
2567 left:num <- get *editor, left:offset
2568 right:num <- get *editor, right:offset
2569 max-line-length:num <- subtract right, left, -1/exclusive-right, 1/wrap-icon
2570 sentinel:&:duplex-list:char <- get *editor, data:offset
2571 len:num <- previous-line-length curr, sentinel
2572 {
2573 ¦ break-if len
2574 ¦
2575 ¦ prev:&:duplex-list:char <- prev curr
2576 ¦ return-unless prev, curr
2577 ¦ return prev
2578 }
2579 _, max:num <- divide-with-remainder len, max-line-length
2580
2581 {
2582 ¦ break-if max
2583 ¦ max <- copy max-line-length
2584 }
2585 max <- add max, 1
2586 count:num <- copy 0
2587
2588 {
2589 ¦ done?:bool <- greater-or-equal count, max
2590 ¦ break-if done?
2591 ¦ prev:&:duplex-list:char <- prev curr
2592 ¦ break-unless prev
2593 ¦ curr <- copy prev
2594 ¦ count <- add count, 1
2595 ¦ loop
2596 }
2597 return curr
2598 ]
2599
2600 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys [
2601 local-scope
2602
2603 assume-screen 10/width, 4/height
2604
2605
2606 s:text <- new [abcdef
2607 g
2608 h
2609 i]
2610 e:&:editor <- new-editor s, 0/left, 5/right
2611 editor-render screen, e
2612 screen-should-contain [
2613 ¦ . .
2614 ¦ .abcd↩ .
2615 ¦ .ef .
2616 ¦ .g .
2617 ]
2618
2619 assume-console [
2620 ¦ press page-down
2621 ]
2622 run [
2623 ¦ editor-event-loop screen, console, e
2624 ]
2625 screen-should-contain [
2626 ¦ . .
2627 ¦ .g .
2628 ¦ .h .
2629 ¦ .i .
2630 ]
2631
2632 assume-console [
2633 ¦ press up-arrow
2634 ]
2635 run [
2636 ¦ editor-event-loop screen, console, e
2637 ]
2638
2639 screen-should-contain [
2640 ¦ . .
2641 ¦ .ef .
2642 ¦ .g .
2643 ¦ .h .
2644 ]
2645 ]
2646
2647 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-2 [
2648 local-scope
2649
2650 assume-screen 10/width, 5/height
2651
2652 s:text <- new [abcdefghij
2653 k
2654 l
2655 m]
2656 e:&:editor <- new-editor s, 0/left, 5/right
2657 editor-render screen, e
2658
2659 assume-console [
2660 ¦ press page-down
2661 ]
2662 run [
2663 ¦ editor-event-loop screen, console, e
2664 ]
2665 screen-should-contain [
2666 ¦ . .
2667 ¦ .k .
2668 ¦ .l .
2669 ¦ .m .
2670 ¦ .╌╌╌╌╌ .
2671 ]
2672
2673 assume-console [
2674 ¦ press up-arrow
2675 ]
2676 run [
2677 ¦ editor-event-loop screen, console, e
2678 ]
2679
2680 screen-should-contain [
2681 ¦ . .
2682 ¦ .ij .
2683 ¦ .k .
2684 ¦ .l .
2685 ¦ .m .
2686 ]
2687
2688 assume-console [
2689 ¦ press up-arrow
2690 ]
2691 run [
2692 ¦ editor-event-loop screen, console, e
2693 ]
2694
2695 screen-should-contain [
2696 ¦ . .
2697 ¦ .efgh↩ .
2698 ¦ .ij .
2699 ¦ .k .
2700 ¦ .l .
2701 ]
2702
2703 assume-console [
2704 ¦ press up-arrow
2705 ]
2706 run [
2707 ¦ editor-event-loop screen, console, e
2708 ]
2709
2710 screen-should-contain [
2711 ¦ . .
2712 ¦ .abcd↩ .
2713 ¦ .efgh↩ .
2714 ¦ .ij .
2715 ¦ .k .
2716 ]
2717 ]
2718
2719
2720
2721 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-3 [
2722 local-scope
2723
2724 assume-screen 10/width, 4/height
2725
2726
2727 s:text <- new [abcdef
2728 g
2729 h
2730 i]
2731 e:&:editor <- new-editor s, 0/left, 6/right
2732 editor-render screen, e
2733 screen-should-contain [
2734 ¦ . .
2735 ¦ .abcde↩ .
2736 ¦ .f .
2737 ¦ .g .
2738 ]
2739
2740 assume-console [
2741 ¦ press page-down
2742 ]
2743 run [
2744 ¦ editor-event-loop screen, console, e
2745 ]
2746 screen-should-contain [
2747 ¦ . .
2748 ¦ .g .
2749 ¦ .h .
2750 ¦ .i .
2751 ]
2752
2753 assume-console [
2754 ¦ press up-arrow
2755 ]
2756 run [
2757 ¦ editor-event-loop screen, console, e
2758 ]
2759
2760 screen-should-contain [
2761 ¦ . .
2762 ¦ .f .
2763 ¦ .g .
2764 ¦ .h .
2765 ]
2766 ]
2767
2768
2769 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-4 [
2770 local-scope
2771 assume-screen 10/width, 4/height
2772
2773 s:text <- new [a
2774 b
2775
2776 c
2777 d
2778 e]
2779 e:&:editor <- new-editor s, 0/left, 6/right
2780 editor-render screen, e
2781 assume-console [
2782 ¦ press page-down
2783 ]
2784 run [
2785 ¦ editor-event-loop screen, console, e
2786 ]
2787 screen-should-contain [
2788 ¦ . .
2789 ¦ . .
2790 ¦ .c .
2791 ¦ .d .
2792 ]
2793 assume-console [
2794 ¦ press page-down
2795 ]
2796 run [
2797 ¦ editor-event-loop screen, console, e
2798 ]
2799 screen-should-contain [
2800 ¦ . .
2801 ¦ .d .
2802 ¦ .e .
2803 ¦ .╌╌╌╌╌╌ .
2804 ]
2805 assume-console [
2806 ¦ press page-up
2807 ]
2808 run [
2809 ¦ editor-event-loop screen, console, e
2810 ]
2811 screen-should-contain [
2812 ¦ . .
2813 ¦ . .
2814 ¦ .c .
2815 ¦ .d .
2816 ]
2817 ]
2818
2819 scenario editor-scrolls-up-on-left-arrow [
2820 local-scope
2821
2822 assume-screen 5/width, 4/height
2823
2824 s:text <- new [a
2825 b
2826 c
2827 d
2828 e]
2829 e:&:editor <- new-editor s, 0/left, 5/right
2830 editor-render screen, e
2831
2832 assume-console [
2833 ¦ press page-down
2834 ]
2835 run [
2836 ¦ editor-event-loop screen, console, e
2837 ]
2838 screen-should-contain [
2839 ¦ . .
2840 ¦ .c .
2841 ¦ .d .
2842 ¦ .e .
2843 ]
2844
2845 assume-console [
2846 ¦ press left-arrow
2847 ]
2848 run [
2849 ¦ editor-event-loop screen, console, e
2850 ¦ 3:num/raw <- get *e, cursor-row:offset
2851 ¦ 4:num/raw <- get *e, cursor-column:offset
2852 ]
2853
2854 screen-should-contain [
2855 ¦ . .
2856 ¦ .b .
2857 ¦ .c .
2858 ¦ .d .
2859 ]
2860 memory-should-contain [
2861 ¦ 3 <- 1
2862 ¦ 4 <- 1
2863 ]
2864 ]
2865
2866 scenario editor-can-scroll-up-to-start-of-file [
2867 local-scope
2868
2869 assume-screen 10/width, 4/height
2870
2871 s:text <- new [a
2872 b
2873 c
2874 d]
2875 e:&:editor <- new-editor s, 0/left, 10/right
2876 editor-render screen, e
2877 screen-should-contain [
2878 ¦ . .
2879 ¦ .a .
2880 ¦ .b .
2881 ¦ .c .
2882 ]
2883
2884
2885 assume-console [
2886 ¦ press page-down
2887 ¦ press up-arrow
2888 ¦ press up-arrow
2889 ]
2890 run [
2891 ¦ editor-event-loop screen, console, e
2892 ]
2893
2894 screen-should-contain [
2895 ¦ . .
2896 ¦ .a .
2897 ¦ .b .
2898 ¦ .c .
2899 ]
2900
2901 assume-console [
2902 ¦ press up-arrow
2903 ]
2904 run [
2905 ¦ editor-event-loop screen, console, e
2906 ]
2907
2908 screen-should-contain [
2909 ¦ . .
2910 ¦ .a .
2911 ¦ .b .
2912 ¦ .c .
2913 ]
2914 ]
2915
2916
2917
2918 scenario editor-can-scroll [
2919 local-scope
2920 assume-screen 10/width, 4/height
2921 s:text <- new [a
2922 b
2923 c
2924 d]
2925 e:&:editor <- new-editor s, 0/left, 10/right
2926 editor-render screen, e
2927 screen-should-contain [
2928 ¦ . .
2929 ¦ .a .
2930 ¦ .b .
2931 ¦ .c .
2932 ]
2933
2934 assume-console [
2935 ¦ press page-down
2936 ]
2937 run [
2938 ¦ editor-event-loop screen, console, e
2939 ]
2940
2941 screen-should-contain [
2942 ¦ . .
2943 ¦ .c .
2944 ¦ .d .
2945 ¦ .╌╌╌╌╌╌╌╌╌╌.
2946 ]
2947 ]
2948
2949 after <handle-special-character> [
2950 {
2951 ¦ page-down?:bool <- equal c, 6/ctrl-f
2952 ¦ break-unless page-down?
2953 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
2954 ¦ <move-cursor-begin>
2955 ¦ page-down editor
2956 ¦ undo-coalesce-tag:num <- copy 0/never
2957 ¦ <move-cursor-end>
2958 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2959 ¦ movement?:bool <- not-equal top-of-screen, old-top
2960 ¦ return movement?/go-render
2961 }
2962 ]
2963
2964 after <handle-special-key> [
2965 {
2966 ¦ page-down?:bool <- equal k, 65518/page-down
2967 ¦ break-unless page-down?
2968 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
2969 ¦ <move-cursor-begin>
2970 ¦ page-down editor
2971 ¦ undo-coalesce-tag:num <- copy 0/never
2972 ¦ <move-cursor-end>
2973 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2974 ¦ movement?:bool <- not-equal top-of-screen, old-top
2975 ¦ return movement?/go-render
2976 }
2977 ]
2978
2979
2980
2981 def page-down editor:&:editor -> editor:&:editor [
2982 local-scope
2983 load-ingredients
2984
2985 bottom-of-screen:&:duplex-list:char <- get *editor, bottom-of-screen:offset
2986 return-unless bottom-of-screen
2987
2988 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
2989 before-cursor:&:duplex-list:char <- prev bottom-of-screen
2990 *editor <- put *editor, before-cursor:offset, before-cursor
2991
2992 {
2993 ¦ last:char <- get *before-cursor, value:offset
2994 ¦ newline?:bool <- equal last, 10/newline
2995 ¦ break-unless newline?:bool
2996 ¦ before-cursor <- prev before-cursor
2997 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
2998 }
2999
3000 move-to-start-of-line editor
3001 before-cursor <- get *editor, before-cursor:offset
3002 *editor <- put *editor, top-of-screen:offset, before-cursor
3003 ]
3004
3005 scenario editor-does-not-scroll-past-end [
3006 local-scope
3007 assume-screen 10/width, 4/height
3008 s:text <- new [a
3009 b]
3010 e:&:editor <- new-editor s, 0/left, 10/right
3011 editor-render screen, e
3012 screen-should-contain [
3013 ¦ . .
3014 ¦ .a .
3015 ¦ .b .
3016 ¦ .╌╌╌╌╌╌╌╌╌╌.
3017 ]
3018
3019 assume-console [
3020 ¦ press page-down
3021 ]
3022 run [
3023 ¦ editor-event-loop screen, console, e
3024 ]
3025
3026 screen-should-contain [
3027 ¦ . .
3028 ¦ .a .
3029 ¦ .b .
3030 ¦ .╌╌╌╌╌╌╌╌╌╌.
3031 ]
3032 ]
3033
3034 scenario editor-starts-next-page-at-start-of-wrapped-line [
3035 local-scope
3036
3037 assume-screen 10/width, 4/height
3038
3039 s:text <- new [a
3040 b
3041 cdefgh]
3042
3043 e:&:editor <- new-editor s, 0/left, 4/right
3044 editor-render screen, e
3045
3046 screen-should-contain [
3047 ¦ . .
3048 ¦ .a .
3049 ¦ .b .
3050 ¦ .cde↩ .
3051 ]
3052
3053 assume-console [
3054 ¦ press page-down
3055 ]
3056 run [
3057 ¦ editor-event-loop screen, console, e
3058 ]
3059
3060 screen-should-contain [
3061 ¦ . .
3062 ¦ .cde↩ .
3063 ¦ .fgh .
3064 ¦ .╌╌╌╌ .
3065 ]
3066 ]
3067
3068 scenario editor-starts-next-page-at-start-of-wrapped-line-2 [
3069 local-scope
3070
3071 assume-screen 10/width, 4/height
3072
3073
3074 s:text <- new [a
3075 bcdefgh]
3076 e:&:editor <- new-editor s, 0/left, 4/right
3077 editor-render screen, e
3078
3079 screen-should-contain [
3080 ¦ . .
3081 ¦ .a .
3082 ¦ .bcd↩ .
3083 ¦ .efg↩ .
3084 ]
3085
3086 assume-console [
3087 ¦ press page-down
3088 ]
3089 run [
3090 ¦ editor-event-loop screen, console, e
3091 ]
3092
3093 screen-should-contain [
3094 ¦ . .
3095 ¦ .bcd↩ .
3096 ¦ .efg↩ .
3097 ¦ .h .
3098 ]
3099 ]
3100
3101
3102
3103 scenario editor-can-scroll-up [
3104 local-scope
3105 assume-screen 10/width, 4/height
3106 s:text <- new [a
3107 b
3108 c
3109 d]
3110 e:&:editor <- new-editor s, 0/left, 10/right
3111 editor-render screen, e
3112 screen-should-contain [
3113 ¦ . .
3114 ¦ .a .
3115 ¦ .b .
3116 ¦ .c .
3117 ]
3118
3119 assume-console [
3120 ¦ press page-down
3121 ]
3122 run [
3123 ¦ editor-event-loop screen, console, e
3124 ]
3125
3126 screen-should-contain [
3127 ¦ . .
3128 ¦ .c .
3129 ¦ .d .
3130 ¦ .╌╌╌╌╌╌╌╌╌╌.
3131 ]
3132
3133 assume-console [
3134 ¦ press page-up
3135 ]
3136 run [
3137 ¦ editor-event-loop screen, console, e
3138 ]
3139
3140 screen-should-contain [
3141 ¦ . .
3142 ¦ .a .
3143 ¦ .b .
3144 ¦ .c .
3145 ]
3146 ]
3147
3148 after <handle-special-character> [
3149 {
3150 ¦ page-up?:bool <- equal c, 2/ctrl-b
3151 ¦ break-unless page-up?
3152 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3153 ¦ <move-cursor-begin>
3154 ¦ editor <- page-up editor, screen-height
3155 ¦ undo-coalesce-tag:num <- copy 0/never
3156 ¦ <move-cursor-end>
3157 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3158 ¦ movement?:bool <- not-equal top-of-screen, old-top
3159 ¦ return movement?/go-render
3160 }
3161 ]
3162
3163 after <handle-special-key> [
3164 {
3165 ¦ page-up?:bool <- equal k, 65519/page-up
3166 ¦ break-unless page-up?
3167 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3168 ¦ <move-cursor-begin>
3169 ¦ editor <- page-up editor, screen-height
3170 ¦ undo-coalesce-tag:num <- copy 0/never
3171 ¦ <move-cursor-end>
3172 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3173 ¦ movement?:bool <- not-equal top-of-screen, old-top
3174 ¦
3175 ¦ return movement?/go-render
3176 }
3177 ]
3178
3179 def page-up editor:&:editor, screen-height:num -> editor:&:editor [
3180 local-scope
3181 load-ingredients
3182 max:num <- subtract screen-height, 1/menu-bar, 1/overlapping-line
3183 count:num <- copy 0
3184 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3185 {
3186 ¦ done?:bool <- greater-or-equal count, max
3187 ¦ break-if done?
3188 ¦ prev:&:duplex-list:char <- before-previous-line top-of-screen, editor
3189 ¦ break-unless prev
3190 ¦ top-of-screen <- copy prev
3191 ¦ *editor <- put *editor, top-of-screen:offset, top-of-screen
3192 ¦ count <- add count, 1
3193 ¦ loop
3194 }
3195 ]
3196
3197 scenario editor-can-scroll-up-multiple-pages [
3198 local-scope
3199
3200 assume-screen 10/width, 4/height
3201
3202 s:text <- new [a
3203 b
3204 c
3205 d
3206 e
3207 f
3208 g
3209 h]
3210 e:&:editor <- new-editor s, 0/left, 10/right
3211 editor-render screen, e
3212 screen-should-contain [
3213 ¦ . .
3214 ¦ .a .
3215 ¦ .b .
3216 ¦ .c .
3217 ]
3218
3219 assume-console [
3220 ¦ press page-down
3221 ¦ press page-down
3222 ]
3223 run [
3224 ¦ editor-event-loop screen, console, e
3225 ]
3226
3227 screen-should-contain [
3228 ¦ . .
3229 ¦ .e .
3230 ¦ .f .
3231 ¦ .g .
3232 ]
3233
3234 assume-console [
3235 ¦ press page-up
3236 ]
3237 run [
3238 ¦ editor-event-loop screen, console, e
3239 ]
3240
3241 screen-should-contain [
3242 ¦ . .
3243 ¦ .c .
3244 ¦ .d .
3245 ¦ .e .
3246 ]
3247
3248 assume-console [
3249 ¦ press page-up
3250 ]
3251 run [
3252 ¦ editor-event-loop screen, console, e
3253 ]
3254
3255 screen-should-contain [
3256 ¦ . .
3257 ¦ .a .
3258 ¦ .b .
3259 ¦ .c .
3260 ]
3261 ]
3262
3263 scenario editor-can-scroll-up-wrapped-lines [
3264 local-scope
3265
3266 assume-screen 10/width, 6/height
3267
3268 s:text <- new [a
3269 b
3270 cdefgh
3271 i
3272 j
3273 k
3274 l
3275 m
3276 n
3277 o]
3278
3279 e:&:editor <- new-editor s, 0/left, 4/right
3280 editor-render screen, e
3281
3282 screen-should-contain [
3283 ¦ . .
3284 ¦ .a .
3285 ¦ .b .
3286 ¦ .cde↩ .
3287 ¦ .fgh .
3288 ¦ .i .
3289 ]
3290
3291 assume-console [
3292 ¦ press page-down
3293 ¦ left-click 5, 0
3294 ¦ press down-arrow
3295 ]
3296 run [
3297 ¦ editor-event-loop screen, console, e
3298 ]
3299
3300 screen-should-contain [
3301 ¦ . .
3302 ¦ .j .
3303 ¦ .k .
3304 ¦ .l .
3305 ¦ .m .
3306 ¦ .n .
3307 ]
3308
3309 assume-console [
3310 ¦ press page-up
3311 ]
3312 run [
3313 ¦ editor-event-loop screen, console, e
3314 ]
3315
3316 screen-should-contain [
3317 ¦ . .
3318 ¦ .b .
3319 ¦ .cde↩ .
3320 ¦ .fgh .
3321 ¦ .i .
3322 ¦ .j .
3323 ]
3324 ]
3325
3326 scenario editor-can-scroll-up-wrapped-lines-2 [
3327 local-scope
3328
3329 assume-screen 10/width, 4/height
3330
3331
3332 s:text <- new [a
3333 bcdefgh]
3334 e:&:editor <- new-editor s, 0/left, 4/right
3335 editor-render screen, e
3336
3337 screen-should-contain [
3338 ¦ . .
3339 ¦ .a .
3340 ¦ .bcd↩ .
3341 ¦ .efg↩ .
3342 ]
3343
3344 assume-console [
3345 ¦ press page-down
3346 ]
3347 run [
3348 ¦ editor-event-loop screen, console, e
3349 ]
3350
3351 screen-should-contain [
3352 ¦ . .
3353 ¦ .bcd↩ .
3354 ¦ .efg↩ .
3355 ¦ .h .
3356 ]
3357
3358 assume-console [
3359 ¦ press page-up
3360 ]
3361 run [
3362 ¦ editor-event-loop screen, console, e
3363 ]
3364
3365 screen-should-contain [
3366 ¦ . .
3367 ¦ .a .
3368 ¦ .bcd↩ .
3369 ¦ .efg↩ .
3370 ]
3371 ]
3372
3373 scenario editor-can-scroll-up-past-nonempty-lines [
3374 local-scope
3375 assume-screen 10/width, 4/height
3376
3377 s:text <- new [axx
3378 bxx
3379 cxx
3380 dxx
3381 exx
3382 fxx
3383 gxx
3384 hxx
3385 ]
3386 e:&:editor <- new-editor s, 0/left, 4/right
3387 editor-render screen, e
3388 screen-should-contain [
3389 ¦ . .
3390 ¦ .axx .
3391 ¦ .bxx .
3392 ¦ .cxx .
3393 ]
3394 assume-console [
3395 ¦ press page-down
3396 ]
3397 run [
3398 ¦ editor-event-loop screen, console, e
3399 ]
3400 screen-should-contain [
3401 ¦ . .
3402 ¦ .cxx .
3403 ¦ .dxx .
3404 ¦ .exx .
3405 ]
3406 assume-console [
3407 ¦ press page-down
3408 ]
3409 run [
3410 ¦ editor-event-loop screen, console, e
3411 ]
3412 screen-should-contain [
3413 ¦ . .
3414 ¦ .exx .
3415 ¦ .fxx .
3416 ¦ .gxx .
3417 ]
3418
3419 assume-console [
3420 ¦ press page-up
3421 ]
3422 run [
3423 ¦ editor-event-loop screen, console, e
3424 ]
3425 screen-should-contain [
3426 ¦ . .
3427 ¦ .cxx .
3428 ¦ .dxx .
3429 ¦ .exx .
3430 ]
3431 ]
3432
3433 scenario editor-can-scroll-up-past-empty-lines [
3434 local-scope
3435 assume-screen 10/width, 4/height
3436
3437 s:text <- new [axy
3438 bxy
3439 cxy
3440
3441 dxy
3442 exy
3443 fxy
3444 gxy
3445 ]
3446 e:&:editor <- new-editor s, 0/left, 4/right
3447 editor-render screen, e
3448 screen-should-contain [
3449 ¦ . .
3450 ¦ .axy .
3451 ¦ .bxy .
3452 ¦ .cxy .
3453 ]
3454 assume-console [
3455 ¦ press page-down
3456 ]
3457 run [
3458 ¦ editor-event-loop screen, console, e
3459 ]
3460 screen-should-contain [
3461 ¦ . .
3462 ¦ .cxy .
3463 ¦ . .
3464 ¦ .dxy .
3465 ]
3466 assume-console [
3467 ¦ press page-down
3468 ]
3469 run [
3470 ¦ editor-event-loop screen, console, e
3471 ]
3472 screen-should-contain [
3473 ¦ . .
3474 ¦ .dxy .
3475 ¦ .exy .
3476 ¦ .fxy .
3477 ]
3478
3479 assume-console [
3480 ¦ press page-up
3481 ]
3482 run [
3483 ¦ editor-event-loop screen, console, e
3484 ]
3485 screen-should-contain [
3486 ¦ . .
3487 ¦ .cxy .
3488 ¦ . .
3489 ¦ .dxy .
3490 ]
3491 ]