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 ¦ ¦ at-left?:bool <- equal cursor-column, left
1021 ¦ ¦ break-if at-left?
1022 ¦ ¦ curr <- before-previous-screen-line curr, editor
1023 ¦ ¦ no-motion?:bool <- equal curr, old
1024 ¦ ¦ return-if no-motion?
1025 ¦ }
1026 ¦ {
1027 ¦ ¦ curr <- before-previous-screen-line curr, editor
1028 ¦ ¦ no-motion?:bool <- equal curr, old
1029 ¦ ¦ return-if no-motion?
1030 ¦ }
1031 ¦ before-cursor <- copy curr
1032 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1033 ¦ cursor-row <- subtract cursor-row, 1
1034 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
1035 ¦
1036 ¦ target-column:num <- copy cursor-column
1037 ¦ cursor-column <- copy left
1038 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1039 ¦ {
1040 ¦ ¦ done?:bool <- greater-or-equal cursor-column, target-column
1041 ¦ ¦ break-if done?
1042 ¦ ¦ curr:&:duplex-list:char <- next before-cursor
1043 ¦ ¦ break-unless curr
1044 ¦ ¦ currc:char <- get *curr, value:offset
1045 ¦ ¦ at-newline?:bool <- equal currc, 10/newline
1046 ¦ ¦ break-if at-newline?
1047 ¦ ¦
1048 ¦ ¦ before-cursor <- copy curr
1049 ¦ ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1050 ¦ ¦ cursor-column <- add cursor-column, 1
1051 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1052 ¦ ¦ loop
1053 ¦ }
1054 ¦ return
1055 }
1056 {
1057 ¦
1058 ¦ break-unless already-at-top?
1059 ¦ <scroll-up>
1060 ¦ return 1/go-render
1061 }
1062 ]
1063
1064 scenario editor-adjusts-column-at-previous-line [
1065 local-scope
1066 assume-screen 10/width, 5/height
1067 s:text <- new [ab
1068 def]
1069 e:&:editor <- new-editor s, 0/left, 10/right
1070 editor-render screen, e
1071 $clear-trace
1072 assume-console [
1073 ¦ left-click 2, 3
1074 ¦ press up-arrow
1075 ]
1076 run [
1077 ¦ editor-event-loop screen, console, e
1078 ¦ 3:num/raw <- get *e, cursor-row:offset
1079 ¦ 4:num/raw <- get *e, cursor-column:offset
1080 ]
1081 memory-should-contain [
1082 ¦ 3 <- 1
1083 ¦ 4 <- 2
1084 ]
1085 check-trace-count-for-label 0, [print-character]
1086 assume-console [
1087 ¦ type [0]
1088 ]
1089 run [
1090 ¦ editor-event-loop screen, console, e
1091 ]
1092 screen-should-contain [
1093 ¦ . .
1094 ¦ .ab0 .
1095 ¦ .def .
1096 ¦ .╌╌╌╌╌╌╌╌╌╌.
1097 ¦ . .
1098 ]
1099 ]
1100
1101 scenario editor-adjusts-column-at-empty-line [
1102 local-scope
1103 assume-screen 10/width, 5/height
1104 s:text <- new [
1105 def]
1106 e:&:editor <- new-editor s, 0/left, 10/right
1107 editor-render screen, e
1108 $clear-trace
1109 assume-console [
1110 ¦ left-click 2, 3
1111 ¦ press up-arrow
1112 ]
1113 run [
1114 ¦ editor-event-loop screen, console, e
1115 ¦ 3:num/raw <- get *e, cursor-row:offset
1116 ¦ 4:num/raw <- get *e, cursor-column:offset
1117 ]
1118 memory-should-contain [
1119 ¦ 3 <- 1
1120 ¦ 4 <- 0
1121 ]
1122 check-trace-count-for-label 0, [print-character]
1123 assume-console [
1124 ¦ type [0]
1125 ]
1126 run [
1127 ¦ editor-event-loop screen, console, e
1128 ]
1129 screen-should-contain [
1130 ¦ . .
1131 ¦ .0 .
1132 ¦ .def .
1133 ¦ .╌╌╌╌╌╌╌╌╌╌.
1134 ¦ . .
1135 ]
1136 ]
1137
1138 scenario editor-moves-to-previous-line-from-zero-margin [
1139 local-scope
1140 assume-screen 10/width, 5/height
1141
1142 s:text <- new [abc
1143 def
1144 ghi]
1145 e:&:editor <- new-editor s, 0/left, 10/right
1146 editor-render screen, e
1147 $clear-trace
1148
1149 assume-console [
1150 ¦ left-click 3, 0
1151 ¦ press up-arrow
1152 ]
1153 run [
1154 ¦ editor-event-loop screen, console, e
1155 ¦ 3:num/raw <- get *e, cursor-row:offset
1156 ¦ 4:num/raw <- get *e, cursor-column:offset
1157 ]
1158 memory-should-contain [
1159 ¦ 3 <- 2
1160 ¦ 4 <- 0
1161 ]
1162 check-trace-count-for-label 0, [print-character]
1163 assume-console [
1164 ¦ type [0]
1165 ]
1166 run [
1167 ¦ editor-event-loop screen, console, e
1168 ]
1169 screen-should-contain [
1170 ¦ . .
1171 ¦ .abc .
1172 ¦ .0def .
1173 ¦ .ghi .
1174 ¦ .╌╌╌╌╌╌╌╌╌╌.
1175 ]
1176 ]
1177
1178 scenario editor-moves-to-previous-line-from-left-margin [
1179 local-scope
1180 assume-screen 10/width, 5/height
1181
1182 s:text <- new [abc
1183 def
1184 ghi]
1185 e:&:editor <- new-editor s, 1/left, 10/right
1186 editor-render screen, e
1187 $clear-trace
1188
1189 assume-console [
1190 ¦ left-click 3, 1
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 <- 2
1200 ¦ 4 <- 1
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 ¦ . abc .
1212 ¦ . 0def .
1213 ¦ . ghi .
1214 ¦ . ╌╌╌╌╌╌╌╌╌.
1215 ]
1216 ]
1217
1218 scenario editor-moves-to-top-line-in-presence-of-wrapped-line [
1219 local-scope
1220 assume-screen 10/width, 5/height
1221 e:&:editor <- new-editor [abcde], 0/left, 5/right
1222 editor-render screen, e
1223 screen-should-contain [
1224 ¦ . .
1225 ¦ .abcd↩ .
1226 ¦ .e .
1227 ¦ .╌╌╌╌╌ .
1228 ]
1229 $clear-trace
1230 assume-console [
1231 ¦ left-click 2, 0
1232 ¦ press up-arrow
1233 ]
1234 run [
1235 ¦ editor-event-loop screen, console, e
1236 ¦ 3:num/raw <- get *e, cursor-row:offset
1237 ¦ 4:num/raw <- get *e, cursor-column:offset
1238 ]
1239 memory-should-contain [
1240 ¦ 3 <- 1
1241 ¦ 4 <- 0
1242 ]
1243 check-trace-count-for-label 0, [print-character]
1244 assume-console [
1245 ¦ type [0]
1246 ]
1247 run [
1248 ¦ editor-event-loop screen, console, e
1249 ]
1250 screen-should-contain [
1251 ¦ . .
1252 ¦ .0abc↩ .
1253 ¦ .de .
1254 ¦ .╌╌╌╌╌ .
1255 ]
1256 ]
1257
1258 scenario editor-moves-to-top-line-in-presence-of-wrapped-line-2 [
1259 local-scope
1260 assume-screen 10/width, 5/height
1261 s:text <- new [abc
1262 defgh]
1263 e:&:editor <- new-editor s, 0/left, 5/right
1264 editor-render screen, e
1265 screen-should-contain [
1266 ¦ . .
1267 ¦ .abc .
1268 ¦ .defg↩ .
1269 ¦ .h .
1270 ¦ .╌╌╌╌╌ .
1271 ]
1272 $clear-trace
1273 assume-console [
1274 ¦ left-click 3, 0
1275 ¦ press up-arrow
1276 ¦ press up-arrow
1277 ]
1278 run [
1279 ¦ editor-event-loop screen, console, e
1280 ¦ 3:num/raw <- get *e, cursor-row:offset
1281 ¦ 4:num/raw <- get *e, cursor-column:offset
1282 ]
1283 memory-should-contain [
1284 ¦ 3 <- 1
1285 ¦ 4 <- 0
1286 ]
1287 check-trace-count-for-label 0, [print-character]
1288 assume-console [
1289 ¦ type [0]
1290 ]
1291 run [
1292 ¦ editor-event-loop screen, console, e
1293 ]
1294 screen-should-contain [
1295 ¦ . .
1296 ¦ .0abc .
1297 ¦ .defg↩ .
1298 ¦ .h .
1299 ¦ .╌╌╌╌╌ .
1300 ]
1301 ]
1302
1303
1304
1305 scenario editor-moves-to-next-line-with-down-arrow [
1306 local-scope
1307 assume-screen 10/width, 5/height
1308 s:text <- new [abc
1309 def]
1310 e:&:editor <- new-editor s, 0/left, 10/right
1311 editor-render screen, e
1312 $clear-trace
1313
1314 assume-console [
1315 ¦ press down-arrow
1316 ]
1317 run [
1318 ¦ editor-event-loop screen, console, e
1319 ¦ 3:num/raw <- get *e, cursor-row:offset
1320 ¦ 4:num/raw <- get *e, cursor-column:offset
1321 ]
1322
1323 memory-should-contain [
1324 ¦ 3 <- 2
1325 ¦ 4 <- 0
1326 ]
1327 check-trace-count-for-label 0, [print-character]
1328 assume-console [
1329 ¦ type [0]
1330 ]
1331 run [
1332 ¦ editor-event-loop screen, console, e
1333 ]
1334 screen-should-contain [
1335 ¦ . .
1336 ¦ .abc .
1337 ¦ .0def .
1338 ¦ .╌╌╌╌╌╌╌╌╌╌.
1339 ¦ . .
1340 ]
1341 ]
1342
1343 after <handle-special-key> [
1344 {
1345 ¦ move-to-next-line?:bool <- equal k, 65516/down-arrow
1346 ¦ break-unless move-to-next-line?
1347 ¦ <move-cursor-begin>
1348 ¦ go-render? <- move-to-next-line editor, screen-height
1349 ¦ undo-coalesce-tag:num <- copy 4/down-arrow
1350 ¦ <move-cursor-end>
1351 ¦ return
1352 }
1353 ]
1354
1355 def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
1356 local-scope
1357 load-ingredients
1358 cursor-row:num <- get *editor, cursor-row:offset
1359 cursor-column:num <- get *editor, cursor-column:offset
1360 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1361 left:num <- get *editor, left:offset
1362 right:num <- get *editor, right:offset
1363 last-line:num <- subtract screen-height, 1
1364 already-at-bottom?:bool <- greater-or-equal cursor-row, last-line
1365 {
1366 ¦
1367 ¦ break-if already-at-bottom?
1368 ¦
1369 ¦ max:num <- subtract right, left
1370 ¦ next-line:&:duplex-list:char <- before-start-of-next-line before-cursor, max
1371 ¦ {
1372 ¦ ¦
1373 ¦ ¦
1374 ¦ ¦ no-motion?:bool <- equal next-line, before-cursor
1375 ¦ ¦ break-unless no-motion?
1376 ¦ ¦ scroll?:bool <- greater-than cursor-row, 1
1377 ¦ ¦ break-if scroll?, +try-to-scroll
1378 ¦ ¦ return 0/don't-render
1379 ¦ }
1380 ¦ cursor-row <- add cursor-row, 1
1381 ¦ *editor <- put *editor, cursor-row:offset, cursor-row
1382 ¦ before-cursor <- copy next-line
1383 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1384 ¦ target-column:num <- copy cursor-column
1385 ¦ cursor-column <- copy left
1386 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1387 ¦ {
1388 ¦ ¦ done?:bool <- greater-or-equal cursor-column, target-column
1389 ¦ ¦ break-if done?
1390 ¦ ¦ curr:&:duplex-list:char <- next before-cursor
1391 ¦ ¦ break-unless curr
1392 ¦ ¦ currc:char <- get *curr, value:offset
1393 ¦ ¦ at-newline?:bool <- equal currc, 10/newline
1394 ¦ ¦ break-if at-newline?
1395 ¦ ¦
1396 ¦ ¦ before-cursor <- copy curr
1397 ¦ ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1398 ¦ ¦ cursor-column <- add cursor-column, 1
1399 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1400 ¦ ¦ loop
1401 ¦ }
1402 ¦ return 0/don't-render
1403 }
1404 +try-to-scroll
1405 <scroll-down>
1406 go-render? <- copy 1/true
1407 ]
1408
1409 scenario editor-adjusts-column-at-next-line [
1410 local-scope
1411 assume-screen 10/width, 5/height
1412 s:text <- new [abc
1413 de]
1414 e:&:editor <- new-editor s, 0/left, 10/right
1415 editor-render screen, e
1416 $clear-trace
1417 assume-console [
1418 ¦ left-click 1, 3
1419 ¦ press down-arrow
1420 ]
1421 run [
1422 ¦ editor-event-loop screen, console, e
1423 ¦ 3:num/raw <- get *e, cursor-row:offset
1424 ¦ 4:num/raw <- get *e, cursor-column:offset
1425 ]
1426 memory-should-contain [
1427 ¦ 3 <- 2
1428 ¦ 4 <- 2
1429 ]
1430 check-trace-count-for-label 0, [print-character]
1431 assume-console [
1432 ¦ type [0]
1433 ]
1434 run [
1435 ¦ editor-event-loop screen, console, e
1436 ]
1437 screen-should-contain [
1438 ¦ . .
1439 ¦ .abc .
1440 ¦ .de0 .
1441 ¦ .╌╌╌╌╌╌╌╌╌╌.
1442 ¦ . .
1443 ]
1444 ]
1445
1446
1447
1448 scenario editor-moves-to-start-of-line-with-ctrl-a [
1449 local-scope
1450 assume-screen 10/width, 5/height
1451 s:text <- new [123
1452 456]
1453 e:&:editor <- new-editor s, 0/left, 10/right
1454 editor-render screen, e
1455 $clear-trace
1456
1457 assume-console [
1458 ¦ left-click 2, 3
1459 ¦ press ctrl-a
1460 ]
1461 run [
1462 ¦ editor-event-loop screen, console, e
1463 ¦ 4:num/raw <- get *e, cursor-row:offset
1464 ¦ 5:num/raw <- get *e, cursor-column:offset
1465 ]
1466
1467 memory-should-contain [
1468 ¦ 4 <- 2
1469 ¦ 5 <- 0
1470 ]
1471 check-trace-count-for-label 0, [print-character]
1472 ]
1473
1474 after <handle-special-character> [
1475 {
1476 ¦ move-to-start-of-line?:bool <- equal c, 1/ctrl-a
1477 ¦ break-unless move-to-start-of-line?
1478 ¦ <move-cursor-begin>
1479 ¦ move-to-start-of-screen-line editor
1480 ¦ undo-coalesce-tag:num <- copy 0/never
1481 ¦ <move-cursor-end>
1482 ¦ return 0/don't-render
1483 }
1484 ]
1485
1486 after <handle-special-key> [
1487 {
1488 ¦ move-to-start-of-line?:bool <- equal k, 65521/home
1489 ¦ break-unless move-to-start-of-line?
1490 ¦ <move-cursor-begin>
1491 ¦ move-to-start-of-screen-line editor
1492 ¦ undo-coalesce-tag:num <- copy 0/never
1493 ¦ <move-cursor-end>
1494 ¦ return 0/don't-render
1495 }
1496 ]
1497
1498
1499
1500 def move-to-start-of-screen-line editor:&:editor -> editor:&:editor [
1501 local-scope
1502 load-ingredients
1503
1504 left:num <- get *editor, left:offset
1505 col:num <- get *editor, cursor-column:offset
1506
1507 curr:&:duplex-list:char <- get *editor, before-cursor:offset
1508
1509 {
1510 ¦ done?:bool <- equal col, left
1511 ¦ break-if done?
1512 ¦ assert curr, [move-to-start-of-line tried to move before start of text]
1513 ¦ curr <- prev curr
1514 ¦ col <- subtract col, 1
1515 ¦ loop
1516 }
1517 *editor <- put *editor, cursor-column:offset, col
1518 *editor <- put *editor, before-cursor:offset, curr
1519 ]
1520
1521 scenario editor-moves-to-start-of-line-with-ctrl-a-2 [
1522 local-scope
1523 assume-screen 10/width, 5/height
1524 s:text <- new [123
1525 456]
1526 e:&:editor <- new-editor s, 0/left, 10/right
1527 editor-render screen, e
1528 $clear-trace
1529
1530 assume-console [
1531 ¦ left-click 1, 3
1532 ¦ press ctrl-a
1533 ]
1534 run [
1535 ¦ editor-event-loop screen, console, e
1536 ¦ 4:num/raw <- get *e, cursor-row:offset
1537 ¦ 5:num/raw <- get *e, cursor-column:offset
1538 ]
1539
1540 memory-should-contain [
1541 ¦ 4 <- 1
1542 ¦ 5 <- 0
1543 ]
1544 check-trace-count-for-label 0, [print-character]
1545 ]
1546
1547 scenario editor-moves-to-start-of-line-with-home [
1548 local-scope
1549 assume-screen 10/width, 5/height
1550 s:text <- new [123
1551 456]
1552 e:&:editor <- new-editor s, 0/left, 10/right
1553 $clear-trace
1554
1555 assume-console [
1556 ¦ left-click 2, 3
1557 ¦ press home
1558 ]
1559 run [
1560 ¦ editor-event-loop screen, console, e
1561 ¦ 3:num/raw <- get *e, cursor-row:offset
1562 ¦ 4:num/raw <- get *e, cursor-column:offset
1563 ]
1564
1565 memory-should-contain [
1566 ¦ 3 <- 2
1567 ¦ 4 <- 0
1568 ]
1569 check-trace-count-for-label 0, [print-character]
1570 ]
1571
1572 scenario editor-moves-to-start-of-line-with-home-2 [
1573 local-scope
1574 assume-screen 10/width, 5/height
1575 s:text <- new [123
1576 456]
1577 e:&:editor <- new-editor s, 0/left, 10/right
1578 editor-render screen, e
1579 $clear-trace
1580
1581 assume-console [
1582 ¦ left-click 1, 3
1583 ¦ press home
1584 ]
1585 run [
1586 ¦ editor-event-loop screen, console, e
1587 ¦ 3:num/raw <- get *e, cursor-row:offset
1588 ¦ 4:num/raw <- get *e, cursor-column:offset
1589 ]
1590
1591 memory-should-contain [
1592 ¦ 3 <- 1
1593 ¦ 4 <- 0
1594 ]
1595 check-trace-count-for-label 0, [print-character]
1596 ]
1597
1598 scenario editor-moves-to-start-of-screen-line-with-ctrl-a [
1599 local-scope
1600 assume-screen 10/width, 5/height
1601 e:&:editor <- new-editor [123456], 0/left, 5/right
1602 editor-render screen, e
1603 screen-should-contain [
1604 ¦ . .
1605 ¦ .1234↩ .
1606 ¦ .56 .
1607 ¦ .╌╌╌╌╌ .
1608 ¦ . .
1609 ]
1610 $clear-trace
1611
1612 assume-console [
1613 ¦ left-click 2, 1
1614 ¦ press ctrl-a
1615 ¦ press up-arrow
1616 ]
1617 run [
1618 ¦ editor-event-loop screen, console, e
1619 ¦ 4:num/raw <- get *e, cursor-row:offset
1620 ¦ 5:num/raw <- get *e, cursor-column:offset
1621 ]
1622
1623 memory-should-contain [
1624 ¦ 4 <- 1
1625 ¦ 5 <- 0
1626 ]
1627 check-trace-count-for-label 0, [print-character]
1628
1629 assume-console [
1630 ¦ type [a]
1631 ]
1632 run [
1633 ¦ editor-event-loop screen, console, e
1634 ¦ 4:num/raw <- get *e, cursor-row:offset
1635 ¦ 5:num/raw <- get *e, cursor-column:offset
1636 ]
1637 screen-should-contain [
1638 ¦ . .
1639 ¦ .a123↩ .
1640 ¦ .456 .
1641 ¦ .╌╌╌╌╌ .
1642 ¦ . .
1643 ]
1644 memory-should-contain [
1645 ¦ 4 <- 1
1646 ¦ 5 <- 1
1647 ]
1648 ]
1649
1650
1651
1652 scenario editor-moves-to-end-of-line-with-ctrl-e [
1653 local-scope
1654 assume-screen 10/width, 5/height
1655 s:text <- new [123
1656 456]
1657 e:&:editor <- new-editor s, 0/left, 10/right
1658 editor-render screen, e
1659 $clear-trace
1660
1661 assume-console [
1662 ¦ left-click 1, 1
1663 ¦ press ctrl-e
1664 ]
1665 run [
1666 ¦ editor-event-loop screen, console, e
1667 ¦ 4:num/raw <- get *e, cursor-row:offset
1668 ¦ 5:num/raw <- get *e, cursor-column:offset
1669 ]
1670
1671 memory-should-contain [
1672 ¦ 4 <- 1
1673 ¦ 5 <- 3
1674 ]
1675 check-trace-count-for-label 0, [print-character]
1676
1677 assume-console [
1678 ¦ type [z]
1679 ]
1680 run [
1681 ¦ editor-event-loop screen, console, e
1682 ¦ 4:num/raw <- get *e, cursor-row:offset
1683 ¦ 5:num/raw <- get *e, cursor-column:offset
1684 ]
1685 memory-should-contain [
1686 ¦ 4 <- 1
1687 ¦ 5 <- 4
1688 ]
1689 screen-should-contain [
1690 ¦ . .
1691 ¦ .123z .
1692 ¦ .456 .
1693 ¦ .╌╌╌╌╌╌╌╌╌╌.
1694 ¦ . .
1695 ]
1696 check-trace-count-for-label 1, [print-character]
1697 ]
1698
1699 after <handle-special-character> [
1700 {
1701 ¦ move-to-end-of-line?:bool <- equal c, 5/ctrl-e
1702 ¦ break-unless move-to-end-of-line?
1703 ¦ <move-cursor-begin>
1704 ¦ move-to-end-of-line editor
1705 ¦ undo-coalesce-tag:num <- copy 0/never
1706 ¦ <move-cursor-end>
1707 ¦ return 0/don't-render
1708 }
1709 ]
1710
1711 after <handle-special-key> [
1712 {
1713 ¦ move-to-end-of-line?:bool <- equal k, 65520/end
1714 ¦ break-unless move-to-end-of-line?
1715 ¦ <move-cursor-begin>
1716 ¦ move-to-end-of-line editor
1717 ¦ undo-coalesce-tag:num <- copy 0/never
1718 ¦ <move-cursor-end>
1719 ¦ return 0/don't-render
1720 }
1721 ]
1722
1723 def move-to-end-of-line editor:&:editor -> editor:&:editor [
1724 local-scope
1725 load-ingredients
1726 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1727 cursor-column:num <- get *editor, cursor-column:offset
1728 right:num <- get *editor, right:offset
1729
1730 {
1731 ¦ next:&:duplex-list:char <- next before-cursor
1732 ¦ break-unless next
1733 ¦ nextc:char <- get *next, value:offset
1734 ¦ at-end-of-line?:bool <- equal nextc, 10/newline
1735 ¦ break-if at-end-of-line?
1736 ¦ cursor-column <- add cursor-column, 1
1737 ¦ at-right?:bool <- equal cursor-column, right
1738 ¦ break-if at-right?
1739 ¦ *editor <- put *editor, cursor-column:offset, cursor-column
1740 ¦ before-cursor <- copy next
1741 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
1742 ¦ loop
1743 }
1744 ]
1745
1746 scenario editor-moves-to-end-of-line-with-ctrl-e-2 [
1747 local-scope
1748 assume-screen 10/width, 5/height
1749 s:text <- new [123
1750 456]
1751 e:&:editor <- new-editor s, 0/left, 10/right
1752 editor-render screen, e
1753 $clear-trace
1754
1755 assume-console [
1756 ¦ left-click 2, 1
1757 ¦ press ctrl-e
1758 ]
1759 run [
1760 ¦ editor-event-loop screen, console, e
1761 ¦ 4:num/raw <- get *e, cursor-row:offset
1762 ¦ 5:num/raw <- get *e, cursor-column:offset
1763 ]
1764
1765 memory-should-contain [
1766 ¦ 4 <- 2
1767 ¦ 5 <- 3
1768 ]
1769 check-trace-count-for-label 0, [print-character]
1770 ]
1771
1772 scenario editor-moves-to-end-of-line-with-end [
1773 local-scope
1774 assume-screen 10/width, 5/height
1775 s:text <- new [123
1776 456]
1777 e:&:editor <- new-editor s, 0/left, 10/right
1778 editor-render screen, e
1779 $clear-trace
1780
1781 assume-console [
1782 ¦ left-click 1, 1
1783 ¦ press end
1784 ]
1785 run [
1786 ¦ editor-event-loop screen, console, e
1787 ¦ 3:num/raw <- get *e, cursor-row:offset
1788 ¦ 4:num/raw <- get *e, cursor-column:offset
1789 ]
1790
1791 memory-should-contain [
1792 ¦ 3 <- 1
1793 ¦ 4 <- 3
1794 ]
1795 check-trace-count-for-label 0, [print-character]
1796 ]
1797
1798 scenario editor-moves-to-end-of-line-with-end-2 [
1799 local-scope
1800 assume-screen 10/width, 5/height
1801 s:text <- new [123
1802 456]
1803 e:&:editor <- new-editor s, 0/left, 10/right
1804 editor-render screen, e
1805 $clear-trace
1806
1807 assume-console [
1808 ¦ left-click 2, 1
1809 ¦ press end
1810 ]
1811 run [
1812 ¦ editor-event-loop screen, console, e
1813 ¦ 3:num/raw <- get *e, cursor-row:offset
1814 ¦ 4:num/raw <- get *e, cursor-column:offset
1815 ]
1816
1817 memory-should-contain [
1818 ¦ 3 <- 2
1819 ¦ 4 <- 3
1820 ]
1821 check-trace-count-for-label 0, [print-character]
1822 ]
1823
1824 scenario editor-moves-to-end-of-wrapped-line [
1825 local-scope
1826 assume-screen 10/width, 5/height
1827 s:text <- new [123456
1828 789]
1829 e:&:editor <- new-editor s, 0/left, 5/right
1830 editor-render screen, e
1831 $clear-trace
1832
1833 assume-console [
1834 ¦ left-click 1, 1
1835 ¦ press end
1836 ]
1837 run [
1838 ¦ editor-event-loop screen, console, e
1839 ¦ 10:num/raw <- get *e, cursor-row:offset
1840 ¦ 11:num/raw <- get *e, cursor-column:offset
1841 ]
1842
1843 memory-should-contain [
1844 ¦ 10 <- 1
1845 ¦ 11 <- 3
1846 ]
1847
1848 check-trace-count-for-label 0, [print-character]
1849
1850 assume-console [
1851 ¦ type [a]
1852 ]
1853 run [
1854 ¦ editor-event-loop screen, console, e
1855 ]
1856 screen-should-contain [
1857 ¦ . .
1858 ¦ .123a↩ .
1859 ¦ .456 .
1860 ¦ .789 .
1861 ¦ .╌╌╌╌╌ .
1862 ]
1863 ]
1864
1865
1866
1867 scenario editor-deletes-to-start-of-line-with-ctrl-u [
1868 local-scope
1869 assume-screen 10/width, 5/height
1870 s:text <- new [123
1871 456]
1872 e:&:editor <- new-editor s, 0/left, 10/right
1873 editor-render screen, e
1874 $clear-trace
1875
1876 assume-console [
1877 ¦ left-click 2, 2
1878 ¦ press ctrl-u
1879 ]
1880 run [
1881 ¦ editor-event-loop screen, console, e
1882 ]
1883
1884 screen-should-contain [
1885 ¦ . .
1886 ¦ .123 .
1887 ¦ .6 .
1888 ¦ .╌╌╌╌╌╌╌╌╌╌.
1889 ¦ . .
1890 ]
1891 check-trace-count-for-label 10, [print-character]
1892 ]
1893
1894 after <handle-special-character> [
1895 {
1896 ¦ delete-to-start-of-line?:bool <- equal c, 21/ctrl-u
1897 ¦ break-unless delete-to-start-of-line?
1898 ¦ <delete-to-start-of-line-begin>
1899 ¦ deleted-cells:&:duplex-list:char <- delete-to-start-of-line editor
1900 ¦ <delete-to-start-of-line-end>
1901 ¦ go-render?:bool <- minimal-render-for-ctrl-u screen, editor, deleted-cells
1902 ¦ return
1903 }
1904 ]
1905
1906 def minimal-render-for-ctrl-u screen:&:screen, editor:&:editor, deleted-cells:&:duplex-list:char -> go-render?:bool, screen:&:screen [
1907 local-scope
1908 load-ingredients
1909 curr-column:num <- get *editor, cursor-column:offset
1910
1911 buf:&:buffer:char <- new-buffer 30
1912 curr:&:duplex-list:char <- get *editor, before-cursor:offset
1913 i:num <- copy curr-column
1914 right:num <- get *editor, right:offset
1915 {
1916 ¦
1917 ¦ wrap?:bool <- greater-or-equal i, right
1918 ¦ return-if wrap?, 1/go-render
1919 ¦ curr <- next curr
1920 ¦ break-unless curr
1921 ¦ c:char <- get *curr, value:offset
1922 ¦ b:bool <- equal c, 10
1923 ¦ break-if b
1924 ¦ buf <- append buf, c
1925 ¦ i <- add i, 1
1926 ¦ loop
1927 }
1928
1929 num-deleted-cells:num <- length deleted-cells
1930 old-row-len:num <- add i, num-deleted-cells
1931 left:num <- get *editor, left:offset
1932 end:num <- subtract right, left
1933 wrap?:bool <- greater-or-equal old-row-len, end
1934 return-if wrap?, 1/go-render
1935 curr-line:text <- buffer-to-array buf
1936 curr-row:num <- get *editor, cursor-row:offset
1937 render-code screen, curr-line, curr-column, right, curr-row
1938 return 0/dont-render
1939 ]
1940
1941 def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
1942 local-scope
1943 load-ingredients
1944
1945 init:&:duplex-list:char <- get *editor, data:offset
1946 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
1947 update-top-of-screen?:bool <- copy 0/false
1948 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
1949 start:&:duplex-list:char <- copy before-cursor
1950 end:&:duplex-list:char <- next before-cursor
1951 {
1952 ¦ at-start-of-text?:bool <- equal start, init
1953 ¦ break-if at-start-of-text?
1954 ¦ curr:char <- get *start, value:offset
1955 ¦ at-start-of-line?:bool <- equal curr, 10/newline
1956 ¦ break-if at-start-of-line?
1957 ¦
1958 ¦ at-top-of-screen?:bool <- equal start, top-of-screen
1959 ¦ update-top-of-screen?:bool <- or update-top-of-screen?, at-top-of-screen?
1960 ¦ start <- prev start
1961 ¦ assert start, [delete-to-start-of-line tried to move before start of text]
1962 ¦ loop
1963 }
1964
1965 result:&:duplex-list:char <- next start
1966 remove-between start, end
1967
1968 {
1969 ¦ break-unless update-top-of-screen?
1970 ¦ put *editor, top-of-screen:offset, start
1971 }
1972
1973 before-cursor <- copy start
1974 *editor <- put *editor, before-cursor:offset, before-cursor
1975 left:num <- get *editor, left:offset
1976 *editor <- put *editor, cursor-column:offset, left
1977
1978 right:num <- get *editor, right:offset
1979 width:num <- subtract right, left
1980 num-deleted:num <- length result
1981 cursor-row-adjustment:num <- divide-with-remainder num-deleted, width
1982 return-unless cursor-row-adjustment
1983 cursor-row:num <- get *editor, cursor-row:offset
1984 cursor-row-in-editor:num <- subtract cursor-row, 1
1985 at-top?:bool <- lesser-or-equal cursor-row-in-editor, cursor-row-adjustment
1986 {
1987 ¦ break-unless at-top?
1988 ¦ cursor-row <- copy 1
1989 }
1990 {
1991 ¦ break-if at-top?
1992 ¦ cursor-row <- subtract cursor-row, cursor-row-adjustment
1993 }
1994 put *editor, cursor-row:offset, cursor-row
1995 ]
1996
1997 def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num, screen:&:screen [
1998 local-scope
1999 load-ingredients
2000 return-unless s
2001 color:num <- copy 7/white
2002 column:num <- copy left
2003 screen <- move-cursor screen, row, column
2004 screen-height:num <- screen-height screen
2005 i:num <- copy 0
2006 len:num <- length *s
2007 {
2008 ¦ +next-character
2009 ¦ done?:bool <- greater-or-equal i, len
2010 ¦ break-if done?
2011 ¦ done? <- greater-or-equal row, screen-height
2012 ¦ break-if done?
2013 ¦ c:char <- index *s, i
2014 ¦ <character-c-received>
2015 ¦ {
2016 ¦ ¦
2017 ¦ ¦ newline?:bool <- equal c, 10/newline
2018 ¦ ¦ break-unless newline?
2019 ¦ ¦
2020 ¦ ¦ {
2021 ¦ ¦ ¦ done?:bool <- greater-than column, right
2022 ¦ ¦ ¦ break-if done?
2023 ¦ ¦ ¦ space:char <- copy 32/space
2024 ¦ ¦ ¦ print screen, space
2025 ¦ ¦ ¦ column <- add column, 1
2026 ¦ ¦ ¦ loop
2027 ¦ ¦ }
2028 ¦ ¦ row <- add row, 1
2029 ¦ ¦ column <- copy left
2030 ¦ ¦ screen <- move-cursor screen, row, column
2031 ¦ ¦ i <- add i, 1
2032 ¦ ¦ loop +next-character
2033 ¦ }
2034 ¦ {
2035 ¦ ¦
2036 ¦ ¦ at-right?:bool <- equal column, right
2037 ¦ ¦ break-unless at-right?
2038 ¦ ¦
2039 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left
2040 ¦ ¦ print screen, wrap-icon, 245/grey
2041 ¦ ¦ column <- copy left
2042 ¦ ¦ row <- add row, 1
2043 ¦ ¦ screen <- move-cursor screen, row, column
2044 ¦ ¦
2045 ¦ ¦ loop +next-character
2046 ¦ }
2047 ¦ i <- add i, 1
2048 ¦ print screen, c, color
2049 ¦ column <- add column, 1
2050 ¦ loop
2051 }
2052 was-at-left?:bool <- equal column, left
2053 clear-line-until screen, right
2054 {
2055 ¦ break-if was-at-left?
2056 ¦ row <- add row, 1
2057 }
2058 move-cursor screen, row, left
2059 ]
2060
2061 scenario editor-deletes-to-start-of-line-with-ctrl-u-2 [
2062 local-scope
2063 assume-screen 10/width, 5/height
2064 s:text <- new [123
2065 456]
2066 e:&:editor <- new-editor s, 0/left, 10/right
2067 editor-render screen, e
2068 $clear-trace
2069
2070 assume-console [
2071 ¦ left-click 1, 2
2072 ¦ press ctrl-u
2073 ]
2074 run [
2075 ¦ editor-event-loop screen, console, e
2076 ]
2077
2078 screen-should-contain [
2079 ¦ . .
2080 ¦ .3 .
2081 ¦ .456 .
2082 ¦ .╌╌╌╌╌╌╌╌╌╌.
2083 ¦ . .
2084 ]
2085 check-trace-count-for-label 10, [print-character]
2086 ]
2087
2088 scenario editor-deletes-to-start-of-line-with-ctrl-u-3 [
2089 local-scope
2090 assume-screen 10/width, 5/height
2091 s:text <- new [123
2092 456]
2093 e:&:editor <- new-editor s, 0/left, 10/right
2094 editor-render screen, e
2095 $clear-trace
2096
2097 assume-console [
2098 ¦ left-click 1, 3
2099 ¦ press ctrl-u
2100 ]
2101 run [
2102 ¦ editor-event-loop screen, console, e
2103 ]
2104
2105 screen-should-contain [
2106 ¦ . .
2107 ¦ . .
2108 ¦ .456 .
2109 ¦ .╌╌╌╌╌╌╌╌╌╌.
2110 ¦ . .
2111 ]
2112 check-trace-count-for-label 10, [print-character]
2113 ]
2114
2115 scenario editor-deletes-to-start-of-final-line-with-ctrl-u [
2116 local-scope
2117 assume-screen 10/width, 5/height
2118 s:text <- new [123
2119 456]
2120 e:&:editor <- new-editor s, 0/left, 10/right
2121 editor-render screen, e
2122 $clear-trace
2123
2124 assume-console [
2125 ¦ left-click 2, 3
2126 ¦ press ctrl-u
2127 ]
2128 run [
2129 ¦ editor-event-loop screen, console, e
2130 ]
2131
2132 screen-should-contain [
2133 ¦ . .
2134 ¦ .123 .
2135 ¦ . .
2136 ¦ .╌╌╌╌╌╌╌╌╌╌.
2137 ¦ . .
2138 ]
2139 check-trace-count-for-label 10, [print-character]
2140 ]
2141
2142 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u [
2143 local-scope
2144 assume-screen 10/width, 10/height
2145
2146 s:text <- new [123456
2147 789]
2148 e:&:editor <- new-editor s, 0/left, 5/right
2149 editor-render screen, e
2150 screen-should-contain [
2151 ¦ . .
2152 ¦ .1234↩ .
2153 ¦ .56 .
2154 ¦ .789 .
2155 ¦ .╌╌╌╌╌ .
2156 ¦ . .
2157 ]
2158 $clear-trace
2159
2160 assume-console [
2161 ¦ left-click 1, 3
2162 ¦ press ctrl-u
2163 ]
2164 run [
2165 ¦ editor-event-loop screen, console, e
2166 ]
2167
2168 screen-should-contain [
2169 ¦ . .
2170 ¦ .456 .
2171 ¦ .789 .
2172 ¦ .╌╌╌╌╌ .
2173 ¦ . .
2174 ]
2175 check-trace-count-for-label 45, [print-character]
2176 ]
2177
2178
2179 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-2 [
2180 local-scope
2181 assume-screen 10/width, 10/height
2182
2183 s:text <- new [1
2184 2
2185 345678
2186 9]
2187 e:&:editor <- new-editor s, 0/left, 5/right
2188 editor-render screen, e
2189 screen-should-contain [
2190 ¦ . .
2191 ¦ .1 .
2192 ¦ .2 .
2193 ¦ .3456↩ .
2194 ¦ .78 .
2195 ¦ .9 .
2196 ¦ .╌╌╌╌╌ .
2197 ¦ . .
2198 ]
2199
2200 assume-console [
2201 ¦ left-click 4, 1
2202 ¦ press ctrl-u
2203 ]
2204 run [
2205 ¦ editor-event-loop screen, console, e
2206 ¦ 10:num/raw <- get *e, cursor-row:offset
2207 ¦ 11:num/raw <- get *e, cursor-column:offset
2208 ]
2209 screen-should-contain [
2210 ¦ . .
2211 ¦ .1 .
2212 ¦ .2 .
2213 ¦ .8 .
2214 ¦ .9 .
2215 ¦ .╌╌╌╌╌ .
2216 ¦ . .
2217 ]
2218
2219 memory-should-contain [
2220 ¦ 10 <- 3
2221 ¦ 11 <- 0
2222 ]
2223 ]
2224
2225
2226 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-3 [
2227 local-scope
2228 assume-screen 10/width, 10/height
2229
2230 s:text <- new [1
2231 2
2232 3456789abcd
2233 e]
2234 e:&:editor <- new-editor s, 0/left, 5/right
2235 editor-render screen, e
2236 assume-console [
2237 ¦ left-click 4, 1
2238 ]
2239 editor-event-loop screen, console, e
2240 screen-should-contain [
2241 ¦ . .
2242 ¦ .1 .
2243 ¦ .2 .
2244 ¦ .3456↩ .
2245 ¦ .789a↩ .
2246 ¦ .bcd .
2247 ¦ .e .
2248 ¦ .╌╌╌╌╌ .
2249 ¦ . .
2250 ]
2251 assume-console [
2252 ¦ left-click 5, 1
2253 ¦ press ctrl-u
2254 ]
2255 run [
2256 ¦ editor-event-loop screen, console, e
2257 ¦ 10:num/raw <- get *e, cursor-row:offset
2258 ¦ 11:num/raw <- get *e, cursor-column:offset
2259 ]
2260 screen-should-contain [
2261 ¦ . .
2262 ¦ .1 .
2263 ¦ .2 .
2264 ¦ .cd .
2265 ¦ .e .
2266 ¦ .╌╌╌╌╌ .
2267 ¦ . .
2268 ]
2269
2270 memory-should-contain [
2271 ¦ 10 <- 3
2272 ¦ 11 <- 0
2273 ]
2274 ]
2275
2276
2277 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-4 [
2278 local-scope
2279 assume-screen 10/width, 10/height
2280
2281 s:text <- new [1234567
2282 89]
2283 e:&:editor <- new-editor s, 0/left, 5/right
2284 editor-render screen, e
2285 screen-should-contain [
2286 ¦ . .
2287 ¦ .1234↩ .
2288 ¦ .567 .
2289 ¦ .89 .
2290 ¦ .╌╌╌╌╌ .
2291 ¦ . .
2292 ]
2293
2294 assume-console [
2295 ¦ left-click 2, 1
2296 ¦ press ctrl-u
2297 ]
2298 run [
2299 ¦ editor-event-loop screen, console, e
2300 ¦ 10:num/raw <- get *e, cursor-row:offset
2301 ¦ 11:num/raw <- get *e, cursor-column:offset
2302 ]
2303 screen-should-contain [
2304 ¦ . .
2305 ¦ .67 .
2306 ¦ .89 .
2307 ¦ .╌╌╌╌╌ .
2308 ¦ . .
2309 ]
2310
2311 memory-should-contain [
2312 ¦ 10 <- 1
2313 ¦ 11 <- 0
2314 ]
2315 ]
2316
2317
2318 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-5 [
2319 local-scope
2320 assume-screen 10/width, 10/height
2321
2322 s:text <- new [1
2323 2
2324 345678
2325 9]
2326 e:&:editor <- new-editor s, 0/left, 5/right
2327 editor-render screen, e
2328
2329 assume-console [
2330 ¦ left-click 4, 1
2331 ¦ press ctrl-t
2332 ]
2333 editor-event-loop screen, console, e
2334 screen-should-contain [
2335 ¦ . .
2336 ¦ .78 .
2337 ¦ .9 .
2338 ¦ .╌╌╌╌╌ .
2339 ¦ . .
2340 ]
2341 assume-console [
2342 ¦ left-click 1, 1
2343 ¦ press ctrl-u
2344 ]
2345 run [
2346 ¦ editor-event-loop screen, console, e
2347 ¦ 10:num/raw <- get *e, cursor-row:offset
2348 ¦ 11:num/raw <- get *e, cursor-column:offset
2349 ]
2350
2351 screen-should-contain [
2352 ¦ . .
2353 ¦ .8 .
2354 ¦ .9 .
2355 ¦ .╌╌╌╌╌ .
2356 ¦ . .
2357 ]
2358 memory-should-contain [
2359 ¦ 10 <- 1
2360 ¦ 11 <- 0
2361 ]
2362
2363 assume-console [
2364 ¦ press up-arrow
2365 ]
2366 run [
2367 ¦ editor-event-loop screen, console, e
2368 ]
2369 screen-should-contain [
2370 ¦ . .
2371 ¦ .2 .
2372 ¦ .8 .
2373 ¦ .9 .
2374 ¦ .╌╌╌╌╌ .
2375 ¦ . .
2376 ]
2377 ]
2378
2379
2380 scenario editor-deletes-to-start-of-wrapped-line-with-ctrl-u-6 [
2381 local-scope
2382 assume-screen 10/width, 10/height
2383
2384 s:text <- new [1
2385 2
2386 3456789abcd
2387 e]
2388 e:&:editor <- new-editor s, 0/left, 5/right
2389 editor-render screen, e
2390
2391 assume-console [
2392 ¦ left-click 4, 1
2393 ¦ press ctrl-t
2394 ¦ press ctrl-s
2395 ]
2396 editor-event-loop screen, console, e
2397 screen-should-contain [
2398 ¦ . .
2399 ¦ .bcd .
2400 ¦ .e .
2401 ¦ .╌╌╌╌╌ .
2402 ¦ . .
2403 ]
2404 assume-console [
2405 ¦ left-click 1, 1
2406 ¦ press ctrl-u
2407 ]
2408 run [
2409 ¦ editor-event-loop screen, console, e
2410 ¦ 10:num/raw <- get *e, cursor-row:offset
2411 ¦ 11:num/raw <- get *e, cursor-column:offset
2412 ]
2413
2414 screen-should-contain [
2415 ¦ . .
2416 ¦ .cd .
2417 ¦ .e .
2418 ¦ .╌╌╌╌╌ .
2419 ¦ . .
2420 ]
2421 memory-should-contain [
2422 ¦ 10 <- 1
2423 ¦ 11 <- 0
2424 ]
2425
2426 assume-console [
2427 ¦ press up-arrow
2428 ]
2429 run [
2430 ¦ editor-event-loop screen, console, e
2431 ]
2432 screen-should-contain [
2433 ¦ . .
2434 ¦ .2 .
2435 ¦ .cd .
2436 ¦ .e .
2437 ¦ .╌╌╌╌╌ .
2438 ¦ . .
2439 ]
2440 ]
2441
2442
2443
2444 scenario editor-deletes-to-end-of-line-with-ctrl-k [
2445 local-scope
2446 assume-screen 10/width, 5/height
2447 s:text <- new [123
2448 456]
2449 e:&:editor <- new-editor s, 0/left, 10/right
2450 editor-render screen, e
2451 $clear-trace
2452
2453 assume-console [
2454 ¦ left-click 1, 1
2455 ¦ press ctrl-k
2456 ]
2457 run [
2458 ¦ editor-event-loop screen, console, e
2459 ]
2460
2461 screen-should-contain [
2462 ¦ . .
2463 ¦ .1 .
2464 ¦ .456 .
2465 ¦ .╌╌╌╌╌╌╌╌╌╌.
2466 ¦ . .
2467 ]
2468 check-trace-count-for-label 9, [print-character]
2469 ]
2470
2471 after <handle-special-character> [
2472 {
2473 ¦ delete-to-end-of-line?:bool <- equal c, 11/ctrl-k
2474 ¦ break-unless delete-to-end-of-line?
2475 ¦ <delete-to-end-of-line-begin>
2476 ¦ deleted-cells:&:duplex-list:char <- delete-to-end-of-line editor
2477 ¦ <delete-to-end-of-line-end>
2478 ¦
2479 ¦ go-render?:bool <- minimal-render-for-ctrl-k screen, editor, deleted-cells
2480 ¦ return
2481 }
2482 ]
2483
2484 def minimal-render-for-ctrl-k screen:&:screen, editor:&:editor, deleted-cells:&:duplex-list:char -> go-render?:bool, screen:&:screen [
2485 local-scope
2486 load-ingredients
2487
2488 return-unless deleted-cells, 0/dont-render
2489
2490 curr-column:num <- get *editor, cursor-column:offset
2491 num-deleted-cells:num <- length deleted-cells
2492 old-row-len:num <- add curr-column, num-deleted-cells
2493 left:num <- get *editor, left:offset
2494 right:num <- get *editor, right:offset
2495 end:num <- subtract right, left
2496 wrap?:bool <- greater-or-equal old-row-len, end
2497 return-if wrap?, 1/go-render
2498 clear-line-until screen, right
2499 return 0/dont-render
2500 ]
2501
2502 def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
2503 local-scope
2504 load-ingredients
2505
2506 start:&:duplex-list:char <- get *editor, before-cursor:offset
2507 end:&:duplex-list:char <- next start
2508 {
2509 ¦ at-end-of-text?:bool <- equal end, 0/null
2510 ¦ break-if at-end-of-text?
2511 ¦ curr:char <- get *end, value:offset
2512 ¦ at-end-of-line?:bool <- equal curr, 10/newline
2513 ¦ break-if at-end-of-line?
2514 ¦ end <- next end
2515 ¦ loop
2516 }
2517
2518 result <- next start
2519 remove-between start, end
2520 ]
2521
2522 scenario editor-deletes-to-end-of-line-with-ctrl-k-2 [
2523 local-scope
2524 assume-screen 10/width, 5/height
2525 s:text <- new [123
2526 456]
2527 e:&:editor <- new-editor s, 0/left, 10/right
2528 editor-render screen, e
2529 $clear-trace
2530
2531 assume-console [
2532 ¦ left-click 2, 1
2533 ¦ press ctrl-k
2534 ]
2535 run [
2536 ¦ editor-event-loop screen, console, e
2537 ]
2538
2539 screen-should-contain [
2540 ¦ . .
2541 ¦ .123 .
2542 ¦ .4 .
2543 ¦ .╌╌╌╌╌╌╌╌╌╌.
2544 ¦ . .
2545 ]
2546 check-trace-count-for-label 9, [print-character]
2547 ]
2548
2549 scenario editor-deletes-to-end-of-line-with-ctrl-k-3 [
2550 local-scope
2551 assume-screen 10/width, 5/height
2552 s:text <- new [123
2553 456]
2554 e:&:editor <- new-editor s, 0/left, 10/right
2555 editor-render screen, e
2556 $clear-trace
2557
2558 assume-console [
2559 ¦ left-click 1, 2
2560 ¦ press ctrl-k
2561 ]
2562 run [
2563 ¦ editor-event-loop screen, console, e
2564 ]
2565
2566 screen-should-contain [
2567 ¦ . .
2568 ¦ .12 .
2569 ¦ .456 .
2570 ¦ .╌╌╌╌╌╌╌╌╌╌.
2571 ¦ . .
2572 ]
2573 check-trace-count-for-label 8, [print-character]
2574 ]
2575
2576 scenario editor-deletes-to-end-of-line-with-ctrl-k-4 [
2577 local-scope
2578 assume-screen 10/width, 5/height
2579 s:text <- new [123
2580 456]
2581 e:&:editor <- new-editor s, 0/left, 10/right
2582 editor-render screen, e
2583 $clear-trace
2584
2585 assume-console [
2586 ¦ left-click 1, 3
2587 ¦ press ctrl-k
2588 ]
2589 run [
2590 ¦ editor-event-loop screen, console, e
2591 ]
2592
2593 screen-should-contain [
2594 ¦ . .
2595 ¦ .123 .
2596 ¦ .456 .
2597 ¦ .╌╌╌╌╌╌╌╌╌╌.
2598 ¦ . .
2599 ]
2600 check-trace-count-for-label 7, [print-character]
2601 ]
2602
2603 scenario editor-deletes-to-end-of-line-with-ctrl-k-5 [
2604 local-scope
2605 assume-screen 10/width, 5/height
2606 s:text <- new [123
2607 456]
2608 e:&:editor <- new-editor s, 0/left, 10/right
2609 editor-render screen, e
2610 $clear-trace
2611
2612 assume-console [
2613 ¦ left-click 2, 2
2614 ¦ press ctrl-k
2615 ]
2616 run [
2617 ¦ editor-event-loop screen, console, e
2618 ]
2619
2620 screen-should-contain [
2621 ¦ . .
2622 ¦ .123 .
2623 ¦ .45 .
2624 ¦ .╌╌╌╌╌╌╌╌╌╌.
2625 ¦ . .
2626 ]
2627 check-trace-count-for-label 8, [print-character]
2628 ]
2629
2630 scenario editor-deletes-to-end-of-line-with-ctrl-k-6 [
2631 local-scope
2632 assume-screen 10/width, 5/height
2633 s:text <- new [123
2634 456]
2635 e:&:editor <- new-editor s, 0/left, 10/right
2636 editor-render screen, e
2637 $clear-trace
2638
2639 assume-console [
2640 ¦ left-click 2, 3
2641 ¦ press ctrl-k
2642 ]
2643 run [
2644 ¦ editor-event-loop screen, console, e
2645 ]
2646
2647 screen-should-contain [
2648 ¦ . .
2649 ¦ .123 .
2650 ¦ .456 .
2651 ¦ .╌╌╌╌╌╌╌╌╌╌.
2652 ¦ . .
2653 ]
2654
2655 check-trace-count-for-label 0, [print-character]
2656 ]
2657
2658 scenario editor-deletes-to-end-of-wrapped-line-with-ctrl-k [
2659 local-scope
2660 assume-screen 10/width, 5/height
2661
2662 s:text <- new [1234
2663 567]
2664 e:&:editor <- new-editor s, 0/left, 4/right
2665 editor-render screen, e
2666 $clear-trace
2667
2668 assume-console [
2669 ¦ press ctrl-k
2670 ]
2671 run [
2672 ¦ editor-event-loop screen, console, e
2673 ]
2674
2675 screen-should-contain [
2676 ¦ . .
2677 ¦ . .
2678 ¦ .567 .
2679 ¦ .╌╌╌╌ .
2680 ¦ . .
2681 ]
2682
2683 check-trace-count-for-label 16, [print-character]
2684 ]
2685
2686
2687
2688 scenario editor-can-scroll-down-using-arrow-keys [
2689 local-scope
2690
2691 assume-screen 10/width, 4/height
2692
2693 s:text <- new [a
2694 b
2695 c
2696 d]
2697 e:&:editor <- new-editor s, 0/left, 10/right
2698 editor-render screen, e
2699 screen-should-contain [
2700 ¦ . .
2701 ¦ .a .
2702 ¦ .b .
2703 ¦ .c .
2704 ]
2705
2706 assume-console [
2707 ¦ left-click 3, 0
2708 ¦ press down-arrow
2709 ]
2710 run [
2711 ¦ editor-event-loop screen, console, e
2712 ]
2713
2714 screen-should-contain [
2715 ¦ . .
2716 ¦ .b .
2717 ¦ .c .
2718 ¦ .d .
2719 ]
2720 ]
2721
2722 after <scroll-down> [
2723 trace 10, [app], [scroll down]
2724 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
2725 left:num <- get *editor, left:offset
2726 right:num <- get *editor, right:offset
2727 max:num <- subtract right, left
2728 old-top:&:duplex-list:char <- copy top-of-screen
2729 top-of-screen <- before-start-of-next-line top-of-screen, max
2730 *editor <- put *editor, top-of-screen:offset, top-of-screen
2731 no-movement?:bool <- equal old-top, top-of-screen
2732 return-if no-movement?, 0/don't-render
2733 ]
2734
2735
2736
2737
2738
2739 def before-start-of-next-line original:&:duplex-list:char, max:num -> curr:&:duplex-list:char [
2740 local-scope
2741 load-ingredients
2742 count:num <- copy 0
2743 curr:&:duplex-list:char <- copy original
2744
2745 {
2746 ¦ c:char <- get *curr, value:offset
2747 ¦ at-newline?:bool <- equal c, 10/newline
2748 ¦ break-unless at-newline?
2749 ¦ curr <- next curr
2750 ¦ count <- add count, 1
2751 }
2752 {
2753 ¦ return-unless curr, original
2754 ¦ done?:bool <- greater-or-equal count, max
2755 ¦ break-if done?
2756 ¦ c:char <- get *curr, value:offset
2757 ¦ at-newline?:bool <- equal c, 10/newline
2758 ¦ break-if at-newline?
2759 ¦ curr <- next curr
2760 ¦ count <- add count, 1
2761 ¦ loop
2762 }
2763 return-unless curr, original
2764 return curr
2765 ]
2766
2767 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys [
2768 local-scope
2769
2770 assume-screen 10/width, 4/height
2771
2772
2773 s:text <- new [abcdef
2774 g
2775 h
2776 i]
2777 e:&:editor <- new-editor s, 0/left, 5/right
2778 editor-render screen, e
2779 screen-should-contain [
2780 ¦ . .
2781 ¦ .abcd↩ .
2782 ¦ .ef .
2783 ¦ .g .
2784 ]
2785
2786 assume-console [
2787 ¦ left-click 3, 0
2788 ¦ press down-arrow
2789 ]
2790 run [
2791 ¦ editor-event-loop screen, console, e
2792 ]
2793
2794 screen-should-contain [
2795 ¦ . .
2796 ¦ .ef .
2797 ¦ .g .
2798 ¦ .h .
2799 ]
2800 ]
2801
2802 scenario editor-scrolls-down-past-wrapped-line-using-arrow-keys-2 [
2803 local-scope
2804
2805 assume-screen 10/width, 4/height
2806
2807 s:text <- new [abcdefghij
2808 k
2809 l
2810 m]
2811 e:&:editor <- new-editor s, 0/left, 5/right
2812
2813 assume-console [
2814 ¦ left-click 3, 0
2815 ¦ press down-arrow
2816 ]
2817 run [
2818 ¦ editor-event-loop screen, console, e
2819 ]
2820
2821 screen-should-contain [
2822 ¦ . .
2823 ¦ .efgh↩ .
2824 ¦ .ij .
2825 ¦ .k .
2826 ]
2827
2828 assume-console [
2829 ¦ press down-arrow
2830 ]
2831 run [
2832 ¦ editor-event-loop screen, console, e
2833 ]
2834
2835 screen-should-contain [
2836 ¦ . .
2837 ¦ .ij .
2838 ¦ .k .
2839 ¦ .l .
2840 ]
2841 ]
2842
2843 scenario editor-scrolls-down-when-line-wraps [
2844 local-scope
2845
2846 assume-screen 5/width, 4/height
2847
2848 s:text <- new [a
2849 b
2850 cdef]
2851 e:&:editor <- new-editor s, 0/left, 5/right
2852
2853 assume-console [
2854 ¦ left-click 3, 4
2855 ¦ type [g]
2856 ]
2857 run [
2858 ¦ editor-event-loop screen, console, e
2859 ¦ 3:num/raw <- get *e, cursor-row:offset
2860 ¦ 4:num/raw <- get *e, cursor-column:offset
2861 ]
2862
2863 screen-should-contain [
2864 ¦ . .
2865 ¦ .b .
2866 ¦ .cdef↩.
2867 ¦ .g .
2868 ]
2869 memory-should-contain [
2870 ¦ 3 <- 3
2871 ¦ 4 <- 1
2872 ]
2873 ]
2874
2875 scenario editor-scrolls-down-on-newline [
2876 local-scope
2877 assume-screen 5/width, 4/height
2878
2879 s:text <- new [a
2880 b
2881 c]
2882 e:&:editor <- new-editor s, 0/left, 5/right
2883 assume-console [
2884 ¦ left-click 3, 4
2885 ¦ type [
2886 ]
2887 ]
2888 run [
2889 ¦ editor-event-loop screen, console, e
2890 ¦ 3:num/raw <- get *e, cursor-row:offset
2891 ¦ 4:num/raw <- get *e, cursor-column:offset
2892 ]
2893
2894 screen-should-contain [
2895 ¦ . .
2896 ¦ .b .
2897 ¦ .c .
2898 ¦ . .
2899 ]
2900 memory-should-contain [
2901 ¦ 3 <- 3
2902 ¦ 4 <- 0
2903 ]
2904 ]
2905
2906 scenario editor-scrolls-down-on-right-arrow [
2907 local-scope
2908
2909 assume-screen 5/width, 4/height
2910
2911 s:text <- new [a
2912 b
2913 cdefgh]
2914 e:&:editor <- new-editor s, 0/left, 5/right
2915
2916 assume-console [
2917 ¦ left-click 3, 3
2918 ¦ press right-arrow
2919 ]
2920 run [
2921 ¦ editor-event-loop screen, console, e
2922 ¦ 3:num/raw <- get *e, cursor-row:offset
2923 ¦ 4:num/raw <- get *e, cursor-column:offset
2924 ]
2925
2926 screen-should-contain [
2927 ¦ . .
2928 ¦ .b .
2929 ¦ .cdef↩.
2930 ¦ .gh .
2931 ]
2932 memory-should-contain [
2933 ¦ 3 <- 3
2934 ¦ 4 <- 0
2935 ]
2936 ]
2937
2938 scenario editor-scrolls-down-on-right-arrow-2 [
2939 local-scope
2940
2941 assume-screen 5/width, 4/height
2942
2943 s:text <- new [a
2944 b
2945 c
2946 d]
2947 e:&:editor <- new-editor s, 0/left, 5/right
2948
2949 assume-console [
2950 ¦ left-click 3, 3
2951 ¦ press right-arrow
2952 ]
2953 run [
2954 ¦ editor-event-loop screen, console, e
2955 ¦ 3:num/raw <- get *e, cursor-row:offset
2956 ¦ 4:num/raw <- get *e, cursor-column:offset
2957 ]
2958
2959 screen-should-contain [
2960 ¦ . .
2961 ¦ .b .
2962 ¦ .c .
2963 ¦ .d .
2964 ]
2965 memory-should-contain [
2966 ¦ 3 <- 3
2967 ¦ 4 <- 0
2968 ]
2969 ]
2970
2971 scenario editor-scrolls-at-end-on-down-arrow [
2972 local-scope
2973 assume-screen 10/width, 5/height
2974 s:text <- new [abc
2975 de]
2976 e:&:editor <- new-editor s, 0/left, 10/right
2977 editor-render screen, e
2978 $clear-trace
2979
2980 assume-console [
2981 ¦ left-click 2, 0
2982 ¦ press down-arrow
2983 ]
2984 run [
2985 ¦ editor-event-loop screen, console, e
2986 ¦ 3:num/raw <- get *e, cursor-row:offset
2987 ¦ 4:num/raw <- get *e, cursor-column:offset
2988 ]
2989
2990 memory-should-contain [
2991 ¦ 3 <- 1
2992 ¦ 4 <- 2
2993 ]
2994 assume-console [
2995 ¦ type [0]
2996 ]
2997 run [
2998 ¦ editor-event-loop screen, console, e
2999 ]
3000 screen-should-contain [
3001 ¦ . .
3002 ¦ .de0 .
3003 ¦ .╌╌╌╌╌╌╌╌╌╌.
3004 ¦ . .
3005 ]
3006
3007 $clear-trace
3008 assume-console [
3009 ¦ left-click 2, 0
3010 ¦ press down-arrow
3011 ]
3012 run [
3013 ¦ editor-event-loop screen, console, e
3014 ¦ 3:num/raw <- get *e, cursor-row:offset
3015 ¦ 4:num/raw <- get *e, cursor-column:offset
3016 ]
3017
3018 memory-should-contain [
3019 ¦ 3 <- 1
3020 ¦ 4 <- 3
3021 ]
3022 check-trace-count-for-label 0, [print-character]
3023 assume-console [
3024 ¦ type [1]
3025 ]
3026 run [
3027 ¦ editor-event-loop screen, console, e
3028 ]
3029 screen-should-contain [
3030 ¦ . .
3031 ¦ .de01 .
3032 ¦ .╌╌╌╌╌╌╌╌╌╌.
3033 ¦ . .
3034 ]
3035 ]
3036
3037 scenario editor-combines-page-and-line-scroll [
3038 local-scope
3039
3040 assume-screen 10/width, 4/height
3041
3042 s:text <- new [a
3043 b
3044 c
3045 d
3046 e
3047 f
3048 g]
3049 e:&:editor <- new-editor s, 0/left, 5/right
3050 editor-render screen, e
3051
3052 assume-console [
3053 ¦ press page-down
3054 ¦ left-click 3, 0
3055 ¦ press down-arrow
3056 ]
3057 run [
3058 ¦ editor-event-loop screen, console, e
3059 ]
3060
3061 screen-should-contain [
3062 ¦ . .
3063 ¦ .d .
3064 ¦ .e .
3065 ¦ .f .
3066 ]
3067 ]
3068
3069
3070
3071 scenario editor-can-scroll-up-using-arrow-keys [
3072 local-scope
3073
3074 assume-screen 10/width, 4/height
3075
3076 s:text <- new [a
3077 b
3078 c
3079 d]
3080 e:&:editor <- new-editor s, 0/left, 10/right
3081 editor-render screen, e
3082 screen-should-contain [
3083 ¦ . .
3084 ¦ .a .
3085 ¦ .b .
3086 ¦ .c .
3087 ]
3088
3089 assume-console [
3090 ¦ press page-down
3091 ¦ press up-arrow
3092 ]
3093 run [
3094 ¦ editor-event-loop screen, console, e
3095 ]
3096
3097 screen-should-contain [
3098 ¦ . .
3099 ¦ .b .
3100 ¦ .c .
3101 ¦ .d .
3102 ]
3103 ]
3104
3105 after <scroll-up> [
3106 trace 10, [app], [scroll up]
3107 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3108 old-top:&:duplex-list:char <- copy top-of-screen
3109 top-of-screen <- before-previous-screen-line top-of-screen, editor
3110 *editor <- put *editor, top-of-screen:offset, top-of-screen
3111 no-movement?:bool <- equal old-top, top-of-screen
3112 return-if no-movement?, 0/don't-render
3113 ]
3114
3115
3116
3117
3118
3119 def before-previous-screen-line in:&:duplex-list:char, editor:&:editor -> out:&:duplex-list:char [
3120 local-scope
3121 load-ingredients
3122 curr:&:duplex-list:char <- copy in
3123 c:char <- get *curr, value:offset
3124
3125
3126
3127 left:num <- get *editor, left:offset
3128 right:num <- get *editor, right:offset
3129 max-line-length:num <- subtract right, left, -1/exclusive-right, 1/wrap-icon
3130 sentinel:&:duplex-list:char <- get *editor, data:offset
3131 len:num <- previous-line-length curr, sentinel
3132 {
3133 ¦ break-if len
3134 ¦
3135 ¦ prev:&:duplex-list:char <- prev curr
3136 ¦ return-unless prev, curr
3137 ¦ return prev
3138 }
3139 _, max:num <- divide-with-remainder len, max-line-length
3140
3141 {
3142 ¦ break-if max
3143 ¦ max <- copy max-line-length
3144 }
3145 max <- add max, 1
3146 count:num <- copy 0
3147
3148 {
3149 ¦ done?:bool <- greater-or-equal count, max
3150 ¦ break-if done?
3151 ¦ prev:&:duplex-list:char <- prev curr
3152 ¦ break-unless prev
3153 ¦ curr <- copy prev
3154 ¦ count <- add count, 1
3155 ¦ loop
3156 }
3157 return curr
3158 ]
3159
3160 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys [
3161 local-scope
3162
3163 assume-screen 10/width, 4/height
3164
3165
3166 s:text <- new [abcdef
3167 g
3168 h
3169 i]
3170 e:&:editor <- new-editor s, 0/left, 5/right
3171 editor-render screen, e
3172 screen-should-contain [
3173 ¦ . .
3174 ¦ .abcd↩ .
3175 ¦ .ef .
3176 ¦ .g .
3177 ]
3178
3179 assume-console [
3180 ¦ press page-down
3181 ]
3182 run [
3183 ¦ editor-event-loop screen, console, e
3184 ]
3185 screen-should-contain [
3186 ¦ . .
3187 ¦ .g .
3188 ¦ .h .
3189 ¦ .i .
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 ¦ .ef .
3202 ¦ .g .
3203 ¦ .h .
3204 ]
3205 ]
3206
3207 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-2 [
3208 local-scope
3209
3210 assume-screen 10/width, 5/height
3211
3212 s:text <- new [abcdefghij
3213 k
3214 l
3215 m]
3216 e:&:editor <- new-editor s, 0/left, 5/right
3217 editor-render screen, e
3218
3219 assume-console [
3220 ¦ press page-down
3221 ]
3222 run [
3223 ¦ editor-event-loop screen, console, e
3224 ]
3225 screen-should-contain [
3226 ¦ . .
3227 ¦ .k .
3228 ¦ .l .
3229 ¦ .m .
3230 ¦ .╌╌╌╌╌ .
3231 ]
3232
3233 assume-console [
3234 ¦ press up-arrow
3235 ]
3236 run [
3237 ¦ editor-event-loop screen, console, e
3238 ]
3239
3240 screen-should-contain [
3241 ¦ . .
3242 ¦ .ij .
3243 ¦ .k .
3244 ¦ .l .
3245 ¦ .m .
3246 ]
3247
3248 assume-console [
3249 ¦ press up-arrow
3250 ]
3251 run [
3252 ¦ editor-event-loop screen, console, e
3253 ]
3254
3255 screen-should-contain [
3256 ¦ . .
3257 ¦ .efgh↩ .
3258 ¦ .ij .
3259 ¦ .k .
3260 ¦ .l .
3261 ]
3262
3263 assume-console [
3264 ¦ press up-arrow
3265 ]
3266 run [
3267 ¦ editor-event-loop screen, console, e
3268 ]
3269
3270 screen-should-contain [
3271 ¦ . .
3272 ¦ .abcd↩ .
3273 ¦ .efgh↩ .
3274 ¦ .ij .
3275 ¦ .k .
3276 ]
3277 ]
3278
3279
3280
3281 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-3 [
3282 local-scope
3283
3284 assume-screen 10/width, 4/height
3285
3286
3287 s:text <- new [abcdef
3288 g
3289 h
3290 i]
3291 e:&:editor <- new-editor s, 0/left, 6/right
3292 editor-render screen, e
3293 screen-should-contain [
3294 ¦ . .
3295 ¦ .abcde↩ .
3296 ¦ .f .
3297 ¦ .g .
3298 ]
3299
3300 assume-console [
3301 ¦ press page-down
3302 ]
3303 run [
3304 ¦ editor-event-loop screen, console, e
3305 ]
3306 screen-should-contain [
3307 ¦ . .
3308 ¦ .g .
3309 ¦ .h .
3310 ¦ .i .
3311 ]
3312
3313 assume-console [
3314 ¦ press up-arrow
3315 ]
3316 run [
3317 ¦ editor-event-loop screen, console, e
3318 ]
3319
3320 screen-should-contain [
3321 ¦ . .
3322 ¦ .f .
3323 ¦ .g .
3324 ¦ .h .
3325 ]
3326 ]
3327
3328
3329 scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys-4 [
3330 local-scope
3331 assume-screen 10/width, 4/height
3332
3333 s:text <- new [a
3334 b
3335
3336 c
3337 d
3338 e]
3339 e:&:editor <- new-editor s, 0/left, 6/right
3340 editor-render screen, e
3341 assume-console [
3342 ¦ press page-down
3343 ]
3344 run [
3345 ¦ editor-event-loop screen, console, e
3346 ]
3347 screen-should-contain [
3348 ¦ . .
3349 ¦ . .
3350 ¦ .c .
3351 ¦ .d .
3352 ]
3353 assume-console [
3354 ¦ press page-down
3355 ]
3356 run [
3357 ¦ editor-event-loop screen, console, e
3358 ]
3359 screen-should-contain [
3360 ¦ . .
3361 ¦ .d .
3362 ¦ .e .
3363 ¦ .╌╌╌╌╌╌ .
3364 ]
3365 assume-console [
3366 ¦ press page-up
3367 ]
3368 run [
3369 ¦ editor-event-loop screen, console, e
3370 ]
3371 screen-should-contain [
3372 ¦ . .
3373 ¦ . .
3374 ¦ .c .
3375 ¦ .d .
3376 ]
3377 ]
3378
3379 scenario editor-scrolls-up-on-left-arrow [
3380 local-scope
3381
3382 assume-screen 5/width, 4/height
3383
3384 s:text <- new [a
3385 b
3386 c
3387 d
3388 e]
3389 e:&:editor <- new-editor s, 0/left, 5/right
3390 editor-render screen, e
3391
3392 assume-console [
3393 ¦ press page-down
3394 ]
3395 run [
3396 ¦ editor-event-loop screen, console, e
3397 ]
3398 screen-should-contain [
3399 ¦ . .
3400 ¦ .c .
3401 ¦ .d .
3402 ¦ .e .
3403 ]
3404
3405 assume-console [
3406 ¦ press left-arrow
3407 ]
3408 run [
3409 ¦ editor-event-loop screen, console, e
3410 ¦ 3:num/raw <- get *e, cursor-row:offset
3411 ¦ 4:num/raw <- get *e, cursor-column:offset
3412 ]
3413
3414 screen-should-contain [
3415 ¦ . .
3416 ¦ .b .
3417 ¦ .c .
3418 ¦ .d .
3419 ]
3420 memory-should-contain [
3421 ¦ 3 <- 1
3422 ¦ 4 <- 1
3423 ]
3424 ]
3425
3426 scenario editor-can-scroll-up-to-start-of-file [
3427 local-scope
3428
3429 assume-screen 10/width, 4/height
3430
3431 s:text <- new [a
3432 b
3433 c
3434 d]
3435 e:&:editor <- new-editor s, 0/left, 10/right
3436 editor-render screen, e
3437 screen-should-contain [
3438 ¦ . .
3439 ¦ .a .
3440 ¦ .b .
3441 ¦ .c .
3442 ]
3443
3444
3445 assume-console [
3446 ¦ press page-down
3447 ¦ press up-arrow
3448 ¦ press up-arrow
3449 ]
3450 run [
3451 ¦ editor-event-loop screen, console, e
3452 ]
3453
3454 screen-should-contain [
3455 ¦ . .
3456 ¦ .a .
3457 ¦ .b .
3458 ¦ .c .
3459 ]
3460
3461 assume-console [
3462 ¦ press up-arrow
3463 ]
3464 run [
3465 ¦ editor-event-loop screen, console, e
3466 ]
3467
3468 screen-should-contain [
3469 ¦ . .
3470 ¦ .a .
3471 ¦ .b .
3472 ¦ .c .
3473 ]
3474 ]
3475
3476
3477
3478 scenario editor-can-scroll [
3479 local-scope
3480 assume-screen 10/width, 4/height
3481 s:text <- new [a
3482 b
3483 c
3484 d]
3485 e:&:editor <- new-editor s, 0/left, 10/right
3486 editor-render screen, e
3487 screen-should-contain [
3488 ¦ . .
3489 ¦ .a .
3490 ¦ .b .
3491 ¦ .c .
3492 ]
3493
3494 assume-console [
3495 ¦ press page-down
3496 ]
3497 run [
3498 ¦ editor-event-loop screen, console, e
3499 ]
3500
3501 screen-should-contain [
3502 ¦ . .
3503 ¦ .c .
3504 ¦ .d .
3505 ¦ .╌╌╌╌╌╌╌╌╌╌.
3506 ]
3507 ]
3508
3509 after <handle-special-character> [
3510 {
3511 ¦ page-down?:bool <- equal c, 6/ctrl-f
3512 ¦ break-unless page-down?
3513 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3514 ¦ <move-cursor-begin>
3515 ¦ page-down editor
3516 ¦ undo-coalesce-tag:num <- copy 0/never
3517 ¦ <move-cursor-end>
3518 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3519 ¦ movement?:bool <- not-equal top-of-screen, old-top
3520 ¦ return movement?/go-render
3521 }
3522 ]
3523
3524 after <handle-special-key> [
3525 {
3526 ¦ page-down?:bool <- equal k, 65518/page-down
3527 ¦ break-unless page-down?
3528 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3529 ¦ <move-cursor-begin>
3530 ¦ page-down editor
3531 ¦ undo-coalesce-tag:num <- copy 0/never
3532 ¦ <move-cursor-end>
3533 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3534 ¦ movement?:bool <- not-equal top-of-screen, old-top
3535 ¦ return movement?/go-render
3536 }
3537 ]
3538
3539
3540
3541 def page-down editor:&:editor -> editor:&:editor [
3542 local-scope
3543 load-ingredients
3544
3545 bottom-of-screen:&:duplex-list:char <- get *editor, bottom-of-screen:offset
3546 return-unless bottom-of-screen
3547
3548 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
3549 before-cursor:&:duplex-list:char <- prev bottom-of-screen
3550 *editor <- put *editor, before-cursor:offset, before-cursor
3551
3552 {
3553 ¦ last:char <- get *before-cursor, value:offset
3554 ¦ newline?:bool <- equal last, 10/newline
3555 ¦ break-unless newline?:bool
3556 ¦ before-cursor <- prev before-cursor
3557 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
3558 }
3559
3560 move-to-start-of-line editor
3561 before-cursor <- get *editor, before-cursor:offset
3562 *editor <- put *editor, top-of-screen:offset, before-cursor
3563 ]
3564
3565
3566 def move-to-start-of-line editor:&:editor -> editor:&:editor [
3567 local-scope
3568 load-ingredients
3569
3570 left:num <- get *editor, left:offset
3571 cursor-column:num <- copy left
3572 *editor <- put *editor, cursor-column:offset, cursor-column
3573
3574 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
3575 init:&:duplex-list:char <- get *editor, data:offset
3576
3577 {
3578 ¦ at-start-of-text?:bool <- equal before-cursor, init
3579 ¦ break-if at-start-of-text?
3580 ¦ prev:char <- get *before-cursor, value:offset
3581 ¦ at-start-of-line?:bool <- equal prev, 10/newline
3582 ¦ break-if at-start-of-line?
3583 ¦ before-cursor <- prev before-cursor
3584 ¦ *editor <- put *editor, before-cursor:offset, before-cursor
3585 ¦ assert before-cursor, [move-to-start-of-line tried to move before start of text]
3586 ¦ loop
3587 }
3588 ]
3589
3590 scenario editor-does-not-scroll-past-end [
3591 local-scope
3592 assume-screen 10/width, 4/height
3593 s:text <- new [a
3594 b]
3595 e:&:editor <- new-editor s, 0/left, 10/right
3596 editor-render screen, e
3597 screen-should-contain [
3598 ¦ . .
3599 ¦ .a .
3600 ¦ .b .
3601 ¦ .╌╌╌╌╌╌╌╌╌╌.
3602 ]
3603
3604 assume-console [
3605 ¦ press page-down
3606 ]
3607 run [
3608 ¦ editor-event-loop screen, console, e
3609 ]
3610
3611 screen-should-contain [
3612 ¦ . .
3613 ¦ .a .
3614 ¦ .b .
3615 ¦ .╌╌╌╌╌╌╌╌╌╌.
3616 ]
3617 ]
3618
3619 scenario editor-starts-next-page-at-start-of-wrapped-line [
3620 local-scope
3621
3622 assume-screen 10/width, 4/height
3623
3624 s:text <- new [a
3625 b
3626 cdefgh]
3627
3628 e:&:editor <- new-editor s, 0/left, 4/right
3629 editor-render screen, e
3630
3631 screen-should-contain [
3632 ¦ . .
3633 ¦ .a .
3634 ¦ .b .
3635 ¦ .cde↩ .
3636 ]
3637
3638 assume-console [
3639 ¦ press page-down
3640 ]
3641 run [
3642 ¦ editor-event-loop screen, console, e
3643 ]
3644
3645 screen-should-contain [
3646 ¦ . .
3647 ¦ .cde↩ .
3648 ¦ .fgh .
3649 ¦ .╌╌╌╌ .
3650 ]
3651 ]
3652
3653 scenario editor-starts-next-page-at-start-of-wrapped-line-2 [
3654 local-scope
3655
3656 assume-screen 10/width, 4/height
3657
3658
3659 s:text <- new [a
3660 bcdefgh]
3661 e:&:editor <- new-editor s, 0/left, 4/right
3662 editor-render screen, e
3663
3664 screen-should-contain [
3665 ¦ . .
3666 ¦ .a .
3667 ¦ .bcd↩ .
3668 ¦ .efg↩ .
3669 ]
3670
3671 assume-console [
3672 ¦ press page-down
3673 ]
3674 run [
3675 ¦ editor-event-loop screen, console, e
3676 ]
3677
3678 screen-should-contain [
3679 ¦ . .
3680 ¦ .bcd↩ .
3681 ¦ .efg↩ .
3682 ¦ .h .
3683 ]
3684 ]
3685
3686
3687
3688 scenario editor-can-scroll-up [
3689 local-scope
3690 assume-screen 10/width, 4/height
3691 s:text <- new [a
3692 b
3693 c
3694 d]
3695 e:&:editor <- new-editor s, 0/left, 10/right
3696 editor-render screen, e
3697 screen-should-contain [
3698 ¦ . .
3699 ¦ .a .
3700 ¦ .b .
3701 ¦ .c .
3702 ]
3703
3704 assume-console [
3705 ¦ press page-down
3706 ]
3707 run [
3708 ¦ editor-event-loop screen, console, e
3709 ]
3710
3711 screen-should-contain [
3712 ¦ . .
3713 ¦ .c .
3714 ¦ .d .
3715 ¦ .╌╌╌╌╌╌╌╌╌╌.
3716 ]
3717
3718 assume-console [
3719 ¦ press page-up
3720 ]
3721 run [
3722 ¦ editor-event-loop screen, console, e
3723 ]
3724
3725 screen-should-contain [
3726 ¦ . .
3727 ¦ .a .
3728 ¦ .b .
3729 ¦ .c .
3730 ]
3731 ]
3732
3733 after <handle-special-character> [
3734 {
3735 ¦ page-up?:bool <- equal c, 2/ctrl-b
3736 ¦ break-unless page-up?
3737 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3738 ¦ <move-cursor-begin>
3739 ¦ editor <- page-up editor, screen-height
3740 ¦ undo-coalesce-tag:num <- copy 0/never
3741 ¦ <move-cursor-end>
3742 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3743 ¦ movement?:bool <- not-equal top-of-screen, old-top
3744 ¦ return movement?/go-render
3745 }
3746 ]
3747
3748 after <handle-special-key> [
3749 {
3750 ¦ page-up?:bool <- equal k, 65519/page-up
3751 ¦ break-unless page-up?
3752 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
3753 ¦ <move-cursor-begin>
3754 ¦ editor <- page-up editor, screen-height
3755 ¦ undo-coalesce-tag:num <- copy 0/never
3756 ¦ <move-cursor-end>
3757 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3758 ¦ movement?:bool <- not-equal top-of-screen, old-top
3759 ¦
3760 ¦ return movement?/go-render
3761 }
3762 ]
3763
3764 def page-up editor:&:editor, screen-height:num -> editor:&:editor [
3765 local-scope
3766 load-ingredients
3767 max:num <- subtract screen-height, 1/menu-bar, 1/overlapping-line
3768 count:num <- copy 0
3769 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
3770 {
3771 ¦ done?:bool <- greater-or-equal count, max
3772 ¦ break-if done?
3773 ¦ prev:&:duplex-list:char <- before-previous-screen-line top-of-screen, editor
3774 ¦ break-unless prev
3775 ¦ top-of-screen <- copy prev
3776 ¦ *editor <- put *editor, top-of-screen:offset, top-of-screen
3777 ¦ count <- add count, 1
3778 ¦ loop
3779 }
3780 ]
3781
3782 scenario editor-can-scroll-up-multiple-pages [
3783 local-scope
3784
3785 assume-screen 10/width, 4/height
3786
3787 s:text <- new [a
3788 b
3789 c
3790 d
3791 e
3792 f
3793 g
3794 h]
3795 e:&:editor <- new-editor s, 0/left, 10/right
3796 editor-render screen, e
3797 screen-should-contain [
3798 ¦ . .
3799 ¦ .a .
3800 ¦ .b .
3801 ¦ .c .
3802 ]
3803
3804 assume-console [
3805 ¦ press page-down
3806 ¦ press page-down
3807 ]
3808 run [
3809 ¦ editor-event-loop screen, console, e
3810 ]
3811
3812 screen-should-contain [
3813 ¦ . .
3814 ¦ .e .
3815 ¦ .f .
3816 ¦ .g .
3817 ]
3818
3819 assume-console [
3820 ¦ press page-up
3821 ]
3822 run [
3823 ¦ editor-event-loop screen, console, e
3824 ]
3825
3826 screen-should-contain [
3827 ¦ . .
3828 ¦ .c .
3829 ¦ .d .
3830 ¦ .e .
3831 ]
3832
3833 assume-console [
3834 ¦ press page-up
3835 ]
3836 run [
3837 ¦ editor-event-loop screen, console, e
3838 ]
3839
3840 screen-should-contain [
3841 ¦ . .
3842 ¦ .a .
3843 ¦ .b .
3844 ¦ .c .
3845 ]
3846 ]
3847
3848 scenario editor-can-scroll-up-wrapped-lines [
3849 local-scope
3850
3851 assume-screen 10/width, 6/height
3852
3853 s:text <- new [a
3854 b
3855 cdefgh
3856 i
3857 j
3858 k
3859 l
3860 m
3861 n
3862 o]
3863
3864 e:&:editor <- new-editor s, 0/left, 4/right
3865 editor-render screen, e
3866
3867 screen-should-contain [
3868 ¦ . .
3869 ¦ .a .
3870 ¦ .b .
3871 ¦ .cde↩ .
3872 ¦ .fgh .
3873 ¦ .i .
3874 ]
3875
3876 assume-console [
3877 ¦ press page-down
3878 ¦ left-click 5, 0
3879 ¦ press down-arrow
3880 ]
3881 run [
3882 ¦ editor-event-loop screen, console, e
3883 ]
3884
3885 screen-should-contain [
3886 ¦ . .
3887 ¦ .j .
3888 ¦ .k .
3889 ¦ .l .
3890 ¦ .m .
3891 ¦ .n .
3892 ]
3893
3894 assume-console [
3895 ¦ press page-up
3896 ]
3897 run [
3898 ¦ editor-event-loop screen, console, e
3899 ]
3900
3901 screen-should-contain [
3902 ¦ . .
3903 ¦ .b .
3904 ¦ .cde↩ .
3905 ¦ .fgh .
3906 ¦ .i .
3907 ¦ .j .
3908 ]
3909 ]
3910
3911 scenario editor-can-scroll-up-wrapped-lines-2 [
3912 local-scope
3913
3914 assume-screen 10/width, 4/height
3915
3916
3917 s:text <- new [a
3918 bcdefgh]
3919 e:&:editor <- new-editor s, 0/left, 4/right
3920 editor-render screen, e
3921
3922 screen-should-contain [
3923 ¦ . .
3924 ¦ .a .
3925 ¦ .bcd↩ .
3926 ¦ .efg↩ .
3927 ]
3928
3929 assume-console [
3930 ¦ press page-down
3931 ]
3932 run [
3933 ¦ editor-event-loop screen, console, e
3934 ]
3935
3936 screen-should-contain [
3937 ¦ . .
3938 ¦ .bcd↩ .
3939 ¦ .efg↩ .
3940 ¦ .h .
3941 ]
3942
3943 assume-console [
3944 ¦ press page-up
3945 ]
3946 run [
3947 ¦ editor-event-loop screen, console, e
3948 ]
3949
3950 screen-should-contain [
3951 ¦ . .
3952 ¦ .a .
3953 ¦ .bcd↩ .
3954 ¦ .efg↩ .
3955 ]
3956 ]
3957
3958 scenario editor-can-scroll-up-past-nonempty-lines [
3959 local-scope
3960 assume-screen 10/width, 4/height
3961
3962 s:text <- new [axx
3963 bxx
3964 cxx
3965 dxx
3966 exx
3967 fxx
3968 gxx
3969 hxx
3970 ]
3971 e:&:editor <- new-editor s, 0/left, 4/right
3972 editor-render screen, e
3973 screen-should-contain [
3974 ¦ . .
3975 ¦ .axx .
3976 ¦ .bxx .
3977 ¦ .cxx .
3978 ]
3979 assume-console [
3980 ¦ press page-down
3981 ]
3982 run [
3983 ¦ editor-event-loop screen, console, e
3984 ]
3985 screen-should-contain [
3986 ¦ . .
3987 ¦ .cxx .
3988 ¦ .dxx .
3989 ¦ .exx .
3990 ]
3991 assume-console [
3992 ¦ press page-down
3993 ]
3994 run [
3995 ¦ editor-event-loop screen, console, e
3996 ]
3997 screen-should-contain [
3998 ¦ . .
3999 ¦ .exx .
4000 ¦ .fxx .
4001 ¦ .gxx .
4002 ]
4003
4004 assume-console [
4005 ¦ press page-up
4006 ]
4007 run [
4008 ¦ editor-event-loop screen, console, e
4009 ]
4010 screen-should-contain [
4011 ¦ . .
4012 ¦ .cxx .
4013 ¦ .dxx .
4014 ¦ .exx .
4015 ]
4016 ]
4017
4018 scenario editor-can-scroll-up-past-empty-lines [
4019 local-scope
4020 assume-screen 10/width, 4/height
4021
4022 s:text <- new [axy
4023 bxy
4024 cxy
4025
4026 dxy
4027 exy
4028 fxy
4029 gxy
4030 ]
4031 e:&:editor <- new-editor s, 0/left, 4/right
4032 editor-render screen, e
4033 screen-should-contain [
4034 ¦ . .
4035 ¦ .axy .
4036 ¦ .bxy .
4037 ¦ .cxy .
4038 ]
4039 assume-console [
4040 ¦ press page-down
4041 ]
4042 run [
4043 ¦ editor-event-loop screen, console, e
4044 ]
4045 screen-should-contain [
4046 ¦ . .
4047 ¦ .cxy .
4048 ¦ . .
4049 ¦ .dxy .
4050 ]
4051 assume-console [
4052 ¦ press page-down
4053 ]
4054 run [
4055 ¦ editor-event-loop screen, console, e
4056 ]
4057 screen-should-contain [
4058 ¦ . .
4059 ¦ .dxy .
4060 ¦ .exy .
4061 ¦ .fxy .
4062 ]
4063
4064 assume-console [
4065 ¦ press page-up
4066 ]
4067 run [
4068 ¦ editor-event-loop screen, console, e
4069 ]
4070 screen-should-contain [
4071 ¦ . .
4072 ¦ .cxy .
4073 ¦ . .
4074 ¦ .dxy .
4075 ]
4076 ]
4077
4078
4079
4080
4081 after <handle-special-character> [
4082 {
4083 ¦ scroll-up?:bool <- equal c, 19/ctrl-s
4084 ¦ break-unless scroll-up?
4085 ¦ <move-cursor-begin>
4086 ¦ go-render?:bool, editor <- line-up editor, screen-height
4087 ¦ undo-coalesce-tag:num <- copy 5/line-up
4088 ¦ <move-cursor-end>
4089 ¦ return go-render?
4090 }
4091 ]
4092
4093 def line-up editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
4094 local-scope
4095 load-ingredients
4096 left:num <- get *editor, left:offset
4097 right:num <- get *editor, right:offset
4098 max:num <- subtract right, left
4099 old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
4100 new-top:&:duplex-list:char <- before-start-of-next-line old-top, max
4101 movement?:bool <- not-equal old-top, new-top
4102 {
4103 ¦ break-unless movement?
4104 ¦ *editor <- put *editor, top-of-screen:offset, new-top
4105 }
4106 return movement?
4107 ]
4108
4109
4110
4111
4112 after <handle-special-character> [
4113 {
4114 ¦ scroll-down?:bool <- equal c, 24/ctrl-x
4115 ¦ break-unless scroll-down?
4116 ¦ <move-cursor-begin>
4117 ¦ go-render?:bool, editor <- line-down editor, screen-height
4118 ¦ undo-coalesce-tag:num <- copy 6/line-down
4119 ¦ <move-cursor-end>
4120 ¦ return go-render?
4121 }
4122 ]
4123
4124 def line-down editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [
4125 local-scope
4126 load-ingredients
4127 old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
4128 new-top:&:duplex-list:char <- before-previous-screen-line old-top, editor
4129 movement?:bool <- not-equal old-top, new-top
4130 {
4131 ¦ break-unless movement?
4132 ¦ *editor <- put *editor, top-of-screen:offset, new-top
4133 }
4134 return movement?
4135 ]
4136
4137
4138
4139
4140 after <handle-special-character> [
4141 {
4142 ¦ scroll-down?:bool <- equal c, 20/ctrl-t
4143 ¦ break-unless scroll-down?
4144 ¦ <move-cursor-begin>
4145 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset
4146 ¦ cursor:&:duplex-list:char <- get *editor, before-cursor:offset
4147 ¦ cursor <- next cursor
4148 ¦ new-top:&:duplex-list:char <- before-previous-screen-line cursor, editor
4149 ¦ *editor <- put *editor, top-of-screen:offset, new-top
4150 ¦ *editor <- put *editor, cursor-row:offset, 1
4151 ¦ go-render?:bool <- not-equal new-top, old-top
4152 ¦ undo-coalesce-tag:num <- copy 0/never
4153 ¦ <move-cursor-end>
4154 ¦ return go-render?
4155 }
4156 ]
4157
4158
4159
4160 after <handle-special-character> [
4161 {
4162 ¦ comment-toggle?:bool <- equal c, 31/ctrl-slash
4163 ¦ break-unless comment-toggle?
4164 ¦ cursor-column:num <- get *editor, cursor-column:offset
4165 ¦ data:&:duplex-list:char <- get *editor, data:offset
4166 ¦ <insert-character-begin>
4167 ¦ before-line-start:&:duplex-list:char <- before-start-of-screen-line editor
4168 ¦ line-start:&:duplex-list:char <- next before-line-start
4169 ¦ commented-out?:bool <- match line-start, [#? ]
4170 ¦ {
4171 ¦ ¦ break-unless commented-out?
4172 ¦ ¦
4173 ¦ ¦ data <- remove line-start, 3/length-comment-prefix, data
4174 ¦ ¦ cursor-column <- subtract cursor-column, 3/length-comment-prefix
4175 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
4176 ¦ ¦ go-render? <- render-line-from-start screen, editor, 3/size-of-comment-leader
4177 ¦ }
4178 ¦ {
4179 ¦ ¦ break-if commented-out?
4180 ¦ ¦
4181 ¦ ¦ insert before-line-start, [#? ]
4182 ¦ ¦ cursor-column <- add cursor-column, 3/length-comment-prefix
4183 ¦ ¦ *editor <- put *editor, cursor-column:offset, cursor-column
4184 ¦ ¦ go-render? <- render-line-from-start screen, editor, 0
4185 ¦ }
4186 ¦ <insert-character-end>
4187 ¦ return
4188 }
4189 ]
4190
4191
4192
4193
4194 def render-line-from-start screen:&:screen, editor:&:editor, right-margin:num -> go-render?:bool, screen:&:screen [
4195 local-scope
4196 load-ingredients
4197 before-line-start:&:duplex-list:char <- before-start-of-screen-line editor
4198 line-start:&:duplex-list:char <- next before-line-start
4199 color:num <- copy 7/white
4200 left:num <- get *editor, left:offset
4201 cursor-row:num <- get *editor, cursor-row:offset
4202 screen <- move-cursor screen, cursor-row, left
4203 right:num <- get *editor, right:offset
4204 end:num <- subtract right, right-margin
4205 i:num <- copy 0
4206 curr:&:duplex-list:char <- copy line-start
4207 {
4208 ¦ render-all?:bool <- greater-or-equal i, end
4209 ¦ return-if render-all?, 1/go-render
4210 ¦ break-unless curr
4211 ¦ c:char <- get *curr, value:offset
4212 ¦ newline?:bool <- equal c, 10/newline
4213 ¦ break-if newline?
4214 ¦ color <- get-color color, c
4215 ¦ print screen, c, color
4216 ¦ curr <- next curr
4217 ¦ i <- add i, 1
4218 ¦ loop
4219 }
4220 clear-line-until screen, right
4221 return 0/dont-render
4222 ]
4223
4224 def before-start-of-screen-line editor:&:editor -> result:&:duplex-list:char [
4225 local-scope
4226 load-ingredients
4227 cursor:&:duplex-list:char <- get *editor, before-cursor:offset
4228 {
4229 ¦ next:&:duplex-list:char <- next cursor
4230 ¦ break-unless next
4231 ¦ cursor <- copy next
4232 }
4233 result <- before-previous-screen-line cursor, editor
4234 ]
4235
4236 scenario editor-comments-empty-line [
4237 local-scope
4238 assume-screen 10/width, 5/height
4239 e:&:editor <- new-editor [], 0/left, 5/right
4240 editor-render screen, e
4241 $clear-trace
4242 assume-console [
4243 ¦ press ctrl-slash
4244 ]
4245 run [
4246 ¦ editor-event-loop screen, console, e
4247 ¦ 4:num/raw <- get *e, cursor-row:offset
4248 ¦ 5:num/raw <- get *e, cursor-column:offset
4249 ]
4250 screen-should-contain [
4251 ¦ . .
4252 ¦ .#? .
4253 ¦ .╌╌╌╌╌ .
4254 ¦ . .
4255 ]
4256 memory-should-contain [
4257 ¦ 4 <- 1
4258 ¦ 5 <- 3
4259 ]
4260 check-trace-count-for-label 5, [print-character]
4261 ]
4262
4263 scenario editor-comments-at-start-of-contents [
4264 local-scope
4265 assume-screen 10/width, 5/height
4266 e:&:editor <- new-editor [ab], 0/left, 10/right
4267 editor-render screen, e
4268 $clear-trace
4269 assume-console [
4270 ¦ press ctrl-slash
4271 ]
4272 run [
4273 ¦ editor-event-loop screen, console, e
4274 ¦ 4:num/raw <- get *e, cursor-row:offset
4275 ¦ 5:num/raw <- get *e, cursor-column:offset
4276 ]
4277 screen-should-contain [
4278 ¦ . .
4279 ¦ .#? ab .
4280 ¦ .╌╌╌╌╌╌╌╌╌╌.
4281 ¦ . .
4282 ]
4283 memory-should-contain [
4284 ¦ 4 <- 1
4285 ¦ 5 <- 3
4286 ]
4287 check-trace-count-for-label 10, [print-character]
4288 ]
4289
4290 scenario editor-comments-at-end-of-contents [
4291 local-scope
4292 assume-screen 10/width, 5/height
4293 e:&:editor <- new-editor [ab], 0/left, 10/right
4294 editor-render screen, e
4295 $clear-trace
4296 assume-console [
4297 ¦ left-click 1, 7
4298 ¦ press ctrl-slash
4299 ]
4300 run [
4301 ¦ editor-event-loop screen, console, e
4302 ¦ 4:num/raw <- get *e, cursor-row:offset
4303 ¦ 5:num/raw <- get *e, cursor-column:offset
4304 ]
4305 screen-should-contain [
4306 ¦ . .
4307 ¦ .#? ab .
4308 ¦ .╌╌╌╌╌╌╌╌╌╌.
4309 ¦ . .
4310 ]
4311 memory-should-contain [
4312 ¦ 4 <- 1
4313 ¦ 5 <- 5
4314 ]
4315 check-trace-count-for-label 10, [print-character]
4316
4317 $clear-trace
4318 assume-console [
4319 ¦ press ctrl-slash
4320 ]
4321 run [
4322 ¦ editor-event-loop screen, console, e
4323 ¦ 4:num/raw <- get *e, cursor-row:offset
4324 ¦ 5:num/raw <- get *e, cursor-column:offset
4325 ]
4326 screen-should-contain [
4327 ¦ . .
4328 ¦ .ab .
4329 ¦ .╌╌╌╌╌╌╌╌╌╌.
4330 ¦ . .
4331 ]
4332 check-trace-count-for-label 10, [print-character]
4333 ]
4334
4335 scenario editor-comments-almost-wrapping-line [
4336 local-scope
4337 assume-screen 10/width, 5/height
4338
4339 e:&:editor <- new-editor [abcd], 0/left, 5/right
4340 editor-render screen, e
4341 screen-should-contain [
4342 ¦ . .
4343 ¦ .abcd .
4344 ¦ .╌╌╌╌╌ .
4345 ¦ . .
4346 ]
4347 $clear-trace
4348
4349 assume-console [
4350 ¦ left-click 1, 7
4351 ¦ press ctrl-slash
4352 ]
4353 run [
4354 ¦ editor-event-loop screen, console, e
4355 ]
4356 screen-should-contain [
4357 ¦ . .
4358 ¦ .#? a↩ .
4359 ¦ .bcd .
4360 ¦ .╌╌╌╌╌ .
4361 ¦ . .
4362 ]
4363 ]
4364
4365 scenario editor-uncomments-just-wrapping-line [
4366 local-scope
4367 assume-screen 10/width, 5/height
4368
4369 e:&:editor <- new-editor [#? ab], 0/left, 5/right
4370 editor-render screen, e
4371 screen-should-contain [
4372 ¦ . .
4373 ¦ .#? a↩ .
4374 ¦ .b .
4375 ¦ .╌╌╌╌╌ .
4376 ¦ . .
4377 ]
4378 $clear-trace
4379
4380 assume-console [
4381 ¦ left-click 1, 7
4382 ¦ press ctrl-slash
4383 ]
4384 run [
4385 ¦ editor-event-loop screen, console, e
4386 ]
4387 screen-should-contain [
4388 ¦ . .
4389 ¦ .ab .
4390 ¦ .╌╌╌╌╌ .
4391 ¦ . .
4392 ]
4393 ]