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 s:text <- new [ab
11 cd]
12 e:&:editor <- new-editor s, 0/left, 5/right
13 editor-render screen, e
14 $clear-trace
15 assume-console [
16 ¦ press tab
17 ]
18 run [
19 ¦ editor-event-loop screen, console, e
20 ]
21 screen-should-contain [
22 ¦ . .
23 ¦ . ab .
24 ¦ .cd .
25 ]
26
27 check-trace-count-for-label-lesser-than 10, [print-character]
28 ]
29
30 scenario editor-inserts-two-spaces-and-wraps-line-on-tab [
31 local-scope
32 assume-screen 10/width, 5/height
33 e:&:editor <- new-editor [abcd], 0/left, 5/right
34 editor-render screen, e
35 $clear-trace
36 assume-console [
37 ¦ press tab
38 ]
39 run [
40 ¦ editor-event-loop screen, console, e
41 ]
42 screen-should-contain [
43 ¦ . .
44 ¦ . ab↩ .
45 ¦ .cd .
46 ]
47
48 check-trace-count-for-label-greater-than 10, [print-character]
49 ]
50
51 after <handle-special-character> [
52 {
53 ¦ tab?:bool <- equal c, 9/tab
54 ¦ break-unless tab?
55 ¦ <insert-character-begin>
56 ¦
57 ¦
58 ¦ insert-at-cursor editor, 32/space, screen
59 ¦ go-render? <- insert-at-cursor editor, 32/space, screen
60 ¦ <insert-character-end>
61 ¦ return
62 }
63 ]
64
65
66
67 scenario editor-handles-backspace-key [
68 local-scope
69 assume-screen 10/width, 5/height
70 e:&:editor <- new-editor [abc], 0/left, 10/right
71 editor-render screen, e
72 $clear-trace
73 assume-console [
74 ¦ left-click 1, 1
75 ¦ press backspace
76 ]
77 run [
78 ¦ editor-event-loop screen, console, e
79 ¦ 4:num/raw <- get *e, cursor-row:offset
80 ¦ 5:num/raw <- get *e, cursor-column:offset
81 ]
82 screen-should-contain [
83 ¦ . .
84 ¦ .bc .
85 ¦ .╌╌╌╌╌╌╌╌╌╌.
86 ¦ . .
87 ]
88 memory-should-contain [
89 ¦ 4 <- 1
90 ¦ 5 <- 0
91 ]
92 check-trace-count-for-label 3, [print-character]
93 ]
94
95 after <handle-special-character> [
96 {
97 ¦ delete-previous-character?:bool <- equal c, 8/backspace
98 ¦ break-unless delete-previous-character?
99 ¦ <backspace-character-begin>
100 ¦ go-render?:bool, backspaced-cell:&:duplex-list:char <- delete-before-cursor editor, screen
101 ¦ <backspace-character-end>
102 ¦ return
103 }
104 ]
105
106
107
108
109 def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, backspaced-cell:&:duplex-list:char, editor:&:editor, screen:&:screen [
110 local-scope
111 load-ingredients
112 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
113 data:&:duplex-list:char <- get *editor, data:offset
114
115 prev:&:duplex-list:char <- prev before-cursor
116 return-unless prev, 0/no-more-render, 0/nothing-deleted
117 trace 10, [app], [delete-before-cursor]
118 original-row:num <- get *editor, cursor-row:offset
119 scroll?:bool <- move-cursor-coordinates-left editor
120 backspaced-cell:&:duplex-list:char <- copy before-cursor
121 data <- remove before-cursor, data
122 before-cursor <- copy prev
123 *editor <- put *editor, before-cursor:offset, before-cursor
124 return-if scroll?, 1/go-render
125 screen-width:num <- screen-width screen
126 cursor-row:num <- get *editor, cursor-row:offset
127 cursor-column:num <- get *editor, cursor-column:offset
128
129 same-row?:bool <- equal cursor-row, original-row
130 return-unless same-row?, 1/go-render
131 left:num <- get *editor, left:offset
132 right:num <- get *editor, right:offset
133 curr:&:duplex-list:char <- next before-cursor
134 screen <- move-cursor screen, cursor-row, cursor-column
135 curr-column:num <- copy cursor-column
136 {
137 ¦
138 ¦ at-right?:bool <- greater-or-equal curr-column, right
139 ¦ return-if at-right?, 1/go-render
140 ¦ break-unless curr
141 ¦
142 ¦ currc:char <- get *curr, value:offset
143 ¦ at-newline?:bool <- equal currc, 10/newline
144 ¦ break-if at-newline?
145 ¦ screen <- print screen, currc
146 ¦ curr-column <- add curr-column, 1
147 ¦ curr <- next curr
148 ¦ loop
149 }
150
151 space:char <- copy 32/space
152 screen <- print screen, space
153 go-render? <- copy 0/false
154 ]
155
156 def move-cursor-coordinates-left editor:&:editor -> go-render?:bool, editor:&:editor [
157 local-scope
158 load-ingredients
159 go-render?:bool <- copy 0/false
160 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
161 cursor-row:num <- get *editor, cursor-row:offset
162 cursor-column:num <- get *editor, cursor-column:offset
163 left:num <- get *editor, left:offset
164
165 {
166 ¦ at-left-margin?:bool <- equal cursor-column, left
167 ¦ break-if at-left-margin?
168 ¦ trace 10, [app], [decrementing cursor column]
169 ¦ cursor-column <- subtract cursor-column, 1
170 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
171 ¦ return
172 }
173
174 top-of-screen?:bool <- equal cursor-row, 1
175 {
176 ¦ break-if top-of-screen?
177 ¦ cursor-row <- subtract cursor-row, 1
178 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
179 }
180 {
181 ¦ break-unless top-of-screen?
182 ¦ <scroll-up>
183 ¦ go-render? <- copy 1/true
184 }
185 {
186 ¦
187 ¦ previous-character:char <- get *before-cursor, value:offset
188 ¦ previous-character-is-newline?:bool <- equal previous-character, 10/newline
189 ¦ break-unless previous-character-is-newline?
190 ¦
191 ¦ trace 10, [app], [switching to previous line]
192 ¦ d:&:duplex-list:char <- get *editor, data:offset
193 ¦ end-of-line:num <- previous-line-length before-cursor, d
194 ¦ right:num <- get *editor, right:offset
195 ¦ width:num <- subtract right, left
196 ¦ wrap?:bool <- greater-than end-of-line, width
197 ¦ {
198 ¦ ¦ break-unless wrap?
199 ¦ ¦ _, column-offset:num <- divide-with-remainder end-of-line, width
200 ¦ ¦ cursor-column <- add left, column-offset
201 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
202 ¦ }
203 ¦ {
204 ¦ ¦ break-if wrap?
205 ¦ ¦ cursor-column <- add left, end-of-line
206 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
207 ¦ }
208 ¦ return
209 }
210
211 trace 10, [app], [wrapping to previous line]
212 right:num <- get *editor, right:offset
213 cursor-column <- subtract right, 1
214 *editor <- put *editor, cursor-column:offset, cursor-column
215 ]
216
217
218
219 def previous-line-length curr:&:duplex-list:char, start:&:duplex-list:char -> result:num [
220 local-scope
221 load-ingredients
222 result:num <- copy 0
223 return-unless curr
224 at-start?:bool <- equal curr, start
225 return-if at-start?
226 {
227 ¦ curr <- prev curr
228 ¦ break-unless curr
229 ¦ at-start?:bool <- equal curr, start
230 ¦ break-if at-start?
231 ¦ c:char <- get *curr, value:offset
232 ¦ at-newline?:bool <- equal c, 10/newline
233 ¦ break-if at-newline?
234 ¦ result <- add result, 1
235 ¦ loop
236 }
237 ]
238
239 scenario editor-clears-last-line-on-backspace [
240 local-scope
241 assume-screen 10/width, 5/height
242 s:text <- new [ab
243 cd]
244 e:&:editor <- new-editor s, 0/left, 10/right
245 assume-console [
246 ¦ left-click 2, 0
247 ¦ press backspace
248 ]
249 run [
250 ¦ editor-event-loop screen, console, e
251 ¦ 4:num/raw <- get *e, cursor-row:offset
252 ¦ 5:num/raw <- get *e, cursor-column:offset
253 ]
254 screen-should-contain [
255 ¦ . .
256 ¦ .abcd .
257 ¦ .╌╌╌╌╌╌╌╌╌╌.
258 ¦ . .
259 ]
260 memory-should-contain [
261 ¦ 4 <- 1
262 ¦ 5 <- 2
263 ]
264 ]
265
266 scenario editor-joins-and-wraps-lines-on-backspace [
267 local-scope
268 assume-screen 10/width, 5/height
269
270 s:text <- new [abc def
271 ghi jkl]
272 e:&:editor <- new-editor s, 0/left, 10/right
273 editor-render screen, e
274 $clear-trace
275
276 assume-console [
277 ¦ left-click 2, 0
278 ¦ press backspace
279 ]
280 run [
281 ¦ editor-event-loop screen, console, e
282 ]
283
284 screen-should-contain [
285 ¦ . .
286 ¦ .abc defgh↩.
287 ¦ .i jkl .
288 ¦ .╌╌╌╌╌╌╌╌╌╌.
289 ¦ . .
290 ]
291 ]
292
293 scenario editor-wraps-long-lines-on-backspace [
294 local-scope
295 assume-screen 10/width, 5/height
296
297 e:&:editor <- new-editor [abc def ghij], 0/left, 8/right
298 editor-render screen, e
299
300 screen-should-contain [
301 ¦ . .
302 ¦ .abc def↩ .
303 ¦ . ghij .
304 ¦ .╌╌╌╌╌╌╌╌ .
305 ]
306 $clear-trace
307
308 assume-console [
309 ¦ left-click 1, 4
310 ¦ press backspace
311 ]
312 run [
313 ¦ editor-event-loop screen, console, e
314 ]
315
316 screen-should-contain [
317 ¦ . .
318 ¦ .abcdef ↩ .
319 ¦ .ghij .
320 ¦ .╌╌╌╌╌╌╌╌ .
321 ¦ . .
322 ]
323 ]
324
325
326
327 scenario editor-handles-delete-key [
328 local-scope
329 assume-screen 10/width, 5/height
330 e:&:editor <- new-editor [abc], 0/left, 10/right
331 editor-render screen, e
332 $clear-trace
333 assume-console [
334 ¦ press delete
335 ]
336 run [
337 ¦ editor-event-loop screen, console, e
338 ]
339 screen-should-contain [
340 ¦ . .
341 ¦ .bc .
342 ¦ .╌╌╌╌╌╌╌╌╌╌.
343 ¦ . .
344 ]
345 check-trace-count-for-label 3, [print-character]
346 $clear-trace
347 assume-console [
348 ¦ press delete
349 ]
350 run [
351 ¦ editor-event-loop screen, console, e
352 ]
353 screen-should-contain [
354 ¦ . .
355 ¦ .c .
356 ¦ .╌╌╌╌╌╌╌╌╌╌.
357 ¦ . .
358 ]
359 check-trace-count-for-label 2, [print-character]
360 ]
361
362 after <handle-special-key> [
363 {
364 ¦ delete-next-character?:bool <- equal k, 65522/delete
365 ¦ break-unless delete-next-character?
366 ¦ <delete-character-begin>
367 ¦ go-render?:bool, deleted-cell:&:duplex-list:char <- delete-at-cursor editor, screen
368 ¦ <delete-character-end>
369 ¦ return
370 }
371 ]
372
373 def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, deleted-cell:&:duplex-list:char, editor:&:editor, screen:&:screen [
374 local-scope
375 load-ingredients
376 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
377 data:&:duplex-list:char <- get *editor, data:offset
378 deleted-cell:&:duplex-list:char <- next before-cursor
379 return-unless deleted-cell, 0/don't-render
380 currc:char <- get *deleted-cell, value:offset
381 data <- remove deleted-cell, data
382 deleted-newline?:bool <- equal currc, 10/newline
383 return-if deleted-newline?, 1/go-render
384
385 curr:&:duplex-list:char <- next before-cursor
386 cursor-row:num <- get *editor, cursor-row:offset
387 cursor-column:num <- get *editor, cursor-column:offset
388 screen <- move-cursor screen, cursor-row, cursor-column
389 curr-column:num <- copy cursor-column
390 screen-width:num <- screen-width screen
391 {
392 ¦
393 ¦ at-right?:bool <- greater-or-equal curr-column, screen-width
394 ¦ return-if at-right?, 1/go-render
395 ¦ break-unless curr
396 ¦
397 ¦ currc:char <- get *curr, value:offset
398 ¦ at-newline?:bool <- equal currc, 10/newline
399 ¦ break-if at-newline?
400 ¦ screen <- print screen, currc
401 ¦ curr-column <- add curr-column, 1
402 ¦ curr <- next curr
403 ¦ loop
404 }
405
406 space:char <- copy 32/space
407 screen <- print screen, space
408 go-render? <- copy 0/false
409 ]
410
411
412
413 scenario editor-moves-cursor-right-with-key [
414 local-scope
415 assume-screen 10/width, 5/height
416 e:&:editor <- new-editor [abc], 0/left, 10/right
417 editor-render screen, e
418 $clear-trace
419 assume-console [
420 ¦ press right-arrow
421 ¦ type [0]
422 ]
423 run [
424 ¦ editor-event-loop screen, console, e
425 ]
426 screen-should-contain [
427 ¦ . .
428 ¦ .a0bc .
429 ¦ .╌╌╌╌╌╌╌╌╌╌.
430 ¦ . .
431 ]
432 check-trace-count-for-label 3, [print-character]
433 ]
434
435 after <handle-special-key> [
436 {
437 ¦ move-to-next-character?:bool <- equal k, 65514/right-arrow
438 ¦ break-unless move-to-next-character?
439 ¦
440 ¦ next-cursor:&:duplex-list:char <- next before-cursor
441 ¦ break-unless next-cursor
442 ¦
443 ¦ <move-cursor-begin>
444 ¦ before-cursor <- copy next-cursor
445 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
446 ¦ go-render?:bool <- move-cursor-coordinates-right editor, screen-height
447 ¦ screen <- move-cursor screen, cursor-row, cursor-column
448 ¦ undo-coalesce-tag:num <- copy 2/right-arrow
449 ¦ <move-cursor-end>
450 ¦ return
451 }
452 ]
453
454 def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
455 local-scope
456 load-ingredients
457 before-cursor:&:duplex-list:char <- get *editor before-cursor:offset
458 cursor-row:num <- get *editor, cursor-row:offset
459 cursor-column:num <- get *editor, cursor-column:offset
460 left:num <- get *editor, left:offset
461 right:num <- get *editor, right:offset
462
463 {
464 ¦ old-cursor-character:char <- get *before-cursor, value:offset
465 ¦ was-at-newline?:bool <- equal old-cursor-character, 10/newline
466 ¦ break-unless was-at-newline?
467 ¦ cursor-row <- add cursor-row, 1
468 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
469 ¦ cursor-column <- copy left
470 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
471 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height
472 ¦ return-unless below-screen?, 0/don't-render
473 ¦ <scroll-down>
474 ¦ cursor-row <- subtract cursor-row, 1
475 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
476 ¦ return 1/go-render
477 }
478
479 {
480 ¦
481 ¦ wrap-column:num <- subtract right, 1
482 ¦ at-wrap?:bool <- equal cursor-column, wrap-column
483 ¦ break-unless at-wrap?
484 ¦
485 ¦ next:&:duplex-list:char <- next before-cursor
486 ¦ break-unless next
487 ¦ next-character:char <- get *next, value:offset
488 ¦ newline?:bool <- equal next-character, 10/newline
489 ¦ break-if newline?
490 ¦ cursor-row <- add cursor-row, 1
491 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
492 ¦ cursor-column <- copy left
493 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
494 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height
495 ¦ return-unless below-screen?, 0/no-more-render
496 ¦ <scroll-down>
497 ¦ cursor-row <- subtract cursor-row, 1
498 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
499 ¦ return 1/go-render
500 }
501
502 cursor-column <- add cursor-column, 1
503 *editor <- put *editor, cursor-column:offset, cursor-column
504 go-render? <- copy 0/false
505 ]
506
507 scenario editor-moves-cursor-to-next-line-with-right-arrow [
508 local-scope
509 assume-screen 10/width, 5/height
510 s:text <- new [abc
511 d]
512 e:&:editor <- new-editor s, 0/left, 10/right
513 editor-render screen, e
514 $clear-trace
515
516 assume-console [
517 ¦ press right-arrow
518 ¦ press right-arrow
519 ¦ press right-arrow
520 ¦ press right-arrow
521 ]
522 run [
523 ¦ editor-event-loop screen, console, e
524 ]
525 check-trace-count-for-label 0, [print-character]
526
527 assume-console [
528 ¦ type [0]
529 ]
530 run [
531 ¦ editor-event-loop screen, console, e
532 ]
533 screen-should-contain [
534 ¦ . .
535 ¦ .abc .
536 ¦ .0d .
537 ¦ .╌╌╌╌╌╌╌╌╌╌.
538 ¦ . .
539 ]
540 check-trace-count-for-label 2, [print-character]
541 ]
542
543 scenario editor-moves-cursor-to-next-line-with-right-arrow-2 [
544 local-scope
545 assume-screen 10/width, 5/height
546 s:text <- new [abc
547 d]
548 e:&:editor <- new-editor s, 1/left, 10/right
549 editor-render screen, e
550 assume-console [
551 ¦ press right-arrow
552 ¦ press right-arrow
553 ¦ press right-arrow
554 ¦ press right-arrow
555 ¦ type [0]
556 ]
557 run [
558 ¦ editor-event-loop screen, console, e
559 ]
560 screen-should-contain [
561 ¦ . .
562 ¦ . abc .
563 ¦ . 0d .
564 ¦ . ╌╌╌╌╌╌╌╌╌.
565 ¦ . .
566 ]
567 ]
568
569 scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow [
570 local-scope
571 assume-screen 10/width, 5/height
572 e:&:editor <- new-editor [abcdef], 0/left, 5/right
573 editor-render screen, e
574 $clear-trace
575 assume-console [
576 ¦ left-click 1, 3
577 ¦ press right-arrow
578 ]
579 run [
580 ¦ editor-event-loop screen, console, e
581 ¦ 3:num/raw <- get *e, cursor-row:offset
582 ¦ 4:num/raw <- get *e, cursor-column:offset
583 ]
584 screen-should-contain [
585 ¦ . .
586 ¦ .abcd↩ .
587 ¦ .ef .
588 ¦ .╌╌╌╌╌ .
589 ¦ . .
590 ]
591 memory-should-contain [
592 ¦ 3 <- 2
593 ¦ 4 <- 0
594 ]
595 check-trace-count-for-label 0, [print-character]
596 ]
597
598 scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [
599 local-scope
600 assume-screen 10/width, 5/height
601
602 e:&:editor <- new-editor [abcde], 0/left, 5/right
603 editor-render screen, e
604 $clear-trace
605
606 assume-console [
607 ¦ left-click 1, 3
608 ¦ press right-arrow
609 ]
610 run [
611 ¦ editor-event-loop screen, console, e
612 ¦ 3:num/raw <- get *e, cursor-row:offset
613 ¦ 4:num/raw <- get *e, cursor-column:offset
614 ]
615 memory-should-contain [
616 ¦ 3 <- 2
617 ¦ 4 <- 0
618 ]
619
620 assume-console [
621 ¦ press right-arrow
622 ]
623 run [
624 ¦ editor-event-loop screen, console, e
625 ¦ 3:num/raw <- get *e, cursor-row:offset
626 ¦ 4:num/raw <- get *e, cursor-column:offset
627 ]
628 memory-should-contain [
629 ¦ 3 <- 2
630 ¦ 4 <- 1
631 ]
632 check-trace-count-for-label 0, [print-character]
633 ]
634
635 scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-3 [
636 local-scope
637 assume-screen 10/width, 5/height
638 e:&:editor <- new-editor [abcdef], 1/left, 6/right
639 editor-render screen, e
640 $clear-trace
641 assume-console [
642 ¦ left-click 1, 4
643 ¦ press right-arrow
644 ]
645 run [
646 ¦ editor-event-loop screen, console, e
647 ¦ 3:num/raw <- get *e, cursor-row:offset
648 ¦ 4:num/raw <- get *e, cursor-column:offset
649 ]
650 screen-should-contain [
651 ¦ . .
652 ¦ . abcd↩ .
653 ¦ . ef .
654 ¦ . ╌╌╌╌╌ .
655 ¦ . .
656 ]
657 memory-should-contain [
658 ¦ 3 <- 2
659 ¦ 4 <- 1
660 ]
661 check-trace-count-for-label 0, [print-character]
662 ]
663
664 scenario editor-moves-cursor-to-next-line-with-right-arrow-at-end-of-line [
665 local-scope
666 assume-screen 10/width, 5/height
667 s:text <- new [abc
668 d]
669 e:&:editor <- new-editor s, 0/left, 10/right
670 editor-render screen, e
671 $clear-trace
672
673 assume-console [
674 ¦ left-click 1, 3
675 ¦ press right-arrow
676 ¦ type [0]
677 ]
678 run [
679 ¦ editor-event-loop screen, console, e
680 ]
681
682 screen-should-contain [
683 ¦ . .
684 ¦ .abc .
685 ¦ .0d .
686 ¦ .╌╌╌╌╌╌╌╌╌╌.
687 ¦ . .
688 ]
689 check-trace-count-for-label 2, [print-character]
690 ]
691
692
693
694
695
696 scenario editor-moves-cursor-left-with-key [
697 local-scope
698 assume-screen 10/width, 5/height
699 e:&:editor <- new-editor [abc], 0/left, 10/right
700 editor-render screen, e
701 $clear-trace
702 assume-console [
703 ¦ left-click 1, 2
704 ¦ press left-arrow
705 ¦ type [0]
706 ]
707 run [
708 ¦ editor-event-loop screen, console, e
709 ]
710 screen-should-contain [
711 ¦ . .
712 ¦ .a0bc .
713 ¦ .╌╌╌╌╌╌╌╌╌╌.
714 ¦ . .
715 ]
716 check-trace-count-for-label 3, [print-character]
717 ]
718
719 after <handle-special-key> [
720 {
721 ¦ move-to-previous-character?:bool <- equal k, 65515/left-arrow
722 ¦ break-unless move-to-previous-character?
723 ¦ trace 10, [app], [left arrow]
724 ¦
725 ¦ prev:&:duplex-list:char <- prev before-cursor
726 ¦ return-unless prev, 0/don't-render
727 ¦ <move-cursor-begin>
728 ¦ go-render? <- move-cursor-coordinates-left editor
729 ¦ before-cursor <- copy prev
730 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
731 ¦ undo-coalesce-tag:num <- copy 1/left-arrow
732 ¦ <move-cursor-end>
733 ¦ return
734 }
735 ]
736
737 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line [
738 local-scope
739 assume-screen 10/width, 5/height
740
741 s:text <- new [abc
742 d]
743 e:&:editor <- new-editor s, 0/left, 10/right
744 editor-render screen, e
745 $clear-trace
746
747 assume-console [
748 ¦ left-click 2, 0
749 ¦ press left-arrow
750 ]
751 run [
752 ¦ editor-event-loop screen, console, e
753 ¦ 3:num/raw <- get *e, cursor-row:offset
754 ¦ 4:num/raw <- get *e, cursor-column:offset
755 ]
756 memory-should-contain [
757 ¦ 3 <- 1
758 ¦ 4 <- 3
759 ]
760 check-trace-count-for-label 0, [print-character]
761 ]
762
763 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-2 [
764 local-scope
765 assume-screen 10/width, 5/height
766
767 s:text <- new [abc
768 def
769 g]
770 e:&:editor <- new-editor s:text, 0/left, 10/right
771 editor-render screen, e
772 $clear-trace
773
774
775 assume-console [
776 ¦ left-click 3, 0
777 ¦ press left-arrow
778 ¦ type [0]
779 ]
780 run [
781 ¦ editor-event-loop screen, console, e
782 ]
783 screen-should-contain [
784 ¦ . .
785 ¦ .abc .
786 ¦ .def0 .
787 ¦ .g .
788 ¦ .╌╌╌╌╌╌╌╌╌╌.
789 ]
790 check-trace-count-for-label 1, [print-character]
791 ]
792
793 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-3 [
794 local-scope
795 assume-screen 10/width, 5/height
796 s:text <- new [abc
797 def
798 g]
799 e:&:editor <- new-editor s, 0/left, 10/right
800 editor-render screen, e
801 $clear-trace
802
803 assume-console [
804 ¦ left-click 1, 0
805 ¦ press left-arrow
806 ¦ type [0]
807 ]
808 run [
809 ¦ editor-event-loop screen, console, e
810 ]
811
812 screen-should-contain [
813 ¦ . .
814 ¦ .0abc .
815 ¦ .def .
816 ¦ .g .
817 ¦ .╌╌╌╌╌╌╌╌╌╌.
818 ]
819 check-trace-count-for-label 4, [print-character]
820 ]
821
822 scenario editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-4 [
823 local-scope
824 assume-screen 10/width, 5/height
825
826 s:text <- new [abc
827
828 d]
829 e:&:editor <- new-editor s, 0/left, 10/right
830 editor-render screen, e:&:editor
831 $clear-trace
832
833 assume-console [
834 ¦ left-click 3, 0
835 ¦ press left-arrow
836 ¦ type [0]
837 ]
838 run [
839 ¦ editor-event-loop screen, console, e
840 ]
841 screen-should-contain [
842 ¦ . .
843 ¦ .abc .
844 ¦ .0 .
845 ¦ .d .
846 ¦ .╌╌╌╌╌╌╌╌╌╌.
847 ]
848 check-trace-count-for-label 1, [print-character]
849 ]
850
851 scenario editor-moves-across-screen-lines-across-wrap-with-left-arrow [
852 local-scope
853 assume-screen 10/width, 5/height
854
855 e:&:editor <- new-editor [abcdef], 0/left, 5/right
856 editor-render screen, e
857 $clear-trace
858 screen-should-contain [
859 ¦ . .
860 ¦ .abcd↩ .
861 ¦ .ef .
862 ¦ .╌╌╌╌╌ .
863 ¦ . .
864 ]
865
866 assume-console [
867 ¦ left-click 2, 0
868 ¦ press left-arrow
869 ]
870 run [
871 ¦ editor-event-loop screen, console, e
872 ¦ 3:num/raw <- get *e, cursor-row:offset
873 ¦ 4:num/raw <- get *e, cursor-column:offset
874 ]
875 memory-should-contain [
876 ¦ 3 <- 1
877 ¦ 4 <- 3
878 ]
879 check-trace-count-for-label 0, [print-character]
880 ]
881
882 scenario editor-moves-across-screen-lines-to-wrapping-line-with-left-arrow [
883 local-scope
884 assume-screen 10/width, 5/height
885
886 s:text <- new [abcdef
887 g]
888 e:&:editor <- new-editor s, 0/left, 5/right
889 editor-render screen, e
890 $clear-trace
891 screen-should-contain [
892 ¦ . .
893 ¦ .abcd↩ .
894 ¦ .ef .
895 ¦ .g .
896 ¦ .╌╌╌╌╌ .
897 ]
898
899 assume-console [
900 ¦ left-click 3, 0
901 ¦ press left-arrow
902 ]
903 run [
904 ¦ editor-event-loop screen, console, e
905 ¦ 3:num/raw <- get *e, cursor-row:offset
906 ¦ 4:num/raw <- get *e, cursor-column:offset
907 ]
908 memory-should-contain [
909 ¦ 3 <- 2
910 ¦ 4 <- 2
911 ]
912 check-trace-count-for-label 0, [print-character]
913 ]
914
915 scenario editor-moves-across-screen-lines-to-non-wrapping-line-with-left-arrow [
916 local-scope
917 assume-screen 10/width, 5/height
918
919 s:text <- new [abcd
920 e]
921 e:&:editor <- new-editor s, 0/left, 5/right
922 editor-render screen, e
923 $clear-trace
924 screen-should-contain [
925 ¦ . .
926 ¦ .abcd .
927 ¦ .e .
928 ¦ .╌╌╌╌╌ .
929 ¦ . .
930 ]
931
932 assume-console [
933 ¦ left-click 2, 0
934 ¦ press left-arrow
935 ]
936 run [
937 ¦ editor-event-loop screen, console, e
938 ¦ 3:num/raw <- get *e, cursor-row:offset
939 ¦ 4:num/raw <- get *e, cursor-column:offset
940 ]
941 memory-should-contain [
942 ¦ 3 <- 1
943 ¦ 4 <- 4
944 ]
945 check-trace-count-for-label 0, [print-character]
946 ]
947
948
949
950
951
952 scenario editor-moves-to-previous-line-with-up-arrow [
953 local-scope
954 assume-screen 10/width, 5/height
955 s:text <- new [abc
956 def]
957 e:&:editor <- new-editor s, 0/left, 10/right
958 editor-render screen, e
959 $clear-trace
960 assume-console [
961 ¦ left-click 2, 1
962 ¦ press up-arrow
963 ]
964 run [
965 ¦ editor-event-loop screen, console, e
966 ¦ 3:num/raw <- get *e, cursor-row:offset
967 ¦ 4:num/raw <- get *e, cursor-column:offset
968 ]
969 memory-should-contain [
970 ¦ 3 <- 1
971 ¦ 4 <- 1
972 ]
973 check-trace-count-for-label 0, [print-character]
974 assume-console [
975 ¦ type [0]
976 ]
977 run [
978 ¦ editor-event-loop screen, console, e
979 ]
980 screen-should-contain [
981 ¦ . .
982 ¦ .a0bc .
983 ¦ .def .
984 ¦ .╌╌╌╌╌╌╌╌╌╌.
985 ¦ . .
986 ]
987 ]
988
989 after <handle-special-key> [
990 {
991 ¦ move-to-previous-line?:bool <- equal k, 65517/up-arrow
992 ¦ break-unless move-to-previous-line?
993 ¦ <move-cursor-begin>
994 ¦ go-render? <- move-to-previous-line editor
995 ¦ undo-coalesce-tag:num <- copy 3/up-arrow
996 ¦ <move-cursor-end>
997 ¦ return
998 }
999 ]
1000
1001 def move-to-previous-line editor:&:editor -> go-render?:bool, editor:&:editor [
1002 local-scope
1003 load-ingredients
1004 go-render?:bool <- copy 0/false
1005 cursor-row:num <- get *editor, cursor-row:offset
1006 cursor-column:num <- get *editor, cursor-column:offset
1007 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1008 left:num <- get *editor, left:offset
1009 right:num <- get *editor, right:offset
1010 already-at-top?:bool <- lesser-or-equal cursor-row, 1/top
1011 {
1012 ¦
1013 ¦ break-if already-at-top?
1014 ¦
1015 ¦
1016 ¦
1017 ¦ curr:&:duplex-list:char <- copy before-cursor
1018 ¦ old:&:duplex-list:char <- copy curr
1019 ¦ {
1020 ¦ ¦ break-unless cursor-column
1021 ¦ ¦ curr <- before-previous-screen-line curr, editor
1022 ¦ ¦ no-motion?:bool <- equal curr, old
1023 ¦ ¦ return-if no-motion?
1024 ¦ }
1025 ¦ {
1026 ¦ ¦ curr <- before-previous-screen-line curr, editor
1027 ¦ ¦ no-motion?:bool <- equal curr, old
1028 ¦ ¦ return-if no-motion?
1029 ¦ }
1030 ¦ before-cursor <- copy curr
1031 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1032 ¦ cursor-row <- subtract cursor-row, 1
1033 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
1034 ¦
1035 ¦ target-column:num <- copy cursor-column
1036 ¦ cursor-column <- copy left
1037 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1038 ¦ {
1039 ¦ ¦ done?:bool <- greater-or-equal cursor-column, target-column
1040 ¦ ¦ break-if done?
1041 ¦ ¦ curr:&:duplex-list:char <- next before-cursor
1042 ¦ ¦ break-unless curr
1043 ¦ ¦ currc:char <- get *curr, value:offset
1044 ¦ ¦ at-newline?:bool <- equal currc, 10/newline
1045 ¦ ¦ break-if at-newline?
1046 ¦ ¦
1047 ¦ ¦ before-cursor <- copy curr
1048 ¦ ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1049 ¦ ¦ cursor-column <- add cursor-column, 1
1050 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1051 ¦ ¦ loop
1052 ¦ }
1053 ¦ return
1054 }
1055 {
1056 ¦
1057 ¦ break-unless already-at-top?
1058 ¦ <scroll-up>
1059 ¦ return 1/go-render
1060 }
1061 ]
1062
1063 scenario editor-adjusts-column-at-previous-line [
1064 local-scope
1065 assume-screen 10/width, 5/height
1066 s:text <- new [ab
1067 def]
1068 e:&:editor <- new-editor s, 0/left, 10/right
1069 editor-render screen, e
1070 $clear-trace
1071 assume-console [
1072 ¦ left-click 2, 3
1073 ¦ press up-arrow
1074 ]
1075 run [
1076 ¦ editor-event-loop screen, console, e
1077 ¦ 3:num/raw <- get *e, cursor-row:offset
1078 ¦ 4:num/raw <- get *e, cursor-column:offset
1079 ]
1080 memory-should-contain [
1081 ¦ 3 <- 1
1082 ¦ 4 <- 2
1083 ]
1084 check-trace-count-for-label 0, [print-character]
1085 assume-console [
1086 ¦ type [0]
1087 ]
1088 run [
1089 ¦ editor-event-loop screen, console, e
1090 ]
1091 screen-should-contain [
1092 ¦ . .
1093 ¦ .ab0 .
1094 ¦ .def .
1095 ¦ .╌╌╌╌╌╌╌╌╌╌.
1096 ¦ . .
1097 ]
1098 ]
1099
1100 scenario editor-adjusts-column-at-empty-line [
1101 local-scope
1102 assume-screen 10/width, 5/height
1103 s:text <- new [
1104 def]
1105 e:&:editor <- new-editor s, 0/left, 10/right
1106 editor-render screen, e
1107 $clear-trace
1108 assume-console [
1109 ¦ left-click 2, 3
1110 ¦ press up-arrow
1111 ]
1112 run [
1113 ¦ editor-event-loop screen, console, e
1114 ¦ 3:num/raw <- get *e, cursor-row:offset
1115 ¦ 4:num/raw <- get *e, cursor-column:offset
1116 ]
1117 memory-should-contain [
1118 ¦ 3 <- 1
1119 ¦ 4 <- 0
1120 ]
1121 check-trace-count-for-label 0, [print-character]
1122 assume-console [
1123 ¦ type [0]
1124 ]
1125 run [
1126 ¦ editor-event-loop screen, console, e
1127 ]
1128 screen-should-contain [
1129 ¦ . .
1130 ¦ .0 .
1131 ¦ .def .
1132 ¦ .╌╌╌╌╌╌╌╌╌╌.
1133 ¦ . .
1134 ]
1135 ]
1136
1137 scenario editor-moves-to-previous-line-from-left-margin [
1138 local-scope
1139 assume-screen 10/width, 5/height
1140
1141 s:text <- new [abc
1142 def
1143 ghi]
1144 e:&:editor <- new-editor s, 0/left, 10/right
1145 editor-render screen, e
1146 $clear-trace
1147
1148 assume-console [
1149 ¦ left-click 3, 0
1150 ¦ press up-arrow
1151 ]
1152 run [
1153 ¦ editor-event-loop screen, console, e
1154 ¦ 3:num/raw <- get *e, cursor-row:offset
1155 ¦ 4:num/raw <- get *e, cursor-column:offset
1156 ]
1157 memory-should-contain [
1158 ¦ 3 <- 2
1159 ¦ 4 <- 0
1160 ]
1161 check-trace-count-for-label 0, [print-character]
1162 assume-console [
1163 ¦ type [0]
1164 ]
1165 run [
1166 ¦ editor-event-loop screen, console, e
1167 ]
1168 screen-should-contain [
1169 ¦ . .
1170 ¦ .abc .
1171 ¦ .0def .
1172 ¦ .ghi .
1173 ¦ .╌╌╌╌╌╌╌╌╌╌.
1174 ]
1175 ]
1176
1177 scenario editor-moves-to-top-line-in-presence-of-wrapped-line [
1178 local-scope
1179 assume-screen 10/width, 5/height
1180 e:&:editor <- new-editor [abcde], 0/left, 5/right
1181 editor-render screen, e
1182 screen-should-contain [
1183 ¦ . .
1184 ¦ .abcd↩ .
1185 ¦ .e .
1186 ¦ .╌╌╌╌╌ .
1187 ]
1188 $clear-trace
1189 assume-console [
1190 ¦ left-click 2, 0
1191 ¦ press up-arrow
1192 ]
1193 run [
1194 ¦ editor-event-loop screen, console, e
1195 ¦ 3:num/raw <- get *e, cursor-row:offset
1196 ¦ 4:num/raw <- get *e, cursor-column:offset
1197 ]
1198 memory-should-contain [
1199 ¦ 3 <- 1
1200 ¦ 4 <- 0
1201 ]
1202 check-trace-count-for-label 0, [print-character]
1203 assume-console [
1204 ¦ type [0]
1205 ]
1206 run [
1207 ¦ editor-event-loop screen, console, e
1208 ]
1209 screen-should-contain [
1210 ¦ . .
1211 ¦ .0abc↩ .
1212 ¦ .de .
1213 ¦ .╌╌╌╌╌ .
1214 ]
1215 ]
1216
1217 scenario editor-moves-to-top-line-in-presence-of-wrapped-line-2 [
1218 local-scope
1219 assume-screen 10/width, 5/height
1220 s:text <- new [abc
1221 defgh]
1222 e:&:editor <- new-editor s, 0/left, 5/right
1223 editor-render screen, e
1224 screen-should-contain [
1225 ¦ . .
1226 ¦ .abc .
1227 ¦ .defg↩ .
1228 ¦ .h .
1229 ¦ .╌╌╌╌╌ .
1230 ]
1231 $clear-trace
1232 assume-console [
1233 ¦ left-click 3, 0
1234 ¦ press up-arrow
1235 ¦ press up-arrow
1236 ]
1237 run [
1238 ¦ editor-event-loop screen, console, e
1239 ¦ 3:num/raw <- get *e, cursor-row:offset
1240 ¦ 4:num/raw <- get *e, cursor-column:offset
1241 ]
1242 memory-should-contain [
1243 ¦ 3 <- 1
1244 ¦ 4 <- 0
1245 ]
1246 check-trace-count-for-label 0, [print-character]
1247 assume-console [
1248 ¦ type [0]
1249 ]
1250 run [
1251 ¦ editor-event-loop screen, console, e
1252 ]
1253 screen-should-contain [
1254 ¦ . .
1255 ¦ .0abc .
1256 ¦ .defg↩ .
1257 ¦ .h .
1258 ¦ .╌╌╌╌╌ .
1259 ]
1260 ]
1261
1262
1263
1264 scenario editor-moves-to-next-line-with-down-arrow [
1265 local-scope
1266 assume-screen 10/width, 5/height
1267 s:text <- new [abc
1268 def]
1269 e:&:editor <- new-editor s, 0/left, 10/right
1270 editor-render screen, e
1271 $clear-trace
1272
1273 assume-console [
1274 ¦ press down-arrow
1275 ]
1276 run [
1277 ¦ editor-event-loop screen, console, e
1278 ¦ 3:num/raw <- get *e, cursor-row:offset
1279 ¦ 4:num/raw <- get *e, cursor-column:offset
1280 ]
1281
1282 memory-should-contain [
1283 ¦ 3 <- 2
1284 ¦ 4 <- 0
1285 ]
1286 check-trace-count-for-label 0, [print-character]
1287 assume-console [
1288 ¦ type [0]
1289 ]
1290 run [
1291 ¦ editor-event-loop screen, console, e
1292 ]
1293 screen-should-contain [
1294 ¦ . .
1295 ¦ .abc .
1296 ¦ .0def .
1297 ¦ .╌╌╌╌╌╌╌╌╌╌.
1298 ¦ . .
1299 ]
1300 ]
1301
1302 after <handle-special-key> [
1303 {
1304 ¦ move-to-next-line?:bool <- equal k, 65516/down-arrow
1305 ¦ break-unless move-to-next-line?
1306 ¦ <move-cursor-begin>
1307 ¦ go-render? <- move-to-next-line editor, screen-height
1308 ¦ undo-coalesce-tag:num <- copy 4/down-arrow
1309 ¦ <move-cursor-end>
1310 ¦ return
1311 }
1312 ]
1313
1314 def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
1315 local-scope
1316 load-ingredients
1317 cursor-row:num <- get *editor, cursor-row:offset
1318 cursor-column:num <- get *editor, cursor-column:offset
1319 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1320 left:num <- get *editor, left:offset
1321 right:num <- get *editor, right:offset
1322 last-line:num <- subtract screen-height, 1
1323 already-at-bottom?:bool <- greater-or-equal cursor-row, last-line
1324 {
1325 ¦
1326 ¦ break-if already-at-bottom?
1327 ¦
1328 ¦ max:num <- subtract right, left
1329 ¦ next-line:&:duplex-list:char <- before-start-of-next-line before-cursor, max
1330 ¦ {
1331 ¦ ¦
1332 ¦ ¦
1333 ¦ ¦ no-motion?:bool <- equal next-line, before-cursor
1334 ¦ ¦ break-unless no-motion?
1335 ¦ ¦ scroll?:bool <- greater-than cursor-row, 1
1336 ¦ ¦ break-if scroll?, +try-to-scroll
1337 ¦ ¦ return 0/don't-render
1338 ¦ }
1339 ¦ cursor-row <- add cursor-row, 1
1340 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
1341 ¦ before-cursor <- copy next-line
1342 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1343 ¦ target-column:num <- copy cursor-column
1344 ¦ cursor-column <- copy left
1345 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1346 ¦ {
1347 ¦ ¦ done?:bool <- greater-or-equal cursor-column, target-column
1348 ¦ ¦ break-if done?
1349 ¦ ¦ curr:&:duplex-list:char <- next before-cursor
1350 ¦ ¦ break-unless curr
1351 ¦ ¦ currc:char <- get *curr, value:offset
1352 ¦ ¦ at-newline?:bool <- equal currc, 10/newline
1353 ¦ ¦ break-if at-newline?
1354 ¦ ¦
1355 ¦ ¦ before-cursor <- copy curr
1356 ¦ ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1357 ¦ ¦ cursor-column <- add cursor-column, 1
1358 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1359 ¦ ¦ loop
1360 ¦ }
1361 ¦ return 0/don't-render
1362 }
1363 +try-to-scroll
1364 <scroll-down>
1365 go-render? <- copy 1/true
1366 ]
1367
1368 scenario editor-adjusts-column-at-next-line [
1369 local-scope
1370 assume-screen 10/width, 5/height
1371 s:text <- new [abc
1372 de]
1373 e:&:editor <- new-editor s, 0/left, 10/right
1374 editor-render screen, e
1375 $clear-trace
1376 assume-console [
1377 ¦ left-click 1, 3
1378 ¦ press down-arrow
1379 ]
1380 run [
1381 ¦ editor-event-loop screen, console, e
1382 ¦ 3:num/raw <- get *e, cursor-row:offset
1383 ¦ 4:num/raw <- get *e, cursor-column:offset
1384 ]
1385 memory-should-contain [
1386 ¦ 3 <- 2
1387 ¦ 4 <- 2
1388 ]
1389 check-trace-count-for-label 0, [print-character]
1390 assume-console [
1391 ¦ type [0]
1392 ]
1393 run [
1394 ¦ editor-event-loop screen, console, e
1395 ]
1396 screen-should-contain [
1397 ¦ . .
1398 ¦ .abc .
1399 ¦ .de0 .
1400 ¦ .╌╌╌╌╌╌╌╌╌╌.
1401 ¦ . .
1402 ]
1403 ]
1404
1405
1406
1407 scenario editor-moves-to-start-of-line-with-ctrl-a [
1408 local-scope
1409 assume-screen 10/width, 5/height
1410 s:text <- new [123
1411 456]
1412 e:&:editor <- new-editor s, 0/left, 10/right
1413 editor-render screen, e
1414 $clear-trace
1415
1416 assume-console [
1417 ¦ left-click 2, 3
1418 ¦ press ctrl-a
1419 ]
1420 run [
1421 ¦ editor-event-loop screen, console, e
1422 ¦ 4:num/raw <- get *e, cursor-row:offset
1423 ¦ 5:num/raw <- get *e, cursor-column:offset
1424 ]
1425
1426 memory-should-contain [
1427 ¦ 4 <- 2
1428 ¦ 5 <- 0
1429 ]
1430 check-trace-count-for-label 0, [print-character]
1431 ]
1432
1433 after <handle-special-character> [
1434 {
1435 ¦ move-to-start-of-line?:bool <- equal c, 1/ctrl-a
1436 ¦ break-unless move-to-start-of-line?
1437 ¦ <move-cursor-begin>
1438 ¦ move-to-start-of-screen-line editor
1439 ¦ undo-coalesce-tag:num <- copy 0/never
1440 ¦ <move-cursor-end>
1441 ¦ return 0/don't-render
1442 }
1443 ]
1444
1445 after <handle-special-key> [
1446 {
1447 ¦ move-to-start-of-line?:bool <- equal k, 65521/home
1448 ¦ break-unless move-to-start-of-line?
1449 ¦ <move-cursor-begin>
1450 ¦ move-to-start-of-screen-line editor
1451 ¦ undo-coalesce-tag:num <- copy 0/never
1452 ¦ <move-cursor-end>
1453 ¦ return 0/don't-render
1454 }
1455 ]
1456
1457
1458
1459 def move-to-start-of-screen-line editor:&:editor -> editor:&:editor [
1460 local-scope
1461 load-ingredients
1462
1463 left:num <- get *editor, left:offset
1464 col:num <- get *editor, cursor-column:offset
1465
1466 curr:&:duplex-list:char <- get *editor, before-cursor:offset
1467
1468 {
1469 ¦ done?:bool <- equal col, left
1470 ¦ break-if done?
1471 ¦ assert curr, [move-to-start-of-line tried to move before start of text]
1472 ¦ curr <- prev curr
1473 ¦ col <- subtract col, 1
1474 ¦ loop
1475 }
1476 *editor <- put *editor, cursor-column:offset, col
1477 *editor <- put *editor, before-cursor:offset, curr
1478 ]
1479
1480 scenario editor-moves-to-start-of-line-with-ctrl-a-2 [
1481 local-scope
1482 assume-screen 10/width, 5/height
1483 s:text <- new [123
1484 456]
1485 e:&:editor <- new-editor s, 0/left, 10/right
1486 editor-render screen, e
1487 $clear-trace
1488
1489 assume-console [
1490 ¦ left-click 1, 3
1491 ¦ press ctrl-a
1492 ]
1493 run [
1494 ¦ editor-event-loop screen, console, e
1495 ¦ 4:num/raw <- get *e, cursor-row:offset
1496 ¦ 5:num/raw <- get *e, cursor-column:offset
1497 ]
1498
1499 memory-should-contain [
1500 ¦ 4 <- 1
1501 ¦ 5 <- 0
1502 ]
1503 check-trace-count-for-label 0, [print-character]
1504 ]
1505
1506 scenario editor-moves-to-start-of-line-with-home [
1507 local-scope
1508 assume-screen 10/width, 5/height
1509 s:text <- new [123
1510 456]
1511 e:&:editor <- new-editor s, 0/left, 10/right
1512 $clear-trace
1513
1514 assume-console [
1515 ¦ left-click 2, 3
1516 ¦ press home
1517 ]
1518 run [
1519 ¦ editor-event-loop screen, console, e
1520 ¦ 3:num/raw <- get *e, cursor-row:offset
1521 ¦ 4:num/raw <- get *e, cursor-column:offset
1522 ]
1523
1524 memory-should-contain [
1525 ¦ 3 <- 2
1526 ¦ 4 <- 0
1527 ]
1528 check-trace-count-for-label 0, [print-character]
1529 ]
1530
1531 scenario editor-moves-to-start-of-line-with-home-2 [
1532 local-scope
1533 assume-screen 10/width, 5/height
1534 s:text <- new [123
1535 456]
1536 e:&:editor <- new-editor s, 0/left, 10/right
1537 editor-render screen, e
1538 $clear-trace
1539
1540 assume-console [
1541 ¦ left-click 1, 3
1542 ¦ press home
1543 ]
1544 run [
1545 ¦ editor-event-loop screen, console, e
1546 ¦ 3:num/raw <- get *e, cursor-row:offset
1547 ¦ 4:num/raw <- get *e, cursor-column:offset
1548 ]
1549
1550 memory-should-contain [
1551 ¦ 3 <- 1
1552 ¦ 4 <- 0
1553 ]
1554 check-trace-count-for-label 0, [print-character]
1555 ]
1556
1557 scenario editor-moves-to-start-of-screen-line-with-ctrl-a [
1558 local-scope
1559 assume-screen 10/width, 5/height
1560 e:&:editor <- new-editor [123456], 0/left, 5/right
1561 editor-render screen, e
1562 screen-should-contain [
1563 ¦ . .
1564 ¦ .1234↩ .
1565 ¦ .56 .
1566 ¦ .╌╌╌╌╌ .
1567 ¦ . .
1568 ]
1569 $clear-trace
1570
1571 assume-console [
1572 ¦ left-click 2, 1
1573 ¦ press ctrl-a
1574 ¦ press up-arrow
1575 ]
1576 run [
1577 ¦ editor-event-loop screen, console, e
1578 ¦ 4:num/raw <- get *e, cursor-row:offset
1579 ¦ 5:num/raw <- get *e, cursor-column:offset
1580 ]
1581
1582 memory-should-contain [
1583 ¦ 4 <- 1
1584 ¦ 5 <- 0
1585 ]
1586 check-trace-count-for-label 0, [print-character]
1587
1588 assume-console [
1589 ¦ type [a]
1590 ]
1591 run [
1592 ¦ editor-event-loop screen, console, e
1593 ¦ 4:num/raw <- get *e, cursor-row:offset
1594 ¦ 5:num/raw <- get *e, cursor-column:offset
1595 ]
1596 screen-should-contain [
1597 ¦ . .
1598 ¦ .a123↩ .
1599 ¦ .456 .
1600 ¦ .╌╌╌╌╌ .
1601 ¦ . .
1602 ]
1603 memory-should-contain [
1604 ¦ 4 <- 1
1605 ¦ 5 <- 1
1606 ]
1607 ]
1608
1609
1610
1611 scenario editor-moves-to-end-of-line-with-ctrl-e [
1612 local-scope
1613 assume-screen 10/width, 5/height
1614 s:text <- new [123
1615 456]
1616 e:&:editor <- new-editor s, 0/left, 10/right
1617 editor-render screen, e
1618 $clear-trace
1619
1620 assume-console [
1621 ¦ left-click 1, 1
1622 ¦ press ctrl-e
1623 ]
1624 run [
1625 ¦ editor-event-loop screen, console, e
1626 ¦ 4:num/raw <- get *e, cursor-row:offset
1627 ¦ 5:num/raw <- get *e, cursor-column:offset
1628 ]
1629
1630 memory-should-contain [
1631 ¦ 4 <- 1
1632 ¦ 5 <- 3
1633 ]
1634 check-trace-count-for-label 0, [print-character]
1635
1636 assume-console [
1637 ¦ type [z]
1638 ]
1639 run [
1640 ¦ editor-event-loop screen, console, e
1641 ¦ 4:num/raw <- get *e, cursor-row:offset
1642 ¦ 5:num/raw <- get *e, cursor-column:offset
1643 ]
1644 memory-should-contain [
1645 ¦ 4 <- 1
1646 ¦ 5 <- 4
1647 ]
1648 screen-should-contain [
1649 ¦ . .
1650 ¦ .123z .
1651 ¦ .456 .
1652 ¦ .╌╌╌╌╌╌╌╌╌╌.
1653 ¦ . .
1654 ]
1655 check-trace-count-for-label 1, [print-character]
1656 ]
1657
1658 after <handle-special-character> [
1659 {
1660 ¦ move-to-end-of-line?:bool <- equal c, 5/ctrl-e
1661 ¦ break-unless move-to-end-of-line?
1662 ¦ <move-cursor-begin>
1663 ¦ move-to-end-of-line editor
1664 ¦ undo-coalesce-tag:num <- copy 0/never
1665 ¦ <move-cursor-end>
1666 ¦ return 0/don't-render
1667 }
1668 ]
1669
1670 after <handle-special-key> [
1671 {
1672 ¦ move-to-end-of-line?:bool <- equal k, 65520/end
1673 ¦ break-unless move-to-end-of-line?
1674 ¦ <move-cursor-begin>
1675 ¦ move-to-end-of-line editor
1676 ¦ undo-coalesce-tag:num <- copy 0/never
1677 ¦ <move-cursor-end>
1678 ¦ return 0/don't-render
1679 }
1680 ]
1681
1682 def move-to-end-of-line editor:&:editor -> editor:&:editor [
1683 local-scope
1684 load-ingredients
1685 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1686 cursor-column:num <- get *editor, cursor-column:offset
1687 right:num <- get *editor, right:offset
1688
1689 {
1690 ¦ next:&:duplex-list:char <- next before-cursor
1691 ¦ break-unless next
1692 ¦ nextc:char <- get *next, value:offset
1693 ¦ at-end-of-line?:bool <- equal nextc, 10/newline
1694 ¦ break-if at-end-of-line?
1695 ¦ cursor-column <- add cursor-column, 1
1696 ¦ at-right?:bool <- equal cursor-column, right
1697 ¦ break-if at-right?
1698 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1699 ¦ before-cursor <- copy next
1700 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1701 ¦ loop
1702 }
1703 ]
1704
1705 scenario editor-moves-to-end-of-line-with-ctrl-e-2 [
1706 local-scope
1707 assume-screen 10/width, 5/height
1708 s:text <- new [123
1709 456]
1710 e:&:editor <- new-editor s, 0/left, 10/right
1711 editor-render screen, e
1712 $clear-trace
1713
1714 assume-console [
1715 ¦ left-click 2, 1
1716 ¦ press ctrl-e
1717 ]
1718 run [
1719 ¦ editor-event-loop screen, console, e
1720 ¦ 4:num/raw <- get *e, cursor-row:offset
1721 ¦ 5:num/raw <- get *e, cursor-column:offset
1722 ]
1723
1724 memory-should-contain [
1725 ¦ 4 <- 2
1726 ¦ 5 <- 3
1727 ]
1728 check-trace-count-for-label 0, [print-character]
1729 ]
1730
1731 scenario editor-moves-to-end-of-line-with-end [
1732 local-scope
1733 assume-screen 10/width, 5/height
1734 s:text <- new [123
1735 456]
1736 e:&:editor <- new-editor s, 0/left, 10/right
1737 editor-render screen, e
1738 $clear-trace
1739
1740 assume-console [
1741 ¦ left-click 1, 1
1742 ¦ press end
1743 ]
1744 run [
1745 ¦ editor-event-loop screen, console, e
1746 ¦ 3:num/raw <- get *e, cursor-row:offset
1747 ¦ 4:num/raw <- get *e, cursor-column:offset
1748 ]
1749
1750 memory-should-contain [
1751 ¦ 3 <- 1
1752 ¦ 4 <- 3
1753 ]
1754 check-trace-count-for-label 0, [print-character]
1755 ]
1756
1757 scenario editor-moves-to-end-of-line-with-end-2 [
1758 local-scope
1759 assume-screen 10/width, 5/height
1760 s:text <- new [123
1761 456]
1762 e:&:editor <- new-editor s, 0/left, 10/right
1763 editor-render screen, e
1764 $clear-trace
1765
1766 assume-console [
1767 ¦ left-click 2, 1
1768 ¦ press end
1769 ]
1770 run [
1771 ¦ editor-event-loop screen, console, e
1772 ¦ 3:num/raw <- get *e, cursor-row:offset
1773 ¦ 4:num/raw <- get *e, cursor-column:offset
1774 ]
1775
1776 memory-should-contain [
1777 ¦ 3 <- 2
1778 ¦ 4 <- 3
1779 ]
1780 check-trace-count-for-label 0, [print-character]
1781 ]
1782
1783 scenario editor-moves-to-end-of-wrapped-line [
1784 local-scope
1785 assume-screen 10/width, 5/height
1786 s:text <- new [123456
1787 789]
1788 e:&:editor <- new-editor s, 0/left, 5/right
1789 editor-render screen, e
1790 $clear-trace
1791
1792 assume-console [
1793 ¦ left-click 1, 1
1794 ¦ press end
1795 ]
1796 run [
1797 ¦ editor-event-loop screen, console, e
1798 ¦ 10:num/raw <- get *e, cursor-row:offset
1799 ¦ 11:num/raw <- get *e, cursor-column:offset
1800 ]
1801
1802 memory-should-contain [
1803 ¦ 10 <- 1
1804 ¦ 11 <- 3
1805 ]
1806
1807 check-trace-count-for-label 0, [print-character]
1808
1809 assume-console [
1810 ¦ type [a]
1811 ]
1812 run [
1813 ¦ editor-event-loop screen, console, e
1814 ]
1815 screen-should-contain [
1816 ¦ . .
1817 ¦ .123a↩ .
1818 ¦ .456 .
1819 ¦ .789 .
1820 ¦ .╌╌╌╌╌ .
1821 ]
1822 ]
1823
1824
1825
1826 scenario editor-deletes-to-start-of-line-with-ctrl-u [
1827 local-scope
1828 assume-screen 10/width, 5/height
1829 s:text <- new [123
1830 456]
1831 e:&:editor <- new-editor s, 0/left, 10/right
1832 editor-render screen, e
1833 $clear-trace
1834
1835 assume-console [
1836 ¦ left-click 2, 2
1837 ¦ press ctrl-u
1838 ]
1839 run [
1840 ¦ editor-event-loop screen, console, e
1841 ]
1842
1843 screen-should-contain [
1844 ¦ . .
1845 ¦ .123 .
1846 ¦ .6 .
1847 ¦ .╌╌╌╌╌╌╌╌╌╌.
1848 ¦ . .
1849 ]
1850 check-trace-count-for-label 10, [print-character]
1851 ]
1852
1853 after <handle-special-character> [
1854 {
1855 ¦ delete-to-start-of-line?:bool <- equal c, 21/ctrl-u
1856 ¦ break-unless delete-to-start-of-line?
1857 ¦ <delete-to-start-of-line-begin>
1858 ¦ deleted-cells:&:duplex-list:char <- delete-to-start-of-line editor
1859 ¦ <delete-to-start-of-line-end>
1860 ¦ go-render?:bool <- minimal-render-for-ctrl-u screen, editor, deleted-cells
1861 ¦ return
1862 }
1863 ]
1864
1865 def minimal-render-for-ctrl-u screen:&:screen, editor:&:editor, deleted-cells:&:duplex-list:char -> go-render?:bool, screen:&:screen [
1866 local-scope
1867 load-ingredients
1868 curr-column:num <- get *editor, cursor-column:offset
1869
1870 buf:&:buffer:char <- new-buffer 30
1871 curr:&:duplex-list:char <- get *editor, before-cursor:offset
1872 i:num <- copy curr-column
1873 right:num <- get *editor, right:offset
1874 {
1875 ¦
1876 ¦ wrap?:bool <- greater-or-equal i, right
1877 ¦ return-if wrap?, 1/go-render
1878 ¦ curr <- next curr
1879 ¦ break-unless curr
1880 ¦ c:char <- get *curr, value:offset
1881 ¦ b:bool <- equal c, 10
1882 ¦ break-if b
1883 ¦ buf <- append buf, c
1884 ¦ i <- add i, 1
1885 ¦ loop
1886 }
1887
1888 num-deleted-cells:num <- length deleted-cells
1889 old-row-len:num <- add i, num-deleted-cells
1890 left:num <- get *editor, left:offset
1891 end:num <- subtract right, left
1892 wrap?:bool <- greater-or-equal old-row-len, end
1893 return-if wrap?, 1/go-render
1894 curr-line:text <- buffer-to-array buf
1895 curr-row:num <- get *editor, cursor-row:offset
1896 render-code screen, curr-line, curr-column, right, curr-row
1897 return 0/dont-render
1898 ]
1899
1900 def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
1901 local-scope
1902 load-ingredients
1903
1904 init:&:duplex-list:char <- get *editor, data:offset
1905 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
1906 update-top-of-screen?:bool <- copy 0/false
1907 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1908 start:&:duplex-list:char <- copy before-cursor
1909 end:&:duplex-list:char <- next before-cursor
1910 {
1911 ¦ at-start-of-text?:bool <- equal start, init
1912 ¦ break-if at-start-of-text?
1913 ¦ curr:char <- get *start, value:offset
1914 ¦ at-start-of-line?:bool <- equal curr, 10/newline
1915 ¦ break-if at-start-of-line?
1916 ¦
1917 ¦ at-top-of-screen?:bool <- equal start, top-of-screen
1918 ¦ update-top-of-screen?:bool <- or update-top-of-screen?, at-top-of-screen?
1919 ¦ start <- prev start
1920 ¦ assert start, [delete-to-start-of-line tried to move before start of text]
1921 ¦ loop
1922 }
1923
1924 result:&:duplex-list:char <- next start
1925 remove-between start, end
1926
1927 {
1928 ¦ break-unless update-top-of-screen?
1929 ¦ put *editor, top-of-screen:offset, start
1930 }
1931
1932 before-cursor <- copy start
1933 *editor <- put *editor, before-cursor:offset, before-cursor
1934 left:num <- get *editor, left:offset
1935 *editor <- put *editor, cursor-column:offset, left
1936
1937 right:num <- get *editor, right:offset
1938 width:num <- subtract right, left
1939 num-deleted:num <- length result
1940 cursor-row-adjustment:num <- divide-with-remainder num-deleted, width
1941 return-unless cursor-row-adjustment
1942 cursor-row:num <- get *editor, cursor-row:offset
1943 cursor-row-in-editor:num <- subtract cursor-row, 1
1944 at-top?:bool <- lesser-or-equal cursor-row-in-editor, cursor-row-adjustment
1945 {
1946 ¦ break-unless at-top?
1947 ¦ cursor-row <- copy 1
1948 }
1949 {
1950 ¦ break-if at-top?
1951 ¦ cursor-row <- subtract cursor-row, cursor-row-adjustment
1952 }
1953 put *editor, cursor-row:offset, cursor-row
1954 ]
1955
1956 def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num, screen:&:screen [
1957 local-scope
1958 load-ingredients
1959 return-unless s
1960 color:num <- copy 7/white
1961 column:num <- copy left
1962 screen <- move-cursor screen, row, column
1963 screen-height:num <- screen-height screen
1964 i:num <- copy 0
1965 len:num <- length *s
1966 {
1967 ¦ +next-character
1968 ¦ done?:bool <- greater-or-equal i, len
1969 ¦ break-if done?
1970 ¦ done? <- greater-or-equal row, screen-height
1971 ¦ break-if done?
1972 ¦ c:char <- index *s, i
1973 ¦ <character-c-received>
1974 ¦ {
1975 ¦ ¦
1976 ¦ ¦ newline?:bool <- equal c, 10/newline
1977 ¦ ¦ break-unless newline?
1978 ¦ ¦
1979 ¦ ¦ {
1980 ¦ ¦ ¦ done?:bool <- greater-than column, right
1981 ¦ ¦ ¦ break-if done?
1982 ¦ ¦ ¦ space:char <- copy 32/space
1983 ¦ ¦ ¦ print screen, space
1984 ¦ ¦ ¦ column <- add column, 1
1985 ¦ ¦ ¦ loop
1986 ¦ ¦ }
1987 ¦ ¦ row <- add row, 1
1988 ¦ ¦ column <- copy left
1989 ¦ ¦ screen <- move-cursor screen, row, column
1990 ¦ ¦ i <- add i, 1
1991 ¦ ¦ loop +next-character
1992 ¦ }
1993 ¦ {
1994 ¦ ¦
1995 ¦ ¦ at-right?:bool <- equal column, right
1996 ¦ ¦ break-unless at-right?
1997 ¦ ¦
1998 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left
1999 ¦ ¦ print screen, wrap-icon, 245/grey
2000 ¦ ¦ column <- copy left
2001 ¦ ¦ row <- add row, 1
2002 ¦ ¦ screen <- move-cursor screen, row, column
2003 ¦ ¦
2004 ¦ ¦ loop +next-character
2005 ¦ }
2006 ¦ i <- add i, 1
2007 ¦ print screen, c, color
2008 ¦ column <- add column, 1
2009 ¦ loop
2010 }
2011 was-at-left?:bool <- equal column, left
2012 clear-line-until screen, right
2013 {
2014 ¦ break-if was-at-left?
2015 ¦ row <- add row, 1
2016 }
2017 move-cursor screen, row, left
2018 ]
2019
2020 scenario editor-deletes-to-start-of-line-with-ctrl-u-2 [
2021 local-scope
2022 assume-screen 10/width, 5/height
2023 s:text <- new [123
2024 456]
2025 e:&:editor <- new-editor s, 0/left, 10/right
2026 editor-render screen, e
2027 $clear-trace
2028
2029 assume-console [
2030 ¦ left-click 1, 2
2031 ¦ press ctrl-u
2032 ]
2033 run [
2034 ¦ editor-event-loop screen, console, e
2035 ]
2036
2037 screen-should-contain [
2038 ¦ . .
2039 ¦ .3 .
2040 ¦ .456 .
2041 ¦ .╌╌╌╌╌╌╌╌╌╌.
2042 ¦ . .
2043 ]
2044 check-trace-count-for-label 10, [print-character]
2045 ]
2046
2047 scenario editor-deletes-to-start-of-line-with-ctrl-u-3 [
2048 local-scope
2049 assume-screen 10/width, 5/height
2050 s:text <- new [123
2051 456]
2052 e:&:editor <- new-editor s, 0/left, 10/right
2053 editor-render screen, e
2054 $clear-trace
2055
2056 assume-console [
2057 ¦ left-click 1, 3
2058 ¦ press ctrl-u
2059 ]
2060 run [
2061 ¦ editor-event-loop screen, console, e
2062 ]
2063
2064 screen-should-contain [
2065 ¦ . .
2066 ¦ . .
2067 ¦ .456 .
2068 ¦ .╌╌╌╌╌╌╌╌╌╌.
2069 ¦ . .
2070 ]
2071 check-trace-count-for-label 10, [print-character]
2072 ]
2073
2074 scenario editor-deletes-to-start-of-final-line-with-ctrl-u [
2075 local-scope
2076 assume-screen 10/width, 5/height
2077 s:text <- new [123
2078 456]
2079 e:&:editor <- new-editor s, 0/left, 10/right
2080 editor-render screen, e
2081 $clear-trace
2082
2083 assume-console [
2084 ¦ left-click 2, 3
2085 ¦ press ctrl-u
2086 ]
2087 run [
2088 ¦ editor-event-loop screen, console, e
2089 ]
2090
2091 screen-should-contain [
2092 ¦ . .
2093 ¦ .123 .
2094 ¦ . .
2095 ¦ .╌╌╌╌╌╌╌╌╌╌.
2096 ¦ . .
2097 ]
2098 check-trace-count-for-label 10, [print-character]
2099 ]
2100
2101 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u [
2102 local-scope
2103 assume-screen 10/width, 10/height
2104
2105 s:text <- new [123456
2106 789]
2107 e:&:editor <- new-editor s, 0/left, 5/right
2108 editor-render screen, e
2109 screen-should-contain [
2110 ¦ . .
2111 ¦ .1234↩ .
2112 ¦ .56 .
2113 ¦ .789 .
2114 ¦ .╌╌╌╌╌ .
2115 ¦ . .
2116 ]
2117 $clear-trace
2118
2119 assume-console [
2120 ¦ left-click 1, 3
2121 ¦ press ctrl-u
2122 ]
2123 run [
2124 ¦ editor-event-loop screen, console, e
2125 ]
2126
2127 screen-should-contain [
2128 ¦ . .
2129 ¦ .456 .
2130 ¦ .789 .
2131 ¦ .╌╌╌╌╌ .
2132 ¦ . .
2133 ]
2134 check-trace-count-for-label 45, [print-character]
2135 ]
2136
2137
2138 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-2 [
2139 local-scope
2140 assume-screen 10/width, 10/height
2141
2142 s:text <- new [1
2143 2
2144 345678
2145 9]
2146 e:&:editor <- new-editor s, 0/left, 5/right
2147 editor-render screen, e
2148 screen-should-contain [
2149 ¦ . .
2150 ¦ .1 .
2151 ¦ .2 .
2152 ¦ .3456↩ .
2153 ¦ .78 .
2154 ¦ .9 .
2155 ¦ .╌╌╌╌╌ .
2156 ¦ . .
2157 ]
2158
2159 assume-console [
2160 ¦ left-click 4, 1
2161 ¦ press ctrl-u
2162 ]
2163 run [
2164 ¦ editor-event-loop screen, console, e
2165 ¦ 10:num/raw <- get *e, cursor-row:offset
2166 ¦ 11:num/raw <- get *e, cursor-column:offset
2167 ]
2168 screen-should-contain [
2169 ¦ . .
2170 ¦ .1 .
2171 ¦ .2 .
2172 ¦ .8 .
2173 ¦ .9 .
2174 ¦ .╌╌╌╌╌ .
2175 ¦ . .
2176 ]
2177
2178 memory-should-contain [
2179 ¦ 10 <- 3
2180 ¦ 11 <- 0
2181 ]
2182 ]
2183
2184
2185 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-3 [
2186 local-scope
2187 assume-screen 10/width, 10/height
2188
2189 s:text <- new [1
2190 2
2191 3456789abcd
2192 e]
2193 e:&:editor <- new-editor s, 0/left, 5/right
2194 editor-render screen, e
2195 assume-console [
2196 ¦ left-click 4, 1
2197 ]
2198 editor-event-loop screen, console, e
2199 screen-should-contain [
2200 ¦ . .
2201 ¦ .1 .
2202 ¦ .2 .
2203 ¦ .3456↩ .
2204 ¦ .789a↩ .
2205 ¦ .bcd .
2206 ¦ .e .
2207 ¦ .╌╌╌╌╌ .
2208 ¦ . .
2209 ]
2210 assume-console [
2211 ¦ left-click 5, 1
2212 ¦ press ctrl-u
2213 ]
2214 run [
2215 ¦ editor-event-loop screen, console, e
2216 ¦ 10:num/raw <- get *e, cursor-row:offset
2217 ¦ 11:num/raw <- get *e, cursor-column:offset
2218 ]
2219 screen-should-contain [
2220 ¦ . .
2221 ¦ .1 .
2222 ¦ .2 .
2223 ¦ .cd .
2224 ¦ .e .
2225 ¦ .╌╌╌╌╌ .
2226 ¦ . .
2227 ]
2228
2229 memory-should-contain [
2230 ¦ 10 <- 3
2231 ¦ 11 <- 0
2232 ]
2233 ]
2234
2235
2236 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-4 [
2237 local-scope
2238 assume-screen 10/width, 10/height
2239
2240 s:text <- new [1234567
2241 89]
2242 e:&:editor <- new-editor s, 0/left, 5/right
2243 editor-render screen, e
2244 screen-should-contain [
2245 ¦ . .
2246 ¦ .1234↩ .
2247 ¦ .567 .
2248 ¦ .89 .
2249 ¦ .╌╌╌╌╌ .
2250 ¦ . .
2251 ]
2252
2253 assume-console [
2254 ¦ left-click 2, 1
2255 ¦ press ctrl-u
2256 ]
2257 run [
2258 ¦ editor-event-loop screen, console, e
2259 ¦ 10:num/raw <- get *e, cursor-row:offset
2260 ¦ 11:num/raw <- get *e, cursor-column:offset
2261 ]
2262 screen-should-contain [
2263 ¦ . .
2264 ¦ .67 .
2265 ¦ .89 .
2266 ¦ .╌╌╌╌╌ .
2267 ¦ . .
2268 ]
2269
2270 memory-should-contain [
2271 ¦ 10 <- 1
2272 ¦ 11 <- 0
2273 ]
2274 ]
2275
2276
2277 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-5 [
2278 local-scope
2279 assume-screen 10/width, 10/height
2280
2281 s:text <- new [1
2282 2
2283 345678
2284 9]
2285 e:&:editor <- new-editor s, 0/left, 5/right
2286 editor-render screen, e
2287
2288 assume-console [
2289 ¦ left-click 4, 1
2290 ¦ press ctrl-t
2291 ]
2292 editor-event-loop screen, console, e
2293 screen-should-contain [
2294 ¦ . .
2295 ¦ .78 .
2296 ¦ .9 .
2297 ¦ .╌╌╌╌╌ .
2298 ¦ . .
2299 ]
2300 assume-console [
2301 ¦ left-click 1, 1
2302 ¦ press ctrl-u
2303 ]
2304 run [
2305 ¦ editor-event-loop screen, console, e
2306 ¦ 10:num/raw <- get *e, cursor-row:offset
2307 ¦ 11:num/raw <- get *e, cursor-column:offset
2308 ]
2309
2310 screen-should-contain [
2311 ¦ . .
2312 ¦ .8 .
2313 ¦ .9 .
2314 ¦ .╌╌╌╌╌ .
2315 ¦ . .
2316 ]
2317 memory-should-contain [
2318 ¦ 10 <- 1
2319 ¦ 11 <- 0
2320 ]
2321
2322 assume-console [
2323 ¦ press up-arrow
2324 ]
2325 run [
2326 ¦ editor-event-loop screen, console, e
2327 ]
2328 screen-should-contain [
2329 ¦ . .
2330 ¦ .2 .
2331 ¦ .8 .
2332 ¦ .9 .
2333 ¦ .╌╌╌╌╌ .
2334 ¦ . .
2335 ]
2336 ]
2337
2338
2339 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-6 [
2340 local-scope
2341 assume-screen 10/width, 10/height
2342
2343 s:text <- new [1
2344 2
2345 3456789abcd
2346 e]
2347 e:&:editor <- new-editor s, 0/left, 5/right
2348 editor-render screen, e
2349
2350 assume-console [
2351 ¦ left-click 4, 1
2352 ¦ press ctrl-t
2353 ¦ press ctrl-s
2354 ]
2355 editor-event-loop screen, console, e
2356 screen-should-contain [
2357 ¦ . .
2358 ¦ .bcd .
2359 ¦ .e .
2360 ¦ .╌╌╌╌╌ .
2361 ¦ . .
2362 ]
2363 assume-console [
2364 ¦ left-click 1, 1
2365 ¦ press ctrl-u
2366 ]
2367 run [
2368 ¦ editor-event-loop screen, console, e
2369 ¦ 10:num/raw <- get *e, cursor-row:offset
2370 ¦ 11:num/raw <- get *e, cursor-column:offset
2371 ]
2372
2373 screen-should-contain [
2374 ¦ . .
2375 ¦ .cd .
2376 ¦ .e .
2377 ¦ .╌╌╌╌╌ .
2378 ¦ . .
2379 ]
2380 memory-should-contain [
2381 ¦ 10 <- 1
2382 ¦ 11 <- 0
2383 ]
2384
2385 assume-console [
2386 ¦ press up-arrow
2387 ]
2388 run [
2389 ¦ editor-event-loop screen, console, e
2390 ]
2391 screen-should-contain [
2392 ¦ . .
2393 ¦ .2 .
2394 ¦ .cd .
2395 ¦ .e .
2396 ¦ .╌╌╌╌╌ .
2397 ¦ . .
2398 ]
2399 ]
2400
2401
2402
2403 scenario editor-deletes-to-end-of-line-with-ctrl-k [
2404 local-scope
2405 assume-screen 10/width, 5/height
2406 s:text <- new [123
2407 456]
2408 e:&:editor <- new-editor s, 0/left, 10/right
2409 editor-render screen, e
2410 $clear-trace
2411
2412 assume-console [
2413 ¦ left-click 1, 1
2414 ¦ press ctrl-k
2415 ]
2416 run [
2417 ¦ editor-event-loop screen, console, e
2418 ]
2419
2420 screen-should-contain [
2421 ¦ . .
2422 ¦ .1 .
2423 ¦ .456 .
2424 ¦ .╌╌╌╌╌╌╌╌╌╌.
2425 ¦ . .
2426 ]
2427 check-trace-count-for-label 9, [print-character]
2428 ]
2429
2430 after <handle-special-character> [
2431 {
2432 ¦ delete-to-end-of-line?:bool <- equal c, 11/ctrl-k
2433 ¦ break-unless delete-to-end-of-line?
2434 ¦ <delete-to-end-of-line-begin>
2435 ¦ deleted-cells:&:duplex-list:char <- delete-to-end-of-line editor
2436 ¦ <delete-to-end-of-line-end>
2437 ¦
2438 ¦ go-render?:bool <- minimal-render-for-ctrl-k screen, editor, deleted-cells
2439 ¦ return
2440 }
2441 ]
2442
2443 def minimal-render-for-ctrl-k screen:&:screen, editor:&:editor, deleted-cells:&:duplex-list:char -> go-render?:bool, screen:&:screen [
2444 local-scope
2445 load-ingredients
2446
2447 return-unless deleted-cells, 0/dont-render
2448
2449 curr-column:num <- get *editor, cursor-column:offset
2450 num-deleted-cells:num <- length deleted-cells
2451 old-row-len:num <- add curr-column, num-deleted-cells
2452 left:num <- get *editor, left:offset
2453 right:num <- get *editor, right:offset
2454 end:num <- subtract right, left
2455 wrap?:bool <- greater-or-equal old-row-len, end
2456 return-if wrap?, 1/go-render
2457 clear-line-until screen, right
2458 return 0/dont-render
2459 ]
2460
2461 def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
2462 local-scope
2463 load-ingredients
2464
2465 start:&:duplex-list:char <- get *editor, before-cursor:offset
2466 end:&:duplex-list:char <- next start
2467 {
2468 ¦ at-end-of-text?:bool <- equal end, 0/null
2469 ¦ break-if at-end-of-text?
2470 ¦ curr:char <- get *end, value:offset
2471 ¦ at-end-of-line?:bool <- equal curr, 10/newline
2472 ¦ break-if at-end-of-line?
2473 ¦ end <- next end
2474 ¦ loop
2475 }
2476
2477 result <- next start
2478 remove-between start, end
2479 ]
2480
2481 scenario editor-deletes-to-end-of-line-with-ctrl-k-2 [
2482 local-scope
2483 assume-screen 10/width, 5/height
2484 s:text <- new [123
2485 456]
2486 e:&:editor <- new-editor s, 0/left, 10/right
2487 editor-render screen, e
2488 $clear-trace
2489
2490 assume-console [
2491 ¦ left-click 2, 1
2492 ¦ press ctrl-k
2493 ]
2494 run [
2495 ¦ editor-event-loop screen, console, e
2496 ]
2497
2498 screen-should-contain [
2499 ¦ . .
2500 ¦ .123 .
2501 ¦ .4 .
2502 ¦ .╌╌╌╌╌╌╌╌╌╌.
2503 ¦ . .
2504 ]
2505 check-trace-count-for-label 9, [print-character]
2506 ]
2507
2508 scenario editor-deletes-to-end-of-line-with-ctrl-k-3 [
2509 local-scope
2510 assume-screen 10/width, 5/height
2511 s:text <- new [123
2512 456]
2513 e:&:editor <- new-editor s, 0/left, 10/right
2514 editor-render screen, e
2515 $clear-trace
2516
2517 assume-console [
2518 ¦ left-click 1, 2
2519 ¦ press ctrl-k
2520 ]
2521 run [
2522 ¦ editor-event-loop screen, console, e
2523 ]
2524
2525 screen-should-contain [
2526 ¦ . .
2527 ¦ .12 .
2528 ¦ .456 .
2529 ¦ .╌╌╌╌╌╌╌╌╌╌.
2530 ¦ . .
2531 ]
2532 check-trace-count-for-label 8, [print-character]
2533 ]
2534
2535 scenario editor-deletes-to-end-of-line-with-ctrl-k-4 [
2536 local-scope
2537 assume-screen 10/width, 5/height
2538 s:text <- new [123
2539 456]
2540 e:&:editor <- new-editor s, 0/left, 10/right
2541 editor-render screen, e
2542 $clear-trace
2543
2544 assume-console [
2545 ¦ left-click 1, 3
2546 ¦ press ctrl-k
2547 ]
2548 run [
2549 ¦ editor-event-loop screen, console, e
2550 ]
2551
2552 screen-should-contain [
2553 ¦ . .
2554 ¦ .123 .
2555 ¦ .456 .
2556 ¦ .╌╌╌╌╌╌╌╌╌╌.
2557 ¦ . .
2558 ]
2559 check-trace-count-for-label 7, [print-character]
2560 ]
2561
2562 scenario editor-deletes-to-end-of-line-with-ctrl-k-5 [
2563 local-scope
2564 assume-screen 10/width, 5/height
2565 s:text <- new [123
2566 456]
2567 e:&:editor <- new-editor s, 0/left, 10/right
2568 editor-render screen, e
2569 $clear-trace
2570
2571 assume-console [
2572 ¦ left-click 2, 2
2573 ¦ press ctrl-k
2574 ]
2575 run [
2576 ¦ editor-event-loop screen, console, e
2577 ]
2578
2579 screen-should-contain [
2580 ¦ . .
2581 ¦ .123 .
2582 ¦ .45 .
2583 ¦ .╌╌╌╌╌╌╌╌╌╌.
2584 ¦ . .
2585 ]
2586 check-trace-count-for-label 8, [print-character]
2587 ]
2588
2589 scenario editor-deletes-to-end-of-line-with-ctrl-k-6 [
2590 local-scope
2591 assume-screen 10/width, 5/height
2592 s:text <- new [123
2593 456]
2594 e:&:editor <- new-editor s, 0/left, 10/right
2595 editor-render screen, e
2596 $clear-trace
2597
2598 assume-console [
2599 ¦ left-click 2, 3
2600 ¦ press ctrl-k
2601 ]
2602 run [
2603 ¦ editor-event-loop screen, console, e
2604 ]
2605
2606 screen-should-contain [
2607 ¦ . .
2608 ¦ .123 .
2609 ¦ .456 .
2610 ¦ .╌╌╌╌╌╌╌╌╌╌.
2611 ¦ . .
2612 ]
2613
2614 check-trace-count-for-label 0, [print-character]
2615 ]
2616
2617 scenario editor-deletes-to-end-of-wrapped-line-with-ctrl-k [
2618 local-scope
2619 assume-screen 10/width, 5/height
2620
2621 s:text <- new [1234
2622 567]
2623 e:&:editor <- new-editor s, 0/left, 4/right
2624 editor-render screen, e
2625 $clear-trace
2626
2627 assume-console [
2628 ¦ press ctrl-k
2629 ]
2630 run [
2631 ¦ editor-event-loop screen, console, e
2632 ]
2633
2634 screen-should-contain [
2635 ¦ . .
2636 ¦ . .
2637 ¦ .567 .
2638 ¦ .╌╌╌╌ .
2639 ¦ . .
2640 ]
2641
2642 check-trace-count-for-label 16, [print-character]
2643 ]
2644
2645
2646
2647 scenario editor-can-scroll-down-using-arrow-keys [
2648 local-scope
2649
2650 assume-screen 10/width, 4/height
2651
2652 s:text <- new [a
2653 b
2654 c
2655 d]
2656 e:&:editor <- new-editor s, 0/left, 10/right
2657 editor-render screen, e
2658 screen-should-contain [
2659 ¦ . .
2660 ¦ .a .
2661 ¦ .b .
2662 ¦ .c .
2663 ]
2664
2665 assume-console [
2666 ¦ left-click 3, 0
2667 ¦ press down-arrow
2668 ]
2669 run [
2670 ¦ editor-event-loop screen, console, e
2671 ]
2672
2673 screen-should-contain [
2674 ¦ . .
2675 ¦ .b .
2676 ¦ .c .
2677 ¦ .d .
2678 ]
2679 ]
2680
2681 after <scroll-down> [
2682 trace 10, [app], [scroll down]
2683 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2684 left:num <- get *editor, left:offset
2685 right:num <- get *editor, right:offset
2686 max:num <- subtract right, left
2687 old-top:&:duplex-list:char <- copy top-of-screen
2688 top-of-screen <- before-start-of-next-line top-of-screen, max
2689 *editor <- put *editor, top-of-screen:offset, top-of-screen
2690 no-movement?:bool <- equal old-top, top-of-screen
2691 return-if no-movement?, 0/don't-render
2692 ]
2693
2694
2695
2696
2697
2698 def before-start-of-next-line original:&:duplex-list:char, max:num -> curr:&:duplex-list:char [
2699 local-scope
2700 load-ingredients
2701 count:num <- copy 0
2702 curr:&:duplex-list:char <- copy original
2703
2704 {
2705 ¦ c:char <- get *curr, value:offset
2706 ¦ at-newline?:bool <- equal c, 10/newline
2707 ¦ break-unless at-newline?
2708 ¦ curr <- next curr
2709 ¦ count <- add count, 1
2710 }
2711 {
2712 ¦ return-unless curr, original
2713 ¦ done?:bool <- greater-or-equal count, max
2714 ¦ break-if done?
2715 ¦ c:char <- get *curr, value:offset
2716 ¦ at-newline?:bool <- equal c, 10/newline
2717 ¦ break-if at-newline?
2718 ¦ curr <- next curr
2719 ¦ count <- add count, 1
2720 ¦ loop
2721 }
2722 return-unless curr, original
2723 return curr
2724 ]
2725
2726 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys [
2727 local-scope
2728
2729 assume-screen 10/width, 4/height
2730
2731
2732 s:text <- new [abcdef
2733 g
2734 h
2735 i]
2736 e:&:editor <- new-editor s, 0/left, 5/right
2737 editor-render screen, e
2738 screen-should-contain [
2739 ¦ . .
2740 ¦ .abcd↩ .
2741 ¦ .ef .
2742 ¦ .g .
2743 ]
2744
2745 assume-console [
2746 ¦ left-click 3, 0
2747 ¦ press down-arrow
2748 ]
2749 run [
2750 ¦ editor-event-loop screen, console, e
2751 ]
2752
2753 screen-should-contain [
2754 ¦ . .
2755 ¦ .ef .
2756 ¦ .g .
2757 ¦ .h .
2758 ]
2759 ]
2760
2761 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys-2 [
2762 local-scope
2763
2764 assume-screen 10/width, 4/height
2765
2766 s:text <- new [abcdefghij
2767 k
2768 l
2769 m]
2770 e:&:editor <- new-editor s, 0/left, 5/right
2771
2772 assume-console [
2773 ¦ left-click 3, 0
2774 ¦ press down-arrow
2775 ]
2776 run [
2777 ¦ editor-event-loop screen, console, e
2778 ]
2779
2780 screen-should-contain [
2781 ¦ . .
2782 ¦ .efgh↩ .
2783 ¦ .ij .
2784 ¦ .k .
2785 ]
2786
2787 assume-console [
2788 ¦ press down-arrow
2789 ]
2790 run [
2791 ¦ editor-event-loop screen, console, e
2792 ]
2793
2794 screen-should-contain [
2795 ¦ . .
2796 ¦ .ij .
2797 ¦ .k .
2798 ¦ .l .
2799 ]
2800 ]
2801
2802 scenario editor-scrolls-down-when-line-wraps [
2803 local-scope
2804
2805 assume-screen 5/width, 4/height
2806
2807 s:text <- new [a
2808 b
2809 cdef]
2810 e:&:editor <- new-editor s, 0/left, 5/right
2811
2812 assume-console [
2813 ¦ left-click 3, 4
2814 ¦ type [g]
2815 ]
2816 run [
2817 ¦ editor-event-loop screen, console, e
2818 ¦ 3:num/raw <- get *e, cursor-row:offset
2819 ¦ 4:num/raw <- get *e, cursor-column:offset
2820 ]
2821
2822 screen-should-contain [
2823 ¦ . .
2824 ¦ .b .
2825 ¦ .cdef↩.
2826 ¦ .g .
2827 ]
2828 memory-should-contain [
2829 ¦ 3 <- 3
2830 ¦ 4 <- 1
2831 ]
2832 ]
2833
2834 scenario editor-scrolls-down-on-newline [
2835 local-scope
2836 assume-screen 5/width, 4/height
2837
2838 s:text <- new [a
2839 b
2840 c]
2841 e:&:editor <- new-editor s, 0/left, 5/right
2842 assume-console [
2843 ¦ left-click 3, 4
2844 ¦ type [
2845 ]
2846 ]
2847 run [
2848 ¦ editor-event-loop screen, console, e
2849 ¦ 3:num/raw <- get *e, cursor-row:offset
2850 ¦ 4:num/raw <- get *e, cursor-column:offset
2851 ]
2852
2853 screen-should-contain [
2854 ¦ . .
2855 ¦ .b .
2856 ¦ .c .
2857 ¦ . .
2858 ]
2859 memory-should-contain [
2860 ¦ 3 <- 3
2861 ¦ 4 <- 0
2862 ]
2863 ]
2864
2865 scenario editor-scrolls-down-on-right-arrow [
2866 local-scope
2867
2868 assume-screen 5/width, 4/height
2869
2870 s:text <- new [a
2871 b
2872 cdefgh]
2873 e:&:editor <- new-editor s, 0/left, 5/right
2874
2875 assume-console [
2876 ¦ left-click 3, 3
2877 ¦ press right-arrow
2878 ]
2879 run [
2880 ¦ editor-event-loop screen, console, e
2881 ¦ 3:num/raw <- get *e, cursor-row:offset
2882 ¦ 4:num/raw <- get *e, cursor-column:offset
2883 ]
2884
2885 screen-should-contain [
2886 ¦ . .
2887 ¦ .b .
2888 ¦ .cdef↩.
2889 ¦ .gh .
2890 ]
2891 memory-should-contain [
2892 ¦ 3 <- 3
2893 ¦ 4 <- 0
2894 ]
2895 ]
2896
2897 scenario editor-scrolls-down-on-right-arrow-2 [
2898 local-scope
2899
2900 assume-screen 5/width, 4/height
2901
2902 s:text <- new [a
2903 b
2904 c
2905 d]
2906 e:&:editor <- new-editor s, 0/left, 5/right
2907
2908 assume-console [
2909 ¦ left-click 3, 3
2910 ¦ press right-arrow
2911 ]
2912 run [
2913 ¦ editor-event-loop screen, console, e
2914 ¦ 3:num/raw <- get *e, cursor-row:offset
2915 ¦ 4:num/raw <- get *e, cursor-column:offset
2916 ]
2917
2918 screen-should-contain [
2919 ¦ . .
2920 ¦ .b .
2921 ¦ .c .
2922 ¦ .d .
2923 ]
2924 memory-should-contain [
2925 ¦ 3 <- 3
2926 ¦ 4 <- 0
2927 ]
2928 ]
2929
2930 scenario editor-scrolls-at-end-on-down-arrow [
2931 local-scope
2932 assume-screen 10/width, 5/height
2933 s:text <- new [abc
2934 de]
2935 e:&:editor <- new-editor s, 0/left, 10/right
2936 editor-render screen, e
2937 $clear-trace
2938
2939 assume-console [
2940 ¦ left-click 2, 0
2941 ¦ press down-arrow
2942 ]
2943 run [
2944 ¦ editor-event-loop screen, console, e
2945 ¦ 3:num/raw <- get *e, cursor-row:offset
2946 ¦ 4:num/raw <- get *e, cursor-column:offset
2947 ]
2948
2949 memory-should-contain [
2950 ¦ 3 <- 1
2951 ¦ 4 <- 2
2952 ]
2953 assume-console [
2954 ¦ type [0]
2955 ]
2956 run [
2957 ¦ editor-event-loop screen, console, e
2958 ]
2959 screen-should-contain [
2960 ¦ . .
2961 ¦ .de0 .
2962 ¦ .╌╌╌╌╌╌╌╌╌╌.
2963 ¦ . .
2964 ]
2965
2966 $clear-trace
2967 assume-console [
2968 ¦ left-click 2, 0
2969 ¦ press down-arrow
2970 ]
2971 run [
2972 ¦ editor-event-loop screen, console, e
2973 ¦ 3:num/raw <- get *e, cursor-row:offset
2974 ¦ 4:num/raw <- get *e, cursor-column:offset
2975 ]
2976
2977 memory-should-contain [
2978 ¦ 3 <- 1
2979 ¦ 4 <- 3
2980 ]
2981 check-trace-count-for-label 0, [print-character]
2982 assume-console [
2983 ¦ type [1]
2984 ]
2985 run [
2986 ¦ editor-event-loop screen, console, e
2987 ]
2988 screen-should-contain [
2989 ¦ . .
2990 ¦ .de01 .
2991 ¦ .╌╌╌╌╌╌╌╌╌╌.
2992 ¦ . .
2993 ]
2994 ]
2995
2996 scenario editor-combines-page-and-line-scroll [
2997 local-scope
2998
2999 assume-screen 10/width, 4/height
3000
3001 s:text <- new [a
3002 b
3003 c
3004 d
3005 e
3006 f
3007 g]
3008 e:&:editor <- new-editor s, 0/left, 5/right
3009 editor-render screen, e
3010
3011 assume-console [
3012 ¦ press page-down
3013 ¦ left-click 3, 0
3014 ¦ press down-arrow
3015 ]
3016 run [
3017 ¦ editor-event-loop screen, console, e
3018 ]
3019
3020 screen-should-contain [
3021 ¦ . .
3022 ¦ .d .
3023 ¦ .e .
3024 ¦ .f .
3025 ]
3026 ]
3027
3028
3029
3030 scenario editor-can-scroll-up-using-arrow-keys [
3031 local-scope
3032
3033 assume-screen 10/width, 4/height
3034
3035 s:text <- new [a
3036 b
3037 c
3038 d]
3039 e:&:editor <- new-editor s, 0/left, 10/right
3040 editor-render screen, e
3041 screen-should-contain [
3042 ¦ . .
3043 ¦ .a .
3044 ¦ .b .
3045 ¦ .c .
3046 ]
3047
3048 assume-console [
3049 ¦ press page-down
3050 ¦ press up-arrow
3051 ]
3052 run [
3053 ¦ editor-event-loop screen, console, e
3054 ]
3055
3056 screen-should-contain [
3057 ¦ . .
3058 ¦ .b .
3059 ¦ .c .
3060 ¦ .d .
3061 ]
3062 ]
3063
3064 after <scroll-up> [
3065 trace 10, [app], [scroll up]
3066 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3067 old-top:&:duplex-list:char <- copy top-of-screen
3068 top-of-screen <- before-previous-screen-line top-of-screen, editor
3069 *editor <- put *editor, top-of-screen:offset, top-of-screen
3070 no-movement?:bool <- equal old-top, top-of-screen
3071 return-if no-movement?, 0/don't-render
3072 ]
3073
3074
3075
3076
3077
3078 def before-previous-screen-line in:&:duplex-list:char, editor:&:editor -> out:&:duplex-list:char [
3079 local-scope
3080 load-ingredients
3081 curr:&:duplex-list:char <- copy in
3082 c:char <- get *curr, value:offset
3083
3084
3085
3086 left:num <- get *editor, left:offset
3087 right:num <- get *editor, right:offset
3088 max-line-length:num <- subtract right, left, -1/exclusive-right, 1/wrap-icon
3089 sentinel:&:duplex-list:char <- get *editor, data:offset
3090 len:num <- previous-line-length curr, sentinel
3091 {
3092 ¦ break-if len
3093 ¦
3094 ¦ prev:&:duplex-list:char <- prev curr
3095 ¦ return-unless prev, curr
3096 ¦ return prev
3097 }
3098 _, max:num <- divide-with-remainder len, max-line-length
3099
3100 {
3101 ¦ break-if max
3102 ¦ max <- copy max-line-length
3103 }
3104 max <- add max, 1
3105 count:num <- copy 0
3106
3107 {
3108 ¦ done?:bool <- greater-or-equal count, max
3109 ¦ break-if done?
3110 ¦ prev:&:duplex-list:char <- prev curr
3111 ¦ break-unless prev
3112 ¦ curr <- copy prev
3113 ¦ count <- add count, 1
3114 ¦ loop
3115 }
3116 return curr
3117 ]
3118
3119 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys [
3120 local-scope
3121
3122 assume-screen 10/width, 4/height
3123
3124
3125 s:text <- new [abcdef
3126 g
3127 h
3128 i]
3129 e:&:editor <- new-editor s, 0/left, 5/right
3130 editor-render screen, e
3131 screen-should-contain [
3132 ¦ . .
3133 ¦ .abcd↩ .
3134 ¦ .ef .
3135 ¦ .g .
3136 ]
3137
3138 assume-console [
3139 ¦ press page-down
3140 ]
3141 run [
3142 ¦ editor-event-loop screen, console, e
3143 ]
3144 screen-should-contain [
3145 ¦ . .
3146 ¦ .g .
3147 ¦ .h .
3148 ¦ .i .
3149 ]
3150
3151 assume-console [
3152 ¦ press up-arrow
3153 ]
3154 run [
3155 ¦ editor-event-loop screen, console, e
3156 ]
3157
3158 screen-should-contain [
3159 ¦ . .
3160 ¦ .ef .
3161 ¦ .g .
3162 ¦ .h .
3163 ]
3164 ]
3165
3166 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-2 [
3167 local-scope
3168
3169 assume-screen 10/width, 5/height
3170
3171 s:text <- new [abcdefghij
3172 k
3173 l
3174 m]
3175 e:&:editor <- new-editor s, 0/left, 5/right
3176 editor-render screen, e
3177
3178 assume-console [
3179 ¦ press page-down
3180 ]
3181 run [
3182 ¦ editor-event-loop screen, console, e
3183 ]
3184 screen-should-contain [
3185 ¦ . .
3186 ¦ .k .
3187 ¦ .l .
3188 ¦ .m .
3189 ¦ .╌╌╌╌╌ .
3190 ]
3191
3192 assume-console [
3193 ¦ press up-arrow
3194 ]
3195 run [
3196 ¦ editor-event-loop screen, console, e
3197 ]
3198
3199 screen-should-contain [
3200 ¦ . .
3201 ¦ .ij .
3202 ¦ .k .
3203 ¦ .l .
3204 ¦ .m .
3205 ]
3206
3207 assume-console [
3208 ¦ press up-arrow
3209 ]
3210 run [
3211 ¦ editor-event-loop screen, console, e
3212 ]
3213
3214 screen-should-contain [
3215 ¦ . .
3216 ¦ .efgh↩ .
3217 ¦ .ij .
3218 ¦ .k .
3219 ¦ .l .
3220 ]
3221
3222 assume-console [
3223 ¦ press up-arrow
3224 ]
3225 run [
3226 ¦ editor-event-loop screen, console, e
3227 ]
3228
3229 screen-should-contain [
3230 ¦ . .
3231 ¦ .abcd↩ .
3232 ¦ .efgh↩ .
3233 ¦ .ij .
3234 ¦ .k .
3235 ]
3236 ]
3237
3238
3239
3240 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-3 [
3241 local-scope
3242
3243 assume-screen 10/width, 4/height
3244
3245
3246 s:text <- new [abcdef
3247 g
3248 h
3249 i]
3250 e:&:editor <- new-editor s, 0/left, 6/right
3251 editor-render screen, e
3252 screen-should-contain [
3253 ¦ . .
3254 ¦ .abcde↩ .
3255 ¦ .f .
3256 ¦ .g .
3257 ]
3258
3259 assume-console [
3260 ¦ press page-down
3261 ]
3262 run [
3263 ¦ editor-event-loop screen, console, e
3264 ]
3265 screen-should-contain [
3266 ¦ . .
3267 ¦ .g .
3268 ¦ .h .
3269 ¦ .i .
3270 ]
3271
3272 assume-console [
3273 ¦ press up-arrow
3274 ]
3275 run [
3276 ¦ editor-event-loop screen, console, e
3277 ]
3278
3279 screen-should-contain [
3280 ¦ . .
3281 ¦ .f .
3282 ¦ .g .
3283 ¦ .h .
3284 ]
3285 ]
3286
3287
3288 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-4 [
3289 local-scope
3290 assume-screen 10/width, 4/height
3291
3292 s:text <- new [a
3293 b
3294
3295 c
3296 d
3297 e]
3298 e:&:editor <- new-editor s, 0/left, 6/right
3299 editor-render screen, e
3300 assume-console [
3301 ¦ press page-down
3302 ]
3303 run [
3304 ¦ editor-event-loop screen, console, e
3305 ]
3306 screen-should-contain [
3307 ¦ . .
3308 ¦ . .
3309 ¦ .c .
3310 ¦ .d .
3311 ]
3312 assume-console [
3313 ¦ press page-down
3314 ]
3315 run [
3316 ¦ editor-event-loop screen, console, e
3317 ]
3318 screen-should-contain [
3319 ¦ . .
3320 ¦ .d .
3321 ¦ .e .
3322 ¦ .╌╌╌╌╌╌ .
3323 ]
3324 assume-console [
3325 ¦ press page-up
3326 ]
3327 run [
3328 ¦ editor-event-loop screen, console, e
3329 ]
3330 screen-should-contain [
3331 ¦ . .
3332 ¦ . .
3333 ¦ .c .
3334 ¦ .d .
3335 ]
3336 ]
3337
3338 scenario editor-scrolls-up-on-left-arrow [
3339 local-scope
3340
3341 assume-screen 5/width, 4/height
3342
3343 s:text <- new [a
3344 b
3345 c
3346 d
3347 e]
3348 e:&:editor <- new-editor s, 0/left, 5/right
3349 editor-render screen, e
3350
3351 assume-console [
3352 ¦ press page-down
3353 ]
3354 run [
3355 ¦ editor-event-loop screen, console, e
3356 ]
3357 screen-should-contain [
3358 ¦ . .
3359 ¦ .c .
3360 ¦ .d .
3361 ¦ .e .
3362 ]
3363
3364 assume-console [
3365 ¦ press left-arrow
3366 ]
3367 run [
3368 ¦ editor-event-loop screen, console, e
3369 ¦ 3:num/raw <- get *e, cursor-row:offset
3370 ¦ 4:num/raw <- get *e, cursor-column:offset
3371 ]
3372
3373 screen-should-contain [
3374 ¦ . .
3375 ¦ .b .
3376 ¦ .c .
3377 ¦ .d .
3378 ]
3379 memory-should-contain [
3380 ¦ 3 <- 1
3381 ¦ 4 <- 1
3382 ]
3383 ]
3384
3385 scenario editor-can-scroll-up-to-start-of-file [
3386 local-scope
3387
3388 assume-screen 10/width, 4/height
3389
3390 s:text <- new [a
3391 b
3392 c
3393 d]
3394 e:&:editor <- new-editor s, 0/left, 10/right
3395 editor-render screen, e
3396 screen-should-contain [
3397 ¦ . .
3398 ¦ .a .
3399 ¦ .b .
3400 ¦ .c .
3401 ]
3402
3403
3404 assume-console [
3405 ¦ press page-down
3406 ¦ press up-arrow
3407 ¦ press up-arrow
3408 ]
3409 run [
3410 ¦ editor-event-loop screen, console, e
3411 ]
3412
3413 screen-should-contain [
3414 ¦ . .
3415 ¦ .a .
3416 ¦ .b .
3417 ¦ .c .
3418 ]
3419
3420 assume-console [
3421 ¦ press up-arrow
3422 ]
3423 run [
3424 ¦ editor-event-loop screen, console, e
3425 ]
3426
3427 screen-should-contain [
3428 ¦ . .
3429 ¦ .a .
3430 ¦ .b .
3431 ¦ .c .
3432 ]
3433 ]
3434
3435
3436
3437 scenario editor-can-scroll [
3438 local-scope
3439 assume-screen 10/width, 4/height
3440 s:text <- new [a
3441 b
3442 c
3443 d]
3444 e:&:editor <- new-editor s, 0/left, 10/right
3445 editor-render screen, e
3446 screen-should-contain [
3447 ¦ . .
3448 ¦ .a .
3449 ¦ .b .
3450 ¦ .c .
3451 ]
3452
3453 assume-console [
3454 ¦ press page-down
3455 ]
3456 run [
3457 ¦ editor-event-loop screen, console, e
3458 ]
3459
3460 screen-should-contain [
3461 ¦ . .
3462 ¦ .c .
3463 ¦ .d .
3464 ¦ .╌╌╌╌╌╌╌╌╌╌.
3465 ]
3466 ]
3467
3468 after <handle-special-character> [
3469 {
3470 ¦ page-down?:bool <- equal c, 6/ctrl-f
3471 ¦ break-unless page-down?
3472 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3473 ¦ <move-cursor-begin>
3474 ¦ page-down editor
3475 ¦ undo-coalesce-tag:num <- copy 0/never
3476 ¦ <move-cursor-end>
3477 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3478 ¦ movement?:bool <- not-equal top-of-screen, old-top
3479 ¦ return movement?/go-render
3480 }
3481 ]
3482
3483 after <handle-special-key> [
3484 {
3485 ¦ page-down?:bool <- equal k, 65518/page-down
3486 ¦ break-unless page-down?
3487 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3488 ¦ <move-cursor-begin>
3489 ¦ page-down editor
3490 ¦ undo-coalesce-tag:num <- copy 0/never
3491 ¦ <move-cursor-end>
3492 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3493 ¦ movement?:bool <- not-equal top-of-screen, old-top
3494 ¦ return movement?/go-render
3495 }
3496 ]
3497
3498
3499
3500 def page-down editor:&:editor -> editor:&:editor [
3501 local-scope
3502 load-ingredients
3503
3504 bottom-of-screen:&:duplex-list:char <- get *editor, bottom-of-screen:offset
3505 return-unless bottom-of-screen
3506
3507 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
3508 before-cursor:&:duplex-list:char <- prev bottom-of-screen
3509 *editor <- put *editor, before-cursor:offset, before-cursor
3510
3511 {
3512 ¦ last:char <- get *before-cursor, value:offset
3513 ¦ newline?:bool <- equal last, 10/newline
3514 ¦ break-unless newline?:bool
3515 ¦ before-cursor <- prev before-cursor
3516 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
3517 }
3518
3519 move-to-start-of-line editor
3520 before-cursor <- get *editor, before-cursor:offset
3521 *editor <- put *editor, top-of-screen:offset, before-cursor
3522 ]
3523
3524
3525 def move-to-start-of-line editor:&:editor -> editor:&:editor [
3526 local-scope
3527 load-ingredients
3528
3529 left:num <- get *editor, left:offset
3530 cursor-column:num <- copy left
3531 *editor <- put *editor, cursor-column:offset, cursor-column
3532
3533 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
3534 init:&:duplex-list:char <- get *editor, data:offset
3535
3536 {
3537 ¦ at-start-of-text?:bool <- equal before-cursor, init
3538 ¦ break-if at-start-of-text?
3539 ¦ prev:char <- get *before-cursor, value:offset
3540 ¦ at-start-of-line?:bool <- equal prev, 10/newline
3541 ¦ break-if at-start-of-line?
3542 ¦ before-cursor <- prev before-cursor
3543 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
3544 ¦ assert before-cursor, [move-to-start-of-line tried to move before start of text]
3545 ¦ loop
3546 }
3547 ]
3548
3549 scenario editor-does-not-scroll-past-end [
3550 local-scope
3551 assume-screen 10/width, 4/height
3552 s:text <- new [a
3553 b]
3554 e:&:editor <- new-editor s, 0/left, 10/right
3555 editor-render screen, e
3556 screen-should-contain [
3557 ¦ . .
3558 ¦ .a .
3559 ¦ .b .
3560 ¦ .╌╌╌╌╌╌╌╌╌╌.
3561 ]
3562
3563 assume-console [
3564 ¦ press page-down
3565 ]
3566 run [
3567 ¦ editor-event-loop screen, console, e
3568 ]
3569
3570 screen-should-contain [
3571 ¦ . .
3572 ¦ .a .
3573 ¦ .b .
3574 ¦ .╌╌╌╌╌╌╌╌╌╌.
3575 ]
3576 ]
3577
3578 scenario editor-starts-next-page-at-start-of-wrapped-line [
3579 local-scope
3580
3581 assume-screen 10/width, 4/height
3582
3583 s:text <- new [a
3584 b
3585 cdefgh]
3586
3587 e:&:editor <- new-editor s, 0/left, 4/right
3588 editor-render screen, e
3589
3590 screen-should-contain [
3591 ¦ . .
3592 ¦ .a .
3593 ¦ .b .
3594 ¦ .cde↩ .
3595 ]
3596
3597 assume-console [
3598 ¦ press page-down
3599 ]
3600 run [
3601 ¦ editor-event-loop screen, console, e
3602 ]
3603
3604 screen-should-contain [
3605 ¦ . .
3606 ¦ .cde↩ .
3607 ¦ .fgh .
3608 ¦ .╌╌╌╌ .
3609 ]
3610 ]
3611
3612 scenario editor-starts-next-page-at-start-of-wrapped-line-2 [
3613 local-scope
3614
3615 assume-screen 10/width, 4/height
3616
3617
3618 s:text <- new [a
3619 bcdefgh]
3620 e:&:editor <- new-editor s, 0/left, 4/right
3621 editor-render screen, e
3622
3623 screen-should-contain [
3624 ¦ . .
3625 ¦ .a .
3626 ¦ .bcd↩ .
3627 ¦ .efg↩ .
3628 ]
3629
3630 assume-console [
3631 ¦ press page-down
3632 ]
3633 run [
3634 ¦ editor-event-loop screen, console, e
3635 ]
3636
3637 screen-should-contain [
3638 ¦ . .
3639 ¦ .bcd↩ .
3640 ¦ .efg↩ .
3641 ¦ .h .
3642 ]
3643 ]
3644
3645
3646
3647 scenario editor-can-scroll-up [
3648 local-scope
3649 assume-screen 10/width, 4/height
3650 s:text <- new [a
3651 b
3652 c
3653 d]
3654 e:&:editor <- new-editor s, 0/left, 10/right
3655 editor-render screen, e
3656 screen-should-contain [
3657 ¦ . .
3658 ¦ .a .
3659 ¦ .b .
3660 ¦ .c .
3661 ]
3662
3663 assume-console [
3664 ¦ press page-down
3665 ]
3666 run [
3667 ¦ editor-event-loop screen, console, e
3668 ]
3669
3670 screen-should-contain [
3671 ¦ . .
3672 ¦ .c .
3673 ¦ .d .
3674 ¦ .╌╌╌╌╌╌╌╌╌╌.
3675 ]
3676
3677 assume-console [
3678 ¦ press page-up
3679 ]
3680 run [
3681 ¦ editor-event-loop screen, console, e
3682 ]
3683
3684 screen-should-contain [
3685 ¦ . .
3686 ¦ .a .
3687 ¦ .b .
3688 ¦ .c .
3689 ]
3690 ]
3691
3692 after <handle-special-character> [
3693 {
3694 ¦ page-up?:bool <- equal c, 2/ctrl-b
3695 ¦ break-unless page-up?
3696 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3697 ¦ <move-cursor-begin>
3698 ¦ editor <- page-up editor, screen-height
3699 ¦ undo-coalesce-tag:num <- copy 0/never
3700 ¦ <move-cursor-end>
3701 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3702 ¦ movement?:bool <- not-equal top-of-screen, old-top
3703 ¦ return movement?/go-render
3704 }
3705 ]
3706
3707 after <handle-special-key> [
3708 {
3709 ¦ page-up?:bool <- equal k, 65519/page-up
3710 ¦ break-unless page-up?
3711 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3712 ¦ <move-cursor-begin>
3713 ¦ editor <- page-up editor, screen-height
3714 ¦ undo-coalesce-tag:num <- copy 0/never
3715 ¦ <move-cursor-end>
3716 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3717 ¦ movement?:bool <- not-equal top-of-screen, old-top
3718 ¦
3719 ¦ return movement?/go-render
3720 }
3721 ]
3722
3723 def page-up editor:&:editor, screen-height:num -> editor:&:editor [
3724 local-scope
3725 load-ingredients
3726 max:num <- subtract screen-height, 1/menu-bar, 1/overlapping-line
3727 count:num <- copy 0
3728 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3729 {
3730 ¦ done?:bool <- greater-or-equal count, max
3731 ¦ break-if done?
3732 ¦ prev:&:duplex-list:char <- before-previous-screen-line top-of-screen, editor
3733 ¦ break-unless prev
3734 ¦ top-of-screen <- copy prev
3735 ¦ *editor <- put *editor, top-of-screen:offset, top-of-screen
3736 ¦ count <- add count, 1
3737 ¦ loop
3738 }
3739 ]
3740
3741 scenario editor-can-scroll-up-multiple-pages [
3742 local-scope
3743
3744 assume-screen 10/width, 4/height
3745
3746 s:text <- new [a
3747 b
3748 c
3749 d
3750 e
3751 f
3752 g
3753 h]
3754 e:&:editor <- new-editor s, 0/left, 10/right
3755 editor-render screen, e
3756 screen-should-contain [
3757 ¦ . .
3758 ¦ .a .
3759 ¦ .b .
3760 ¦ .c .
3761 ]
3762
3763 assume-console [
3764 ¦ press page-down
3765 ¦ press page-down
3766 ]
3767 run [
3768 ¦ editor-event-loop screen, console, e
3769 ]
3770
3771 screen-should-contain [
3772 ¦ . .
3773 ¦ .e .
3774 ¦ .f .
3775 ¦ .g .
3776 ]
3777
3778 assume-console [
3779 ¦ press page-up
3780 ]
3781 run [
3782 ¦ editor-event-loop screen, console, e
3783 ]
3784
3785 screen-should-contain [
3786 ¦ . .
3787 ¦ .c .
3788 ¦ .d .
3789 ¦ .e .
3790 ]
3791
3792 assume-console [
3793 ¦ press page-up
3794 ]
3795 run [
3796 ¦ editor-event-loop screen, console, e
3797 ]
3798
3799 screen-should-contain [
3800 ¦ . .
3801 ¦ .a .
3802 ¦ .b .
3803 ¦ .c .
3804 ]
3805 ]
3806
3807 scenario editor-can-scroll-up-wrapped-lines [
3808 local-scope
3809
3810 assume-screen 10/width, 6/height
3811
3812 s:text <- new [a
3813 b
3814 cdefgh
3815 i
3816 j
3817 k
3818 l
3819 m
3820 n
3821 o]
3822
3823 e:&:editor <- new-editor s, 0/left, 4/right
3824 editor-render screen, e
3825
3826 screen-should-contain [
3827 ¦ . .
3828 ¦ .a .
3829 ¦ .b .
3830 ¦ .cde↩ .
3831 ¦ .fgh .
3832 ¦ .i .
3833 ]
3834
3835 assume-console [
3836 ¦ press page-down
3837 ¦ left-click 5, 0
3838 ¦ press down-arrow
3839 ]
3840 run [
3841 ¦ editor-event-loop screen, console, e
3842 ]
3843
3844 screen-should-contain [
3845 ¦ . .
3846 ¦ .j .
3847 ¦ .k .
3848 ¦ .l .
3849 ¦ .m .
3850 ¦ .n .
3851 ]
3852
3853 assume-console [
3854 ¦ press page-up
3855 ]
3856 run [
3857 ¦ editor-event-loop screen, console, e
3858 ]
3859
3860 screen-should-contain [
3861 ¦ . .
3862 ¦ .b .
3863 ¦ .cde↩ .
3864 ¦ .fgh .
3865 ¦ .i .
3866 ¦ .j .
3867 ]
3868 ]
3869
3870 scenario editor-can-scroll-up-wrapped-lines-2 [
3871 local-scope
3872
3873 assume-screen 10/width, 4/height
3874
3875
3876 s:text <- new [a
3877 bcdefgh]
3878 e:&:editor <- new-editor s, 0/left, 4/right
3879 editor-render screen, e
3880
3881 screen-should-contain [
3882 ¦ . .
3883 ¦ .a .
3884 ¦ .bcd↩ .
3885 ¦ .efg↩ .
3886 ]
3887
3888 assume-console [
3889 ¦ press page-down
3890 ]
3891 run [
3892 ¦ editor-event-loop screen, console, e
3893 ]
3894
3895 screen-should-contain [
3896 ¦ . .
3897 ¦ .bcd↩ .
3898 ¦ .efg↩ .
3899 ¦ .h .
3900 ]
3901
3902 assume-console [
3903 ¦ press page-up
3904 ]
3905 run [
3906 ¦ editor-event-loop screen, console, e
3907 ]
3908
3909 screen-should-contain [
3910 ¦ . .
3911 ¦ .a .
3912 ¦ .bcd↩ .
3913 ¦ .efg↩ .
3914 ]
3915 ]
3916
3917 scenario editor-can-scroll-up-past-nonempty-lines [
3918 local-scope
3919 assume-screen 10/width, 4/height
3920
3921 s:text <- new [axx
3922 bxx
3923 cxx
3924 dxx
3925 exx
3926 fxx
3927 gxx
3928 hxx
3929 ]
3930 e:&:editor <- new-editor s, 0/left, 4/right
3931 editor-render screen, e
3932 screen-should-contain [
3933 ¦ . .
3934 ¦ .axx .
3935 ¦ .bxx .
3936 ¦ .cxx .
3937 ]
3938 assume-console [
3939 ¦ press page-down
3940 ]
3941 run [
3942 ¦ editor-event-loop screen, console, e
3943 ]
3944 screen-should-contain [
3945 ¦ . .
3946 ¦ .cxx .
3947 ¦ .dxx .
3948 ¦ .exx .
3949 ]
3950 assume-console [
3951 ¦ press page-down
3952 ]
3953 run [
3954 ¦ editor-event-loop screen, console, e
3955 ]
3956 screen-should-contain [
3957 ¦ . .
3958 ¦ .exx .
3959 ¦ .fxx .
3960 ¦ .gxx .
3961 ]
3962
3963 assume-console [
3964 ¦ press page-up
3965 ]
3966 run [
3967 ¦ editor-event-loop screen, console, e
3968 ]
3969 screen-should-contain [
3970 ¦ . .
3971 ¦ .cxx .
3972 ¦ .dxx .
3973 ¦ .exx .
3974 ]
3975 ]
3976
3977 scenario editor-can-scroll-up-past-empty-lines [
3978 local-scope
3979 assume-screen 10/width, 4/height
3980
3981 s:text <- new [axy
3982 bxy
3983 cxy
3984
3985 dxy
3986 exy
3987 fxy
3988 gxy
3989 ]
3990 e:&:editor <- new-editor s, 0/left, 4/right
3991 editor-render screen, e
3992 screen-should-contain [
3993 ¦ . .
3994 ¦ .axy .
3995 ¦ .bxy .
3996 ¦ .cxy .
3997 ]
3998 assume-console [
3999 ¦ press page-down
4000 ]
4001 run [
4002 ¦ editor-event-loop screen, console, e
4003 ]
4004 screen-should-contain [
4005 ¦ . .
4006 ¦ .cxy .
4007 ¦ . .
4008 ¦ .dxy .
4009 ]
4010 assume-console [
4011 ¦ press page-down
4012 ]
4013 run [
4014 ¦ editor-event-loop screen, console, e
4015 ]
4016 screen-should-contain [
4017 ¦ . .
4018 ¦ .dxy .
4019 ¦ .exy .
4020 ¦ .fxy .
4021 ]
4022
4023 assume-console [
4024 ¦ press page-up
4025 ]
4026 run [
4027 ¦ editor-event-loop screen, console, e
4028 ]
4029 screen-should-contain [
4030 ¦ . .
4031 ¦ .cxy .
4032 ¦ . .
4033 ¦ .dxy .
4034 ]
4035 ]
4036
4037
4038
4039
4040 after <handle-special-character> [
4041 {
4042 ¦ scroll-up?:bool <- equal c, 19/ctrl-s
4043 ¦ break-unless scroll-up?
4044 ¦ <move-cursor-begin>
4045 ¦ go-render?:bool, editor <- line-up editor, screen-height
4046 ¦ undo-coalesce-tag:num <- copy 5/line-up
4047 ¦ <move-cursor-end>
4048 ¦ return go-render?
4049 }
4050 ]
4051
4052 def line-up editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
4053 local-scope
4054 load-ingredients
4055 left:num <- get *editor, left:offset
4056 right:num <- get *editor, right:offset
4057 max:num <- subtract right, left
4058 old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
4059 new-top:&:duplex-list:char <- before-start-of-next-line old-top, max
4060 movement?:bool <- not-equal old-top, new-top
4061 {
4062 ¦ break-unless movement?
4063 ¦ *editor <- put *editor, top-of-screen:offset, new-top
4064 }
4065 return movement?
4066 ]
4067
4068
4069
4070
4071 after <handle-special-character> [
4072 {
4073 ¦ scroll-down?:bool <- equal c, 24/ctrl-x
4074 ¦ break-unless scroll-down?
4075 ¦ <move-cursor-begin>
4076 ¦ go-render?:bool, editor <- line-down editor, screen-height
4077 ¦ undo-coalesce-tag:num <- copy 6/line-down
4078 ¦ <move-cursor-end>
4079 ¦ return go-render?
4080 }
4081 ]
4082
4083 def line-down editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
4084 local-scope
4085 load-ingredients
4086 old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
4087 new-top:&:duplex-list:char <- before-previous-screen-line old-top, editor
4088 movement?:bool <- not-equal old-top, new-top
4089 {
4090 ¦ break-unless movement?
4091 ¦ *editor <- put *editor, top-of-screen:offset, new-top
4092 }
4093 return movement?
4094 ]
4095
4096
4097
4098
4099 after <handle-special-character> [
4100 {
4101 ¦ scroll-down?:bool <- equal c, 20/ctrl-t
4102 ¦ break-unless scroll-down?
4103 ¦ <move-cursor-begin>
4104 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
4105 ¦ cursor:&:duplex-list:char <- get *editor, before-cursor:offset
4106 ¦ cursor <- next cursor
4107 ¦ new-top:&:duplex-list:char <- before-previous-screen-line cursor, editor
4108 ¦ *editor <- put *editor, top-of-screen:offset, new-top
4109 ¦ *editor <- put *editor, cursor-row:offset, 1
4110 ¦ go-render?:bool <- not-equal new-top, old-top
4111 ¦ undo-coalesce-tag:num <- copy 0/never
4112 ¦ <move-cursor-end>
4113 ¦ return go-render?
4114 }
4115 ]
4116
4117
4118
4119 after <handle-special-character> [
4120 {
4121 ¦ comment-toggle?:bool <- equal c, 31/ctrl-slash
4122 ¦ break-unless comment-toggle?
4123 ¦ cursor-column:num <- get *editor, cursor-column:offset
4124 ¦ data:&:duplex-list:char <- get *editor, data:offset
4125 ¦ <insert-character-begin>
4126 ¦ before-line-start:&:duplex-list:char <- before-start-of-screen-line editor
4127 ¦ line-start:&:duplex-list:char <- next before-line-start
4128 ¦ commented-out?:bool <- match line-start, [#? ]
4129 ¦ {
4130 ¦ ¦ break-unless commented-out?
4131 ¦ ¦
4132 ¦ ¦ data <- remove line-start, 3/length-comment-prefix, data
4133 ¦ ¦ cursor-column <- subtract cursor-column, 3/length-comment-prefix
4134 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
4135 ¦ ¦ go-render? <- render-line-from-start screen, editor, 3/size-of-comment-leader
4136 ¦ }
4137 ¦ {
4138 ¦ ¦ break-if commented-out?
4139 ¦ ¦
4140 ¦ ¦ insert before-line-start, [#? ]
4141 ¦ ¦ cursor-column <- add cursor-column, 3/length-comment-prefix
4142 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
4143 ¦ ¦ go-render? <- render-line-from-start screen, editor, 0
4144 ¦ }
4145 ¦ <insert-character-end>
4146 ¦ return
4147 }
4148 ]
4149
4150
4151
4152
4153 def render-line-from-start screen:&:screen, editor:&:editor, right-margin:num -> go-render?:bool, screen:&:screen [
4154 local-scope
4155 load-ingredients
4156 before-line-start:&:duplex-list:char <- before-start-of-screen-line editor
4157 line-start:&:duplex-list:char <- next before-line-start
4158 color:num <- copy 7/white
4159 left:num <- get *editor, left:offset
4160 cursor-row:num <- get *editor, cursor-row:offset
4161 screen <- move-cursor screen, cursor-row, left
4162 right:num <- get *editor, right:offset
4163 end:num <- subtract right, right-margin
4164 i:num <- copy 0
4165 curr:&:duplex-list:char <- copy line-start
4166 {
4167 ¦ render-all?:bool <- greater-or-equal i, end
4168 ¦ return-if render-all?, 1/go-render
4169 ¦ break-unless curr
4170 ¦ c:char <- get *curr, value:offset
4171 ¦ newline?:bool <- equal c, 10/newline
4172 ¦ break-if newline?
4173 ¦ color <- get-color color, c
4174 ¦ print screen, c, color
4175 ¦ curr <- next curr
4176 ¦ i <- add i, 1
4177 ¦ loop
4178 }
4179 clear-line-until screen, right
4180 return 0/dont-render
4181 ]
4182
4183 def before-start-of-screen-line editor:&:editor -> result:&:duplex-list:char [
4184 local-scope
4185 load-ingredients
4186 cursor:&:duplex-list:char <- get *editor, before-cursor:offset
4187 {
4188 ¦ next:&:duplex-list:char <- next cursor
4189 ¦ break-unless next
4190 ¦ cursor <- copy next
4191 }
4192 result <- before-previous-screen-line cursor, editor
4193 ]
4194
4195 scenario editor-comments-empty-line [
4196 local-scope
4197 assume-screen 10/width, 5/height
4198 e:&:editor <- new-editor [], 0/left, 5/right
4199 editor-render screen, e
4200 $clear-trace
4201 assume-console [
4202 ¦ press ctrl-slash
4203 ]
4204 run [
4205 ¦ editor-event-loop screen, console, e
4206 ¦ 4:num/raw <- get *e, cursor-row:offset
4207 ¦ 5:num/raw <- get *e, cursor-column:offset
4208 ]
4209 screen-should-contain [
4210 ¦ . .
4211 ¦ .#? .
4212 ¦ .╌╌╌╌╌ .
4213 ¦ . .
4214 ]
4215 memory-should-contain [
4216 ¦ 4 <- 1
4217 ¦ 5 <- 3
4218 ]
4219 check-trace-count-for-label 5, [print-character]
4220 ]
4221
4222 scenario editor-comments-at-start-of-contents [
4223 local-scope
4224 assume-screen 10/width, 5/height
4225 e:&:editor <- new-editor [ab], 0/left, 10/right
4226 editor-render screen, e
4227 $clear-trace
4228 assume-console [
4229 ¦ press ctrl-slash
4230 ]
4231 run [
4232 ¦ editor-event-loop screen, console, e
4233 ¦ 4:num/raw <- get *e, cursor-row:offset
4234 ¦ 5:num/raw <- get *e, cursor-column:offset
4235 ]
4236 screen-should-contain [
4237 ¦ . .
4238 ¦ .#? ab .
4239 ¦ .╌╌╌╌╌╌╌╌╌╌.
4240 ¦ . .
4241 ]
4242 memory-should-contain [
4243 ¦ 4 <- 1
4244 ¦ 5 <- 3
4245 ]
4246 check-trace-count-for-label 10, [print-character]
4247 ]
4248
4249 scenario editor-comments-at-end-of-contents [
4250 local-scope
4251 assume-screen 10/width, 5/height
4252 e:&:editor <- new-editor [ab], 0/left, 10/right
4253 editor-render screen, e
4254 $clear-trace
4255 assume-console [
4256 ¦ left-click 1, 7
4257 ¦ press ctrl-slash
4258 ]
4259 run [
4260 ¦ editor-event-loop screen, console, e
4261 ¦ 4:num/raw <- get *e, cursor-row:offset
4262 ¦ 5:num/raw <- get *e, cursor-column:offset
4263 ]
4264 screen-should-contain [
4265 ¦ . .
4266 ¦ .#? ab .
4267 ¦ .╌╌╌╌╌╌╌╌╌╌.
4268 ¦ . .
4269 ]
4270 memory-should-contain [
4271 ¦ 4 <- 1
4272 ¦ 5 <- 5
4273 ]
4274 check-trace-count-for-label 10, [print-character]
4275
4276 $clear-trace
4277 assume-console [
4278 ¦ press ctrl-slash
4279 ]
4280 run [
4281 ¦ editor-event-loop screen, console, e
4282 ¦ 4:num/raw <- get *e, cursor-row:offset
4283 ¦ 5:num/raw <- get *e, cursor-column:offset
4284 ]
4285 screen-should-contain [
4286 ¦ . .
4287 ¦ .ab .
4288 ¦ .╌╌╌╌╌╌╌╌╌╌.
4289 ¦ . .
4290 ]
4291 check-trace-count-for-label 10, [print-character]
4292 ]
4293
4294 scenario editor-comments-almost-wrapping-line [
4295 local-scope
4296 assume-screen 10/width, 5/height
4297
4298 e:&:editor <- new-editor [abcd], 0/left, 5/right
4299 editor-render screen, e
4300 screen-should-contain [
4301 ¦ . .
4302 ¦ .abcd .
4303 ¦ .╌╌╌╌╌ .
4304 ¦ . .
4305 ]
4306 $clear-trace
4307
4308 assume-console [
4309 ¦ left-click 1, 7
4310 ¦ press ctrl-slash
4311 ]
4312 run [
4313 ¦ editor-event-loop screen, console, e
4314 ]
4315 screen-should-contain [
4316 ¦ . .
4317 ¦ .#? a↩ .
4318 ¦ .bcd .
4319 ¦ .╌╌╌╌╌ .
4320 ¦ . .
4321 ]
4322 ]
4323
4324 scenario editor-uncomments-just-wrapping-line [
4325 local-scope
4326 assume-screen 10/width, 5/height
4327
4328 e:&:editor <- new-editor [#? ab], 0/left, 5/right
4329 editor-render screen, e
4330 screen-should-contain [
4331 ¦ . .
4332 ¦ .#? a↩ .
4333 ¦ .b .
4334 ¦ .╌╌╌╌╌ .
4335 ¦ . .
4336 ]
4337 $clear-trace
4338
4339 assume-console [
4340 ¦ left-click 1, 7
4341 ¦ press ctrl-slash
4342 ]
4343 run [
4344 ¦ editor-event-loop screen, console, e
4345 ]
4346 screen-should-contain [
4347 ¦ . .
4348 ¦ .ab .
4349 ¦ .╌╌╌╌╌ .
4350 ¦ . .
4351 ]
4352 ]