From 94ffc3776c8037416e4834eb5b94644587c18e10 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 18 Feb 2018 15:55:42 -0800 Subject: 4209 --- html/edit/002-typing.mu.html | 1736 +++++++++++++++++++++--------------------- 1 file changed, 867 insertions(+), 869 deletions(-) (limited to 'html/edit/002-typing.mu.html') diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html index c1ff1791..d41306e4 100644 --- a/html/edit/002-typing.mu.html +++ b/html/edit/002-typing.mu.html @@ -331,881 +331,879 @@ if ('onhashchange' in window) { 269 left:num <- get *editor, left:offset 270 right:num <- get *editor, right:offset 271 row:num, column:num <- render screen, editor - 272 clear-line-until screen, right + 272 draw-horizontal screen, row, left, right, 9480/horizontal-dotted 273 row <- add row, 1 - 274 draw-horizontal screen, row, left, right, 9480/horizontal-dotted - 275 row <- add row, 1 - 276 clear-screen-from screen, row, left, left, right - 277 assert-no-scroll screen, old-top-idx - 278 ] - 279 - 280 scenario editor-handles-empty-event-queue [ - 281 local-scope - 282 assume-screen 10/width, 5/height - 283 e:&:editor <- new-editor [abc], 0/left, 10/right - 284 editor-render screen, e - 285 assume-console [] - 286 run [ - 287 editor-event-loop screen, console, e - 288 ] - 289 screen-should-contain [ - 290 . . - 291 .abc . - 292 .╌╌╌╌╌╌╌╌╌╌. - 293 . . - 294 ] - 295 ] - 296 - 297 scenario editor-handles-mouse-clicks [ - 298 local-scope - 299 assume-screen 10/width, 5/height - 300 e:&:editor <- new-editor [abc], 0/left, 10/right - 301 editor-render screen, e - 302 $clear-trace - 303 assume-console [ - 304 left-click 1, 1 # on the 'b' - 305 ] - 306 run [ - 307 editor-event-loop screen, console, e - 308 3:num/raw <- get *e, cursor-row:offset - 309 4:num/raw <- get *e, cursor-column:offset - 310 ] - 311 screen-should-contain [ - 312 . . - 313 .abc . - 314 .╌╌╌╌╌╌╌╌╌╌. - 315 . . - 316 ] - 317 memory-should-contain [ - 318 3 <- 1 # cursor is at row 0.. - 319 4 <- 1 # ..and column 1 - 320 ] - 321 check-trace-count-for-label 0, [print-character] - 322 ] - 323 - 324 scenario editor-handles-mouse-clicks-outside-text [ - 325 local-scope - 326 assume-screen 10/width, 5/height - 327 e:&:editor <- new-editor [abc], 0/left, 10/right - 328 $clear-trace - 329 assume-console [ - 330 left-click 1, 7 # last line, to the right of text - 331 ] - 332 run [ - 333 editor-event-loop screen, console, e - 334 3:num/raw <- get *e, cursor-row:offset - 335 4:num/raw <- get *e, cursor-column:offset - 336 ] - 337 memory-should-contain [ - 338 3 <- 1 # cursor row - 339 4 <- 3 # cursor column - 340 ] - 341 check-trace-count-for-label 0, [print-character] - 342 ] - 343 - 344 scenario editor-handles-mouse-clicks-outside-text-2 [ - 345 local-scope - 346 assume-screen 10/width, 5/height - 347 s:text <- new [abc - 348 def] - 349 e:&:editor <- new-editor s, 0/left, 10/right - 350 $clear-trace - 351 assume-console [ - 352 left-click 1, 7 # interior line, to the right of text - 353 ] - 354 run [ - 355 editor-event-loop screen, console, e - 356 3:num/raw <- get *e, cursor-row:offset - 357 4:num/raw <- get *e, cursor-column:offset - 358 ] - 359 memory-should-contain [ - 360 3 <- 1 # cursor row - 361 4 <- 3 # cursor column - 362 ] - 363 check-trace-count-for-label 0, [print-character] - 364 ] - 365 - 366 scenario editor-handles-mouse-clicks-outside-text-3 [ - 367 local-scope - 368 assume-screen 10/width, 5/height - 369 s:text <- new [abc - 370 def] - 371 e:&:editor <- new-editor s, 0/left, 10/right - 372 $clear-trace - 373 assume-console [ - 374 left-click 3, 7 # below text - 375 ] - 376 run [ - 377 editor-event-loop screen, console, e - 378 3:num/raw <- get *e, cursor-row:offset - 379 4:num/raw <- get *e, cursor-column:offset - 380 ] - 381 memory-should-contain [ - 382 3 <- 2 # cursor row - 383 4 <- 3 # cursor column - 384 ] - 385 check-trace-count-for-label 0, [print-character] - 386 ] - 387 - 388 scenario editor-handles-mouse-clicks-outside-column [ - 389 local-scope - 390 assume-screen 10/width, 5/height - 391 # editor occupies only left half of screen - 392 e:&:editor <- new-editor [abc], 0/left, 5/right - 393 editor-render screen, e - 394 $clear-trace - 395 assume-console [ - 396 # click on right half of screen - 397 left-click 3, 8 - 398 ] - 399 run [ - 400 editor-event-loop screen, console, e - 401 3:num/raw <- get *e, cursor-row:offset - 402 4:num/raw <- get *e, cursor-column:offset - 403 ] - 404 screen-should-contain [ - 405 . . - 406 .abc . - 407 .╌╌╌╌╌ . - 408 . . - 409 ] - 410 memory-should-contain [ - 411 3 <- 1 # no change to cursor row - 412 4 <- 0 # ..or column - 413 ] - 414 check-trace-count-for-label 0, [print-character] - 415 ] - 416 - 417 scenario editor-handles-mouse-clicks-in-menu-area [ - 418 local-scope - 419 assume-screen 10/width, 5/height - 420 e:&:editor <- new-editor [abc], 0/left, 5/right - 421 editor-render screen, e - 422 $clear-trace - 423 assume-console [ - 424 # click on first, 'menu' row - 425 left-click 0, 3 - 426 ] - 427 run [ - 428 editor-event-loop screen, console, e - 429 3:num/raw <- get *e, cursor-row:offset - 430 4:num/raw <- get *e, cursor-column:offset - 431 ] - 432 # no change to cursor - 433 memory-should-contain [ - 434 3 <- 1 - 435 4 <- 0 - 436 ] - 437 ] - 438 - 439 scenario editor-inserts-characters-into-empty-editor [ - 440 local-scope - 441 assume-screen 10/width, 5/height - 442 e:&:editor <- new-editor [], 0/left, 5/right - 443 editor-render screen, e - 444 $clear-trace - 445 assume-console [ - 446 type [abc] - 447 ] - 448 run [ - 449 editor-event-loop screen, console, e - 450 ] - 451 screen-should-contain [ - 452 . . - 453 .abc . - 454 .╌╌╌╌╌ . - 455 . . - 456 ] - 457 check-trace-count-for-label 3, [print-character] - 458 ] - 459 - 460 scenario editor-inserts-characters-at-cursor [ - 461 local-scope - 462 assume-screen 10/width, 5/height - 463 e:&:editor <- new-editor [abc], 0/left, 10/right - 464 editor-render screen, e - 465 $clear-trace - 466 # type two letters at different places - 467 assume-console [ - 468 type [0] - 469 left-click 1, 2 - 470 type [d] - 471 ] - 472 run [ - 473 editor-event-loop screen, console, e - 474 ] - 475 screen-should-contain [ - 476 . . - 477 .0adbc . - 478 .╌╌╌╌╌╌╌╌╌╌. - 479 . . - 480 ] - 481 check-trace-count-for-label 7, [print-character] # 4 for first letter, 3 for second - 482 ] - 483 - 484 scenario editor-inserts-characters-at-cursor-2 [ - 485 local-scope - 486 assume-screen 10/width, 5/height - 487 e:&:editor <- new-editor [abc], 0/left, 10/right - 488 editor-render screen, e - 489 $clear-trace - 490 assume-console [ - 491 left-click 1, 5 # right of last line - 492 type [d] - 493 ] - 494 run [ - 495 editor-event-loop screen, console, e - 496 ] - 497 screen-should-contain [ - 498 . . - 499 .abcd . - 500 .╌╌╌╌╌╌╌╌╌╌. - 501 . . - 502 ] - 503 check-trace-count-for-label 1, [print-character] - 504 ] - 505 - 506 scenario editor-inserts-characters-at-cursor-5 [ - 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 assume-console [ - 515 left-click 1, 5 # right of non-last line - 516 type [e] - 517 ] - 518 run [ - 519 editor-event-loop screen, console, e - 520 ] - 521 screen-should-contain [ - 522 . . - 523 .abce . - 524 .d . - 525 .╌╌╌╌╌╌╌╌╌╌. - 526 . . - 527 ] - 528 check-trace-count-for-label 1, [print-character] - 529 ] - 530 - 531 scenario editor-inserts-characters-at-cursor-3 [ - 532 local-scope - 533 assume-screen 10/width, 5/height - 534 e:&:editor <- new-editor [abc], 0/left, 10/right - 535 editor-render screen, e - 536 $clear-trace - 537 assume-console [ - 538 left-click 3, 5 # below all text - 539 type [d] - 540 ] - 541 run [ - 542 editor-event-loop screen, console, e - 543 ] - 544 screen-should-contain [ - 545 . . - 546 .abcd . - 547 .╌╌╌╌╌╌╌╌╌╌. - 548 . . - 549 ] - 550 check-trace-count-for-label 1, [print-character] - 551 ] - 552 - 553 scenario editor-inserts-characters-at-cursor-4 [ - 554 local-scope - 555 assume-screen 10/width, 5/height - 556 s:text <- new [abc - 557 d] - 558 e:&:editor <- new-editor s, 0/left, 10/right - 559 editor-render screen, e - 560 $clear-trace - 561 assume-console [ - 562 left-click 3, 5 # below all text - 563 type [e] - 564 ] - 565 run [ - 566 editor-event-loop screen, console, e - 567 ] - 568 screen-should-contain [ - 569 . . - 570 .abc . - 571 .de . - 572 .╌╌╌╌╌╌╌╌╌╌. - 573 . . - 574 ] - 575 check-trace-count-for-label 1, [print-character] - 576 ] - 577 - 578 scenario editor-inserts-characters-at-cursor-6 [ - 579 local-scope - 580 assume-screen 10/width, 5/height - 581 s:text <- new [abc - 582 d] - 583 e:&:editor <- new-editor s, 0/left, 10/right - 584 editor-render screen, e - 585 $clear-trace - 586 assume-console [ - 587 left-click 3, 5 # below all text - 588 type [ef] - 589 ] - 590 run [ - 591 editor-event-loop screen, console, e - 592 ] - 593 screen-should-contain [ - 594 . . - 595 .abc . - 596 .def . - 597 .╌╌╌╌╌╌╌╌╌╌. - 598 . . - 599 ] - 600 check-trace-count-for-label 2, [print-character] - 601 ] - 602 - 603 scenario editor-moves-cursor-after-inserting-characters [ - 604 local-scope - 605 assume-screen 10/width, 5/height - 606 e:&:editor <- new-editor [ab], 0/left, 5/right - 607 editor-render screen, e - 608 assume-console [ - 609 type [01] - 610 ] - 611 run [ - 612 editor-event-loop screen, console, e - 613 ] - 614 screen-should-contain [ - 615 . . - 616 .01ab . - 617 .╌╌╌╌╌ . - 618 . . - 619 ] - 620 ] + 274 clear-screen-from screen, row, left, left, right + 275 assert-no-scroll screen, old-top-idx + 276 ] + 277 + 278 scenario editor-handles-empty-event-queue [ + 279 local-scope + 280 assume-screen 10/width, 5/height + 281 e:&:editor <- new-editor [abc], 0/left, 10/right + 282 editor-render screen, e + 283 assume-console [] + 284 run [ + 285 editor-event-loop screen, console, e + 286 ] + 287 screen-should-contain [ + 288 . . + 289 .abc . + 290 .╌╌╌╌╌╌╌╌╌╌. + 291 . . + 292 ] + 293 ] + 294 + 295 scenario editor-handles-mouse-clicks [ + 296 local-scope + 297 assume-screen 10/width, 5/height + 298 e:&:editor <- new-editor [abc], 0/left, 10/right + 299 editor-render screen, e + 300 $clear-trace + 301 assume-console [ + 302 left-click 1, 1 # on the 'b' + 303 ] + 304 run [ + 305 editor-event-loop screen, console, e + 306 3:num/raw <- get *e, cursor-row:offset + 307 4:num/raw <- get *e, cursor-column:offset + 308 ] + 309 screen-should-contain [ + 310 . . + 311 .abc . + 312 .╌╌╌╌╌╌╌╌╌╌. + 313 . . + 314 ] + 315 memory-should-contain [ + 316 3 <- 1 # cursor is at row 0.. + 317 4 <- 1 # ..and column 1 + 318 ] + 319 check-trace-count-for-label 0, [print-character] + 320 ] + 321 + 322 scenario editor-handles-mouse-clicks-outside-text [ + 323 local-scope + 324 assume-screen 10/width, 5/height + 325 e:&:editor <- new-editor [abc], 0/left, 10/right + 326 $clear-trace + 327 assume-console [ + 328 left-click 1, 7 # last line, to the right of text + 329 ] + 330 run [ + 331 editor-event-loop screen, console, e + 332 3:num/raw <- get *e, cursor-row:offset + 333 4:num/raw <- get *e, cursor-column:offset + 334 ] + 335 memory-should-contain [ + 336 3 <- 1 # cursor row + 337 4 <- 3 # cursor column + 338 ] + 339 check-trace-count-for-label 0, [print-character] + 340 ] + 341 + 342 scenario editor-handles-mouse-clicks-outside-text-2 [ + 343 local-scope + 344 assume-screen 10/width, 5/height + 345 s:text <- new [abc + 346 def] + 347 e:&:editor <- new-editor s, 0/left, 10/right + 348 $clear-trace + 349 assume-console [ + 350 left-click 1, 7 # interior line, to the right of text + 351 ] + 352 run [ + 353 editor-event-loop screen, console, e + 354 3:num/raw <- get *e, cursor-row:offset + 355 4:num/raw <- get *e, cursor-column:offset + 356 ] + 357 memory-should-contain [ + 358 3 <- 1 # cursor row + 359 4 <- 3 # cursor column + 360 ] + 361 check-trace-count-for-label 0, [print-character] + 362 ] + 363 + 364 scenario editor-handles-mouse-clicks-outside-text-3 [ + 365 local-scope + 366 assume-screen 10/width, 5/height + 367 s:text <- new [abc + 368 def] + 369 e:&:editor <- new-editor s, 0/left, 10/right + 370 $clear-trace + 371 assume-console [ + 372 left-click 3, 7 # below text + 373 ] + 374 run [ + 375 editor-event-loop screen, console, e + 376 3:num/raw <- get *e, cursor-row:offset + 377 4:num/raw <- get *e, cursor-column:offset + 378 ] + 379 memory-should-contain [ + 380 3 <- 2 # cursor row + 381 4 <- 3 # cursor column + 382 ] + 383 check-trace-count-for-label 0, [print-character] + 384 ] + 385 + 386 scenario editor-handles-mouse-clicks-outside-column [ + 387 local-scope + 388 assume-screen 10/width, 5/height + 389 # editor occupies only left half of screen + 390 e:&:editor <- new-editor [abc], 0/left, 5/right + 391 editor-render screen, e + 392 $clear-trace + 393 assume-console [ + 394 # click on right half of screen + 395 left-click 3, 8 + 396 ] + 397 run [ + 398 editor-event-loop screen, console, e + 399 3:num/raw <- get *e, cursor-row:offset + 400 4:num/raw <- get *e, cursor-column:offset + 401 ] + 402 screen-should-contain [ + 403 . . + 404 .abc . + 405 .╌╌╌╌╌ . + 406 . . + 407 ] + 408 memory-should-contain [ + 409 3 <- 1 # no change to cursor row + 410 4 <- 0 # ..or column + 411 ] + 412 check-trace-count-for-label 0, [print-character] + 413 ] + 414 + 415 scenario editor-handles-mouse-clicks-in-menu-area [ + 416 local-scope + 417 assume-screen 10/width, 5/height + 418 e:&:editor <- new-editor [abc], 0/left, 5/right + 419 editor-render screen, e + 420 $clear-trace + 421 assume-console [ + 422 # click on first, 'menu' row + 423 left-click 0, 3 + 424 ] + 425 run [ + 426 editor-event-loop screen, console, e + 427 3:num/raw <- get *e, cursor-row:offset + 428 4:num/raw <- get *e, cursor-column:offset + 429 ] + 430 # no change to cursor + 431 memory-should-contain [ + 432 3 <- 1 + 433 4 <- 0 + 434 ] + 435 ] + 436 + 437 scenario editor-inserts-characters-into-empty-editor [ + 438 local-scope + 439 assume-screen 10/width, 5/height + 440 e:&:editor <- new-editor [], 0/left, 5/right + 441 editor-render screen, e + 442 $clear-trace + 443 assume-console [ + 444 type [abc] + 445 ] + 446 run [ + 447 editor-event-loop screen, console, e + 448 ] + 449 screen-should-contain [ + 450 . . + 451 .abc . + 452 .╌╌╌╌╌ . + 453 . . + 454 ] + 455 check-trace-count-for-label 3, [print-character] + 456 ] + 457 + 458 scenario editor-inserts-characters-at-cursor [ + 459 local-scope + 460 assume-screen 10/width, 5/height + 461 e:&:editor <- new-editor [abc], 0/left, 10/right + 462 editor-render screen, e + 463 $clear-trace + 464 # type two letters at different places + 465 assume-console [ + 466 type [0] + 467 left-click 1, 2 + 468 type [d] + 469 ] + 470 run [ + 471 editor-event-loop screen, console, e + 472 ] + 473 screen-should-contain [ + 474 . . + 475 .0adbc . + 476 .╌╌╌╌╌╌╌╌╌╌. + 477 . . + 478 ] + 479 check-trace-count-for-label 7, [print-character] # 4 for first letter, 3 for second + 480 ] + 481 + 482 scenario editor-inserts-characters-at-cursor-2 [ + 483 local-scope + 484 assume-screen 10/width, 5/height + 485 e:&:editor <- new-editor [abc], 0/left, 10/right + 486 editor-render screen, e + 487 $clear-trace + 488 assume-console [ + 489 left-click 1, 5 # right of last line + 490 type [d] + 491 ] + 492 run [ + 493 editor-event-loop screen, console, e + 494 ] + 495 screen-should-contain [ + 496 . . + 497 .abcd . + 498 .╌╌╌╌╌╌╌╌╌╌. + 499 . . + 500 ] + 501 check-trace-count-for-label 1, [print-character] + 502 ] + 503 + 504 scenario editor-inserts-characters-at-cursor-5 [ + 505 local-scope + 506 assume-screen 10/width, 5/height + 507 s:text <- new [abc + 508 d] + 509 e:&:editor <- new-editor s, 0/left, 10/right + 510 editor-render screen, e + 511 $clear-trace + 512 assume-console [ + 513 left-click 1, 5 # right of non-last line + 514 type [e] + 515 ] + 516 run [ + 517 editor-event-loop screen, console, e + 518 ] + 519 screen-should-contain [ + 520 . . + 521 .abce . + 522 .d . + 523 .╌╌╌╌╌╌╌╌╌╌. + 524 . . + 525 ] + 526 check-trace-count-for-label 1, [print-character] + 527 ] + 528 + 529 scenario editor-inserts-characters-at-cursor-3 [ + 530 local-scope + 531 assume-screen 10/width, 5/height + 532 e:&:editor <- new-editor [abc], 0/left, 10/right + 533 editor-render screen, e + 534 $clear-trace + 535 assume-console [ + 536 left-click 3, 5 # below all text + 537 type [d] + 538 ] + 539 run [ + 540 editor-event-loop screen, console, e + 541 ] + 542 screen-should-contain [ + 543 . . + 544 .abcd . + 545 .╌╌╌╌╌╌╌╌╌╌. + 546 . . + 547 ] + 548 check-trace-count-for-label 1, [print-character] + 549 ] + 550 + 551 scenario editor-inserts-characters-at-cursor-4 [ + 552 local-scope + 553 assume-screen 10/width, 5/height + 554 s:text <- new [abc + 555 d] + 556 e:&:editor <- new-editor s, 0/left, 10/right + 557 editor-render screen, e + 558 $clear-trace + 559 assume-console [ + 560 left-click 3, 5 # below all text + 561 type [e] + 562 ] + 563 run [ + 564 editor-event-loop screen, console, e + 565 ] + 566 screen-should-contain [ + 567 . . + 568 .abc . + 569 .de . + 570 .╌╌╌╌╌╌╌╌╌╌. + 571 . . + 572 ] + 573 check-trace-count-for-label 1, [print-character] + 574 ] + 575 + 576 scenario editor-inserts-characters-at-cursor-6 [ + 577 local-scope + 578 assume-screen 10/width, 5/height + 579 s:text <- new [abc + 580 d] + 581 e:&:editor <- new-editor s, 0/left, 10/right + 582 editor-render screen, e + 583 $clear-trace + 584 assume-console [ + 585 left-click 3, 5 # below all text + 586 type [ef] + 587 ] + 588 run [ + 589 editor-event-loop screen, console, e + 590 ] + 591 screen-should-contain [ + 592 . . + 593 .abc . + 594 .def . + 595 .╌╌╌╌╌╌╌╌╌╌. + 596 . . + 597 ] + 598 check-trace-count-for-label 2, [print-character] + 599 ] + 600 + 601 scenario editor-moves-cursor-after-inserting-characters [ + 602 local-scope + 603 assume-screen 10/width, 5/height + 604 e:&:editor <- new-editor [ab], 0/left, 5/right + 605 editor-render screen, e + 606 assume-console [ + 607 type [01] + 608 ] + 609 run [ + 610 editor-event-loop screen, console, e + 611 ] + 612 screen-should-contain [ + 613 . . + 614 .01ab . + 615 .╌╌╌╌╌ . + 616 . . + 617 ] + 618 ] + 619 + 620 # if the cursor reaches the right margin, wrap the line 621 - 622 # if the cursor reaches the right margin, wrap the line - 623 - 624 scenario editor-wraps-line-on-insert [ - 625 local-scope - 626 assume-screen 5/width, 5/height - 627 e:&:editor <- new-editor [abc], 0/left, 5/right - 628 editor-render screen, e - 629 # type a letter - 630 assume-console [ - 631 type [e] - 632 ] - 633 run [ - 634 editor-event-loop screen, console, e - 635 ] - 636 # no wrap yet - 637 screen-should-contain [ - 638 . . - 639 .eabc . - 640 .╌╌╌╌╌. - 641 . . - 642 . . - 643 ] - 644 # type a second letter - 645 assume-console [ - 646 type [f] - 647 ] - 648 run [ - 649 editor-event-loop screen, console, e - 650 ] - 651 # now wrap - 652 screen-should-contain [ - 653 . . - 654 .efab↩. - 655 .c . - 656 .╌╌╌╌╌. - 657 . . - 658 ] - 659 ] - 660 - 661 scenario editor-wraps-line-on-insert-2 [ - 662 local-scope - 663 # create an editor with some text - 664 assume-screen 10/width, 5/height - 665 s:text <- new [abcdefg - 666 defg] - 667 e:&:editor <- new-editor s, 0/left, 5/right - 668 editor-render screen, e - 669 # type more text at the start - 670 assume-console [ - 671 left-click 3, 0 - 672 type [abc] - 673 ] - 674 run [ - 675 editor-event-loop screen, console, e - 676 3:num/raw <- get *e, cursor-row:offset - 677 4:num/raw <- get *e, cursor-column:offset - 678 ] - 679 # cursor is not wrapped - 680 memory-should-contain [ - 681 3 <- 3 - 682 4 <- 3 - 683 ] - 684 # but line is wrapped - 685 screen-should-contain [ - 686 . . + 622 scenario editor-wraps-line-on-insert [ + 623 local-scope + 624 assume-screen 5/width, 5/height + 625 e:&:editor <- new-editor [abc], 0/left, 5/right + 626 editor-render screen, e + 627 # type a letter + 628 assume-console [ + 629 type [e] + 630 ] + 631 run [ + 632 editor-event-loop screen, console, e + 633 ] + 634 # no wrap yet + 635 screen-should-contain [ + 636 . . + 637 .eabc . + 638 .╌╌╌╌╌. + 639 . . + 640 . . + 641 ] + 642 # type a second letter + 643 assume-console [ + 644 type [f] + 645 ] + 646 run [ + 647 editor-event-loop screen, console, e + 648 ] + 649 # now wrap + 650 screen-should-contain [ + 651 . . + 652 .efab↩. + 653 .c . + 654 .╌╌╌╌╌. + 655 . . + 656 ] + 657 ] + 658 + 659 scenario editor-wraps-line-on-insert-2 [ + 660 local-scope + 661 # create an editor with some text + 662 assume-screen 10/width, 5/height + 663 s:text <- new [abcdefg + 664 defg] + 665 e:&:editor <- new-editor s, 0/left, 5/right + 666 editor-render screen, e + 667 # type more text at the start + 668 assume-console [ + 669 left-click 3, 0 + 670 type [abc] + 671 ] + 672 run [ + 673 editor-event-loop screen, console, e + 674 3:num/raw <- get *e, cursor-row:offset + 675 4:num/raw <- get *e, cursor-column:offset + 676 ] + 677 # cursor is not wrapped + 678 memory-should-contain [ + 679 3 <- 3 + 680 4 <- 3 + 681 ] + 682 # but line is wrapped + 683 screen-should-contain [ + 684 . . + 685 .abcd↩ . + 686 .efg . 687 .abcd↩ . 688 .efg . - 689 .abcd↩ . - 690 .efg . - 691 ] - 692 ] - 693 - 694 after <insert-character-special-case> [ - 695 # if the line wraps at the cursor, move cursor to start of next row - 696 { - 697 # if either: - 698 # a) we're at the end of the line and at the column of the wrap indicator, or - 699 # b) we're not at end of line and just before the column of the wrap indicator - 700 wrap-column:num <- copy right - 701 before-wrap-column:num <- subtract wrap-column, 1 - 702 at-wrap?:bool <- greater-or-equal cursor-column, wrap-column - 703 just-before-wrap?:bool <- greater-or-equal cursor-column, before-wrap-column - 704 next:&:duplex-list:char <- next before-cursor - 705 # at end of line? next == 0 || next.value == 10/newline - 706 at-end-of-line?:bool <- equal next, 0 - 707 { - 708 break-if at-end-of-line? - 709 next-character:char <- get *next, value:offset - 710 at-end-of-line? <- equal next-character, 10/newline - 711 } - 712 # break unless ((eol? and at-wrap?) or (~eol? and just-before-wrap?)) - 713 move-cursor-to-next-line?:bool <- copy 0/false - 714 { - 715 break-if at-end-of-line? - 716 move-cursor-to-next-line? <- copy just-before-wrap? - 717 # if we're moving the cursor because it's in the middle of a wrapping - 718 # line, adjust it to left-most column - 719 potential-new-cursor-column:num <- copy left - 720 } - 721 { - 722 break-unless at-end-of-line? - 723 move-cursor-to-next-line? <- copy at-wrap? - 724 # if we're moving the cursor because it's at the end of a wrapping line, - 725 # adjust it to one past the left-most column to make room for the - 726 # newly-inserted wrap-indicator - 727 potential-new-cursor-column:num <- add left, 1/make-room-for-wrap-indicator - 728 } - 729 break-unless move-cursor-to-next-line? - 730 cursor-column <- copy potential-new-cursor-column - 731 *editor <- put *editor, cursor-column:offset, cursor-column - 732 cursor-row <- add cursor-row, 1 - 733 *editor <- put *editor, cursor-row:offset, cursor-row - 734 # if we're out of the screen, scroll down - 735 { - 736 below-screen?:bool <- greater-or-equal cursor-row, screen-height - 737 break-unless below-screen? - 738 <scroll-down> - 739 } - 740 return 1/go-render - 741 } - 742 ] - 743 - 744 scenario editor-wraps-cursor-after-inserting-characters-in-middle-of-line [ - 745 local-scope - 746 assume-screen 10/width, 5/height - 747 e:&:editor <- new-editor [abcde], 0/left, 5/right - 748 assume-console [ - 749 left-click 1, 3 # right before the wrap icon - 750 type [f] - 751 ] - 752 run [ - 753 editor-event-loop screen, console, e - 754 3:num/raw <- get *e, cursor-row:offset - 755 4:num/raw <- get *e, cursor-column:offset - 756 ] - 757 screen-should-contain [ - 758 . . - 759 .abcf↩ . - 760 .de . - 761 .╌╌╌╌╌ . - 762 . . - 763 ] - 764 memory-should-contain [ - 765 3 <- 2 # cursor row - 766 4 <- 0 # cursor column - 767 ] - 768 ] - 769 - 770 scenario editor-wraps-cursor-after-inserting-characters-at-end-of-line [ - 771 local-scope - 772 assume-screen 10/width, 5/height - 773 # create an editor containing two lines - 774 s:text <- new [abc - 775 xyz] - 776 e:&:editor <- new-editor s, 0/left, 5/right - 777 editor-render screen, e - 778 screen-should-contain [ - 779 . . - 780 .abc . - 781 .xyz . - 782 .╌╌╌╌╌ . - 783 . . - 784 ] - 785 assume-console [ - 786 left-click 1, 4 # at end of first line - 787 type [de] # trigger wrap - 788 ] - 789 run [ - 790 editor-event-loop screen, console, e - 791 ] - 792 screen-should-contain [ - 793 . . - 794 .abcd↩ . - 795 .e . - 796 .xyz . - 797 .╌╌╌╌╌ . - 798 ] - 799 ] - 800 - 801 scenario editor-wraps-cursor-to-left-margin [ - 802 local-scope - 803 assume-screen 10/width, 5/height - 804 e:&:editor <- new-editor [abcde], 2/left, 7/right - 805 assume-console [ - 806 left-click 1, 5 # line is full; no wrap icon yet - 807 type [01] - 808 ] - 809 run [ - 810 editor-event-loop screen, console, e - 811 3:num/raw <- get *e, cursor-row:offset - 812 4:num/raw <- get *e, cursor-column:offset - 813 ] - 814 screen-should-contain [ - 815 . . - 816 . abc0↩ . - 817 . 1de . - 818 . ╌╌╌╌╌ . - 819 . . - 820 ] - 821 memory-should-contain [ - 822 3 <- 2 # cursor row - 823 4 <- 3 # cursor column - 824 ] - 825 ] + 689 ] + 690 ] + 691 + 692 after <insert-character-special-case> [ + 693 # if the line wraps at the cursor, move cursor to start of next row + 694 { + 695 # if either: + 696 # a) we're at the end of the line and at the column of the wrap indicator, or + 697 # b) we're not at end of line and just before the column of the wrap indicator + 698 wrap-column:num <- copy right + 699 before-wrap-column:num <- subtract wrap-column, 1 + 700 at-wrap?:bool <- greater-or-equal cursor-column, wrap-column + 701 just-before-wrap?:bool <- greater-or-equal cursor-column, before-wrap-column + 702 next:&:duplex-list:char <- next before-cursor + 703 # at end of line? next == 0 || next.value == 10/newline + 704 at-end-of-line?:bool <- equal next, 0 + 705 { + 706 break-if at-end-of-line? + 707 next-character:char <- get *next, value:offset + 708 at-end-of-line? <- equal next-character, 10/newline + 709 } + 710 # break unless ((eol? and at-wrap?) or (~eol? and just-before-wrap?)) + 711 move-cursor-to-next-line?:bool <- copy 0/false + 712 { + 713 break-if at-end-of-line? + 714 move-cursor-to-next-line? <- copy just-before-wrap? + 715 # if we're moving the cursor because it's in the middle of a wrapping + 716 # line, adjust it to left-most column + 717 potential-new-cursor-column:num <- copy left + 718 } + 719 { + 720 break-unless at-end-of-line? + 721 move-cursor-to-next-line? <- copy at-wrap? + 722 # if we're moving the cursor because it's at the end of a wrapping line, + 723 # adjust it to one past the left-most column to make room for the + 724 # newly-inserted wrap-indicator + 725 potential-new-cursor-column:num <- add left, 1/make-room-for-wrap-indicator + 726 } + 727 break-unless move-cursor-to-next-line? + 728 cursor-column <- copy potential-new-cursor-column + 729 *editor <- put *editor, cursor-column:offset, cursor-column + 730 cursor-row <- add cursor-row, 1 + 731 *editor <- put *editor, cursor-row:offset, cursor-row + 732 # if we're out of the screen, scroll down + 733 { + 734 below-screen?:bool <- greater-or-equal cursor-row, screen-height + 735 break-unless below-screen? + 736 <scroll-down> + 737 } + 738 return 1/go-render + 739 } + 740 ] + 741 + 742 scenario editor-wraps-cursor-after-inserting-characters-in-middle-of-line [ + 743 local-scope + 744 assume-screen 10/width, 5/height + 745 e:&:editor <- new-editor [abcde], 0/left, 5/right + 746 assume-console [ + 747 left-click 1, 3 # right before the wrap icon + 748 type [f] + 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 screen-should-contain [ + 756 . . + 757 .abcf↩ . + 758 .de . + 759 .╌╌╌╌╌ . + 760 . . + 761 ] + 762 memory-should-contain [ + 763 3 <- 2 # cursor row + 764 4 <- 0 # cursor column + 765 ] + 766 ] + 767 + 768 scenario editor-wraps-cursor-after-inserting-characters-at-end-of-line [ + 769 local-scope + 770 assume-screen 10/width, 5/height + 771 # create an editor containing two lines + 772 s:text <- new [abc + 773 xyz] + 774 e:&:editor <- new-editor s, 0/left, 5/right + 775 editor-render screen, e + 776 screen-should-contain [ + 777 . . + 778 .abc . + 779 .xyz . + 780 .╌╌╌╌╌ . + 781 . . + 782 ] + 783 assume-console [ + 784 left-click 1, 4 # at end of first line + 785 type [de] # trigger wrap + 786 ] + 787 run [ + 788 editor-event-loop screen, console, e + 789 ] + 790 screen-should-contain [ + 791 . . + 792 .abcd↩ . + 793 .e . + 794 .xyz . + 795 .╌╌╌╌╌ . + 796 ] + 797 ] + 798 + 799 scenario editor-wraps-cursor-to-left-margin [ + 800 local-scope + 801 assume-screen 10/width, 5/height + 802 e:&:editor <- new-editor [abcde], 2/left, 7/right + 803 assume-console [ + 804 left-click 1, 5 # line is full; no wrap icon yet + 805 type [01] + 806 ] + 807 run [ + 808 editor-event-loop screen, console, e + 809 3:num/raw <- get *e, cursor-row:offset + 810 4:num/raw <- get *e, cursor-column:offset + 811 ] + 812 screen-should-contain [ + 813 . . + 814 . abc0↩ . + 815 . 1de . + 816 . ╌╌╌╌╌ . + 817 . . + 818 ] + 819 memory-should-contain [ + 820 3 <- 2 # cursor row + 821 4 <- 3 # cursor column + 822 ] + 823 ] + 824 + 825 # if newline, move cursor to start of next line, and maybe align indent with previous line 826 - 827 # if newline, move cursor to start of next line, and maybe align indent with previous line - 828 - 829 container editor [ - 830 indent?:bool - 831 ] - 832 - 833 after <editor-initialization> [ - 834 *result <- put *result, indent?:offset, 1/true - 835 ] - 836 - 837 scenario editor-moves-cursor-down-after-inserting-newline [ - 838 local-scope - 839 assume-screen 10/width, 5/height - 840 e:&:editor <- new-editor [abc], 0/left, 10/right - 841 assume-console [ - 842 type [0 - 843 1] - 844 ] - 845 run [ - 846 editor-event-loop screen, console, e - 847 ] - 848 screen-should-contain [ - 849 . . - 850 .0 . - 851 .1abc . - 852 .╌╌╌╌╌╌╌╌╌╌. - 853 . . - 854 ] - 855 ] - 856 - 857 after <handle-special-character> [ - 858 { - 859 newline?:bool <- equal c, 10/newline - 860 break-unless newline? - 861 <begin-insert-enter> - 862 insert-new-line-and-indent editor, screen - 863 <end-insert-enter> - 864 return 1/go-render - 865 } - 866 ] - 867 - 868 def insert-new-line-and-indent editor:&:editor, screen:&:screen -> editor:&:editor, screen:&:screen [ - 869 local-scope - 870 load-inputs - 871 cursor-row:num <- get *editor, cursor-row:offset - 872 cursor-column:num <- get *editor, cursor-column:offset - 873 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset - 874 left:num <- get *editor, left:offset - 875 right:num <- get *editor, right:offset - 876 screen-height:num <- screen-height screen - 877 # update cursor coordinates - 878 at-start-of-wrapped-line?:bool <- at-start-of-wrapped-line? editor - 879 { - 880 break-if at-start-of-wrapped-line? - 881 cursor-row <- add cursor-row, 1 - 882 *editor <- put *editor, cursor-row:offset, cursor-row - 883 } - 884 cursor-column <- copy left - 885 *editor <- put *editor, cursor-column:offset, cursor-column - 886 # maybe scroll - 887 { - 888 below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal, never greater - 889 break-unless below-screen? - 890 <scroll-down> - 891 cursor-row <- subtract cursor-row, 1 # bring back into screen range - 892 *editor <- put *editor, cursor-row:offset, cursor-row - 893 } - 894 # insert newline - 895 insert 10/newline, before-cursor - 896 before-cursor <- next before-cursor - 897 *editor <- put *editor, before-cursor:offset, before-cursor - 898 # indent if necessary - 899 indent?:bool <- get *editor, indent?:offset - 900 return-unless indent? - 901 d:&:duplex-list:char <- get *editor, data:offset - 902 end-of-previous-line:&:duplex-list:char <- prev before-cursor - 903 indent:num <- line-indent end-of-previous-line, d - 904 i:num <- copy 0 - 905 { - 906 indent-done?:bool <- greater-or-equal i, indent - 907 break-if indent-done? - 908 insert-at-cursor editor, 32/space, screen - 909 i <- add i, 1 - 910 loop - 911 } - 912 ] - 913 - 914 def at-start-of-wrapped-line? editor:&:editor -> result:bool [ - 915 local-scope - 916 load-inputs - 917 left:num <- get *editor, left:offset - 918 cursor-column:num <- get *editor, cursor-column:offset - 919 cursor-at-left?:bool <- equal cursor-column, left - 920 return-unless cursor-at-left?, 0/false - 921 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset - 922 before-before-cursor:&:duplex-list:char <- prev before-cursor - 923 return-unless before-before-cursor, 0/false # cursor is at start of editor - 924 char-before-cursor:char <- get *before-cursor, value:offset - 925 cursor-after-newline?:bool <- equal char-before-cursor, 10/newline - 926 return-if cursor-after-newline?, 0/false - 927 # if cursor is at left margin and not at start, but previous character is not a newline, - 928 # then we're at start of a wrapped line - 929 return 1/true - 930 ] - 931 - 932 # takes a pointer 'curr' into the doubly-linked list and its sentinel, counts - 933 # the number of spaces at the start of the line containing 'curr'. - 934 def line-indent curr:&:duplex-list:char, start:&:duplex-list:char -> result:num [ - 935 local-scope - 936 load-inputs - 937 result:num <- copy 0 - 938 return-unless curr - 939 at-start?:bool <- equal curr, start - 940 return-if at-start? - 941 { - 942 curr <- prev curr - 943 break-unless curr - 944 at-start?:bool <- equal curr, start - 945 break-if at-start? - 946 c:char <- get *curr, value:offset - 947 at-newline?:bool <- equal c, 10/newline - 948 break-if at-newline? - 949 # if c is a space, increment result - 950 is-space?:bool <- equal c, 32/space - 951 { - 952 break-unless is-space? - 953 result <- add result, 1 - 954 } - 955 # if c is not a space, reset result - 956 { - 957 break-if is-space? - 958 result <- copy 0 - 959 } - 960 loop - 961 } - 962 ] - 963 - 964 scenario editor-moves-cursor-down-after-inserting-newline-2 [ - 965 local-scope - 966 assume-screen 10/width, 5/height - 967 e:&:editor <- new-editor [abc], 1/left, 10/right - 968 assume-console [ - 969 type [0 - 970 1] - 971 ] - 972 run [ - 973 editor-event-loop screen, console, e - 974 ] - 975 screen-should-contain [ - 976 . . - 977 . 0 . - 978 . 1abc . - 979 . ╌╌╌╌╌╌╌╌╌. - 980 . . - 981 ] - 982 ] - 983 - 984 scenario editor-clears-previous-line-completely-after-inserting-newline [ - 985 local-scope - 986 assume-screen 10/width, 5/height - 987 e:&:editor <- new-editor [abcde], 0/left, 5/right - 988 editor-render screen, e - 989 screen-should-contain [ - 990 . . - 991 .abcd↩ . - 992 .e . - 993 .╌╌╌╌╌ . - 994 . . - 995 ] - 996 assume-console [ - 997 press enter - 998 ] - 999 run [ -1000 editor-event-loop screen, console, e -1001 ] -1002 # line should be fully cleared -1003 screen-should-contain [ -1004 . . -1005 . . -1006 .abcd↩ . -1007 .e . -1008 .╌╌╌╌╌ . -1009 ] -1010 ] -1011 -1012 scenario editor-splits-wrapped-line-after-inserting-newline [ -1013 local-scope -1014 assume-screen 10/width, 5/height -1015 e:&:editor <- new-editor [abcdef], 0/left, 5/right -1016 editor-render screen, e -1017 screen-should-contain [ -1018 . . -1019 .abcd↩ . -1020 .ef . -1021 .╌╌╌╌╌ . -1022 . . -1023 ] -1024 assume-console [ -1025 left-click 2, 0 -1026 press enter -1027 ] -1028 run [ -1029 editor-event-loop screen, console, e -1030 10:num/raw <- get *e, cursor-row:offset -1031 11:num/raw <- get *e, cursor-column:offset -1032 ] -1033 screen-should-contain [ -1034 . . -1035 .abcd . -1036 .ef . -1037 .╌╌╌╌╌ . -1038 ] -1039 memory-should-contain [ -1040 10 <- 2 # cursor-row -1041 11 <- 0 # cursor-column -1042 ] -1043 ] -1044 -1045 scenario editor-inserts-indent-after-newline [ -1046 local-scope -1047 assume-screen 10/width, 10/height -1048 s:text <- new [ab -1049 cd -1050 ef] -1051 e:&:editor <- new-editor s, 0/left, 10/right -1052 # position cursor after 'cd' and hit 'newline' -1053 assume-console [ -1054 left-click 2, 8 -1055 type [ -1056 ] -1057 ] -1058 run [ -1059 editor-event-loop screen, console, e -1060 3:num/raw <- get *e, cursor-row:offset -1061 4:num/raw <- get *e, cursor-column:offset -1062 ] -1063 # cursor should be below start of previous line -1064 memory-should-contain [ -1065 3 <- 3 # cursor row -1066 4 <- 2 # cursor column (indented) -1067 ] -1068 ] -1069 -1070 scenario editor-skips-indent-around-paste [ -1071 local-scope -1072 assume-screen 10/width, 10/height -1073 s:text <- new [ab -1074 cd -1075 ef] -1076 e:&:editor <- new-editor s, 0/left, 10/right -1077 # position cursor after 'cd' and hit 'newline' surrounded by paste markers -1078 assume-console [ -1079 left-click 2, 8 -1080 press 65507 # start paste -1081 press enter -1082 press 65506 # end paste -1083 ] -1084 run [ -1085 editor-event-loop screen, console, e -1086 3:num/raw <- get *e, cursor-row:offset -1087 4:num/raw <- get *e, cursor-column:offset -1088 ] -1089 # cursor should be below start of previous line -1090 memory-should-contain [ -1091 3 <- 3 # cursor row -1092 4 <- 0 # cursor column (not indented) -1093 ] -1094 ] -1095 -1096 after <handle-special-key> [ -1097 { -1098 paste-start?:bool <- equal k, 65507/paste-start -1099 break-unless paste-start? -1100 *editor <- put *editor, indent?:offset, 0/false -1101 return 1/go-render -1102 } -1103 ] -1104 -1105 after <handle-special-key> [ -1106 { -1107 paste-end?:bool <- equal k, 65506/paste-end -1108 break-unless paste-end? -1109 *editor <- put *editor, indent?:offset, 1/true -1110 return 1/go-render -1111 } -1112 ] + 827 container editor [ + 828 indent?:bool + 829 ] + 830 + 831 after <editor-initialization> [ + 832 *result <- put *result, indent?:offset, 1/true + 833 ] + 834 + 835 scenario editor-moves-cursor-down-after-inserting-newline [ + 836 local-scope + 837 assume-screen 10/width, 5/height + 838 e:&:editor <- new-editor [abc], 0/left, 10/right + 839 assume-console [ + 840 type [0 + 841 1] + 842 ] + 843 run [ + 844 editor-event-loop screen, console, e + 845 ] + 846 screen-should-contain [ + 847 . . + 848 .0 . + 849 .1abc . + 850 .╌╌╌╌╌╌╌╌╌╌. + 851 . . + 852 ] + 853 ] + 854 + 855 after <handle-special-character> [ + 856 { + 857 newline?:bool <- equal c, 10/newline + 858 break-unless newline? + 859 <begin-insert-enter> + 860 insert-new-line-and-indent editor, screen + 861 <end-insert-enter> + 862 return 1/go-render + 863 } + 864 ] + 865 + 866 def insert-new-line-and-indent editor:&:editor, screen:&:screen -> editor:&:editor, screen:&:screen [ + 867 local-scope + 868 load-inputs + 869 cursor-row:num <- get *editor, cursor-row:offset + 870 cursor-column:num <- get *editor, cursor-column:offset + 871 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset + 872 left:num <- get *editor, left:offset + 873 right:num <- get *editor, right:offset + 874 screen-height:num <- screen-height screen + 875 # update cursor coordinates + 876 at-start-of-wrapped-line?:bool <- at-start-of-wrapped-line? editor + 877 { + 878 break-if at-start-of-wrapped-line? + 879 cursor-row <- add cursor-row, 1 + 880 *editor <- put *editor, cursor-row:offset, cursor-row + 881 } + 882 cursor-column <- copy left + 883 *editor <- put *editor, cursor-column:offset, cursor-column + 884 # maybe scroll + 885 { + 886 below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal, never greater + 887 break-unless below-screen? + 888 <scroll-down> + 889 cursor-row <- subtract cursor-row, 1 # bring back into screen range + 890 *editor <- put *editor, cursor-row:offset, cursor-row + 891 } + 892 # insert newline + 893 insert 10/newline, before-cursor + 894 before-cursor <- next before-cursor + 895 *editor <- put *editor, before-cursor:offset, before-cursor + 896 # indent if necessary + 897 indent?:bool <- get *editor, indent?:offset + 898 return-unless indent? + 899 d:&:duplex-list:char <- get *editor, data:offset + 900 end-of-previous-line:&:duplex-list:char <- prev before-cursor + 901 indent:num <- line-indent end-of-previous-line, d + 902 i:num <- copy 0 + 903 { + 904 indent-done?:bool <- greater-or-equal i, indent + 905 break-if indent-done? + 906 insert-at-cursor editor, 32/space, screen + 907 i <- add i, 1 + 908 loop + 909 } + 910 ] + 911 + 912 def at-start-of-wrapped-line? editor:&:editor -> result:bool [ + 913 local-scope + 914 load-inputs + 915 left:num <- get *editor, left:offset + 916 cursor-column:num <- get *editor, cursor-column:offset + 917 cursor-at-left?:bool <- equal cursor-column, left + 918 return-unless cursor-at-left?, 0/false + 919 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset + 920 before-before-cursor:&:duplex-list:char <- prev before-cursor + 921 return-unless before-before-cursor, 0/false # cursor is at start of editor + 922 char-before-cursor:char <- get *before-cursor, value:offset + 923 cursor-after-newline?:bool <- equal char-before-cursor, 10/newline + 924 return-if cursor-after-newline?, 0/false + 925 # if cursor is at left margin and not at start, but previous character is not a newline, + 926 # then we're at start of a wrapped line + 927 return 1/true + 928 ] + 929 + 930 # takes a pointer 'curr' into the doubly-linked list and its sentinel, counts + 931 # the number of spaces at the start of the line containing 'curr'. + 932 def line-indent curr:&:duplex-list:char, start:&:duplex-list:char -> result:num [ + 933 local-scope + 934 load-inputs + 935 result:num <- copy 0 + 936 return-unless curr + 937 at-start?:bool <- equal curr, start + 938 return-if at-start? + 939 { + 940 curr <- prev curr + 941 break-unless curr + 942 at-start?:bool <- equal curr, start + 943 break-if at-start? + 944 c:char <- get *curr, value:offset + 945 at-newline?:bool <- equal c, 10/newline + 946 break-if at-newline? + 947 # if c is a space, increment result + 948 is-space?:bool <- equal c, 32/space + 949 { + 950 break-unless is-space? + 951 result <- add result, 1 + 952 } + 953 # if c is not a space, reset result + 954 { + 955 break-if is-space? + 956 result <- copy 0 + 957 } + 958 loop + 959 } + 960 ] + 961 + 962 scenario editor-moves-cursor-down-after-inserting-newline-2 [ + 963 local-scope + 964 assume-screen 10/width, 5/height + 965 e:&:editor <- new-editor [abc], 1/left, 10/right + 966 assume-console [ + 967 type [0 + 968 1] + 969 ] + 970 run [ + 971 editor-event-loop screen, console, e + 972 ] + 973 screen-should-contain [ + 974 . . + 975 . 0 . + 976 . 1abc . + 977 . ╌╌╌╌╌╌╌╌╌. + 978 . . + 979 ] + 980 ] + 981 + 982 scenario editor-clears-previous-line-completely-after-inserting-newline [ + 983 local-scope + 984 assume-screen 10/width, 5/height + 985 e:&:editor <- new-editor [abcde], 0/left, 5/right + 986 editor-render screen, e + 987 screen-should-contain [ + 988 . . + 989 .abcd↩ . + 990 .e . + 991 .╌╌╌╌╌ . + 992 . . + 993 ] + 994 assume-console [ + 995 press enter + 996 ] + 997 run [ + 998 editor-event-loop screen, console, e + 999 ] +1000 # line should be fully cleared +1001 screen-should-contain [ +1002 . . +1003 . . +1004 .abcd↩ . +1005 .e . +1006 .╌╌╌╌╌ . +1007 ] +1008 ] +1009 +1010 scenario editor-splits-wrapped-line-after-inserting-newline [ +1011 local-scope +1012 assume-screen 10/width, 5/height +1013 e:&:editor <- new-editor [abcdef], 0/left, 5/right +1014 editor-render screen, e +1015 screen-should-contain [ +1016 . . +1017 .abcd↩ . +1018 .ef . +1019 .╌╌╌╌╌ . +1020 . . +1021 ] +1022 assume-console [ +1023 left-click 2, 0 +1024 press enter +1025 ] +1026 run [ +1027 editor-event-loop screen, console, e +1028 10:num/raw <- get *e, cursor-row:offset +1029 11:num/raw <- get *e, cursor-column:offset +1030 ] +1031 screen-should-contain [ +1032 . . +1033 .abcd . +1034 .ef . +1035 .╌╌╌╌╌ . +1036 ] +1037 memory-should-contain [ +1038 10 <- 2 # cursor-row +1039 11 <- 0 # cursor-column +1040 ] +1041 ] +1042 +1043 scenario editor-inserts-indent-after-newline [ +1044 local-scope +1045 assume-screen 10/width, 10/height +1046 s:text <- new [ab +1047 cd +1048 ef] +1049 e:&:editor <- new-editor s, 0/left, 10/right +1050 # position cursor after 'cd' and hit 'newline' +1051 assume-console [ +1052 left-click 2, 8 +1053 type [ +1054 ] +1055 ] +1056 run [ +1057 editor-event-loop screen, console, e +1058 3:num/raw <- get *e, cursor-row:offset +1059 4:num/raw <- get *e, cursor-column:offset +1060 ] +1061 # cursor should be below start of previous line +1062 memory-should-contain [ +1063 3 <- 3 # cursor row +1064 4 <- 2 # cursor column (indented) +1065 ] +1066 ] +1067 +1068 scenario editor-skips-indent-around-paste [ +1069 local-scope +1070 assume-screen 10/width, 10/height +1071 s:text <- new [ab +1072 cd +1073 ef] +1074 e:&:editor <- new-editor s, 0/left, 10/right +1075 # position cursor after 'cd' and hit 'newline' surrounded by paste markers +1076 assume-console [ +1077 left-click 2, 8 +1078 press 65507 # start paste +1079 press enter +1080 press 65506 # end paste +1081 ] +1082 run [ +1083 editor-event-loop screen, console, e +1084 3:num/raw <- get *e, cursor-row:offset +1085 4:num/raw <- get *e, cursor-column:offset +1086 ] +1087 # cursor should be below start of previous line +1088 memory-should-contain [ +1089 3 <- 3 # cursor row +1090 4 <- 0 # cursor column (not indented) +1091 ] +1092 ] +1093 +1094 after <handle-special-key> [ +1095 { +1096 paste-start?:bool <- equal k, 65507/paste-start +1097 break-unless paste-start? +1098 *editor <- put *editor, indent?:offset, 0/false +1099 return 1/go-render +1100 } +1101 ] +1102 +1103 after <handle-special-key> [ +1104 { +1105 paste-end?:bool <- equal k, 65506/paste-end +1106 break-unless paste-end? +1107 *editor <- put *editor, indent?:offset, 1/true +1108 return 1/go-render +1109 } +1110 ] +1111 +1112 ## helpers 1113 -1114 ## helpers -1115 -1116 def draw-horizontal screen:&:screen, row:num, x:num, right:num -> screen:&:screen [ -1117 local-scope -1118 load-inputs -1119 height:num <- screen-height screen -1120 past-bottom?:bool <- greater-or-equal row, height -1121 return-if past-bottom? -1122 style:char, style-found?:bool <- next-input -1123 { -1124 break-if style-found? -1125 style <- copy 9472/horizontal -1126 } -1127 color:num, color-found?:bool <- next-input -1128 { -1129 # default color to white -1130 break-if color-found? -1131 color <- copy 245/grey -1132 } -1133 bg-color:num, bg-color-found?:bool <- next-input -1134 { -1135 break-if bg-color-found? -1136 bg-color <- copy 0/black -1137 } -1138 screen <- move-cursor screen, row, x -1139 { -1140 continue?:bool <- lesser-or-equal x, right # right is inclusive, to match editor semantics -1141 break-unless continue? -1142 print screen, style, color, bg-color -1143 x <- add x, 1 -1144 loop -1145 } -1146 ] +1114 def draw-horizontal screen:&:screen, row:num, x:num, right:num -> screen:&:screen [ +1115 local-scope +1116 load-inputs +1117 height:num <- screen-height screen +1118 past-bottom?:bool <- greater-or-equal row, height +1119 return-if past-bottom? +1120 style:char, style-found?:bool <- next-input +1121 { +1122 break-if style-found? +1123 style <- copy 9472/horizontal +1124 } +1125 color:num, color-found?:bool <- next-input +1126 { +1127 # default color to white +1128 break-if color-found? +1129 color <- copy 245/grey +1130 } +1131 bg-color:num, bg-color-found?:bool <- next-input +1132 { +1133 break-if bg-color-found? +1134 bg-color <- copy 0/black +1135 } +1136 screen <- move-cursor screen, row, x +1137 { +1138 continue?:bool <- lesser-or-equal x, right # right is inclusive, to match editor semantics +1139 break-unless continue? +1140 print screen, style, color, bg-color +1141 x <- add x, 1 +1142 loop +1143 } +1144 ] -- cgit 1.4.1-2-gfad0