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