From 4f2adf06713eeec995d7811cd1d7a4dfe3cdda86 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 27 May 2017 21:32:51 -0700 Subject: 3883 --- html/064list.mu.html | 137 +- html/065duplex_list.mu.html | 176 ++- html/081print.mu.html | 475 +++---- html/chessboard.mu.html | 16 +- html/edit/001-editor.mu.html | 749 +++++----- html/edit/002-typing.mu.html | 28 +- html/edit/003-shortcuts.mu.html | 36 +- html/edit/004-programming-environment.mu.html | 28 +- html/edit/005-sandbox.mu.html | 1798 +++++++++++++------------ html/edit/006-sandbox-copy.mu.html | 138 +- html/edit/007-sandbox-delete.mu.html | 44 +- html/edit/008-sandbox-edit.mu.html | 30 +- html/edit/009-sandbox-test.mu.html | 12 +- html/edit/010-sandbox-trace.mu.html | 18 +- html/edit/011-errors.mu.html | 24 +- html/edit/012-editor-undo.mu.html | 2 +- html/screen.mu.html | 6 +- 17 files changed, 1977 insertions(+), 1740 deletions(-) diff --git a/html/064list.mu.html b/html/064list.mu.html index f11fea88..9f206ff4 100644 --- a/html/064list.mu.html +++ b/html/064list.mu.html @@ -338,7 +338,7 @@ if ('onhashchange' in window) { 276 277 scenario reverse-list [ 278 local-scope -279 list:&:list:number <- push 1, 0 +279 list:&:list:num <- push 1, 0 280 list <- push 2, list 281 list <- push 3, list 282 run [ @@ -352,68 +352,81 @@ if ('onhashchange' in window) { 290 ] 291 ] 292 -293 def to-text in:&:list:_elem -> result:text [ +293 scenario stash-list [ 294 local-scope -295 load-ingredients -296 buf:&:buffer:char <- new-buffer 80 -297 buf <- to-buffer in, buf -298 result <- buffer-to-array buf -299 ] -300 -301 # variant of 'to-text' which stops printing after a few elements (and so is robust to cycles) -302 def to-text-line in:&:list:_elem -> result:text [ -303 local-scope -304 load-ingredients -305 buf:&:buffer:char <- new-buffer 80 -306 buf <- to-buffer in, buf, 6 # max elements to display -307 result <- buffer-to-array buf -308 ] -309 -310 def to-buffer in:&:list:_elem, buf:&:buffer:char -> buf:&:buffer:char [ -311 local-scope -312 load-ingredients -313 { -314 ¦ break-if in -315 ¦ buf <- append buf, [[]] -316 ¦ return -317 } -318 # append in.value to buf -319 val:_elem <- get *in, value:offset -320 buf <- append buf, val -321 # now prepare next -322 next:&:list:_elem <- rest in -323 nextn:num <- copy next -324 return-unless next -325 buf <- append buf, [ -> ] -326 # and recurse -327 remaining:num, optional-ingredient-found?:bool <- next-ingredient -328 { -329 ¦ break-if optional-ingredient-found? -330 ¦ # unlimited recursion -331 ¦ buf <- to-buffer next, buf -332 ¦ return -333 } -334 { -335 ¦ break-unless remaining -336 ¦ # limited recursion -337 ¦ remaining <- subtract remaining, 1 -338 ¦ buf <- to-buffer next, buf, remaining -339 ¦ return -340 } -341 # past recursion depth; insert ellipses and stop -342 append buf, [...] -343 ] -344 -345 scenario stash-empty-list [ -346 local-scope -347 x:&:list:num <- copy 0 -348 run [ -349 ¦ stash x -350 ] -351 trace-should-contain [ -352 ¦ app: [] -353 ] -354 ] +295 list:&:list:num <- push 1, 0 +296 list <- push 2, list +297 list <- push 3, list +298 run [ +299 ¦ stash [list:], list +300 ] +301 trace-should-contain [ +302 ¦ app: list: 3 -> 2 -> 1 +303 ] +304 ] +305 +306 def to-text in:&:list:_elem -> result:text [ +307 local-scope +308 load-ingredients +309 buf:&:buffer:char <- new-buffer 80 +310 buf <- to-buffer in, buf +311 result <- buffer-to-array buf +312 ] +313 +314 # variant of 'to-text' which stops printing after a few elements (and so is robust to cycles) +315 def to-text-line in:&:list:_elem -> result:text [ +316 local-scope +317 load-ingredients +318 buf:&:buffer:char <- new-buffer 80 +319 buf <- to-buffer in, buf, 6 # max elements to display +320 result <- buffer-to-array buf +321 ] +322 +323 def to-buffer in:&:list:_elem, buf:&:buffer:char -> buf:&:buffer:char [ +324 local-scope +325 load-ingredients +326 { +327 ¦ break-if in +328 ¦ buf <- append buf, [[]] +329 ¦ return +330 } +331 # append in.value to buf +332 val:_elem <- get *in, value:offset +333 buf <- append buf, val +334 # now prepare next +335 next:&:list:_elem <- rest in +336 nextn:num <- copy next +337 return-unless next +338 buf <- append buf, [ -> ] +339 # and recurse +340 remaining:num, optional-ingredient-found?:bool <- next-ingredient +341 { +342 ¦ break-if optional-ingredient-found? +343 ¦ # unlimited recursion +344 ¦ buf <- to-buffer next, buf +345 ¦ return +346 } +347 { +348 ¦ break-unless remaining +349 ¦ # limited recursion +350 ¦ remaining <- subtract remaining, 1 +351 ¦ buf <- to-buffer next, buf, remaining +352 ¦ return +353 } +354 # past recursion depth; insert ellipses and stop +355 append buf, [...] +356 ] +357 +358 scenario stash-empty-list [ +359 local-scope +360 x:&:list:num <- copy 0 +361 run [ +362 ¦ stash x +363 ] +364 trace-should-contain [ +365 ¦ app: [] +366 ] +367 ] diff --git a/html/065duplex_list.mu.html b/html/065duplex_list.mu.html index 8f0cf4a8..59924127 100644 --- a/html/065duplex_list.mu.html +++ b/html/065duplex_list.mu.html @@ -561,7 +561,7 @@ if ('onhashchange' in window) { 499 load-ingredients 500 return-unless in 501 return-unless start -502 end:&:duplex-list:_elem <- last start +502 end:&:duplex-list:_elem <- last start 503 next:&:duplex-list:_elem <- next in 504 { 505 ¦ break-unless next @@ -572,47 +572,145 @@ if ('onhashchange' in window) { 510 *start <- put *start, prev:offset, in 511 ] 512 -513 def append in:&:duplex-list:_elem, new:&:duplex-list:_elem/contained-in:in -> in:&:duplex-list:_elem [ -514 local-scope -515 load-ingredients -516 last:&:duplex-list:_elem <- last in -517 *last <- put *last, next:offset, new +513 # insert contents of 'new' after 'in' +514 def insert in:&:duplex-list:_elem, new:&:@:_elem -> in:&:duplex-list:_elem [ +515 local-scope +516 load-ingredients +517 return-unless in 518 return-unless new -519 *new <- put *new, prev:offset, last -520 ] -521 -522 def last in:&:duplex-list:_elem -> result:&:duplex-list:_elem [ -523 local-scope -524 load-ingredients -525 result <- copy in -526 { -527 ¦ next:&:duplex-list:_elem <- next result -528 ¦ break-unless next -529 ¦ result <- copy next -530 ¦ loop -531 } -532 ] -533 -534 # helper for debugging -535 def dump-from x:&:duplex-list:_elem [ +519 len:num <- length *new +520 return-unless len +521 curr:&:duplex-list:_elem <- copy in +522 idx:num <- copy 0 +523 { +524 ¦ done?:bool <- greater-or-equal idx, len +525 ¦ break-if done? +526 ¦ c:_elem <- index *new, idx +527 ¦ insert c, curr +528 ¦ # next iter +529 ¦ curr <- next curr +530 ¦ idx <- add idx, 1 +531 ¦ loop +532 } +533 ] +534 +535 def append in:&:duplex-list:_elem, new:&:duplex-list:_elem/contained-in:in -> in:&:duplex-list:_elem [ 536 local-scope 537 load-ingredients -538 $print x, [: ] -539 { -540 ¦ break-unless x -541 ¦ c:_elem <- get *x, value:offset -542 ¦ $print c, [ ] -543 ¦ x <- next x -544 ¦ { -545 ¦ ¦ is-newline?:bool <- equal c, 10/newline -546 ¦ ¦ break-unless is-newline? -547 ¦ ¦ $print 10/newline -548 ¦ ¦ $print x, [: ] -549 ¦ } -550 ¦ loop -551 } -552 $print 10/newline, [---], 10/newline -553 ] +538 last:&:duplex-list:_elem <- last in +539 *last <- put *last, next:offset, new +540 return-unless new +541 *new <- put *new, prev:offset, last +542 ] +543 +544 def last in:&:duplex-list:_elem -> result:&:duplex-list:_elem [ +545 local-scope +546 load-ingredients +547 result <- copy in +548 { +549 ¦ next:&:duplex-list:_elem <- next result +550 ¦ break-unless next +551 ¦ result <- copy next +552 ¦ loop +553 } +554 ] +555 +556 # helper for debugging +557 def dump-from x:&:duplex-list:_elem [ +558 local-scope +559 load-ingredients +560 $print x, [: ] +561 { +562 ¦ break-unless x +563 ¦ c:_elem <- get *x, value:offset +564 ¦ $print c, [ ] +565 ¦ x <- next x +566 ¦ { +567 ¦ ¦ is-newline?:bool <- equal c, 10/newline +568 ¦ ¦ break-unless is-newline? +569 ¦ ¦ $print 10/newline +570 ¦ ¦ $print x, [: ] +571 ¦ } +572 ¦ loop +573 } +574 $print 10/newline, [---], 10/newline +575 ] +576 +577 scenario stash-duplex-list [ +578 local-scope +579 list:&:duplex-list:num <- push 1, 0 +580 list <- push 2, list +581 list <- push 3, list +582 run [ +583 ¦ stash [list:], list +584 ] +585 trace-should-contain [ +586 ¦ app: list: 3 <-> 2 <-> 1 +587 ] +588 ] +589 +590 def to-text in:&:duplex-list:_elem -> result:text [ +591 local-scope +592 load-ingredients +593 buf:&:buffer:char <- new-buffer 80 +594 buf <- to-buffer in, buf +595 result <- buffer-to-array buf +596 ] +597 +598 # variant of 'to-text' which stops printing after a few elements (and so is robust to cycles) +599 def to-text-line in:&:duplex-list:_elem -> result:text [ +600 local-scope +601 load-ingredients +602 buf:&:buffer:char <- new-buffer 80 +603 buf <- to-buffer in, buf, 6 # max elements to display +604 result <- buffer-to-array buf +605 ] +606 +607 def to-buffer in:&:duplex-list:_elem, buf:&:buffer:char -> buf:&:buffer:char [ +608 local-scope +609 load-ingredients +610 { +611 ¦ break-if in +612 ¦ buf <- append buf, [[]] +613 ¦ return +614 } +615 # append in.value to buf +616 val:_elem <- get *in, value:offset +617 buf <- append buf, val +618 # now prepare next +619 next:&:duplex-list:_elem <- next in +620 nextn:num <- copy next +621 return-unless next +622 buf <- append buf, [ <-> ] +623 # and recurse +624 remaining:num, optional-ingredient-found?:bool <- next-ingredient +625 { +626 ¦ break-if optional-ingredient-found? +627 ¦ # unlimited recursion +628 ¦ buf <- to-buffer next, buf +629 ¦ return +630 } +631 { +632 ¦ break-unless remaining +633 ¦ # limited recursion +634 ¦ remaining <- subtract remaining, 1 +635 ¦ buf <- to-buffer next, buf, remaining +636 ¦ return +637 } +638 # past recursion depth; insert ellipses and stop +639 append buf, [...] +640 ] +641 +642 scenario stash-empty-duplex-list [ +643 local-scope +644 x:&:duplex-list:num <- copy 0 +645 run [ +646 ¦ stash x +647 ] +648 trace-should-contain [ +649 ¦ app: [] +650 ] +651 ] diff --git a/html/081print.mu.html b/html/081print.mu.html index 22a4c11b..01a5dd12 100644 --- a/html/081print.mu.html +++ b/html/081print.mu.html @@ -286,7 +286,7 @@ if ('onhashchange' in window) { 223 # clear top line and 'rotate' it to the bottom 224 top-idx:num <- get *screen, top-idx:offset # 0 <= top-idx < len(buf) 225 next-top-idx:num <- add top-idx, width # 0 <= next-top-idx <= len(buf) -226 empty-cell:screen-cell <- merge 0, 0 +226 empty-cell:screen-cell <- merge 0/empty, 7/white 227 { 228 ¦ done?:bool <- greater-or-equal top-idx, next-top-idx 229 ¦ break-if done? @@ -546,7 +546,7 @@ if ('onhashchange' in window) { 483 ¦ 21 <- 101 # 'e' 484 ¦ 22 <- 7 # white 485 ¦ 23 <- 0 # unused -486 ¦ 24 <- 0 # no color +486 ¦ 24 <- 7 # white 487 ] 488 ] 489 @@ -600,7 +600,7 @@ if ('onhashchange' in window) { 537 local-scope 538 load-ingredients 539 row:num, column:num <- cursor-position screen -540 height:num <- screen-height screen +540 height:num <- screen-height screen 541 past-bottom?:bool <- greater-or-equal row, height 542 return-if past-bottom? 543 space:char <- copy 32/space @@ -688,229 +688,252 @@ if ('onhashchange' in window) { 625 ¦ return 626 } 627 # fake screen -628 height:num <- get *screen, num-rows:offset -629 row:num <- get *screen, cursor-row:offset -630 max:num <- subtract height, 1 -631 at-bottom?:bool <- greater-or-equal row, max -632 return-if at-bottom? -633 row <- add row, 1 -634 *screen <- put *screen, cursor-row:offset, row -635 ] -636 -637 def cursor-up screen:&:screen -> screen:&:screen [ -638 local-scope -639 load-ingredients -640 { -641 ¦ break-if screen -642 ¦ # real screen -643 ¦ move-cursor-up-on-display -644 ¦ return -645 } -646 # fake screen -647 row:num <- get *screen, cursor-row:offset -648 at-top?:bool <- lesser-or-equal row, 0 -649 return-if at-top? -650 row <- subtract row, 1 -651 *screen <- put *screen, cursor-row:offset, row -652 ] -653 -654 def cursor-right screen:&:screen -> screen:&:screen [ -655 local-scope -656 load-ingredients -657 { -658 ¦ break-if screen -659 ¦ # real screen -660 ¦ move-cursor-right-on-display -661 ¦ return -662 } -663 # fake screen -664 width:num <- get *screen, num-columns:offset -665 column:num <- get *screen, cursor-column:offset -666 max:num <- subtract width, 1 -667 at-bottom?:bool <- greater-or-equal column, max -668 return-if at-bottom? -669 column <- add column, 1 -670 *screen <- put *screen, cursor-column:offset, column -671 ] -672 -673 def cursor-left screen:&:screen -> screen:&:screen [ -674 local-scope -675 load-ingredients -676 { -677 ¦ break-if screen -678 ¦ # real screen -679 ¦ move-cursor-left-on-display -680 ¦ return -681 } -682 # fake screen -683 column:num <- get *screen, cursor-column:offset -684 at-top?:bool <- lesser-or-equal column, 0 -685 return-if at-top? -686 column <- subtract column, 1 -687 *screen <- put *screen, cursor-column:offset, column -688 ] -689 -690 def cursor-to-start-of-line screen:&:screen -> screen:&:screen [ -691 local-scope -692 load-ingredients -693 row:num <- cursor-position screen -694 column:num <- copy 0 -695 screen <- move-cursor screen, row, column -696 ] -697 -698 def cursor-to-next-line screen:&:screen -> screen:&:screen [ -699 local-scope -700 load-ingredients -701 screen <- cursor-down screen -702 screen <- cursor-to-start-of-line screen -703 ] -704 -705 def move-cursor-to-column screen:&:screen, column:num -> screen:&:screen [ -706 local-scope -707 load-ingredients -708 row:num, _ <- cursor-position screen -709 move-cursor screen, row, column -710 ] -711 -712 def screen-width screen:&:screen -> width:num [ -713 local-scope -714 load-ingredients -715 { -716 ¦ break-unless screen -717 ¦ # fake screen -718 ¦ width <- get *screen, num-columns:offset -719 ¦ return -720 } -721 # real screen -722 width <- display-width -723 ] -724 -725 def screen-height screen:&:screen -> height:num [ -726 local-scope -727 load-ingredients -728 { -729 ¦ break-unless screen -730 ¦ # fake screen -731 ¦ height <- get *screen, num-rows:offset -732 ¦ return -733 } -734 # real screen -735 height <- display-height -736 ] -737 -738 def print screen:&:screen, s:text -> screen:&:screen [ -739 local-scope -740 load-ingredients -741 color:num, color-found?:bool <- next-ingredient -742 { -743 ¦ # default color to white -744 ¦ break-if color-found? -745 ¦ color <- copy 7/white -746 } -747 bg-color:num, bg-color-found?:bool <- next-ingredient -748 { -749 ¦ # default bg-color to black -750 ¦ break-if bg-color-found? -751 ¦ bg-color <- copy 0/black -752 } -753 len:num <- length *s -754 i:num <- copy 0 -755 { -756 ¦ done?:bool <- greater-or-equal i, len -757 ¦ break-if done? -758 ¦ c:char <- index *s, i -759 ¦ print screen, c, color, bg-color -760 ¦ i <- add i, 1 -761 ¦ loop -762 } -763 ] -764 -765 scenario print-text-wraps-past-right-margin [ -766 local-scope -767 fake-screen:&:screen <- new-fake-screen 3/width, 2/height -768 run [ -769 ¦ fake-screen <- print fake-screen, [abcd] -770 ¦ 5:num/raw <- get *fake-screen, cursor-row:offset -771 ¦ 6:num/raw <- get *fake-screen, cursor-column:offset -772 ¦ 7:num/raw <- get *fake-screen, top-idx:offset -773 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset -774 ¦ 10:@:screen-cell/raw <- copy *cell -775 ] -776 memory-should-contain [ -777 ¦ 5 <- 1 # cursor-row -778 ¦ 6 <- 1 # cursor-column -779 ¦ 7 <- 0 # top-idx -780 ¦ 10 <- 6 # width*height -781 ¦ 11 <- 97 # 'a' -782 ¦ 12 <- 7 # white -783 ¦ 13 <- 98 # 'b' -784 ¦ 14 <- 7 # white -785 ¦ 15 <- 99 # 'c' -786 ¦ 16 <- 7 # white -787 ¦ 17 <- 100 # 'd' -788 ¦ 18 <- 7 # white -789 ¦ # rest of screen is empty -790 ¦ 19 <- 0 -791 ] -792 ] -793 -794 def print screen:&:screen, n:num -> screen:&:screen [ -795 local-scope -796 load-ingredients -797 color:num, color-found?:bool <- next-ingredient -798 { -799 ¦ # default color to white -800 ¦ break-if color-found? -801 ¦ color <- copy 7/white -802 } -803 bg-color:num, bg-color-found?:bool <- next-ingredient -804 { -805 ¦ # default bg-color to black -806 ¦ break-if bg-color-found? -807 ¦ bg-color <- copy 0/black -808 } -809 # todo: other bases besides decimal -810 s:text <- to-text n -811 screen <- print screen, s, color, bg-color -812 ] -813 -814 def print screen:&:screen, n:bool -> screen:&:screen [ -815 local-scope -816 load-ingredients -817 color:num, color-found?:bool <- next-ingredient -818 { -819 ¦ # default color to white -820 ¦ break-if color-found? -821 ¦ color <- copy 7/white -822 } -823 bg-color:num, bg-color-found?:bool <- next-ingredient -824 { -825 ¦ # default bg-color to black -826 ¦ break-if bg-color-found? -827 ¦ bg-color <- copy 0/black -828 } -829 n2:num <- copy n -830 screen <- print screen, n2, color, bg-color -831 ] -832 -833 def print screen:&:screen, n:&:_elem -> screen:&:screen [ -834 local-scope -835 load-ingredients -836 color:num, color-found?:bool <- next-ingredient -837 { -838 ¦ # default color to white -839 ¦ break-if color-found? -840 ¦ color <- copy 7/white -841 } -842 bg-color:num, bg-color-found?:bool <- next-ingredient -843 { -844 ¦ # default bg-color to black -845 ¦ break-if bg-color-found? -846 ¦ bg-color <- copy 0/black -847 } -848 n2:num <- copy n -849 screen <- print screen, n2, color, bg-color -850 ] +628 cursor-down-on-fake-screen screen +629 ] +630 +631 scenario cursor-down-scrolls [ +632 local-scope +633 fake-screen:&:screen <- new-fake-screen 3/width, 2/height +634 # print something to screen and scroll +635 run [ +636 ¦ print fake-screen, [abc] +637 ¦ cursor-to-next-line fake-screen +638 ¦ cursor-to-next-line fake-screen +639 ¦ data:&:@:screen-cell <- get *fake-screen, data:offset +640 ¦ 10:@:screen-cell/raw <- copy *data +641 ] +642 # screen is now blank +643 memory-should-contain [ +644 ¦ 10 <- 6 # width*height +645 ¦ 11 <- 0 +646 ¦ 12 <- 7 # white +647 ¦ 13 <- 0 +648 ¦ 14 <- 7 # white +649 ¦ 15 <- 0 +650 ¦ 16 <- 7 # white +651 ¦ 17 <- 0 +652 ¦ 18 <- 7 # white +653 ¦ 19 <- 0 +654 ¦ 20 <- 7 # white +655 ¦ 21 <- 0 +656 ¦ 22 <- 7 # white +657 ] +658 ] +659 +660 def cursor-up screen:&:screen -> screen:&:screen [ +661 local-scope +662 load-ingredients +663 { +664 ¦ break-if screen +665 ¦ # real screen +666 ¦ move-cursor-up-on-display +667 ¦ return +668 } +669 # fake screen +670 row:num <- get *screen, cursor-row:offset +671 at-top?:bool <- lesser-or-equal row, 0 +672 return-if at-top? +673 row <- subtract row, 1 +674 *screen <- put *screen, cursor-row:offset, row +675 ] +676 +677 def cursor-right screen:&:screen -> screen:&:screen [ +678 local-scope +679 load-ingredients +680 { +681 ¦ break-if screen +682 ¦ # real screen +683 ¦ move-cursor-right-on-display +684 ¦ return +685 } +686 # fake screen +687 width:num <- get *screen, num-columns:offset +688 column:num <- get *screen, cursor-column:offset +689 max:num <- subtract width, 1 +690 at-bottom?:bool <- greater-or-equal column, max +691 return-if at-bottom? +692 column <- add column, 1 +693 *screen <- put *screen, cursor-column:offset, column +694 ] +695 +696 def cursor-left screen:&:screen -> screen:&:screen [ +697 local-scope +698 load-ingredients +699 { +700 ¦ break-if screen +701 ¦ # real screen +702 ¦ move-cursor-left-on-display +703 ¦ return +704 } +705 # fake screen +706 column:num <- get *screen, cursor-column:offset +707 at-top?:bool <- lesser-or-equal column, 0 +708 return-if at-top? +709 column <- subtract column, 1 +710 *screen <- put *screen, cursor-column:offset, column +711 ] +712 +713 def cursor-to-start-of-line screen:&:screen -> screen:&:screen [ +714 local-scope +715 load-ingredients +716 row:num <- cursor-position screen +717 column:num <- copy 0 +718 screen <- move-cursor screen, row, column +719 ] +720 +721 def cursor-to-next-line screen:&:screen -> screen:&:screen [ +722 local-scope +723 load-ingredients +724 screen <- cursor-down screen +725 screen <- cursor-to-start-of-line screen +726 ] +727 +728 def move-cursor-to-column screen:&:screen, column:num -> screen:&:screen [ +729 local-scope +730 load-ingredients +731 row:num, _ <- cursor-position screen +732 move-cursor screen, row, column +733 ] +734 +735 def screen-width screen:&:screen -> width:num [ +736 local-scope +737 load-ingredients +738 { +739 ¦ break-unless screen +740 ¦ # fake screen +741 ¦ width <- get *screen, num-columns:offset +742 ¦ return +743 } +744 # real screen +745 width <- display-width +746 ] +747 +748 def screen-height screen:&:screen -> height:num [ +749 local-scope +750 load-ingredients +751 { +752 ¦ break-unless screen +753 ¦ # fake screen +754 ¦ height <- get *screen, num-rows:offset +755 ¦ return +756 } +757 # real screen +758 height <- display-height +759 ] +760 +761 def print screen:&:screen, s:text -> screen:&:screen [ +762 local-scope +763 load-ingredients +764 color:num, color-found?:bool <- next-ingredient +765 { +766 ¦ # default color to white +767 ¦ break-if color-found? +768 ¦ color <- copy 7/white +769 } +770 bg-color:num, bg-color-found?:bool <- next-ingredient +771 { +772 ¦ # default bg-color to black +773 ¦ break-if bg-color-found? +774 ¦ bg-color <- copy 0/black +775 } +776 len:num <- length *s +777 i:num <- copy 0 +778 { +779 ¦ done?:bool <- greater-or-equal i, len +780 ¦ break-if done? +781 ¦ c:char <- index *s, i +782 ¦ print screen, c, color, bg-color +783 ¦ i <- add i, 1 +784 ¦ loop +785 } +786 ] +787 +788 scenario print-text-wraps-past-right-margin [ +789 local-scope +790 fake-screen:&:screen <- new-fake-screen 3/width, 2/height +791 run [ +792 ¦ fake-screen <- print fake-screen, [abcd] +793 ¦ 5:num/raw <- get *fake-screen, cursor-row:offset +794 ¦ 6:num/raw <- get *fake-screen, cursor-column:offset +795 ¦ 7:num/raw <- get *fake-screen, top-idx:offset +796 ¦ cell:&:@:screen-cell <- get *fake-screen, data:offset +797 ¦ 10:@:screen-cell/raw <- copy *cell +798 ] +799 memory-should-contain [ +800 ¦ 5 <- 1 # cursor-row +801 ¦ 6 <- 1 # cursor-column +802 ¦ 7 <- 0 # top-idx +803 ¦ 10 <- 6 # width*height +804 ¦ 11 <- 97 # 'a' +805 ¦ 12 <- 7 # white +806 ¦ 13 <- 98 # 'b' +807 ¦ 14 <- 7 # white +808 ¦ 15 <- 99 # 'c' +809 ¦ 16 <- 7 # white +810 ¦ 17 <- 100 # 'd' +811 ¦ 18 <- 7 # white +812 ¦ # rest of screen is empty +813 ¦ 19 <- 0 +814 ] +815 ] +816 +817 def print screen:&:screen, n:num -> screen:&:screen [ +818 local-scope +819 load-ingredients +820 color:num, color-found?:bool <- next-ingredient +821 { +822 ¦ # default color to white +823 ¦ break-if color-found? +824 ¦ color <- copy 7/white +825 } +826 bg-color:num, bg-color-found?:bool <- next-ingredient +827 { +828 ¦ # default bg-color to black +829 ¦ break-if bg-color-found? +830 ¦ bg-color <- copy 0/black +831 } +832 # todo: other bases besides decimal +833 s:text <- to-text n +834 screen <- print screen, s, color, bg-color +835 ] +836 +837 def print screen:&:screen, n:bool -> screen:&:screen [ +838 local-scope +839 load-ingredients +840 color:num, color-found?:bool <- next-ingredient +841 { +842 ¦ # default color to white +843 ¦ break-if color-found? +844 ¦ color <- copy 7/white +845 } +846 bg-color:num, bg-color-found?:bool <- next-ingredient +847 { +848 ¦ # default bg-color to black +849 ¦ break-if bg-color-found? +850 ¦ bg-color <- copy 0/black +851 } +852 n2:num <- copy n +853 screen <- print screen, n2, color, bg-color +854 ] +855 +856 def print screen:&:screen, n:&:_elem -> screen:&:screen [ +857 local-scope +858 load-ingredients +859 color:num, color-found?:bool <- next-ingredient +860 { +861 ¦ # default color to white +862 ¦ break-if color-found? +863 ¦ color <- copy 7/white +864 } +865 bg-color:num, bg-color-found?:bool <- next-ingredient +866 { +867 ¦ # default bg-color to black +868 ¦ break-if bg-color-found? +869 ¦ bg-color <- copy 0/black +870 } +871 n2:num <- copy n +872 screen <- print screen, n2, color, bg-color +873 ] diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html index bf292492..ba7e6443 100644 --- a/html/chessboard.mu.html +++ b/html/chessboard.mu.html @@ -143,16 +143,16 @@ if ('onhashchange' in window) { 79 { 80 ¦ print screen, [Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves. 81 ] - 82 ¦ cursor-to-next-line screen + 82 ¦ cursor-to-next-line screen 83 ¦ print-board screen, board - 84 ¦ cursor-to-next-line screen + 84 ¦ cursor-to-next-line screen 85 ¦ print screen, [Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>. 86 ] - 87 ¦ cursor-to-next-line screen + 87 ¦ cursor-to-next-line screen 88 ¦ print screen [Hit 'q' to exit. 89 ] 90 ¦ { - 91 ¦ ¦ cursor-to-next-line screen + 91 ¦ ¦ cursor-to-next-line screen 92 ¦ ¦ screen <- print screen, [move: ] 93 ¦ ¦ m:&:move, quit:bool, error:bool <- read-move buffered-stdin-in, screen 94 ¦ ¦ break-if quit, +quit @@ -231,14 +231,14 @@ if ('onhashchange' in window) { 167 ¦ ¦ loop 168 ¦ } 169 ¦ row <- subtract row, 1 -170 ¦ cursor-to-next-line screen +170 ¦ cursor-to-next-line screen 171 ¦ loop 172 } 173 # print file letters as legend 174 print screen, [ +----------------] -175 cursor-to-next-line screen +175 cursor-to-next-line screen 176 print screen, [ a b c d e f g h] -177 cursor-to-next-line screen +177 cursor-to-next-line screen 178 ] 179 180 def initial-position -> board:board [ @@ -360,7 +360,7 @@ if ('onhashchange' in window) { 296 ¦ break-if above-min 297 ¦ print screen, [file too low: ] 298 ¦ print screen, c -299 ¦ cursor-to-next-line screen +299 ¦ cursor-to-next-line screen 300 ¦ return 0/dummy, 0/quit, 1/error 301 } 302 { diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html index 7e0b7903..dcc7bfd5 100644 --- a/html/edit/001-editor.mu.html +++ b/html/edit/001-editor.mu.html @@ -71,7 +71,7 @@ if ('onhashchange' in window) { 8 open-console 9 clear-screen 0/screen # non-scrolling app 10 e:&:editor <- new-editor text, 0/left, 5/right - 11 render 0/screen, e + 11 render 0/screen, e 12 wait-for-event 0/console 13 close-console 14 ] @@ -81,7 +81,7 @@ if ('onhashchange' in window) { 18 assume-screen 10/width, 5/height 19 e:&:editor <- new-editor [abc], 0/left, 10/right 20 run [ - 21 ¦ render screen, e + 21 ¦ render screen, e 22 ] 23 screen-should-contain [ 24 ¦ # top line of screen reserved for menu @@ -135,407 +135,392 @@ if ('onhashchange' in window) { 72 def insert-text editor:&:editor, text:text -> editor:&:editor [ 73 local-scope 74 load-ingredients - 75 # early exit if text is empty - 76 return-unless text - 77 len:num <- length *text - 78 return-unless len - 79 idx:num <- copy 0 - 80 # now we can start appending the rest, character by character - 81 curr:&:duplex-list:char <- get *editor, data:offset - 82 { - 83 ¦ done?:bool <- greater-or-equal idx, len - 84 ¦ break-if done? - 85 ¦ c:char <- index *text, idx - 86 ¦ insert c, curr - 87 ¦ # next iter - 88 ¦ curr <- next curr - 89 ¦ idx <- add idx, 1 - 90 ¦ loop - 91 } - 92 ] - 93 - 94 scenario editor-initializes-without-data [ - 95 local-scope - 96 assume-screen 5/width, 3/height - 97 run [ - 98 ¦ e:&:editor <- new-editor 0/data, 2/left, 5/right - 99 ¦ 2:editor/raw <- copy *e -100 ] -101 memory-should-contain [ -102 ¦ # 2 (data) <- just the § sentinel -103 ¦ # 3 (top of screen) <- the § sentinel -104 ¦ 4 <- 0 # bottom-of-screen; null since text fits on screen -105 ¦ # 5 (before cursor) <- the § sentinel -106 ¦ 6 <- 2 # left -107 ¦ 7 <- 4 # right (inclusive) -108 ¦ 8 <- 0 # bottom (not set until render) -109 ¦ 9 <- 1 # cursor row -110 ¦ 10 <- 2 # cursor column -111 ] -112 screen-should-contain [ -113 ¦ . . -114 ¦ . . -115 ¦ . . -116 ] -117 ] -118 -119 # Assumes cursor should be at coordinates (cursor-row, cursor-column) and -120 # updates before-cursor to match. Might also move coordinates if they're -121 # outside text. -122 def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, screen:&:screen, editor:&:editor [ -123 local-scope -124 load-ingredients -125 return-unless editor, 1/top, 0/left -126 left:num <- get *editor, left:offset -127 screen-height:num <- screen-height screen -128 right:num <- get *editor, right:offset -129 # traversing editor -130 curr:&:duplex-list:char <- get *editor, top-of-screen:offset -131 prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev -132 curr <- next curr -133 # traversing screen -134 color:num <- copy 7/white -135 row:num <- copy 1/top -136 column:num <- copy left -137 cursor-row:num <- get *editor, cursor-row:offset -138 cursor-column:num <- get *editor, cursor-column:offset -139 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset -140 screen <- move-cursor screen, row, column -141 { -142 ¦ +next-character -143 ¦ break-unless curr -144 ¦ off-screen?:bool <- greater-or-equal row, screen-height -145 ¦ break-if off-screen? -146 ¦ # update editor.before-cursor -147 ¦ # Doing so at the start of each iteration ensures it stays one step behind -148 ¦ # the current character. -149 ¦ { -150 ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row -151 ¦ ¦ break-unless at-cursor-row? -152 ¦ ¦ at-cursor?:bool <- equal column, cursor-column -153 ¦ ¦ break-unless at-cursor? -154 ¦ ¦ before-cursor <- copy prev -155 ¦ } -156 ¦ c:char <- get *curr, value:offset -157 ¦ <character-c-received> -158 ¦ { -159 ¦ ¦ # newline? move to left rather than 0 -160 ¦ ¦ newline?:bool <- equal c, 10/newline -161 ¦ ¦ break-unless newline? -162 ¦ ¦ # adjust cursor if necessary -163 ¦ ¦ { -164 ¦ ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row -165 ¦ ¦ ¦ break-unless at-cursor-row? -166 ¦ ¦ ¦ left-of-cursor?:bool <- lesser-than column, cursor-column -167 ¦ ¦ ¦ break-unless left-of-cursor? -168 ¦ ¦ ¦ cursor-column <- copy column -169 ¦ ¦ ¦ before-cursor <- prev curr -170 ¦ ¦ } -171 ¦ ¦ # clear rest of line in this window -172 ¦ ¦ clear-line-until screen, right -173 ¦ ¦ # skip to next line -174 ¦ ¦ row <- add row, 1 -175 ¦ ¦ column <- copy left + 75 curr:&:duplex-list:char <- get *editor, data:offset + 76 insert curr, text + 77 ] + 78 + 79 scenario editor-initializes-without-data [ + 80 local-scope + 81 assume-screen 5/width, 3/height + 82 run [ + 83 ¦ e:&:editor <- new-editor 0/data, 2/left, 5/right + 84 ¦ 2:editor/raw <- copy *e + 85 ] + 86 memory-should-contain [ + 87 ¦ # 2 (data) <- just the § sentinel + 88 ¦ # 3 (top of screen) <- the § sentinel + 89 ¦ 4 <- 0 # bottom-of-screen; null since text fits on screen + 90 ¦ # 5 (before cursor) <- the § sentinel + 91 ¦ 6 <- 2 # left + 92 ¦ 7 <- 4 # right (inclusive) + 93 ¦ 8 <- 0 # bottom (not set until render) + 94 ¦ 9 <- 1 # cursor row + 95 ¦ 10 <- 2 # cursor column + 96 ] + 97 screen-should-contain [ + 98 ¦ . . + 99 ¦ . . +100 ¦ . . +101 ] +102 ] +103 +104 # Assumes cursor should be at coordinates (cursor-row, cursor-column) and +105 # updates before-cursor to match. Might also move coordinates if they're +106 # outside text. +107 def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, screen:&:screen, editor:&:editor [ +108 local-scope +109 load-ingredients +110 return-unless editor, 1/top, 0/left +111 left:num <- get *editor, left:offset +112 screen-height:num <- screen-height screen +113 right:num <- get *editor, right:offset +114 # traversing editor +115 curr:&:duplex-list:char <- get *editor, top-of-screen:offset +116 prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev +117 curr <- next curr +118 # traversing screen +119 color:num <- copy 7/white +120 row:num <- copy 1/top +121 column:num <- copy left +122 cursor-row:num <- get *editor, cursor-row:offset +123 cursor-column:num <- get *editor, cursor-column:offset +124 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset +125 screen <- move-cursor screen, row, column +126 { +127 ¦ +next-character +128 ¦ break-unless curr +129 ¦ off-screen?:bool <- greater-or-equal row, screen-height +130 ¦ break-if off-screen? +131 ¦ # update editor.before-cursor +132 ¦ # Doing so at the start of each iteration ensures it stays one step behind +133 ¦ # the current character. +134 ¦ { +135 ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row +136 ¦ ¦ break-unless at-cursor-row? +137 ¦ ¦ at-cursor?:bool <- equal column, cursor-column +138 ¦ ¦ break-unless at-cursor? +139 ¦ ¦ before-cursor <- copy prev +140 ¦ } +141 ¦ c:char <- get *curr, value:offset +142 ¦ <character-c-received> +143 ¦ { +144 ¦ ¦ # newline? move to left rather than 0 +145 ¦ ¦ newline?:bool <- equal c, 10/newline +146 ¦ ¦ break-unless newline? +147 ¦ ¦ # adjust cursor if necessary +148 ¦ ¦ { +149 ¦ ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row +150 ¦ ¦ ¦ break-unless at-cursor-row? +151 ¦ ¦ ¦ left-of-cursor?:bool <- lesser-than column, cursor-column +152 ¦ ¦ ¦ break-unless left-of-cursor? +153 ¦ ¦ ¦ cursor-column <- copy column +154 ¦ ¦ ¦ before-cursor <- prev curr +155 ¦ ¦ } +156 ¦ ¦ # clear rest of line in this window +157 ¦ ¦ clear-line-until screen, right +158 ¦ ¦ # skip to next line +159 ¦ ¦ row <- add row, 1 +160 ¦ ¦ column <- copy left +161 ¦ ¦ screen <- move-cursor screen, row, column +162 ¦ ¦ curr <- next curr +163 ¦ ¦ prev <- next prev +164 ¦ ¦ loop +next-character +165 ¦ } +166 ¦ { +167 ¦ ¦ # at right? wrap. even if there's only one more letter left; we need +168 ¦ ¦ # room for clicking on the cursor after it. +169 ¦ ¦ at-right?:bool <- equal column, right +170 ¦ ¦ break-unless at-right? +171 ¦ ¦ # print wrap icon +172 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left +173 ¦ ¦ print screen, wrap-icon, 245/grey +174 ¦ ¦ column <- copy left +175 ¦ ¦ row <- add row, 1 176 ¦ ¦ screen <- move-cursor screen, row, column -177 ¦ ¦ curr <- next curr -178 ¦ ¦ prev <- next prev -179 ¦ ¦ loop +next-character -180 ¦ } -181 ¦ { -182 ¦ ¦ # at right? wrap. even if there's only one more letter left; we need -183 ¦ ¦ # room for clicking on the cursor after it. -184 ¦ ¦ at-right?:bool <- equal column, right -185 ¦ ¦ break-unless at-right? -186 ¦ ¦ # print wrap icon -187 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left -188 ¦ ¦ print screen, wrap-icon, 245/grey -189 ¦ ¦ column <- copy left -190 ¦ ¦ row <- add row, 1 -191 ¦ ¦ screen <- move-cursor screen, row, column -192 ¦ ¦ # don't increment curr -193 ¦ ¦ loop +next-character -194 ¦ } -195 ¦ print screen, c, color -196 ¦ curr <- next curr -197 ¦ prev <- next prev -198 ¦ column <- add column, 1 -199 ¦ loop -200 } -201 # save first character off-screen -202 *editor <- put *editor, bottom-of-screen:offset, curr -203 # is cursor to the right of the last line? move to end -204 { -205 ¦ at-cursor-row?:bool <- equal row, cursor-row -206 ¦ cursor-outside-line?:bool <- lesser-or-equal column, cursor-column -207 ¦ before-cursor-on-same-line?:bool <- and at-cursor-row?, cursor-outside-line? -208 ¦ above-cursor-row?:bool <- lesser-than row, cursor-row -209 ¦ before-cursor?:bool <- or before-cursor-on-same-line?, above-cursor-row? -210 ¦ break-unless before-cursor? -211 ¦ cursor-row <- copy row -212 ¦ cursor-column <- copy column -213 ¦ before-cursor <- copy prev -214 } -215 *editor <- put *editor, bottom:offset, row -216 *editor <- put *editor, cursor-row:offset, cursor-row -217 *editor <- put *editor, cursor-column:offset, cursor-column -218 *editor <- put *editor, before-cursor:offset, before-cursor -219 return row, column +177 ¦ ¦ # don't increment curr +178 ¦ ¦ loop +next-character +179 ¦ } +180 ¦ print screen, c, color +181 ¦ curr <- next curr +182 ¦ prev <- next prev +183 ¦ column <- add column, 1 +184 ¦ loop +185 } +186 # save first character off-screen +187 *editor <- put *editor, bottom-of-screen:offset, curr +188 # is cursor to the right of the last line? move to end +189 { +190 ¦ at-cursor-row?:bool <- equal row, cursor-row +191 ¦ cursor-outside-line?:bool <- lesser-or-equal column, cursor-column +192 ¦ before-cursor-on-same-line?:bool <- and at-cursor-row?, cursor-outside-line? +193 ¦ above-cursor-row?:bool <- lesser-than row, cursor-row +194 ¦ before-cursor?:bool <- or before-cursor-on-same-line?, above-cursor-row? +195 ¦ break-unless before-cursor? +196 ¦ cursor-row <- copy row +197 ¦ cursor-column <- copy column +198 ¦ before-cursor <- copy prev +199 } +200 *editor <- put *editor, bottom:offset, row +201 *editor <- put *editor, cursor-row:offset, cursor-row +202 *editor <- put *editor, cursor-column:offset, cursor-column +203 *editor <- put *editor, before-cursor:offset, before-cursor +204 return row, column +205 ] +206 +207 def clear-screen-from screen:&:screen, row:num, column:num, left:num, right:num -> screen:&:screen [ +208 local-scope +209 load-ingredients +210 # if it's the real screen, use the optimized primitive +211 { +212 ¦ break-if screen +213 ¦ clear-display-from row, column, left, right +214 ¦ return +215 } +216 # if not, go the slower route +217 screen <- move-cursor screen, row, column +218 clear-line-until screen, right +219 clear-rest-of-screen screen, row, left, right 220 ] 221 -222 def clear-screen-from screen:&:screen, row:num, column:num, left:num, right:num -> screen:&:screen [ +222 def clear-rest-of-screen screen:&:screen, row:num, left:num, right:num -> screen:&:screen [ 223 local-scope 224 load-ingredients -225 # if it's the real screen, use the optimized primitive -226 { -227 ¦ break-if screen -228 ¦ clear-display-from row, column, left, right -229 ¦ return -230 } -231 # if not, go the slower route -232 screen <- move-cursor screen, row, column -233 clear-line-until screen, right -234 clear-rest-of-screen screen, row, left, right -235 ] -236 -237 def clear-rest-of-screen screen:&:screen, row:num, left:num, right:num -> screen:&:screen [ -238 local-scope -239 load-ingredients -240 row <- add row, 1 -241 # if it's the real screen, use the optimized primitive -242 { -243 ¦ break-if screen -244 ¦ clear-display-from row, left, left, right -245 ¦ return -246 } -247 screen <- move-cursor screen, row, left -248 screen-height:num <- screen-height screen -249 { -250 ¦ at-bottom-of-screen?:bool <- greater-or-equal row, screen-height -251 ¦ break-if at-bottom-of-screen? -252 ¦ screen <- move-cursor screen, row, left -253 ¦ clear-line-until screen, right -254 ¦ row <- add row, 1 -255 ¦ loop -256 } -257 ] -258 -259 scenario editor-prints-multiple-lines [ -260 local-scope -261 assume-screen 5/width, 5/height -262 s:text <- new [abc -263 def] -264 e:&:editor <- new-editor s, 0/left, 5/right +225 row <- add row, 1 +226 # if it's the real screen, use the optimized primitive +227 { +228 ¦ break-if screen +229 ¦ clear-display-from row, left, left, right +230 ¦ return +231 } +232 screen <- move-cursor screen, row, left +233 screen-height:num <- screen-height screen +234 { +235 ¦ at-bottom-of-screen?:bool <- greater-or-equal row, screen-height +236 ¦ break-if at-bottom-of-screen? +237 ¦ screen <- move-cursor screen, row, left +238 ¦ clear-line-until screen, right +239 ¦ row <- add row, 1 +240 ¦ loop +241 } +242 ] +243 +244 scenario editor-prints-multiple-lines [ +245 local-scope +246 assume-screen 5/width, 5/height +247 s:text <- new [abc +248 def] +249 e:&:editor <- new-editor s, 0/left, 5/right +250 run [ +251 ¦ render screen, e +252 ] +253 screen-should-contain [ +254 ¦ . . +255 ¦ .abc . +256 ¦ .def . +257 ¦ . . +258 ] +259 ] +260 +261 scenario editor-handles-offsets [ +262 local-scope +263 assume-screen 5/width, 5/height +264 e:&:editor <- new-editor [abc], 1/left, 5/right 265 run [ -266 ¦ render screen, e +266 ¦ render screen, e 267 ] 268 screen-should-contain [ 269 ¦ . . -270 ¦ .abc . -271 ¦ .def . -272 ¦ . . -273 ] -274 ] -275 -276 scenario editor-handles-offsets [ -277 local-scope -278 assume-screen 5/width, 5/height -279 e:&:editor <- new-editor [abc], 1/left, 5/right -280 run [ -281 ¦ render screen, e -282 ] -283 screen-should-contain [ -284 ¦ . . -285 ¦ . abc . -286 ¦ . . -287 ] -288 ] -289 -290 scenario editor-prints-multiple-lines-at-offset [ -291 local-scope -292 assume-screen 5/width, 5/height -293 s:text <- new [abc -294 def] -295 e:&:editor <- new-editor s, 1/left, 5/right +270 ¦ . abc . +271 ¦ . . +272 ] +273 ] +274 +275 scenario editor-prints-multiple-lines-at-offset [ +276 local-scope +277 assume-screen 5/width, 5/height +278 s:text <- new [abc +279 def] +280 e:&:editor <- new-editor s, 1/left, 5/right +281 run [ +282 ¦ render screen, e +283 ] +284 screen-should-contain [ +285 ¦ . . +286 ¦ . abc . +287 ¦ . def . +288 ¦ . . +289 ] +290 ] +291 +292 scenario editor-wraps-long-lines [ +293 local-scope +294 assume-screen 5/width, 5/height +295 e:&:editor <- new-editor [abc def], 0/left, 5/right 296 run [ -297 ¦ render screen, e +297 ¦ render screen, e 298 ] 299 screen-should-contain [ 300 ¦ . . -301 ¦ . abc . -302 ¦ . def . +301 ¦ .abc ↩. +302 ¦ .def . 303 ¦ . . 304 ] -305 ] -306 -307 scenario editor-wraps-long-lines [ -308 local-scope -309 assume-screen 5/width, 5/height -310 e:&:editor <- new-editor [abc def], 0/left, 5/right -311 run [ -312 ¦ render screen, e -313 ] -314 screen-should-contain [ -315 ¦ . . -316 ¦ .abc ↩. -317 ¦ .def . -318 ¦ . . +305 screen-should-contain-in-color 245/grey [ +306 ¦ . . +307 ¦ . ↩. +308 ¦ . . +309 ¦ . . +310 ] +311 ] +312 +313 scenario editor-wraps-barely-long-lines [ +314 local-scope +315 assume-screen 5/width, 5/height +316 e:&:editor <- new-editor [abcde], 0/left, 5/right +317 run [ +318 ¦ render screen, e 319 ] -320 screen-should-contain-in-color 245/grey [ -321 ¦ . . -322 ¦ . ↩. +320 # still wrap, even though the line would fit. We need room to click on the +321 # end of the line +322 screen-should-contain [ 323 ¦ . . -324 ¦ . . -325 ] -326 ] -327 -328 scenario editor-wraps-barely-long-lines [ -329 local-scope -330 assume-screen 5/width, 5/height -331 e:&:editor <- new-editor [abcde], 0/left, 5/right -332 run [ -333 ¦ render screen, e -334 ] -335 # still wrap, even though the line would fit. We need room to click on the -336 # end of the line -337 screen-should-contain [ -338 ¦ . . -339 ¦ .abcd↩. -340 ¦ .e . -341 ¦ . . -342 ] -343 screen-should-contain-in-color 245/grey [ -344 ¦ . . -345 ¦ . ↩. +324 ¦ .abcd↩. +325 ¦ .e . +326 ¦ . . +327 ] +328 screen-should-contain-in-color 245/grey [ +329 ¦ . . +330 ¦ . ↩. +331 ¦ . . +332 ¦ . . +333 ] +334 ] +335 +336 scenario editor-with-empty-text [ +337 local-scope +338 assume-screen 5/width, 5/height +339 e:&:editor <- new-editor [], 0/left, 5/right +340 run [ +341 ¦ render screen, e +342 ¦ 3:num/raw <- get *e, cursor-row:offset +343 ¦ 4:num/raw <- get *e, cursor-column:offset +344 ] +345 screen-should-contain [ 346 ¦ . . 347 ¦ . . -348 ] -349 ] -350 -351 scenario editor-with-empty-text [ -352 local-scope -353 assume-screen 5/width, 5/height -354 e:&:editor <- new-editor [], 0/left, 5/right -355 run [ -356 ¦ render screen, e -357 ¦ 3:num/raw <- get *e, cursor-row:offset -358 ¦ 4:num/raw <- get *e, cursor-column:offset -359 ] -360 screen-should-contain [ -361 ¦ . . -362 ¦ . . -363 ¦ . . -364 ] -365 memory-should-contain [ -366 ¦ 3 <- 1 # cursor row -367 ¦ 4 <- 0 # cursor column -368 ] -369 ] -370 -371 # just a little color for Mu code -372 -373 scenario render-colors-comments [ -374 local-scope -375 assume-screen 5/width, 5/height -376 s:text <- new [abc -377 # de -378 f] -379 e:&:editor <- new-editor s, 0/left, 5/right -380 run [ -381 ¦ render screen, e -382 ] -383 screen-should-contain [ -384 ¦ . . -385 ¦ .abc . -386 ¦ .# de . -387 ¦ .f . -388 ¦ . . -389 ] -390 screen-should-contain-in-color 12/lightblue, [ -391 ¦ . . -392 ¦ . . -393 ¦ .# de . -394 ¦ . . -395 ¦ . . -396 ] -397 screen-should-contain-in-color 7/white, [ -398 ¦ . . -399 ¦ .abc . -400 ¦ . . -401 ¦ .f . -402 ¦ . . -403 ] -404 ] -405 -406 after <character-c-received> [ -407 color <- get-color color, c -408 ] -409 -410 # so far the previous color is all the information we need; that may change -411 def get-color color:num, c:char -> color:num [ -412 local-scope -413 load-ingredients -414 color-is-white?:bool <- equal color, 7/white -415 # if color is white and next character is '#', switch color to blue -416 { -417 ¦ break-unless color-is-white? -418 ¦ starting-comment?:bool <- equal c, 35/# -419 ¦ break-unless starting-comment? -420 ¦ trace 90, [app], [switch color back to blue] -421 ¦ return 12/lightblue -422 } -423 # if color is blue and next character is newline, switch color to white -424 { -425 ¦ color-is-blue?:bool <- equal color, 12/lightblue -426 ¦ break-unless color-is-blue? -427 ¦ ending-comment?:bool <- equal c, 10/newline -428 ¦ break-unless ending-comment? -429 ¦ trace 90, [app], [switch color back to white] +348 ¦ . . +349 ] +350 memory-should-contain [ +351 ¦ 3 <- 1 # cursor row +352 ¦ 4 <- 0 # cursor column +353 ] +354 ] +355 +356 # just a little color for Mu code +357 +358 scenario render-colors-comments [ +359 local-scope +360 assume-screen 5/width, 5/height +361 s:text <- new [abc +362 # de +363 f] +364 e:&:editor <- new-editor s, 0/left, 5/right +365 run [ +366 ¦ render screen, e +367 ] +368 screen-should-contain [ +369 ¦ . . +370 ¦ .abc . +371 ¦ .# de . +372 ¦ .f . +373 ¦ . . +374 ] +375 screen-should-contain-in-color 12/lightblue, [ +376 ¦ . . +377 ¦ . . +378 ¦ .# de . +379 ¦ . . +380 ¦ . . +381 ] +382 screen-should-contain-in-color 7/white, [ +383 ¦ . . +384 ¦ .abc . +385 ¦ . . +386 ¦ .f . +387 ¦ . . +388 ] +389 ] +390 +391 after <character-c-received> [ +392 color <- get-color color, c +393 ] +394 +395 # so far the previous color is all the information we need; that may change +396 def get-color color:num, c:char -> color:num [ +397 local-scope +398 load-ingredients +399 color-is-white?:bool <- equal color, 7/white +400 # if color is white and next character is '#', switch color to blue +401 { +402 ¦ break-unless color-is-white? +403 ¦ starting-comment?:bool <- equal c, 35/# +404 ¦ break-unless starting-comment? +405 ¦ trace 90, [app], [switch color back to blue] +406 ¦ return 12/lightblue +407 } +408 # if color is blue and next character is newline, switch color to white +409 { +410 ¦ color-is-blue?:bool <- equal color, 12/lightblue +411 ¦ break-unless color-is-blue? +412 ¦ ending-comment?:bool <- equal c, 10/newline +413 ¦ break-unless ending-comment? +414 ¦ trace 90, [app], [switch color back to white] +415 ¦ return 7/white +416 } +417 # if color is white (no comments) and next character is '<', switch color to red +418 { +419 ¦ break-unless color-is-white? +420 ¦ starting-assignment?:bool <- equal c, 60/< +421 ¦ break-unless starting-assignment? +422 ¦ return 1/red +423 } +424 # if color is red and next character is space, switch color to white +425 { +426 ¦ color-is-red?:bool <- equal color, 1/red +427 ¦ break-unless color-is-red? +428 ¦ ending-assignment?:bool <- equal c, 32/space +429 ¦ break-unless ending-assignment? 430 ¦ return 7/white 431 } -432 # if color is white (no comments) and next character is '<', switch color to red -433 { -434 ¦ break-unless color-is-white? -435 ¦ starting-assignment?:bool <- equal c, 60/< -436 ¦ break-unless starting-assignment? -437 ¦ return 1/red -438 } -439 # if color is red and next character is space, switch color to white -440 { -441 ¦ color-is-red?:bool <- equal color, 1/red -442 ¦ break-unless color-is-red? -443 ¦ ending-assignment?:bool <- equal c, 32/space -444 ¦ break-unless ending-assignment? -445 ¦ return 7/white -446 } -447 # otherwise no change -448 return color -449 ] -450 -451 scenario render-colors-assignment [ -452 local-scope -453 assume-screen 8/width, 5/height -454 s:text <- new [abc -455 d <- e -456 f] -457 e:&:editor <- new-editor s, 0/left, 8/right -458 run [ -459 ¦ render screen, e -460 ] -461 screen-should-contain [ -462 ¦ . . -463 ¦ .abc . -464 ¦ .d <- e . -465 ¦ .f . -466 ¦ . . -467 ] -468 screen-should-contain-in-color 1/red, [ -469 ¦ . . -470 ¦ . . -471 ¦ . <- . -472 ¦ . . -473 ¦ . . -474 ] -475 ] +432 # otherwise no change +433 return color +434 ] +435 +436 scenario render-colors-assignment [ +437 local-scope +438 assume-screen 8/width, 5/height +439 s:text <- new [abc +440 d <- e +441 f] +442 e:&:editor <- new-editor s, 0/left, 8/right +443 run [ +444 ¦ render screen, e +445 ] +446 screen-should-contain [ +447 ¦ . . +448 ¦ .abc . +449 ¦ .d <- e . +450 ¦ .f . +451 ¦ . . +452 ] +453 screen-should-contain-in-color 1/red, [ +454 ¦ . . +455 ¦ . . +456 ¦ . <- . +457 ¦ . . +458 ¦ . . +459 ] +460 ] diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html index f8774dd1..39cbda87 100644 --- a/html/edit/002-typing.mu.html +++ b/html/edit/002-typing.mu.html @@ -141,7 +141,7 @@ if ('onhashchange' in window) { 78 return-unless editor 79 left:num <- get *editor, left:offset 80 right:num <- get *editor, right:offset - 81 screen-height:num <- screen-height screen + 81 screen-height:num <- screen-height screen 82 # count newlines until screen row 83 curr:&:duplex-list:char <- get *editor, top-of-screen:offset 84 prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev @@ -156,7 +156,7 @@ if ('onhashchange' in window) { 93 { 94 ¦ +next-character 95 ¦ break-unless curr - 96 ¦ off-screen?:bool <- greater-or-equal row, screen-height + 96 ¦ off-screen?:bool <- greater-or-equal row, screen-height 97 ¦ break-if off-screen? 98 ¦ # update editor.before-cursor 99 ¦ # Doing so at the start of each iteration ensures it stays one step behind @@ -230,8 +230,8 @@ if ('onhashchange' in window) { 167 local-scope 168 load-ingredients 169 return-unless editor, 0/don't-render - 170 screen-width:num <- screen-width screen - 171 screen-height:num <- screen-height screen + 170 screen-width:num <- screen-width screen + 171 screen-height:num <- screen-height screen 172 left:num <- get *editor, left:offset 173 right:num <- get *editor, right:offset 174 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset @@ -276,8 +276,8 @@ if ('onhashchange' in window) { 213 right:num <- get *editor, right:offset 214 save-row:num <- copy cursor-row 215 save-column:num <- copy cursor-column - 216 screen-width:num <- screen-width screen - 217 screen-height:num <- screen-height screen + 216 screen-width:num <- screen-width screen + 217 screen-height:num <- screen-height screen 218 # occasionally we'll need to mess with the cursor 219 <insert-character-special-case> 220 # but mostly we'll just move the cursor right @@ -288,7 +288,7 @@ if ('onhashchange' in window) { 225 ¦ # at end of all text? no need to scroll? just print the character and leave 226 ¦ at-end?:bool <- equal next, 0/null 227 ¦ break-unless at-end? - 228 ¦ bottom:num <- subtract screen-height, 1 + 228 ¦ bottom:num <- subtract screen-height, 1 229 ¦ at-bottom?:bool <- equal save-row, bottom 230 ¦ at-right?:bool <- equal save-column, right 231 ¦ overflow?:bool <- and at-bottom?, at-right? @@ -300,7 +300,7 @@ if ('onhashchange' in window) { 237 { 238 ¦ # not at right margin? print the character and rest of line 239 ¦ break-unless next - 240 ¦ at-right?:bool <- greater-or-equal cursor-column, screen-width + 240 ¦ at-right?:bool <- greater-or-equal cursor-column, screen-width 241 ¦ break-if at-right? 242 ¦ curr:&:duplex-list:char <- copy before-cursor 243 ¦ move-cursor screen, save-row, save-column @@ -331,12 +331,12 @@ if ('onhashchange' in window) { 268 old-top-idx:num <- save-top-idx screen 269 left:num <- get *editor, left:offset 270 right:num <- get *editor, right:offset - 271 row:num, column:num <- render screen, editor + 271 row:num, column:num <- render screen, editor 272 clear-line-until screen, right 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 + 276 clear-screen-from screen, row, left, left, right 277 assert-no-scroll screen, old-top-idx 278 ] 279 @@ -796,7 +796,7 @@ if ('onhashchange' in window) { 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 + 736 ¦ ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height 737 ¦ ¦ break-unless below-screen? 738 ¦ ¦ <scroll-down> 739 ¦ } @@ -936,7 +936,7 @@ if ('onhashchange' in window) { 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 + 876 screen-height:num <- screen-height screen 877 # insert newline 878 insert 10/newline, before-cursor 879 before-cursor <- next before-cursor @@ -947,7 +947,7 @@ if ('onhashchange' in window) { 884 *editor <- put *editor, cursor-column:offset, cursor-column 885 # maybe scroll 886 { - 887 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal, never greater + 887 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal, never greater 888 ¦ break-unless below-screen? 889 ¦ <scroll-down> 890 ¦ cursor-row <- subtract cursor-row, 1 # bring back into screen range @@ -1123,7 +1123,7 @@ if ('onhashchange' in window) { 1060 def draw-horizontal screen:&:screen, row:num, x:num, right:num -> screen:&:screen [ 1061 local-scope 1062 load-ingredients -1063 height:num <- screen-height screen +1063 height:num <- screen-height screen 1064 past-bottom?:bool <- greater-or-equal row, height 1065 return-if past-bottom? 1066 style:char, style-found?:bool <- next-ingredient diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html index bf5f463c..d14f0950 100644 --- a/html/edit/003-shortcuts.mu.html +++ b/html/edit/003-shortcuts.mu.html @@ -158,7 +158,7 @@ if ('onhashchange' in window) { 96 before-cursor <- copy prev 97 *editor <- put *editor, before-cursor:offset, before-cursor 98 return-if scroll?, 1/go-render - 99 screen-width:num <- screen-width screen + 99 screen-width:num <- screen-width screen 100 cursor-row:num <- get *editor, cursor-row:offset 101 cursor-column:num <- get *editor, cursor-column:offset 102 # did we just backspace over a newline? @@ -424,10 +424,10 @@ if ('onhashchange' in window) { 362 cursor-column:num <- get *editor, cursor-column:offset 363 screen <- move-cursor screen, cursor-row, cursor-column 364 curr-column:num <- copy cursor-column - 365 screen-width:num <- screen-width screen + 365 screen-width:num <- screen-width screen 366 { 367 ¦ # hit right margin? give up and let caller render - 368 ¦ at-right?:bool <- greater-or-equal curr-column, screen-width + 368 ¦ at-right?:bool <- greater-or-equal curr-column, screen-width 369 ¦ return-if at-right?, 1/go-render 370 ¦ break-unless curr 371 ¦ # newline? done. @@ -480,7 +480,7 @@ if ('onhashchange' in window) { 418 ¦ <move-cursor-begin> 419 ¦ before-cursor <- copy next-cursor 420 ¦ *editor <- put *editor, before-cursor:offset, before-cursor - 421 ¦ go-render?:bool <- move-cursor-coordinates-right editor, screen-height + 421 ¦ go-render?:bool <- move-cursor-coordinates-right editor, screen-height 422 ¦ screen <- move-cursor screen, cursor-row, cursor-column 423 ¦ undo-coalesce-tag:num <- copy 2/right-arrow 424 ¦ <move-cursor-end> @@ -488,7 +488,7 @@ if ('onhashchange' in window) { 426 } 427 ] 428 - 429 def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [ + 429 def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [ 430 local-scope 431 load-ingredients 432 before-cursor:&:duplex-list:char <- get *editor before-cursor:offset @@ -505,7 +505,7 @@ if ('onhashchange' in window) { 443 ¦ *editor <- put *editor, cursor-row:offset, cursor-row 444 ¦ cursor-column <- copy left 445 ¦ *editor <- put *editor, cursor-column:offset, cursor-column - 446 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal + 446 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal 447 ¦ return-unless below-screen?, 0/don't-render 448 ¦ <scroll-down> 449 ¦ cursor-row <- subtract cursor-row, 1 # bring back into screen range @@ -528,7 +528,7 @@ if ('onhashchange' in window) { 466 ¦ *editor <- put *editor, cursor-row:offset, cursor-row 467 ¦ cursor-column <- copy left 468 ¦ *editor <- put *editor, cursor-column:offset, cursor-column - 469 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal + 469 ¦ below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal 470 ¦ return-unless below-screen?, 0/no-more-render 471 ¦ <scroll-down> 472 ¦ cursor-row <- subtract cursor-row, 1 # bring back into screen range @@ -1259,14 +1259,14 @@ if ('onhashchange' in window) { 1197 ¦ move-to-next-line?:bool <- equal k, 65516/down-arrow 1198 ¦ break-unless move-to-next-line? 1199 ¦ <move-cursor-begin> -1200 ¦ go-render? <- move-to-next-line editor, screen-height +1200 ¦ go-render? <- move-to-next-line editor, screen-height 1201 ¦ undo-coalesce-tag:num <- copy 4/down-arrow 1202 ¦ <move-cursor-end> 1203 ¦ return 1204 } 1205 ] 1206 -1207 def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [ +1207 def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, editor:&:editor [ 1208 local-scope 1209 load-ingredients 1210 cursor-row:num <- get *editor, cursor-row:offset @@ -1274,7 +1274,7 @@ if ('onhashchange' in window) { 1212 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset 1213 left:num <- get *editor, left:offset 1214 right:num <- get *editor, right:offset -1215 last-line:num <- subtract screen-height, 1 +1215 last-line:num <- subtract screen-height, 1 1216 already-at-bottom?:bool <- greater-or-equal cursor-row, last-line 1217 { 1218 ¦ # if cursor not at bottom, move it @@ -1787,14 +1787,14 @@ if ('onhashchange' in window) { 1725 color:num <- copy 7/white 1726 column:num <- copy left 1727 screen <- move-cursor screen, row, column -1728 screen-height:num <- screen-height screen +1728 screen-height:num <- screen-height screen 1729 i:num <- copy 0 1730 len:num <- length *s 1731 { 1732 ¦ +next-character 1733 ¦ done?:bool <- greater-or-equal i, len 1734 ¦ break-if done? -1735 ¦ done? <- greater-or-equal row, screen-height +1735 ¦ done? <- greater-or-equal row, screen-height 1736 ¦ break-if done? 1737 ¦ c:char <- index *s, i 1738 ¦ <character-c-received> @@ -3052,8 +3052,8 @@ if ('onhashchange' in window) { 2990 *editor <- put *editor, before-cursor:offset, before-cursor 2991 # keep one line in common with previous page 2992 { -2993 ¦ last:char <- get *before-cursor, value:offset -2994 ¦ newline?:bool <- equal last, 10/newline +2993 ¦ last:char <- get *before-cursor, value:offset +2994 ¦ newline?:bool <- equal last, 10/newline 2995 ¦ break-unless newline?:bool 2996 ¦ before-cursor <- prev before-cursor 2997 ¦ *editor <- put *editor, before-cursor:offset, before-cursor @@ -3213,7 +3213,7 @@ if ('onhashchange' in window) { 3151 ¦ break-unless page-up? 3152 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset 3153 ¦ <move-cursor-begin> -3154 ¦ editor <- page-up editor, screen-height +3154 ¦ editor <- page-up editor, screen-height 3155 ¦ undo-coalesce-tag:num <- copy 0/never 3156 ¦ <move-cursor-end> 3157 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset @@ -3228,7 +3228,7 @@ if ('onhashchange' in window) { 3166 ¦ break-unless page-up? 3167 ¦ old-top:&:duplex-list:char <- get *editor, top-of-screen:offset 3168 ¦ <move-cursor-begin> -3169 ¦ editor <- page-up editor, screen-height +3169 ¦ editor <- page-up editor, screen-height 3170 ¦ undo-coalesce-tag:num <- copy 0/never 3171 ¦ <move-cursor-end> 3172 ¦ top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset @@ -3238,10 +3238,10 @@ if ('onhashchange' in window) { 3176 } 3177 ] 3178 -3179 def page-up editor:&:editor, screen-height:num -> editor:&:editor [ +3179 def page-up editor:&:editor, screen-height:num -> editor:&:editor [ 3180 local-scope 3181 load-ingredients -3182 max:num <- subtract screen-height, 1/menu-bar, 1/overlapping-line +3182 max:num <- subtract screen-height, 1/menu-bar, 1/overlapping-line 3183 count:num <- copy 0 3184 top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset 3185 { diff --git a/html/edit/004-programming-environment.mu.html b/html/edit/004-programming-environment.mu.html index 14c9af6f..72593aa7 100644 --- a/html/edit/004-programming-environment.mu.html +++ b/html/edit/004-programming-environment.mu.html @@ -71,7 +71,7 @@ if ('onhashchange' in window) { 8 open-console 9 clear-screen 0/screen # non-scrolling app 10 env:&:environment <- new-programming-environment 0/filesystem, 0/screen - 11 render-all 0/screen, env, render + 11 render-all 0/screen, env, render 12 event-loop 0/screen, 0/console, env, 0/filesystem 13 ] 14 @@ -84,7 +84,7 @@ if ('onhashchange' in window) { 21 def new-programming-environment resources:&:resources, screen:&:screen, test-sandbox-editor-contents:text -> result:&:environment [ 22 local-scope 23 load-ingredients - 24 width:num <- screen-width screen + 24 width:num <- screen-width screen 25 result <- new environment:type 26 # recipe editor on the left 27 initial-recipe-contents:text <- slurp resources, [lesson/recipes.mu] # ignore errors @@ -177,12 +177,12 @@ if ('onhashchange' in window) { 114 ¦ ¦ ¦ { 115 ¦ ¦ ¦ ¦ break-unless render-recipes-on-no-more-events? 116 ¦ ¦ ¦ ¦ render-recipes-on-no-more-events? <- copy 0/false -117 ¦ ¦ ¦ ¦ screen <- render-recipes screen, env, render +117 ¦ ¦ ¦ ¦ screen <- render-recipes screen, env, render 118 ¦ ¦ ¦ } 119 ¦ ¦ ¦ { 120 ¦ ¦ ¦ ¦ break-unless render-sandboxes-on-no-more-events? 121 ¦ ¦ ¦ ¦ render-sandboxes-on-no-more-events? <- copy 0/false -122 ¦ ¦ ¦ ¦ screen <- render-sandbox-side screen, env, render +122 ¦ ¦ ¦ ¦ screen <- render-sandbox-side screen, env, render 123 ¦ ¦ ¦ } 124 ¦ ¦ } 125 ¦ ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env @@ -195,7 +195,7 @@ if ('onhashchange' in window) { 132 local-scope 133 load-ingredients 134 clear-screen screen # update screen dimensions -135 width:num <- screen-width screen +135 width:num <- screen-width screen 136 divider:num, _ <- divide-with-remainder width, 2 137 # update recipe editor 138 recipes:&:editor <- get *env, recipes:offset @@ -223,7 +223,7 @@ if ('onhashchange' in window) { 160 load-ingredients 161 return-unless editor, 1/top, 0/left 162 left:num <- get *editor, left:offset -163 screen-height:num <- screen-height screen +163 screen-height:num <- screen-height screen 164 right:num <- get *editor, right:offset 165 curr:&:duplex-list:char <- get *editor, top-of-screen:offset 166 prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev @@ -243,7 +243,7 @@ if ('onhashchange' in window) { 180 { 181 ¦ +next-character 182 ¦ break-unless curr -183 ¦ off-screen?:bool <- greater-or-equal row, screen-height +183 ¦ off-screen?:bool <- greater-or-equal row, screen-height 184 ¦ break-if off-screen? 185 ¦ # if we find old-before-cursor still on the new resized screen, update 186 ¦ # editor.cursor-row and editor.cursor-column based on @@ -338,7 +338,7 @@ if ('onhashchange' in window) { 275 ¦ ] 276 ] 277 env:&:environment <- new-programming-environment resources, screen, [def] # contents of sandbox -278 render-all screen, env, render +278 render-all screen, env, render 279 # type one letter in each of them 280 assume-console [ 281 ¦ left-click 1, 1 @@ -388,7 +388,7 @@ if ('onhashchange' in window) { 325 ¦ ] 326 ] 327 env:&:environment <- new-programming-environment resources, screen, [def] -328 render-all screen, env, render +328 render-all screen, env, render 329 # initialize programming environment and highlight cursor 330 assume-console [] 331 run [ @@ -433,7 +433,7 @@ if ('onhashchange' in window) { 370 test-sandbox-editor-contents:text <- new [abc 371 def] 372 env:&:environment <- new-programming-environment resources, screen, test-sandbox-editor-contents -373 render-all screen, env, render +373 render-all screen, env, render 374 screen-should-contain [ 375 ¦ . run (F4) . 376 ¦ . ╎abc . @@ -467,7 +467,7 @@ if ('onhashchange' in window) { 404 old-top-idx:num <- save-top-idx screen 405 # top menu 406 trace 11, [app], [render top menu] -407 width:num <- screen-width screen +407 width:num <- screen-width screen 408 draw-horizontal screen, 0, 0/left, width, 32/space, 0/black, 238/grey 409 button-start:num <- subtract width, 20 410 button-on-screen?:bool <- greater-or-equal button-start, 0 @@ -477,7 +477,7 @@ if ('onhashchange' in window) { 414 # dotted line down the middle 415 trace 11, [app], [render divider] 416 divider:num, _ <- divide-with-remainder width, 2 -417 height:num <- screen-height screen +417 height:num <- screen-height screen 418 draw-vertical screen, divider, 1/top, height, 9482/vertical-dotted 419 # 420 screen <- render-recipes screen, env, render-editor @@ -507,7 +507,7 @@ if ('onhashchange' in window) { 444 # draw dotted line after recipes 445 draw-horizontal screen, row, left, right, 9480/horizontal-dotted 446 row <- add row, 1 -447 clear-screen-from screen, row, left, left, right +447 clear-screen-from screen, row, left, left, right 448 ] 449 450 # replaced in a later layer @@ -523,7 +523,7 @@ if ('onhashchange' in window) { 460 # draw solid line after code (you'll see why in later layers) 461 draw-horizontal screen, row, left, right 462 row <- add row, 1 -463 clear-screen-from screen, row, left, left, right +463 clear-screen-from screen, row, left, left, right 464 ] 465 466 def update-cursor screen:&:screen, recipes:&:editor, current-sandbox:&:editor, sandbox-in-focus?:bool, env:&:environment -> screen:&:screen [ diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html index b08141b5..24eadd50 100644 --- a/html/edit/005-sandbox.mu.html +++ b/html/edit/005-sandbox.mu.html @@ -75,8 +75,8 @@ if ('onhashchange' in window) { 12 open-console 13 clear-screen 0/screen # non-scrolling app 14 env:&:environment <- new-programming-environment 0/filesystem, 0/screen - 15 env <- restore-sandboxes env - 16 render-all 0/screen, env, render + 15 env <- restore-sandboxes env + 16 render-all 0/screen, env, render 17 event-loop 0/screen, 0/console, env, 0/filesystem 18 ] 19 @@ -122,7 +122,7 @@ if ('onhashchange' in window) { 59 ¦ . run (F4) . 60 ¦ . ╎ . 61 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 62 ¦ . ╎0 edit copy delete . + 62 ¦ . ╎0 edit copy to recipe delete . 63 ¦ . ╎divide-with-remainder 11, 3 . 64 ¦ . ╎3 . 65 ¦ . ╎2 . @@ -156,7 +156,7 @@ if ('onhashchange' in window) { 93 ¦ . . 94 ¦ . . 95 ¦ . . - 96 ¦ . 0 edit copy delete . + 96 ¦ . 0 edit copy to recipe delete . 97 ] 98 # run another command 99 assume-console [ @@ -172,11 +172,11 @@ if ('onhashchange' in window) { 109 ¦ . run (F4) . 110 ¦ . ╎ . 111 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 112 ¦ . ╎0 edit copy delete . + 112 ¦ . ╎0 edit copy to recipe delete . 113 ¦ . ╎add 2, 2 . 114 ¦ . ╎4 . 115 ¦ . ╎─────────────────────────────────────────────────. - 116 ¦ . ╎1 edit copy delete . + 116 ¦ . ╎1 edit copy to recipe delete . 117 ¦ . ╎divide-with-remainder 11, 3 . 118 ¦ . ╎3 . 119 ¦ . ╎2 . @@ -193,7 +193,7 @@ if ('onhashchange' in window) { 130 ¦ screen <- update-status screen, [running... ], 245/grey 131 ¦ error?:bool <- run-sandboxes env, resources, screen 132 ¦ # F4 might update warnings and results on both sides - 133 ¦ screen <- render-all screen, env, render + 133 ¦ screen <- render-all screen, env, render 134 ¦ { 135 ¦ ¦ break-if error? 136 ¦ ¦ screen <- update-status screen, [ ], 245/grey @@ -212,7 +212,7 @@ if ('onhashchange' in window) { 149 <run-sandboxes-begin> 150 current-sandbox:&:editor <- get *env, current-sandbox:offset 151 { - 152 ¦ sandbox-contents:text <- editor-contents current-sandbox + 152 ¦ sandbox-contents:text <- editor-contents current-sandbox 153 ¦ break-unless sandbox-contents 154 ¦ # if contents exist, first save them 155 ¦ # run them and turn them into a new sandbox @@ -257,7 +257,7 @@ if ('onhashchange' in window) { 194 local-scope 195 load-ingredients 196 recipes:&:editor <- get *env, recipes:offset - 197 in:text <- editor-contents recipes + 197 in:text <- editor-contents recipes 198 resources <- dump resources, [lesson/recipes.mu], in 199 reload in 200 errors-found? <- copy 0/false @@ -314,22 +314,22 @@ if ('onhashchange' in window) { 251 ¦ render-current-sandbox?:bool <- equal render-from, -1 252 ¦ break-unless render-current-sandbox? 253 ¦ row, column, screen, current-sandbox <- call render-editor, screen, current-sandbox - 254 ¦ clear-screen-from screen, row, column, left, right + 254 ¦ clear-screen-from screen, row, column, left, right 255 ¦ row <- add row, 1 256 } 257 # render sandboxes 258 draw-horizontal screen, row, left, right 259 sandbox:&:sandbox <- get *env, sandbox:offset 260 row, screen <- render-sandboxes screen, sandbox, left, right, row, render-from - 261 clear-rest-of-screen screen, row, left, right + 261 clear-rest-of-screen screen, row, left, right 262 ] 263 264 def render-sandboxes screen:&:screen, sandbox:&:sandbox, left:num, right:num, row:num, render-from:num, idx:num -> row:num, screen:&:screen, sandbox:&:sandbox [ 265 local-scope 266 load-ingredients 267 return-unless sandbox - 268 screen-height:num <- screen-height screen - 269 at-bottom?:bool <- greater-or-equal row, screen-height + 268 screen-height:num <- screen-height screen + 269 at-bottom?:bool <- greater-or-equal row, screen-height 270 return-if at-bottom?:bool 271 hidden?:bool <- lesser-than idx, render-from 272 { @@ -353,15 +353,15 @@ if ('onhashchange' in window) { 290 ¦ ¦ sandbox-screen:&:screen <- get *sandbox, screen:offset 291 ¦ ¦ empty-screen?:bool <- fake-screen-is-empty? sandbox-screen 292 ¦ ¦ break-if empty-screen? - 293 ¦ ¦ row, screen <- render-screen screen, sandbox-screen, left, right, row + 293 ¦ ¦ row, screen <- render-screen screen, sandbox-screen, left, right, row 294 ¦ } 295 ¦ { 296 ¦ ¦ break-unless empty-screen? 297 ¦ ¦ <render-sandbox-response> - 298 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 245/grey, row + 298 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 245/grey, row 299 ¦ } 300 ¦ +render-sandbox-end - 301 ¦ at-bottom?:bool <- greater-or-equal row, screen-height + 301 ¦ at-bottom?:bool <- greater-or-equal row, screen-height 302 ¦ return-if at-bottom? 303 ¦ # draw solid line after sandbox 304 ¦ draw-horizontal screen, row, left, right @@ -382,913 +382,917 @@ if ('onhashchange' in window) { 319 def render-sandbox-menu screen:&:screen, sandbox-index:num, left:num, right:num -> screen:&:screen [ 320 local-scope 321 load-ingredients - 322 move-cursor-to-column screen, left - 323 edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num <- sandbox-menu-columns left, right + 322 move-cursor-to-column screen, left + 323 edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, recipe-button-left:num, recipe-button-right:num, delete-button-left:num <- sandbox-menu-columns left, right 324 print screen, sandbox-index, 232/dark-grey, 245/grey 325 start-buttons:num <- subtract edit-button-left, 1 326 clear-line-until screen, start-buttons, 245/grey - 327 print screen, [edit], 232/black, 94/background-orange - 328 clear-line-until screen, edit-button-right, 94/background-orange + 327 print screen, [edit], 232/black, 25/background-blue + 328 clear-line-until screen, edit-button-right, 25/background-blue 329 print screen, [copy], 232/black, 58/background-green 330 clear-line-until screen, copy-button-right, 58/background-green - 331 print screen, [delete], 232/black, 52/background-red - 332 clear-line-until screen, right, 52/background-red - 333 ] - 334 - 335 # divide up the menu bar for a sandbox into 3 segments, for edit/copy/delete buttons - 336 # delete-button-right == right - 337 # all left/right pairs are inclusive - 338 def sandbox-menu-columns left:num, right:num -> edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, delete-button-left:num [ - 339 local-scope - 340 load-ingredients - 341 start-buttons:num <- add left, 4/space-for-sandbox-index - 342 buttons-space:num <- subtract right, start-buttons - 343 button-width:num <- divide-with-remainder buttons-space, 3 # integer division - 344 buttons-wide-enough?:bool <- greater-or-equal button-width, 8 - 345 assert buttons-wide-enough?, [sandbox must be at least 30 or so characters wide] - 346 edit-button-left:num <- copy start-buttons - 347 copy-button-left:num <- add start-buttons, button-width - 348 edit-button-right:num <- subtract copy-button-left, 1 - 349 delete-button-left:num <- subtract right, button-width - 350 copy-button-right:num <- subtract delete-button-left, 1 - 351 ] - 352 - 353 # print a text 's' to 'editor' in 'color' starting at 'row' - 354 # clear rest of last line, move cursor to next line - 355 # like 'render-code' but without syntax-based colorization - 356 def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num -> row:num, screen:&:screen [ - 357 local-scope - 358 load-ingredients - 359 return-unless s - 360 column:num <- copy left - 361 screen <- move-cursor screen, row, column - 362 screen-height:num <- screen-height screen - 363 i:num <- copy 0 - 364 len:num <- length *s - 365 { - 366 ¦ +next-character - 367 ¦ done?:bool <- greater-or-equal i, len - 368 ¦ break-if done? - 369 ¦ done? <- greater-or-equal row, screen-height - 370 ¦ break-if done? - 371 ¦ c:char <- index *s, i - 372 ¦ { - 373 ¦ ¦ # newline? move to left rather than 0 - 374 ¦ ¦ newline?:bool <- equal c, 10/newline - 375 ¦ ¦ break-unless newline? - 376 ¦ ¦ # clear rest of line in this window - 377 ¦ ¦ { - 378 ¦ ¦ ¦ done?:bool <- greater-than column, right - 379 ¦ ¦ ¦ break-if done? - 380 ¦ ¦ ¦ space:char <- copy 32/space - 381 ¦ ¦ ¦ print screen, space - 382 ¦ ¦ ¦ column <- add column, 1 - 383 ¦ ¦ ¦ loop - 384 ¦ ¦ } - 385 ¦ ¦ row <- add row, 1 - 386 ¦ ¦ column <- copy left - 387 ¦ ¦ screen <- move-cursor screen, row, column - 388 ¦ ¦ i <- add i, 1 - 389 ¦ ¦ loop +next-character - 390 ¦ } - 391 ¦ { - 392 ¦ ¦ # at right? wrap. - 393 ¦ ¦ at-right?:bool <- equal column, right - 394 ¦ ¦ break-unless at-right? - 395 ¦ ¦ # print wrap icon - 396 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left - 397 ¦ ¦ print screen, wrap-icon, 245/grey - 398 ¦ ¦ column <- copy left - 399 ¦ ¦ row <- add row, 1 - 400 ¦ ¦ screen <- move-cursor screen, row, column - 401 ¦ ¦ # don't increment i - 402 ¦ ¦ loop +next-character - 403 ¦ } - 404 ¦ i <- add i, 1 - 405 ¦ print screen, c, color - 406 ¦ column <- add column, 1 - 407 ¦ loop - 408 } - 409 was-at-left?:bool <- equal column, left - 410 clear-line-until screen, right - 411 { - 412 ¦ break-if was-at-left? - 413 ¦ row <- add row, 1 - 414 } - 415 move-cursor screen, row, left - 416 ] - 417 - 418 scenario read-text-wraps-barely-long-lines [ - 419 local-scope - 420 assume-screen 5/width, 5/height - 421 s:text <- new [abcde] - 422 run [ - 423 ¦ render-text screen, s, 0/left, 4/right, 7/white, 1/row - 424 ] - 425 screen-should-contain [ - 426 ¦ . . - 427 ¦ .abcd↩. - 428 ¦ .e . - 429 ¦ . . - 430 ] - 431 ] - 432 - 433 # assumes programming environment has no sandboxes; restores them from previous session - 434 def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environment [ - 435 local-scope - 436 load-ingredients - 437 # read all scenarios, pushing them to end of a list of scenarios - 438 idx:num <- copy 0 - 439 curr:&:sandbox <- copy 0 - 440 prev:&:sandbox <- copy 0 - 441 { - 442 ¦ filename:text <- append [lesson/], idx - 443 ¦ contents:text <- slurp resources, filename - 444 ¦ break-unless contents # stop at first error; assuming file didn't exist - 445 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ # todo: handle empty sandbox - 446 ¦ # create new sandbox for file - 447 ¦ curr <- new sandbox:type - 448 ¦ *curr <- put *curr, data:offset, contents - 449 ¦ <end-restore-sandbox> - 450 ¦ { - 451 ¦ ¦ break-if idx - 452 ¦ ¦ *env <- put *env, sandbox:offset, curr - 453 ¦ } + 331 print screen, [to recipe], 232/black, 94/background-orange + 332 clear-line-until screen, recipe-button-right, 94/background-orange + 333 print screen, [delete], 232/black, 52/background-red + 334 clear-line-until screen, right, 52/background-red + 335 ] + 336 + 337 # divide up the menu bar for a sandbox into 3 segments, for edit/copy/delete buttons + 338 # delete-button-right == right + 339 # all left/right pairs are inclusive + 340 def sandbox-menu-columns left:num, right:num -> edit-button-left:num, edit-button-right:num, copy-button-left:num, copy-button-right:num, recipe-button-left:num, recipe-button-right:num, delete-button-left:num [ + 341 local-scope + 342 load-ingredients + 343 start-buttons:num <- add left, 4/space-for-sandbox-index + 344 buttons-space:num <- subtract right, start-buttons + 345 button-width:num <- divide-with-remainder buttons-space, 4 # integer division + 346 buttons-wide-enough?:bool <- greater-or-equal button-width, 10 + 347 assert buttons-wide-enough?, [sandbox must be at least 40 or so characters wide] + 348 edit-button-left:num <- copy start-buttons + 349 copy-button-left:num <- add start-buttons, button-width + 350 edit-button-right:num <- subtract copy-button-left, 1 + 351 recipe-button-left:num <- add copy-button-left, button-width + 352 copy-button-right:num <- subtract recipe-button-left, 1 + 353 delete-button-left:num <- subtract right, button-width, -2 # because 'to recipe' is wider than 'delete' + 354 recipe-button-right:num <- subtract delete-button-left, 1 + 355 ] + 356 + 357 # print a text 's' to 'editor' in 'color' starting at 'row' + 358 # clear rest of last line, move cursor to next line + 359 # like 'render-code' but without syntax-based colorization + 360 def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num -> row:num, screen:&:screen [ + 361 local-scope + 362 load-ingredients + 363 return-unless s + 364 column:num <- copy left + 365 screen <- move-cursor screen, row, column + 366 screen-height:num <- screen-height screen + 367 i:num <- copy 0 + 368 len:num <- length *s + 369 { + 370 ¦ +next-character + 371 ¦ done?:bool <- greater-or-equal i, len + 372 ¦ break-if done? + 373 ¦ done? <- greater-or-equal row, screen-height + 374 ¦ break-if done? + 375 ¦ c:char <- index *s, i + 376 ¦ { + 377 ¦ ¦ # newline? move to left rather than 0 + 378 ¦ ¦ newline?:bool <- equal c, 10/newline + 379 ¦ ¦ break-unless newline? + 380 ¦ ¦ # clear rest of line in this window + 381 ¦ ¦ { + 382 ¦ ¦ ¦ done?:bool <- greater-than column, right + 383 ¦ ¦ ¦ break-if done? + 384 ¦ ¦ ¦ space:char <- copy 32/space + 385 ¦ ¦ ¦ print screen, space + 386 ¦ ¦ ¦ column <- add column, 1 + 387 ¦ ¦ ¦ loop + 388 ¦ ¦ } + 389 ¦ ¦ row <- add row, 1 + 390 ¦ ¦ column <- copy left + 391 ¦ ¦ screen <- move-cursor screen, row, column + 392 ¦ ¦ i <- add i, 1 + 393 ¦ ¦ loop +next-character + 394 ¦ } + 395 ¦ { + 396 ¦ ¦ # at right? wrap. + 397 ¦ ¦ at-right?:bool <- equal column, right + 398 ¦ ¦ break-unless at-right? + 399 ¦ ¦ # print wrap icon + 400 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left + 401 ¦ ¦ print screen, wrap-icon, 245/grey + 402 ¦ ¦ column <- copy left + 403 ¦ ¦ row <- add row, 1 + 404 ¦ ¦ screen <- move-cursor screen, row, column + 405 ¦ ¦ # don't increment i + 406 ¦ ¦ loop +next-character + 407 ¦ } + 408 ¦ i <- add i, 1 + 409 ¦ print screen, c, color + 410 ¦ column <- add column, 1 + 411 ¦ loop + 412 } + 413 was-at-left?:bool <- equal column, left + 414 clear-line-until screen, right + 415 { + 416 ¦ break-if was-at-left? + 417 ¦ row <- add row, 1 + 418 } + 419 move-cursor screen, row, left + 420 ] + 421 + 422 scenario read-text-wraps-barely-long-lines [ + 423 local-scope + 424 assume-screen 5/width, 5/height + 425 s:text <- new [abcde] + 426 run [ + 427 ¦ render-text screen, s, 0/left, 4/right, 7/white, 1/row + 428 ] + 429 screen-should-contain [ + 430 ¦ . . + 431 ¦ .abcd↩. + 432 ¦ .e . + 433 ¦ . . + 434 ] + 435 ] + 436 + 437 # assumes programming environment has no sandboxes; restores them from previous session + 438 def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environment [ + 439 local-scope + 440 load-ingredients + 441 # read all scenarios, pushing them to end of a list of scenarios + 442 idx:num <- copy 0 + 443 curr:&:sandbox <- copy 0 + 444 prev:&:sandbox <- copy 0 + 445 { + 446 ¦ filename:text <- append [lesson/], idx + 447 ¦ contents:text <- slurp resources, filename + 448 ¦ break-unless contents # stop at first error; assuming file didn't exist + 449 ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ # todo: handle empty sandbox + 450 ¦ # create new sandbox for file + 451 ¦ curr <- new sandbox:type + 452 ¦ *curr <- put *curr, data:offset, contents + 453 ¦ <end-restore-sandbox> 454 ¦ { - 455 ¦ ¦ break-unless idx - 456 ¦ ¦ *prev <- put *prev, next-sandbox:offset, curr + 455 ¦ ¦ break-if idx + 456 ¦ ¦ *env <- put *env, sandbox:offset, curr 457 ¦ } - 458 ¦ idx <- add idx, 1 - 459 ¦ prev <- copy curr - 460 ¦ loop - 461 } - 462 # update sandbox count - 463 *env <- put *env, number-of-sandboxes:offset, idx - 464 ] - 465 - 466 # print the fake sandbox screen to 'screen' with appropriate delimiters - 467 # leave cursor at start of next line - 468 def render-screen screen:&:screen, sandbox-screen:&:screen, left:num, right:num, row:num -> row:num, screen:&:screen [ - 469 local-scope - 470 load-ingredients - 471 return-unless sandbox-screen - 472 # print 'screen:' - 473 row <- render-text screen, [screen:], left, right, 245/grey, row - 474 screen <- move-cursor screen, row, left - 475 # start printing sandbox-screen - 476 column:num <- copy left - 477 s-width:num <- screen-width sandbox-screen - 478 s-height:num <- screen-height sandbox-screen - 479 buf:&:@:screen-cell <- get *sandbox-screen, data:offset - 480 stop-printing:num <- add left, s-width, 3 - 481 max-column:num <- min stop-printing, right - 482 i:num <- copy 0 - 483 len:num <- length *buf - 484 screen-height:num <- screen-height screen - 485 { - 486 ¦ done?:bool <- greater-or-equal i, len - 487 ¦ break-if done? - 488 ¦ done? <- greater-or-equal row, screen-height - 489 ¦ break-if done? - 490 ¦ column <- copy left - 491 ¦ screen <- move-cursor screen, row, column - 492 ¦ # initial leader for each row: two spaces and a '.' - 493 ¦ space:char <- copy 32/space - 494 ¦ print screen, space, 245/grey - 495 ¦ print screen, space, 245/grey - 496 ¦ full-stop:char <- copy 46/period - 497 ¦ print screen, full-stop, 245/grey - 498 ¦ column <- add left, 3 - 499 ¦ { - 500 ¦ ¦ # print row - 501 ¦ ¦ row-done?:bool <- greater-or-equal column, max-column - 502 ¦ ¦ break-if row-done? - 503 ¦ ¦ curr:screen-cell <- index *buf, i - 504 ¦ ¦ c:char <- get curr, contents:offset - 505 ¦ ¦ color:num <- get curr, color:offset - 506 ¦ ¦ { - 507 ¦ ¦ ¦ # damp whites down to grey - 508 ¦ ¦ ¦ white?:bool <- equal color, 7/white - 509 ¦ ¦ ¦ break-unless white? - 510 ¦ ¦ ¦ color <- copy 245/grey - 511 ¦ ¦ } - 512 ¦ ¦ print screen, c, color - 513 ¦ ¦ column <- add column, 1 - 514 ¦ ¦ i <- add i, 1 - 515 ¦ ¦ loop - 516 ¦ } - 517 ¦ # print final '.' - 518 ¦ print screen, full-stop, 245/grey - 519 ¦ column <- add column, 1 - 520 ¦ { - 521 ¦ ¦ # clear rest of current line - 522 ¦ ¦ line-done?:bool <- greater-than column, right - 523 ¦ ¦ break-if line-done? - 524 ¦ ¦ print screen, space - 525 ¦ ¦ column <- add column, 1 - 526 ¦ ¦ loop - 527 ¦ } - 528 ¦ row <- add row, 1 - 529 ¦ loop - 530 } - 531 ] - 532 - 533 scenario run-updates-results [ - 534 local-scope - 535 trace-until 100/app # trace too long - 536 assume-screen 100/width, 12/height - 537 # define a recipe (no indent for the 'add' line below so column numbers are more obvious) - 538 assume-resources [ - 539 ¦ [lesson/recipes.mu] <- [ - 540 ¦ ¦ || - 541 ¦ ¦ |recipe foo [| - 542 ¦ ¦ | local-scope| - 543 ¦ ¦ | z:num <- add 2, 2| - 544 ¦ ¦ | reply z| - 545 ¦ ¦ |]| - 546 ¦ ] - 547 ] - 548 # sandbox editor contains an instruction without storing outputs - 549 env:&:environment <- new-programming-environment resources, screen, [foo] # contents of sandbox editor - 550 # run the code in the editors - 551 assume-console [ - 552 ¦ press F4 - 553 ] - 554 event-loop screen, console, env, resources - 555 screen-should-contain [ - 556 ¦ . run (F4) . - 557 ¦ . ╎ . - 558 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. - 559 ¦ . local-scope ╎0 edit copy delete . - 560 ¦ . z:num <- add 2, 2 ╎foo . - 561 ¦ . reply z ╎4 . - 562 ¦ .] ╎─────────────────────────────────────────────────. - 563 ¦ . ╎ . - 564 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 565 ¦ . ╎ . - 566 ] - 567 # make a change (incrementing one of the args to 'add'), then rerun - 568 assume-console [ - 569 ¦ left-click 4, 28 # one past the value of the second arg - 570 ¦ press backspace - 571 ¦ type [3] - 572 ¦ press F4 - 573 ] - 574 run [ - 575 ¦ event-loop screen, console, env, resources - 576 ] - 577 # check that screen updates the result on the right - 578 screen-should-contain [ - 579 ¦ . run (F4) . - 580 ¦ . ╎ . - 581 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. - 582 ¦ . local-scope ╎0 edit copy delete . - 583 ¦ . z:num <- add 2, 3 ╎foo . - 584 ¦ . reply z ╎5 . - 585 ¦ .] ╎─────────────────────────────────────────────────. - 586 ¦ . ╎ . - 587 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 588 ¦ . ╎ . - 589 ] - 590 ] - 591 - 592 scenario run-instruction-manages-screen-per-sandbox [ - 593 local-scope - 594 trace-until 100/app # trace too long - 595 assume-screen 100/width, 20/height - 596 # empty recipes - 597 assume-resources [ - 598 ] - 599 # sandbox editor contains an instruction - 600 env:&:environment <- new-programming-environment resources, screen, [print screen, 4] # contents of sandbox editor - 601 # run the code in the editor - 602 assume-console [ - 603 ¦ press F4 - 604 ] - 605 run [ - 606 ¦ event-loop screen, console, env, resources - 607 ] - 608 # check that it prints a little toy screen - 609 screen-should-contain [ - 610 ¦ . run (F4) . - 611 ¦ . ╎ . - 612 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 613 ¦ . ╎0 edit copy delete . - 614 ¦ . ╎print screen, 4 . - 615 ¦ . ╎screen: . - 616 ¦ . ╎ .4 . . - 617 ¦ . ╎ . . . - 618 ¦ . ╎ . . . - 619 ¦ . ╎ . . . - 620 ¦ . ╎ . . . - 621 ¦ . ╎─────────────────────────────────────────────────. - 622 ¦ . ╎ . - 623 ] - 624 ] - 625 - 626 def editor-contents editor:&:editor -> result:text [ - 627 local-scope - 628 load-ingredients - 629 buf:&:buffer:char <- new-buffer 80 - 630 curr:&:duplex-list:char <- get *editor, data:offset - 631 # skip § sentinel - 632 assert curr, [editor without data is illegal; must have at least a sentinel] - 633 curr <- next curr - 634 return-unless curr, 0 - 635 { - 636 ¦ break-unless curr - 637 ¦ c:char <- get *curr, value:offset - 638 ¦ buf <- append buf, c - 639 ¦ curr <- next curr - 640 ¦ loop - 641 } - 642 result <- buffer-to-array buf - 643 ] - 644 - 645 scenario editor-provides-edited-contents [ - 646 local-scope - 647 assume-screen 10/width, 5/height - 648 e:&:editor <- new-editor [abc], 0/left, 10/right - 649 assume-console [ - 650 ¦ left-click 1, 2 - 651 ¦ type [def] - 652 ] - 653 run [ - 654 ¦ editor-event-loop screen, console, e - 655 ¦ s:text <- editor-contents e - 656 ¦ 1:@:char/raw <- copy *s - 657 ] - 658 memory-should-contain [ - 659 ¦ 1:array:character <- [abdefc] - 660 ] - 661 ] - 662 - 663 # keep the bottom of recipes from scrolling off the screen - 664 - 665 scenario scrolling-down-past-bottom-of-recipe-editor [ - 666 local-scope - 667 trace-until 100/app - 668 assume-screen 100/width, 10/height - 669 assume-resources [ - 670 ] - 671 env:&:environment <- new-programming-environment resources, screen, [] - 672 render-all screen, env, render - 673 assume-console [ - 674 ¦ press enter - 675 ¦ press down-arrow - 676 ] - 677 event-loop screen, console, env, resources - 678 # no scroll - 679 screen-should-contain [ - 680 ¦ . run (F4) . - 681 ¦ . ╎ . - 682 ¦ . ╎─────────────────────────────────────────────────. - 683 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 684 ¦ . ╎ . - 685 ] - 686 ] - 687 - 688 scenario cursor-down-in-recipe-editor [ - 689 local-scope - 690 trace-until 100/app - 691 assume-screen 100/width, 10/height - 692 assume-resources [ - 693 ] - 694 env:&:environment <- new-programming-environment resources, screen, [] - 695 render-all screen, env, render - 696 assume-console [ - 697 ¦ press enter - 698 ¦ press up-arrow - 699 ¦ press down-arrow # while cursor isn't at bottom - 700 ] - 701 event-loop screen, console, env, resources - 702 cursor:char <- copy 9251/␣ - 703 print screen, cursor - 704 # cursor moves back to bottom - 705 screen-should-contain [ - 706 ¦ . run (F4) . - 707 ¦ . ╎ . - 708 ¦ .␣ ╎─────────────────────────────────────────────────. - 709 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 710 ¦ . ╎ . - 711 ] - 712 ] - 713 - 714 # we'll not use the recipe-editor's 'bottom' element directly, because later - 715 # layers will add other stuff to the left side below the editor (error messages) - 716 - 717 container environment [ - 718 recipe-bottom:num - 719 ] + 458 ¦ { + 459 ¦ ¦ break-unless idx + 460 ¦ ¦ *prev <- put *prev, next-sandbox:offset, curr + 461 ¦ } + 462 ¦ idx <- add idx, 1 + 463 ¦ prev <- copy curr + 464 ¦ loop + 465 } + 466 # update sandbox count + 467 *env <- put *env, number-of-sandboxes:offset, idx + 468 ] + 469 + 470 # print the fake sandbox screen to 'screen' with appropriate delimiters + 471 # leave cursor at start of next line + 472 def render-screen screen:&:screen, sandbox-screen:&:screen, left:num, right:num, row:num -> row:num, screen:&:screen [ + 473 local-scope + 474 load-ingredients + 475 return-unless sandbox-screen + 476 # print 'screen:' + 477 row <- render-text screen, [screen:], left, right, 245/grey, row + 478 screen <- move-cursor screen, row, left + 479 # start printing sandbox-screen + 480 column:num <- copy left + 481 s-width:num <- screen-width sandbox-screen + 482 s-height:num <- screen-height sandbox-screen + 483 buf:&:@:screen-cell <- get *sandbox-screen, data:offset + 484 stop-printing:num <- add left, s-width, 3 + 485 max-column:num <- min stop-printing, right + 486 i:num <- copy 0 + 487 len:num <- length *buf + 488 screen-height:num <- screen-height screen + 489 { + 490 ¦ done?:bool <- greater-or-equal i, len + 491 ¦ break-if done? + 492 ¦ done? <- greater-or-equal row, screen-height + 493 ¦ break-if done? + 494 ¦ column <- copy left + 495 ¦ screen <- move-cursor screen, row, column + 496 ¦ # initial leader for each row: two spaces and a '.' + 497 ¦ space:char <- copy 32/space + 498 ¦ print screen, space, 245/grey + 499 ¦ print screen, space, 245/grey + 500 ¦ full-stop:char <- copy 46/period + 501 ¦ print screen, full-stop, 245/grey + 502 ¦ column <- add left, 3 + 503 ¦ { + 504 ¦ ¦ # print row + 505 ¦ ¦ row-done?:bool <- greater-or-equal column, max-column + 506 ¦ ¦ break-if row-done? + 507 ¦ ¦ curr:screen-cell <- index *buf, i + 508 ¦ ¦ c:char <- get curr, contents:offset + 509 ¦ ¦ color:num <- get curr, color:offset + 510 ¦ ¦ { + 511 ¦ ¦ ¦ # damp whites down to grey + 512 ¦ ¦ ¦ white?:bool <- equal color, 7/white + 513 ¦ ¦ ¦ break-unless white? + 514 ¦ ¦ ¦ color <- copy 245/grey + 515 ¦ ¦ } + 516 ¦ ¦ print screen, c, color + 517 ¦ ¦ column <- add column, 1 + 518 ¦ ¦ i <- add i, 1 + 519 ¦ ¦ loop + 520 ¦ } + 521 ¦ # print final '.' + 522 ¦ print screen, full-stop, 245/grey + 523 ¦ column <- add column, 1 + 524 ¦ { + 525 ¦ ¦ # clear rest of current line + 526 ¦ ¦ line-done?:bool <- greater-than column, right + 527 ¦ ¦ break-if line-done? + 528 ¦ ¦ print screen, space + 529 ¦ ¦ column <- add column, 1 + 530 ¦ ¦ loop + 531 ¦ } + 532 ¦ row <- add row, 1 + 533 ¦ loop + 534 } + 535 ] + 536 + 537 scenario run-updates-results [ + 538 local-scope + 539 trace-until 100/app # trace too long + 540 assume-screen 100/width, 12/height + 541 # define a recipe (no indent for the 'add' line below so column numbers are more obvious) + 542 assume-resources [ + 543 ¦ [lesson/recipes.mu] <- [ + 544 ¦ ¦ || + 545 ¦ ¦ |recipe foo [| + 546 ¦ ¦ | local-scope| + 547 ¦ ¦ | z:num <- add 2, 2| + 548 ¦ ¦ | reply z| + 549 ¦ ¦ |]| + 550 ¦ ] + 551 ] + 552 # sandbox editor contains an instruction without storing outputs + 553 env:&:environment <- new-programming-environment resources, screen, [foo] # contents of sandbox editor + 554 # run the code in the editors + 555 assume-console [ + 556 ¦ press F4 + 557 ] + 558 event-loop screen, console, env, resources + 559 screen-should-contain [ + 560 ¦ . run (F4) . + 561 ¦ . ╎ . + 562 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. + 563 ¦ . local-scope ╎0 edit copy to recipe delete . + 564 ¦ . z:num <- add 2, 2 ╎foo . + 565 ¦ . reply z ╎4 . + 566 ¦ .] ╎─────────────────────────────────────────────────. + 567 ¦ . ╎ . + 568 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 569 ¦ . ╎ . + 570 ] + 571 # make a change (incrementing one of the args to 'add'), then rerun + 572 assume-console [ + 573 ¦ left-click 4, 28 # one past the value of the second arg + 574 ¦ press backspace + 575 ¦ type [3] + 576 ¦ press F4 + 577 ] + 578 run [ + 579 ¦ event-loop screen, console, env, resources + 580 ] + 581 # check that screen updates the result on the right + 582 screen-should-contain [ + 583 ¦ . run (F4) . + 584 ¦ . ╎ . + 585 ¦ .recipe foo [ ╎─────────────────────────────────────────────────. + 586 ¦ . local-scope ╎0 edit copy to recipe delete . + 587 ¦ . z:num <- add 2, 3 ╎foo . + 588 ¦ . reply z ╎5 . + 589 ¦ .] ╎─────────────────────────────────────────────────. + 590 ¦ . ╎ . + 591 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 592 ¦ . ╎ . + 593 ] + 594 ] + 595 + 596 scenario run-instruction-manages-screen-per-sandbox [ + 597 local-scope + 598 trace-until 100/app # trace too long + 599 assume-screen 100/width, 20/height + 600 # empty recipes + 601 assume-resources [ + 602 ] + 603 # sandbox editor contains an instruction + 604 env:&:environment <- new-programming-environment resources, screen, [print screen, 4] # contents of sandbox editor + 605 # run the code in the editor + 606 assume-console [ + 607 ¦ press F4 + 608 ] + 609 run [ + 610 ¦ event-loop screen, console, env, resources + 611 ] + 612 # check that it prints a little toy screen + 613 screen-should-contain [ + 614 ¦ . run (F4) . + 615 ¦ . ╎ . + 616 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 617 ¦ . ╎0 edit copy to recipe delete . + 618 ¦ . ╎print screen, 4 . + 619 ¦ . ╎screen: . + 620 ¦ . ╎ .4 . . + 621 ¦ . ╎ . . . + 622 ¦ . ╎ . . . + 623 ¦ . ╎ . . . + 624 ¦ . ╎ . . . + 625 ¦ . ╎─────────────────────────────────────────────────. + 626 ¦ . ╎ . + 627 ] + 628 ] + 629 + 630 def editor-contents editor:&:editor -> result:text [ + 631 local-scope + 632 load-ingredients + 633 buf:&:buffer:char <- new-buffer 80 + 634 curr:&:duplex-list:char <- get *editor, data:offset + 635 # skip § sentinel + 636 assert curr, [editor without data is illegal; must have at least a sentinel] + 637 curr <- next curr + 638 return-unless curr, 0 + 639 { + 640 ¦ break-unless curr + 641 ¦ c:char <- get *curr, value:offset + 642 ¦ buf <- append buf, c + 643 ¦ curr <- next curr + 644 ¦ loop + 645 } + 646 result <- buffer-to-array buf + 647 ] + 648 + 649 scenario editor-provides-edited-contents [ + 650 local-scope + 651 assume-screen 10/width, 5/height + 652 e:&:editor <- new-editor [abc], 0/left, 10/right + 653 assume-console [ + 654 ¦ left-click 1, 2 + 655 ¦ type [def] + 656 ] + 657 run [ + 658 ¦ editor-event-loop screen, console, e + 659 ¦ s:text <- editor-contents e + 660 ¦ 1:@:char/raw <- copy *s + 661 ] + 662 memory-should-contain [ + 663 ¦ 1:array:character <- [abdefc] + 664 ] + 665 ] + 666 + 667 # keep the bottom of recipes from scrolling off the screen + 668 + 669 scenario scrolling-down-past-bottom-of-recipe-editor [ + 670 local-scope + 671 trace-until 100/app + 672 assume-screen 100/width, 10/height + 673 assume-resources [ + 674 ] + 675 env:&:environment <- new-programming-environment resources, screen, [] + 676 render-all screen, env, render + 677 assume-console [ + 678 ¦ press enter + 679 ¦ press down-arrow + 680 ] + 681 event-loop screen, console, env, resources + 682 # no scroll + 683 screen-should-contain [ + 684 ¦ . run (F4) . + 685 ¦ . ╎ . + 686 ¦ . ╎─────────────────────────────────────────────────. + 687 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 688 ¦ . ╎ . + 689 ] + 690 ] + 691 + 692 scenario cursor-down-in-recipe-editor [ + 693 local-scope + 694 trace-until 100/app + 695 assume-screen 100/width, 10/height + 696 assume-resources [ + 697 ] + 698 env:&:environment <- new-programming-environment resources, screen, [] + 699 render-all screen, env, render + 700 assume-console [ + 701 ¦ press enter + 702 ¦ press up-arrow + 703 ¦ press down-arrow # while cursor isn't at bottom + 704 ] + 705 event-loop screen, console, env, resources + 706 cursor:char <- copy 9251/␣ + 707 print screen, cursor + 708 # cursor moves back to bottom + 709 screen-should-contain [ + 710 ¦ . run (F4) . + 711 ¦ . ╎ . + 712 ¦ .␣ ╎─────────────────────────────────────────────────. + 713 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 714 ¦ . ╎ . + 715 ] + 716 ] + 717 + 718 # we'll not use the recipe-editor's 'bottom' element directly, because later + 719 # layers will add other stuff to the left side below the editor (error messages) 720 - 721 after <render-recipe-components-end> [ - 722 *env <- put *env, recipe-bottom:offset, row + 721 container environment [ + 722 recipe-bottom:num 723 ] 724 - 725 after <global-keypress> [ - 726 { - 727 ¦ break-if sandbox-in-focus? - 728 ¦ down-arrow?:bool <- equal k, 65516/down-arrow - 729 ¦ break-unless down-arrow? - 730 ¦ recipe-editor:&:editor <- get *env, recipes:offset - 731 ¦ recipe-cursor-row:num <- get *recipe-editor, cursor-row:offset - 732 ¦ recipe-editor-bottom:num <- get *recipe-editor, bottom:offset - 733 ¦ at-bottom-of-editor?:bool <- greater-or-equal recipe-cursor-row, recipe-editor-bottom - 734 ¦ break-unless at-bottom-of-editor? - 735 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen - 736 ¦ break-if more-to-scroll? - 737 ¦ loop +next-event - 738 } - 739 { - 740 ¦ break-if sandbox-in-focus? - 741 ¦ page-down?:bool <- equal k, 65518/page-down - 742 ¦ break-unless page-down? - 743 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen - 744 ¦ break-if more-to-scroll? - 745 ¦ loop +next-event - 746 } - 747 ] - 748 - 749 after <global-type> [ - 750 { - 751 ¦ break-if sandbox-in-focus? - 752 ¦ page-down?:bool <- equal k, 6/ctrl-f - 753 ¦ break-unless page-down? - 754 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen - 755 ¦ break-if more-to-scroll? - 756 ¦ loop +next-event - 757 } - 758 ] - 759 - 760 def more-to-scroll? env:&:environment, screen:&:screen -> result:bool [ - 761 local-scope - 762 load-ingredients - 763 recipe-bottom:num <- get *env, recipe-bottom:offset - 764 height:num <- screen-height screen - 765 result <- greater-or-equal recipe-bottom, height - 766 ] - 767 - 768 scenario scrolling-down-past-bottom-of-recipe-editor-2 [ - 769 local-scope - 770 trace-until 100/app - 771 assume-screen 100/width, 10/height - 772 assume-resources [ - 773 ] - 774 env:&:environment <- new-programming-environment resources, screen, [] - 775 render-all screen, env, render - 776 assume-console [ - 777 ¦ # add a line - 778 ¦ press enter - 779 ¦ # cursor back to top line - 780 ¦ press up-arrow - 781 ¦ # try to scroll - 782 ¦ press page-down # or ctrl-f - 783 ] - 784 event-loop screen, console, env, resources - 785 # no scroll, and cursor remains at top line - 786 screen-should-contain [ - 787 ¦ . run (F4) . - 788 ¦ . ╎ . - 789 ¦ . ╎─────────────────────────────────────────────────. - 790 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . - 791 ¦ . ╎ . - 792 ] - 793 ] - 794 - 795 scenario scrolling-down-past-bottom-of-recipe-editor-3 [ - 796 local-scope - 797 trace-until 100/app - 798 assume-screen 100/width, 10/height - 799 assume-resources [ - 800 ] - 801 env:&:environment <- new-programming-environment resources, screen, [ab - 802 cd] - 803 render-all screen, env, render - 804 assume-console [ - 805 ¦ # add a line - 806 ¦ press enter - 807 ¦ # switch to sandbox - 808 ¦ press ctrl-n - 809 ¦ # move cursor - 810 ¦ press down-arrow - 811 ] - 812 event-loop screen, console, env, resources - 813 cursor:char <- copy 9251/␣ - 814 print screen, cursor - 815 # no scroll on recipe side, cursor moves on sandbox side - 816 screen-should-contain [ - 817 ¦ . run (F4) . - 818 ¦ . ╎ab . - 819 ¦ . ╎␣d . - 820 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 821 ¦ . ╎ . - 822 ] - 823 ] - 824 - 825 # scrolling through sandboxes - 826 - 827 scenario scrolling-down-past-bottom-of-sandbox-editor [ - 828 local-scope - 829 trace-until 100/app # trace too long - 830 assume-screen 100/width, 10/height - 831 # initialize - 832 assume-resources [ - 833 ] - 834 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] - 835 render-all screen, env, render - 836 assume-console [ - 837 ¦ # create a sandbox - 838 ¦ press F4 - 839 ] - 840 event-loop screen, console, env, resources - 841 screen-should-contain [ - 842 ¦ . run (F4) . - 843 ¦ . ╎ . - 844 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 845 ¦ . ╎0 edit copy delete . - 846 ¦ . ╎add 2, 2 . - 847 ] - 848 # switch to sandbox window and hit 'page-down' - 849 assume-console [ - 850 ¦ press ctrl-n - 851 ¦ press page-down - 852 ] - 853 run [ - 854 ¦ event-loop screen, console, env, resources - 855 ¦ cursor:char <- copy 9251/␣ - 856 ¦ print screen, cursor - 857 ] - 858 # sandbox editor hidden; first sandbox displayed - 859 # cursor moves to first sandbox - 860 screen-should-contain [ - 861 ¦ . run (F4) . - 862 ¦ . ╎─────────────────────────────────────────────────. - 863 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete . - 864 ¦ . ╎add 2, 2 . - 865 ¦ . ╎4 . - 866 ] - 867 # hit 'page-up' - 868 assume-console [ - 869 ¦ press page-up + 725 after <render-recipe-components-end> [ + 726 *env <- put *env, recipe-bottom:offset, row + 727 ] + 728 + 729 after <global-keypress> [ + 730 { + 731 ¦ break-if sandbox-in-focus? + 732 ¦ down-arrow?:bool <- equal k, 65516/down-arrow + 733 ¦ break-unless down-arrow? + 734 ¦ recipe-editor:&:editor <- get *env, recipes:offset + 735 ¦ recipe-cursor-row:num <- get *recipe-editor, cursor-row:offset + 736 ¦ recipe-editor-bottom:num <- get *recipe-editor, bottom:offset + 737 ¦ at-bottom-of-editor?:bool <- greater-or-equal recipe-cursor-row, recipe-editor-bottom + 738 ¦ break-unless at-bottom-of-editor? + 739 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen + 740 ¦ break-if more-to-scroll? + 741 ¦ loop +next-event + 742 } + 743 { + 744 ¦ break-if sandbox-in-focus? + 745 ¦ page-down?:bool <- equal k, 65518/page-down + 746 ¦ break-unless page-down? + 747 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen + 748 ¦ break-if more-to-scroll? + 749 ¦ loop +next-event + 750 } + 751 ] + 752 + 753 after <global-type> [ + 754 { + 755 ¦ break-if sandbox-in-focus? + 756 ¦ page-down?:bool <- equal k, 6/ctrl-f + 757 ¦ break-unless page-down? + 758 ¦ more-to-scroll?:bool <- more-to-scroll? env, screen + 759 ¦ break-if more-to-scroll? + 760 ¦ loop +next-event + 761 } + 762 ] + 763 + 764 def more-to-scroll? env:&:environment, screen:&:screen -> result:bool [ + 765 local-scope + 766 load-ingredients + 767 recipe-bottom:num <- get *env, recipe-bottom:offset + 768 height:num <- screen-height screen + 769 result <- greater-or-equal recipe-bottom, height + 770 ] + 771 + 772 scenario scrolling-down-past-bottom-of-recipe-editor-2 [ + 773 local-scope + 774 trace-until 100/app + 775 assume-screen 100/width, 10/height + 776 assume-resources [ + 777 ] + 778 env:&:environment <- new-programming-environment resources, screen, [] + 779 render-all screen, env, render + 780 assume-console [ + 781 ¦ # add a line + 782 ¦ press enter + 783 ¦ # cursor back to top line + 784 ¦ press up-arrow + 785 ¦ # try to scroll + 786 ¦ press page-down # or ctrl-f + 787 ] + 788 event-loop screen, console, env, resources + 789 # no scroll, and cursor remains at top line + 790 screen-should-contain [ + 791 ¦ . run (F4) . + 792 ¦ . ╎ . + 793 ¦ . ╎─────────────────────────────────────────────────. + 794 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ . + 795 ¦ . ╎ . + 796 ] + 797 ] + 798 + 799 scenario scrolling-down-past-bottom-of-recipe-editor-3 [ + 800 local-scope + 801 trace-until 100/app + 802 assume-screen 100/width, 10/height + 803 assume-resources [ + 804 ] + 805 env:&:environment <- new-programming-environment resources, screen, [ab + 806 cd] + 807 render-all screen, env, render + 808 assume-console [ + 809 ¦ # add a line + 810 ¦ press enter + 811 ¦ # switch to sandbox + 812 ¦ press ctrl-n + 813 ¦ # move cursor + 814 ¦ press down-arrow + 815 ] + 816 event-loop screen, console, env, resources + 817 cursor:char <- copy 9251/␣ + 818 print screen, cursor + 819 # no scroll on recipe side, cursor moves on sandbox side + 820 screen-should-contain [ + 821 ¦ . run (F4) . + 822 ¦ . ╎ab . + 823 ¦ . ╎␣d . + 824 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 825 ¦ . ╎ . + 826 ] + 827 ] + 828 + 829 # scrolling through sandboxes + 830 + 831 scenario scrolling-down-past-bottom-of-sandbox-editor [ + 832 local-scope + 833 trace-until 100/app # trace too long + 834 assume-screen 100/width, 10/height + 835 # initialize + 836 assume-resources [ + 837 ] + 838 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] + 839 render-all screen, env, render + 840 assume-console [ + 841 ¦ # create a sandbox + 842 ¦ press F4 + 843 ] + 844 event-loop screen, console, env, resources + 845 screen-should-contain [ + 846 ¦ . run (F4) . + 847 ¦ . ╎ . + 848 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 849 ¦ . ╎0 edit copy to recipe delete . + 850 ¦ . ╎add 2, 2 . + 851 ] + 852 # switch to sandbox window and hit 'page-down' + 853 assume-console [ + 854 ¦ press ctrl-n + 855 ¦ press page-down + 856 ] + 857 run [ + 858 ¦ event-loop screen, console, env, resources + 859 ¦ cursor:char <- copy 9251/␣ + 860 ¦ print screen, cursor + 861 ] + 862 # sandbox editor hidden; first sandbox displayed + 863 # cursor moves to first sandbox + 864 screen-should-contain [ + 865 ¦ . run (F4) . + 866 ¦ . ╎─────────────────────────────────────────────────. + 867 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy to recipe delete . + 868 ¦ . ╎add 2, 2 . + 869 ¦ . ╎4 . 870 ] - 871 run [ - 872 ¦ event-loop screen, console, env, resources - 873 ¦ cursor:char <- copy 9251/␣ - 874 ¦ print screen, cursor - 875 ] - 876 # sandbox editor displays again, cursor is in editor - 877 screen-should-contain [ - 878 ¦ . run (F4) . - 879 ¦ . ╎␣ . - 880 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 881 ¦ . ╎0 edit copy delete . - 882 ¦ . ╎add 2, 2 . - 883 ] - 884 ] - 885 - 886 # page-down on sandbox side updates render-from to scroll sandboxes - 887 after <global-keypress> [ - 888 { - 889 ¦ break-unless sandbox-in-focus? - 890 ¦ page-down?:bool <- equal k, 65518/page-down - 891 ¦ break-unless page-down? - 892 ¦ sandbox:&:sandbox <- get *env, sandbox:offset - 893 ¦ break-unless sandbox - 894 ¦ # slide down if possible - 895 ¦ { - 896 ¦ ¦ render-from:num <- get *env, render-from:offset - 897 ¦ ¦ number-of-sandboxes:num <- get *env, number-of-sandboxes:offset - 898 ¦ ¦ max:num <- subtract number-of-sandboxes, 1 - 899 ¦ ¦ at-end?:bool <- greater-or-equal render-from, max - 900 ¦ ¦ loop-if at-end?, +next-event # render nothing - 901 ¦ ¦ render-from <- add render-from, 1 - 902 ¦ ¦ *env <- put *env, render-from:offset, render-from - 903 ¦ } - 904 ¦ screen <- render-sandbox-side screen, env, render - 905 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env - 906 ¦ loop +next-event - 907 } - 908 ] - 909 - 910 # update-cursor takes render-from into account - 911 after <update-cursor-special-cases> [ - 912 { - 913 ¦ break-unless sandbox-in-focus? - 914 ¦ render-from:num <- get *env, render-from:offset - 915 ¦ scrolling?:bool <- greater-or-equal render-from, 0 - 916 ¦ break-unless scrolling? - 917 ¦ cursor-column:num <- get *current-sandbox, left:offset - 918 ¦ screen <- move-cursor screen, 2/row, cursor-column # highlighted sandbox will always start at row 2 - 919 ¦ return - 920 } - 921 ] - 922 - 923 # 'page-up' on sandbox side is like 'page-down': updates render-from when necessary - 924 after <global-keypress> [ - 925 { - 926 ¦ break-unless sandbox-in-focus? - 927 ¦ page-up?:bool <- equal k, 65519/page-up - 928 ¦ break-unless page-up? - 929 ¦ render-from:num <- get *env, render-from:offset - 930 ¦ at-beginning?:bool <- equal render-from, -1 - 931 ¦ break-if at-beginning? - 932 ¦ render-from <- subtract render-from, 1 - 933 ¦ *env <- put *env, render-from:offset, render-from - 934 ¦ screen <- render-sandbox-side screen, env, render - 935 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env - 936 ¦ loop +next-event - 937 } - 938 ] - 939 - 940 # sandbox belonging to 'env' whose next-sandbox is 'in' - 941 # return 0 if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox - 942 def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [ - 943 local-scope - 944 load-ingredients - 945 curr:&:sandbox <- get *env, sandbox:offset - 946 return-unless curr, 0/nil - 947 next:&:sandbox <- get *curr, next-sandbox:offset - 948 { - 949 ¦ return-unless next, 0/nil - 950 ¦ found?:bool <- equal next, in - 951 ¦ break-if found? - 952 ¦ curr <- copy next - 953 ¦ next <- get *curr, next-sandbox:offset - 954 ¦ loop - 955 } - 956 return curr - 957 ] - 958 - 959 scenario scrolling-down-past-bottom-on-recipe-side [ - 960 local-scope - 961 trace-until 100/app # trace too long - 962 assume-screen 100/width, 10/height - 963 # initialize sandbox side and create a sandbox - 964 assume-resources [ - 965 ¦ [lesson/recipes.mu] <- [ - 966 ¦ ¦ || # file containing just a newline - 967 ¦ ] - 968 ] - 969 # create a sandbox - 970 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] - 971 render-all screen, env, render - 972 assume-console [ - 973 ¦ press F4 - 974 ] - 975 event-loop screen, console, env, resources - 976 # hit 'down' in recipe editor - 977 assume-console [ - 978 ¦ press page-down - 979 ] - 980 run [ - 981 ¦ event-loop screen, console, env, resources - 982 ¦ cursor:char <- copy 9251/␣ - 983 ¦ print screen, cursor - 984 ] - 985 # cursor doesn't move when the end is already on-screen - 986 screen-should-contain [ - 987 ¦ . run (F4) . - 988 ¦ .␣ ╎ . - 989 ¦ . ╎─────────────────────────────────────────────────. - 990 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . - 991 ¦ . ╎add 2, 2 . - 992 ] - 993 ] - 994 - 995 scenario scrolling-through-multiple-sandboxes [ - 996 local-scope - 997 trace-until 100/app # trace too long - 998 assume-screen 100/width, 10/height - 999 # initialize environment -1000 assume-resources [ -1001 ] -1002 env:&:environment <- new-programming-environment resources, screen, [] -1003 render-all screen, env, render -1004 # create 2 sandboxes -1005 assume-console [ -1006 ¦ press ctrl-n -1007 ¦ type [add 2, 2] -1008 ¦ press F4 -1009 ¦ type [add 1, 1] -1010 ¦ press F4 -1011 ] -1012 event-loop screen, console, env, resources -1013 cursor:char <- copy 9251/␣ -1014 print screen, cursor -1015 screen-should-contain [ -1016 ¦ . run (F4) . -1017 ¦ . ╎␣ . -1018 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1019 ¦ . ╎0 edit copy delete . -1020 ¦ . ╎add 1, 1 . -1021 ¦ . ╎2 . -1022 ¦ . ╎─────────────────────────────────────────────────. -1023 ¦ . ╎1 edit copy delete . -1024 ¦ . ╎add 2, 2 . -1025 ¦ . ╎4 . -1026 ] -1027 # hit 'page-down' -1028 assume-console [ -1029 ¦ press page-down + 871 # hit 'page-up' + 872 assume-console [ + 873 ¦ press page-up + 874 ] + 875 run [ + 876 ¦ event-loop screen, console, env, resources + 877 ¦ cursor:char <- copy 9251/␣ + 878 ¦ print screen, cursor + 879 ] + 880 # sandbox editor displays again, cursor is in editor + 881 screen-should-contain [ + 882 ¦ . run (F4) . + 883 ¦ . ╎␣ . + 884 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. + 885 ¦ . ╎0 edit copy to recipe delete . + 886 ¦ . ╎add 2, 2 . + 887 ] + 888 ] + 889 + 890 # page-down on sandbox side updates render-from to scroll sandboxes + 891 after <global-keypress> [ + 892 { + 893 ¦ break-unless sandbox-in-focus? + 894 ¦ page-down?:bool <- equal k, 65518/page-down + 895 ¦ break-unless page-down? + 896 ¦ sandbox:&:sandbox <- get *env, sandbox:offset + 897 ¦ break-unless sandbox + 898 ¦ # slide down if possible + 899 ¦ { + 900 ¦ ¦ render-from:num <- get *env, render-from:offset + 901 ¦ ¦ number-of-sandboxes:num <- get *env, number-of-sandboxes:offset + 902 ¦ ¦ max:num <- subtract number-of-sandboxes, 1 + 903 ¦ ¦ at-end?:bool <- greater-or-equal render-from, max + 904 ¦ ¦ loop-if at-end?, +next-event # render nothing + 905 ¦ ¦ render-from <- add render-from, 1 + 906 ¦ ¦ *env <- put *env, render-from:offset, render-from + 907 ¦ } + 908 ¦ screen <- render-sandbox-side screen, env, render + 909 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env + 910 ¦ loop +next-event + 911 } + 912 ] + 913 + 914 # update-cursor takes render-from into account + 915 after <update-cursor-special-cases> [ + 916 { + 917 ¦ break-unless sandbox-in-focus? + 918 ¦ render-from:num <- get *env, render-from:offset + 919 ¦ scrolling?:bool <- greater-or-equal render-from, 0 + 920 ¦ break-unless scrolling? + 921 ¦ cursor-column:num <- get *current-sandbox, left:offset + 922 ¦ screen <- move-cursor screen, 2/row, cursor-column # highlighted sandbox will always start at row 2 + 923 ¦ return + 924 } + 925 ] + 926 + 927 # 'page-up' on sandbox side is like 'page-down': updates render-from when necessary + 928 after <global-keypress> [ + 929 { + 930 ¦ break-unless sandbox-in-focus? + 931 ¦ page-up?:bool <- equal k, 65519/page-up + 932 ¦ break-unless page-up? + 933 ¦ render-from:num <- get *env, render-from:offset + 934 ¦ at-beginning?:bool <- equal render-from, -1 + 935 ¦ break-if at-beginning? + 936 ¦ render-from <- subtract render-from, 1 + 937 ¦ *env <- put *env, render-from:offset, render-from + 938 ¦ screen <- render-sandbox-side screen, env, render + 939 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env + 940 ¦ loop +next-event + 941 } + 942 ] + 943 + 944 # sandbox belonging to 'env' whose next-sandbox is 'in' + 945 # return 0 if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox + 946 def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [ + 947 local-scope + 948 load-ingredients + 949 curr:&:sandbox <- get *env, sandbox:offset + 950 return-unless curr, 0/nil + 951 next:&:sandbox <- get *curr, next-sandbox:offset + 952 { + 953 ¦ return-unless next, 0/nil + 954 ¦ found?:bool <- equal next, in + 955 ¦ break-if found? + 956 ¦ curr <- copy next + 957 ¦ next <- get *curr, next-sandbox:offset + 958 ¦ loop + 959 } + 960 return curr + 961 ] + 962 + 963 scenario scrolling-down-past-bottom-on-recipe-side [ + 964 local-scope + 965 trace-until 100/app # trace too long + 966 assume-screen 100/width, 10/height + 967 # initialize sandbox side and create a sandbox + 968 assume-resources [ + 969 ¦ [lesson/recipes.mu] <- [ + 970 ¦ ¦ || # file containing just a newline + 971 ¦ ] + 972 ] + 973 # create a sandbox + 974 env:&:environment <- new-programming-environment resources, screen, [add 2, 2] + 975 render-all screen, env, render + 976 assume-console [ + 977 ¦ press F4 + 978 ] + 979 event-loop screen, console, env, resources + 980 # hit 'down' in recipe editor + 981 assume-console [ + 982 ¦ press page-down + 983 ] + 984 run [ + 985 ¦ event-loop screen, console, env, resources + 986 ¦ cursor:char <- copy 9251/␣ + 987 ¦ print screen, cursor + 988 ] + 989 # cursor doesn't move when the end is already on-screen + 990 screen-should-contain [ + 991 ¦ . run (F4) . + 992 ¦ .␣ ╎ . + 993 ¦ . ╎─────────────────────────────────────────────────. + 994 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . + 995 ¦ . ╎add 2, 2 . + 996 ] + 997 ] + 998 + 999 scenario scrolling-through-multiple-sandboxes [ +1000 local-scope +1001 trace-until 100/app # trace too long +1002 assume-screen 100/width, 10/height +1003 # initialize environment +1004 assume-resources [ +1005 ] +1006 env:&:environment <- new-programming-environment resources, screen, [] +1007 render-all screen, env, render +1008 # create 2 sandboxes +1009 assume-console [ +1010 ¦ press ctrl-n +1011 ¦ type [add 2, 2] +1012 ¦ press F4 +1013 ¦ type [add 1, 1] +1014 ¦ press F4 +1015 ] +1016 event-loop screen, console, env, resources +1017 cursor:char <- copy 9251/␣ +1018 print screen, cursor +1019 screen-should-contain [ +1020 ¦ . run (F4) . +1021 ¦ . ╎␣ . +1022 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1023 ¦ . ╎0 edit copy to recipe delete . +1024 ¦ . ╎add 1, 1 . +1025 ¦ . ╎2 . +1026 ¦ . ╎─────────────────────────────────────────────────. +1027 ¦ . ╎1 edit copy to recipe delete . +1028 ¦ . ╎add 2, 2 . +1029 ¦ . ╎4 . 1030 ] -1031 run [ -1032 ¦ event-loop screen, console, env, resources -1033 ¦ cursor:char <- copy 9251/␣ -1034 ¦ print screen, cursor -1035 ] -1036 # sandbox editor hidden; first sandbox displayed -1037 # cursor moves to first sandbox -1038 screen-should-contain [ -1039 ¦ . run (F4) . -1040 ¦ . ╎─────────────────────────────────────────────────. -1041 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy delete . -1042 ¦ . ╎add 1, 1 . -1043 ¦ . ╎2 . +1031 # hit 'page-down' +1032 assume-console [ +1033 ¦ press page-down +1034 ] +1035 run [ +1036 ¦ event-loop screen, console, env, resources +1037 ¦ cursor:char <- copy 9251/␣ +1038 ¦ print screen, cursor +1039 ] +1040 # sandbox editor hidden; first sandbox displayed +1041 # cursor moves to first sandbox +1042 screen-should-contain [ +1043 ¦ . run (F4) . 1044 ¦ . ╎─────────────────────────────────────────────────. -1045 ¦ . ╎1 edit copy delete . -1046 ¦ . ╎add 2, 2 . -1047 ¦ . ╎4 . -1048 ] -1049 # hit 'page-down' again -1050 assume-console [ -1051 ¦ press page-down +1045 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎␣ edit copy to recipe delete . +1046 ¦ . ╎add 1, 1 . +1047 ¦ . ╎2 . +1048 ¦ . ╎─────────────────────────────────────────────────. +1049 ¦ . ╎1 edit copy to recipe delete . +1050 ¦ . ╎add 2, 2 . +1051 ¦ . ╎4 . 1052 ] -1053 run [ -1054 ¦ event-loop screen, console, env, resources -1055 ] -1056 # just second sandbox displayed -1057 screen-should-contain [ -1058 ¦ . run (F4) . -1059 ¦ . ╎─────────────────────────────────────────────────. -1060 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . -1061 ¦ . ╎add 2, 2 . -1062 ¦ . ╎4 . +1053 # hit 'page-down' again +1054 assume-console [ +1055 ¦ press page-down +1056 ] +1057 run [ +1058 ¦ event-loop screen, console, env, resources +1059 ] +1060 # just second sandbox displayed +1061 screen-should-contain [ +1062 ¦ . run (F4) . 1063 ¦ . ╎─────────────────────────────────────────────────. -1064 ¦ . ╎ . -1065 ] -1066 # hit 'page-down' again -1067 assume-console [ -1068 ¦ press page-down +1064 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy to recipe delete . +1065 ¦ . ╎add 2, 2 . +1066 ¦ . ╎4 . +1067 ¦ . ╎─────────────────────────────────────────────────. +1068 ¦ . ╎ . 1069 ] -1070 run [ -1071 ¦ event-loop screen, console, env, resources -1072 ] -1073 # no change -1074 screen-should-contain [ -1075 ¦ . run (F4) . -1076 ¦ . ╎─────────────────────────────────────────────────. -1077 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . -1078 ¦ . ╎add 2, 2 . -1079 ¦ . ╎4 . +1070 # hit 'page-down' again +1071 assume-console [ +1072 ¦ press page-down +1073 ] +1074 run [ +1075 ¦ event-loop screen, console, env, resources +1076 ] +1077 # no change +1078 screen-should-contain [ +1079 ¦ . run (F4) . 1080 ¦ . ╎─────────────────────────────────────────────────. -1081 ¦ . ╎ . -1082 ] -1083 # hit 'page-up' -1084 assume-console [ -1085 ¦ press page-up +1081 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy to recipe delete . +1082 ¦ . ╎add 2, 2 . +1083 ¦ . ╎4 . +1084 ¦ . ╎─────────────────────────────────────────────────. +1085 ¦ . ╎ . 1086 ] -1087 run [ -1088 ¦ event-loop screen, console, env, resources -1089 ] -1090 # back to displaying both sandboxes without editor -1091 screen-should-contain [ -1092 ¦ . run (F4) . -1093 ¦ . ╎─────────────────────────────────────────────────. -1094 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . -1095 ¦ . ╎add 1, 1 . -1096 ¦ . ╎2 . +1087 # hit 'page-up' +1088 assume-console [ +1089 ¦ press page-up +1090 ] +1091 run [ +1092 ¦ event-loop screen, console, env, resources +1093 ] +1094 # back to displaying both sandboxes without editor +1095 screen-should-contain [ +1096 ¦ . run (F4) . 1097 ¦ . ╎─────────────────────────────────────────────────. -1098 ¦ . ╎1 edit copy delete . -1099 ¦ . ╎add 2, 2 . -1100 ¦ . ╎4 . -1101 ] -1102 # hit 'page-up' again -1103 assume-console [ -1104 ¦ press page-up +1098 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . +1099 ¦ . ╎add 1, 1 . +1100 ¦ . ╎2 . +1101 ¦ . ╎─────────────────────────────────────────────────. +1102 ¦ . ╎1 edit copy to recipe delete . +1103 ¦ . ╎add 2, 2 . +1104 ¦ . ╎4 . 1105 ] -1106 run [ -1107 ¦ event-loop screen, console, env, resources -1108 ¦ cursor:char <- copy 9251/␣ -1109 ¦ print screen, cursor -1110 ] -1111 # back to displaying both sandboxes as well as editor -1112 screen-should-contain [ -1113 ¦ . run (F4) . -1114 ¦ . ╎␣ . -1115 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1116 ¦ . ╎0 edit copy delete . -1117 ¦ . ╎add 1, 1 . -1118 ¦ . ╎2 . -1119 ¦ . ╎─────────────────────────────────────────────────. -1120 ¦ . ╎1 edit copy delete . -1121 ¦ . ╎add 2, 2 . -1122 ¦ . ╎4 . -1123 ] -1124 # hit 'page-up' again -1125 assume-console [ -1126 ¦ press page-up +1106 # hit 'page-up' again +1107 assume-console [ +1108 ¦ press page-up +1109 ] +1110 run [ +1111 ¦ event-loop screen, console, env, resources +1112 ¦ cursor:char <- copy 9251/␣ +1113 ¦ print screen, cursor +1114 ] +1115 # back to displaying both sandboxes as well as editor +1116 screen-should-contain [ +1117 ¦ . run (F4) . +1118 ¦ . ╎␣ . +1119 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1120 ¦ . ╎0 edit copy to recipe delete . +1121 ¦ . ╎add 1, 1 . +1122 ¦ . ╎2 . +1123 ¦ . ╎─────────────────────────────────────────────────. +1124 ¦ . ╎1 edit copy to recipe delete . +1125 ¦ . ╎add 2, 2 . +1126 ¦ . ╎4 . 1127 ] -1128 run [ -1129 ¦ event-loop screen, console, env, resources -1130 ¦ cursor:char <- copy 9251/␣ -1131 ¦ print screen, cursor -1132 ] -1133 # no change -1134 screen-should-contain [ -1135 ¦ . run (F4) . -1136 ¦ . ╎␣ . -1137 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1138 ¦ . ╎0 edit copy delete . -1139 ¦ . ╎add 1, 1 . -1140 ¦ . ╎2 . -1141 ¦ . ╎─────────────────────────────────────────────────. -1142 ¦ . ╎1 edit copy delete . -1143 ¦ . ╎add 2, 2 . -1144 ¦ . ╎4 . -1145 ] -1146 ] -1147 -1148 scenario scrolling-manages-sandbox-index-correctly [ -1149 local-scope -1150 trace-until 100/app # trace too long -1151 assume-screen 100/width, 10/height -1152 # initialize environment -1153 assume-resources [ -1154 ] -1155 env:&:environment <- new-programming-environment resources, screen, [] -1156 render-all screen, env, render -1157 # create a sandbox -1158 assume-console [ -1159 ¦ press ctrl-n -1160 ¦ type [add 1, 1] -1161 ¦ press F4 -1162 ] -1163 event-loop screen, console, env, resources -1164 screen-should-contain [ -1165 ¦ . run (F4) . -1166 ¦ . ╎ . -1167 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1168 ¦ . ╎0 edit copy delete . -1169 ¦ . ╎add 1, 1 . -1170 ¦ . ╎2 . -1171 ¦ . ╎─────────────────────────────────────────────────. -1172 ¦ . ╎ . -1173 ] -1174 # hit 'page-down' and 'page-up' a couple of times. sandbox index should be stable -1175 assume-console [ -1176 ¦ press page-down +1128 # hit 'page-up' again +1129 assume-console [ +1130 ¦ press page-up +1131 ] +1132 run [ +1133 ¦ event-loop screen, console, env, resources +1134 ¦ cursor:char <- copy 9251/␣ +1135 ¦ print screen, cursor +1136 ] +1137 # no change +1138 screen-should-contain [ +1139 ¦ . run (F4) . +1140 ¦ . ╎␣ . +1141 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1142 ¦ . ╎0 edit copy to recipe delete . +1143 ¦ . ╎add 1, 1 . +1144 ¦ . ╎2 . +1145 ¦ . ╎─────────────────────────────────────────────────. +1146 ¦ . ╎1 edit copy to recipe delete . +1147 ¦ . ╎add 2, 2 . +1148 ¦ . ╎4 . +1149 ] +1150 ] +1151 +1152 scenario scrolling-manages-sandbox-index-correctly [ +1153 local-scope +1154 trace-until 100/app # trace too long +1155 assume-screen 100/width, 10/height +1156 # initialize environment +1157 assume-resources [ +1158 ] +1159 env:&:environment <- new-programming-environment resources, screen, [] +1160 render-all screen, env, render +1161 # create a sandbox +1162 assume-console [ +1163 ¦ press ctrl-n +1164 ¦ type [add 1, 1] +1165 ¦ press F4 +1166 ] +1167 event-loop screen, console, env, resources +1168 screen-should-contain [ +1169 ¦ . run (F4) . +1170 ¦ . ╎ . +1171 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1172 ¦ . ╎0 edit copy to recipe delete . +1173 ¦ . ╎add 1, 1 . +1174 ¦ . ╎2 . +1175 ¦ . ╎─────────────────────────────────────────────────. +1176 ¦ . ╎ . 1177 ] -1178 run [ -1179 ¦ event-loop screen, console, env, resources -1180 ] -1181 # sandbox editor hidden; first sandbox displayed -1182 # cursor moves to first sandbox -1183 screen-should-contain [ -1184 ¦ . run (F4) . -1185 ¦ . ╎─────────────────────────────────────────────────. -1186 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . -1187 ¦ . ╎add 1, 1 . -1188 ¦ . ╎2 . +1178 # hit 'page-down' and 'page-up' a couple of times. sandbox index should be stable +1179 assume-console [ +1180 ¦ press page-down +1181 ] +1182 run [ +1183 ¦ event-loop screen, console, env, resources +1184 ] +1185 # sandbox editor hidden; first sandbox displayed +1186 # cursor moves to first sandbox +1187 screen-should-contain [ +1188 ¦ . run (F4) . 1189 ¦ . ╎─────────────────────────────────────────────────. -1190 ¦ . ╎ . -1191 ] -1192 # hit 'page-up' again -1193 assume-console [ -1194 ¦ press page-up +1190 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . +1191 ¦ . ╎add 1, 1 . +1192 ¦ . ╎2 . +1193 ¦ . ╎─────────────────────────────────────────────────. +1194 ¦ . ╎ . 1195 ] -1196 run [ -1197 ¦ event-loop screen, console, env, resources -1198 ] -1199 # back to displaying both sandboxes as well as editor -1200 screen-should-contain [ -1201 ¦ . run (F4) . -1202 ¦ . ╎ . -1203 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -1204 ¦ . ╎0 edit copy delete . -1205 ¦ . ╎add 1, 1 . -1206 ¦ . ╎2 . -1207 ¦ . ╎─────────────────────────────────────────────────. -1208 ¦ . ╎ . -1209 ] -1210 # hit 'page-down' -1211 assume-console [ -1212 ¦ press page-down +1196 # hit 'page-up' again +1197 assume-console [ +1198 ¦ press page-up +1199 ] +1200 run [ +1201 ¦ event-loop screen, console, env, resources +1202 ] +1203 # back to displaying both sandboxes as well as editor +1204 screen-should-contain [ +1205 ¦ . run (F4) . +1206 ¦ . ╎ . +1207 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +1208 ¦ . ╎0 edit copy to recipe delete . +1209 ¦ . ╎add 1, 1 . +1210 ¦ . ╎2 . +1211 ¦ . ╎─────────────────────────────────────────────────. +1212 ¦ . ╎ . 1213 ] -1214 run [ -1215 ¦ event-loop screen, console, env, resources -1216 ] -1217 # sandbox editor hidden; first sandbox displayed -1218 # cursor moves to first sandbox -1219 screen-should-contain [ -1220 ¦ . run (F4) . -1221 ¦ . ╎─────────────────────────────────────────────────. -1222 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . -1223 ¦ . ╎add 1, 1 . -1224 ¦ . ╎2 . +1214 # hit 'page-down' +1215 assume-console [ +1216 ¦ press page-down +1217 ] +1218 run [ +1219 ¦ event-loop screen, console, env, resources +1220 ] +1221 # sandbox editor hidden; first sandbox displayed +1222 # cursor moves to first sandbox +1223 screen-should-contain [ +1224 ¦ . run (F4) . 1225 ¦ . ╎─────────────────────────────────────────────────. -1226 ¦ . ╎ . -1227 ] -1228 ] +1226 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . +1227 ¦ . ╎add 1, 1 . +1228 ¦ . ╎2 . +1229 ¦ . ╎─────────────────────────────────────────────────. +1230 ¦ . ╎ . +1231 ] +1232 ] diff --git a/html/edit/006-sandbox-copy.mu.html b/html/edit/006-sandbox-copy.mu.html index 1fba95c1..e12c4729 100644 --- a/html/edit/006-sandbox-copy.mu.html +++ b/html/edit/006-sandbox-copy.mu.html @@ -80,7 +80,7 @@ if ('onhashchange' in window) { 18 ¦ . run (F4) . 19 ¦ . ╎ . 20 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 21 ¦ . ╎0 edit copy delete . + 21 ¦ . ╎0 edit copy to recipe delete . 22 ¦ . ╎add 1, 1 . 23 ¦ . ╎2 . 24 ¦ . ╎─────────────────────────────────────────────────. @@ -98,7 +98,7 @@ if ('onhashchange' in window) { 36 ¦ . run (F4) . 37 ¦ . ╎add 1, 1 . 38 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 39 ¦ . ╎0 edit copy delete . + 39 ¦ . ╎0 edit copy to recipe delete . 40 ¦ . ╎add 1, 1 . 41 ¦ . ╎2 . 42 ¦ . ╎─────────────────────────────────────────────────. @@ -115,7 +115,7 @@ if ('onhashchange' in window) { 53 ¦ . run (F4) . 54 ¦ . ╎0add 1, 1 . 55 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 56 ¦ . ╎0 edit copy delete . + 56 ¦ . ╎0 edit copy to recipe delete . 57 ¦ . ╎add 1, 1 . 58 ¦ . ╎2 . 59 ¦ . ╎─────────────────────────────────────────────────. @@ -140,7 +140,7 @@ if ('onhashchange' in window) { 78 ¦ . run (F4) . 79 ¦ . ╎ . 80 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 81 ¦ . ╎0 edit copy delete . + 81 ¦ . ╎0 edit copy to recipe delete . 82 ¦ . ╎add 1, 1 . 83 ¦ . ╎2 . 84 ¦ . ╎─────────────────────────────────────────────────. @@ -148,7 +148,7 @@ if ('onhashchange' in window) { 86 ] 87 # click at right edge of 'copy' button (just before 'delete') 88 assume-console [ - 89 ¦ left-click 3, 84 + 89 ¦ left-click 3, 76 90 ] 91 run [ 92 ¦ event-loop screen, console, env, resources @@ -158,7 +158,7 @@ if ('onhashchange' in window) { 96 ¦ . run (F4) . 97 ¦ . ╎add 1, 1 . 98 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 99 ¦ . ╎0 edit copy delete . + 99 ¦ . ╎0 edit copy to recipe delete . 100 ¦ . ╎add 1, 1 . 101 ¦ . ╎2 . 102 ¦ . ╎─────────────────────────────────────────────────. @@ -175,7 +175,7 @@ if ('onhashchange' in window) { 113 ¦ . run (F4) . 114 ¦ . ╎0add 1, 1 . 115 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -116 ¦ . ╎0 edit copy delete . +116 ¦ . ╎0 edit copy to recipe delete . 117 ¦ . ╎add 1, 1 . 118 ¦ . ╎2 . 119 ¦ . ╎─────────────────────────────────────────────────. @@ -190,7 +190,7 @@ if ('onhashchange' in window) { 128 ¦ break-unless copy? 129 ¦ copy?, env <- try-copy-sandbox click-row, env 130 ¦ break-unless copy? -131 ¦ screen <- render-sandbox-side screen, env, render +131 ¦ screen <- render-sandbox-side screen, env, render 132 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env 133 ¦ loop +next-event 134 } @@ -208,7 +208,7 @@ if ('onhashchange' in window) { 146 assert first-sandbox, [!!] 147 sandbox-left-margin:num <- get *first-sandbox, left:offset 148 sandbox-right-margin:num <- get *first-sandbox, right:offset -149 _, _, copy-button-left:num, copy-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin +149 _, _, copy-button-left:num, copy-button-right:num <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin 150 copy-button-vertical-area?:bool <- within-range? click-column, copy-button-left, copy-button-right 151 return-unless copy-button-vertical-area?, 0/false 152 # finally, is sandbox editor empty? @@ -293,7 +293,7 @@ if ('onhashchange' in window) { 231 ¦ . run (F4) . 232 ¦ . ╎ . 233 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -234 ¦ . ╎0 edit copy delete . +234 ¦ . ╎0 edit copy to recipe delete . 235 ¦ . ╎add 1, 1 . 236 ¦ . ╎2 . 237 ¦ . ╎─────────────────────────────────────────────────. @@ -313,7 +313,7 @@ if ('onhashchange' in window) { 251 ¦ . run (F4) . 252 ¦ . ╎0 . 253 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -254 ¦ . ╎0 edit copy delete . +254 ¦ . ╎0 edit copy to recipe delete . 255 ¦ . ╎add 1, 1 . 256 ¦ . ╎2 . 257 ¦ . ╎─────────────────────────────────────────────────. @@ -330,13 +330,127 @@ if ('onhashchange' in window) { 268 ¦ . run (F4) . 269 ¦ . ╎01 . 270 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -271 ¦ . ╎0 edit copy delete . +271 ¦ . ╎0 edit copy to recipe delete . 272 ¦ . ╎add 1, 1 . 273 ¦ . ╎2 . 274 ¦ . ╎─────────────────────────────────────────────────. 275 ¦ . ╎ . 276 ] 277 ] +278 +279 ## the 'to recipe' button makes it easy to create a function out of a sandbox +280 +281 scenario copy-a-sandbox-to-recipe-side [ +282 local-scope +283 trace-until 100/app # trace too long +284 assume-screen 100/width, 10/height +285 # empty recipes +286 assume-resources [ +287 ] +288 env:&:environment <- new-programming-environment resources, screen, [add 1, 1] # contents of sandbox editor +289 # run it +290 assume-console [ +291 ¦ press F4 +292 ] +293 event-loop screen, console, env, resources +294 screen-should-contain [ +295 ¦ . run (F4) . +296 ¦ . ╎ . +297 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. +298 ¦ . ╎0 edit copy to recipe delete . +299 ¦ . ╎add 1, 1 . +300 ¦ . ╎2 . +301 ¦ . ╎─────────────────────────────────────────────────. +302 ¦ . ╎ . +303 ] +304 # click at left edge of 'copy' button +305 assume-console [ +306 ¦ left-click 3, 78 +307 ] +308 run [ +309 ¦ event-loop screen, console, env, resources +310 ] +311 # it copies into recipe side +312 screen-should-contain [ +313 ¦ . run (F4) . +314 ¦ .add 1, 1 ╎ . +315 ¦ . ╎─────────────────────────────────────────────────. +316 ¦ . ╎0 edit copy to recipe delete . +317 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎add 1, 1 . +318 ¦ . ╎2 . +319 ¦ . ╎─────────────────────────────────────────────────. +320 ¦ . ╎ . +321 ] +322 # cursor should be at the top left of the recipe side +323 assume-console [ +324 ¦ type [0] +325 ] +326 run [ +327 ¦ event-loop screen, console, env, resources +328 ] +329 screen-should-contain [ +330 ¦ . run (F4) . +331 ¦ .0add 1, 1 ╎ . +332 ¦ . ╎─────────────────────────────────────────────────. +333 ¦ . ╎0 edit copy to recipe delete . +334 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎add 1, 1 . +335 ¦ . ╎2 . +336 ¦ . ╎─────────────────────────────────────────────────. +337 ¦ . ╎ . +338 ] +339 ] +340 +341 after <global-touch> [ +342 # support 'copy to recipe' button +343 { +344 ¦ copy?:bool <- should-copy-to-recipe? click-row, click-column, env +345 ¦ break-unless copy? +346 ¦ modified?:bool <- prepend-sandbox-into-recipe-side click-row, env +347 ¦ break-unless modified? +348 ¦ put *env, sandbox-in-focus?:offset, 0/false +349 ¦ screen <- render-recipes screen, env, render +350 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env +351 ¦ loop +next-event +352 } +353 ] +354 +355 # some preconditions for attempting to copy a sandbox into the recipe side +356 def should-copy-to-recipe? click-row:num, click-column:num, env:&:environment -> result:bool [ +357 local-scope +358 load-ingredients +359 # are we below the sandbox editor? +360 click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env +361 return-unless click-sandbox-area?, 0/false +362 # narrower, is the click in the columns spanning the 'copy' button? +363 first-sandbox:&:editor <- get *env, current-sandbox:offset +364 assert first-sandbox, [!!] +365 sandbox-left-margin:num <- get *first-sandbox, left:offset +366 sandbox-right-margin:num <- get *first-sandbox, right:offset +367 _, _, _, _, recipe-button-left:num, recipe-button-right:num <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin +368 result <- within-range? click-column, recipe-button-left, recipe-button-right +369 ] +370 +371 def prepend-sandbox-into-recipe-side click-row:num, env:&:environment -> clicked-on-copy-to-recipe-button?:bool, env:&:environment [ +372 local-scope +373 load-ingredients +374 sandbox:&:sandbox <- find-sandbox env, click-row +375 return-unless sandbox, 0/false +376 recipe-editor:&:editor <- get *env, recipes:offset +377 recipe-data:&:duplex-list:char <- get *recipe-editor, data:offset +378 # make the newly inserted code easy to delineate +379 newline:char <- copy 10 +380 insert newline, recipe-data +381 insert newline, recipe-data +382 # insert code from the selected sandbox +383 sandbox-data:text <- get *sandbox, data:offset +384 insert recipe-data, sandbox-data +385 # reset cursor +386 put *recipe-editor, top-of-screen:offset, recipe-data +387 put *recipe-editor, before-cursor:offset, recipe-data +388 put *recipe-editor, cursor-row:offset, 1 +389 put *recipe-editor, cursor-column:offset, 0 +390 return 1/true +391 ] diff --git a/html/edit/007-sandbox-delete.mu.html b/html/edit/007-sandbox-delete.mu.html index ef975375..8fce15fb 100644 --- a/html/edit/007-sandbox-delete.mu.html +++ b/html/edit/007-sandbox-delete.mu.html @@ -71,7 +71,7 @@ if ('onhashchange' in window) { 9 env:&:environment <- new-programming-environment resources, screen, [] 10 # run a few commands 11 assume-console [ - 12 ¦ left-click 1, 80 + 12 ¦ left-click 1, 75 13 ¦ type [divide-with-remainder 11, 3] 14 ¦ press F4 15 ¦ type [add 2, 2] @@ -82,11 +82,11 @@ if ('onhashchange' in window) { 20 ¦ . run (F4) . 21 ¦ . ╎ . 22 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 23 ¦ . ╎0 edit copy delete . + 23 ¦ . ╎0 edit copy to recipe delete . 24 ¦ . ╎add 2, 2 . 25 ¦ . ╎4 . 26 ¦ . ╎─────────────────────────────────────────────────. - 27 ¦ . ╎1 edit copy delete . + 27 ¦ . ╎1 edit copy to recipe delete . 28 ¦ . ╎divide-with-remainder 11, 3 . 29 ¦ . ╎3 . 30 ¦ . ╎2 . @@ -95,7 +95,7 @@ if ('onhashchange' in window) { 33 ] 34 # delete second sandbox by clicking on left edge of 'delete' button 35 assume-console [ - 36 ¦ left-click 7, 85 + 36 ¦ left-click 7, 90 37 ] 38 run [ 39 ¦ event-loop screen, console, env, resources @@ -104,7 +104,7 @@ if ('onhashchange' in window) { 42 ¦ . run (F4) . 43 ¦ . ╎ . 44 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 45 ¦ . ╎0 edit copy delete . + 45 ¦ . ╎0 edit copy to recipe delete . 46 ¦ . ╎add 2, 2 . 47 ¦ . ╎4 . 48 ¦ . ╎─────────────────────────────────────────────────. @@ -134,7 +134,7 @@ if ('onhashchange' in window) { 72 ¦ break-unless delete? 73 ¦ delete?, env <- try-delete-sandbox click-row, env 74 ¦ break-unless delete? - 75 ¦ screen <- render-sandbox-side screen, env, render + 75 ¦ screen <- render-sandbox-side screen, env, render 76 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env 77 ¦ loop +next-event 78 } @@ -152,7 +152,7 @@ if ('onhashchange' in window) { 90 assert first-sandbox, [!!] 91 sandbox-left-margin:num <- get *first-sandbox, left:offset 92 sandbox-right-margin:num <- get *first-sandbox, right:offset - 93 _, _, _, _, delete-button-left:num <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin + 93 _, _, _, _, _, _, delete-button-left:num <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin 94 result <- within-range? click-column, delete-button-left, sandbox-right-margin 95 ] 96 @@ -216,7 +216,7 @@ if ('onhashchange' in window) { 154 assume-resources [ 155 ] 156 env:&:environment <- new-programming-environment resources, screen, [] -157 render-all screen, env, render +157 render-all screen, env, render 158 # create 2 sandboxes and scroll to second 159 assume-console [ 160 ¦ press ctrl-n @@ -230,11 +230,11 @@ if ('onhashchange' in window) { 168 screen-should-contain [ 169 ¦ . run (F4) . 170 ¦ . ╎─────────────────────────────────────────────────. -171 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +171 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . 172 ¦ . ╎add 1, 1 . 173 ¦ . ╎2 . 174 ¦ . ╎─────────────────────────────────────────────────. -175 ¦ . ╎1 edit copy delete . +175 ¦ . ╎1 edit copy to recipe delete . 176 ] 177 # delete the second sandbox 178 assume-console [ @@ -247,7 +247,7 @@ if ('onhashchange' in window) { 185 screen-should-contain [ 186 ¦ . run (F4) . 187 ¦ . ╎─────────────────────────────────────────────────. -188 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +188 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . 189 ¦ . ╎add 1, 1 . 190 ¦ . ╎2 . 191 ¦ . ╎─────────────────────────────────────────────────. @@ -263,7 +263,7 @@ if ('onhashchange' in window) { 201 assume-resources [ 202 ] 203 env:&:environment <- new-programming-environment resources, screen, [] -204 render-all screen, env, render +204 render-all screen, env, render 205 # create 2 sandboxes and scroll to second 206 assume-console [ 207 ¦ press ctrl-n @@ -277,11 +277,11 @@ if ('onhashchange' in window) { 215 screen-should-contain [ 216 ¦ . run (F4) . 217 ¦ . ╎─────────────────────────────────────────────────. -218 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +218 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . 219 ¦ . ╎add 1, 1 . 220 ¦ . ╎2 . 221 ¦ . ╎─────────────────────────────────────────────────. -222 ¦ . ╎1 edit copy delete . +222 ¦ . ╎1 edit copy to recipe delete . 223 ] 224 # delete the second sandbox 225 assume-console [ @@ -294,7 +294,7 @@ if ('onhashchange' in window) { 232 screen-should-contain [ 233 ¦ . run (F4) . 234 ¦ . ╎─────────────────────────────────────────────────. -235 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +235 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . 236 ¦ . ╎add 2, 2 . 237 ¦ . ╎4 . 238 ¦ . ╎─────────────────────────────────────────────────. @@ -310,7 +310,7 @@ if ('onhashchange' in window) { 248 assume-resources [ 249 ] 250 env:&:environment <- new-programming-environment resources, screen, [] -251 render-all screen, env, render +251 render-all screen, env, render 252 # create 2 sandboxes and scroll to second 253 assume-console [ 254 ¦ press ctrl-n @@ -325,7 +325,7 @@ if ('onhashchange' in window) { 263 screen-should-contain [ 264 ¦ . run (F4) . 265 ¦ . ╎─────────────────────────────────────────────────. -266 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . +266 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy to recipe delete . 267 ¦ . ╎add 2, 2 . 268 ¦ . ╎4 . 269 ¦ . ╎─────────────────────────────────────────────────. @@ -343,7 +343,7 @@ if ('onhashchange' in window) { 281 ¦ . run (F4) . 282 ¦ . ╎ . 283 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -284 ¦ . ╎0 edit copy delete . +284 ¦ . ╎0 edit copy to recipe delete . 285 ¦ . ╎add 1, 1 . 286 ¦ . ╎2 . 287 ¦ . ╎─────────────────────────────────────────────────. @@ -359,7 +359,7 @@ if ('onhashchange' in window) { 297 assume-resources [ 298 ] 299 env:&:environment <- new-programming-environment resources, screen, [] -300 render-all screen, env, render +300 render-all screen, env, render 301 # create 2 sandboxes 302 assume-console [ 303 ¦ press ctrl-n @@ -373,11 +373,11 @@ if ('onhashchange' in window) { 311 ¦ . run (F4) . 312 ¦ . ╎ . 313 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -314 ¦ . ╎0 edit copy delete . +314 ¦ . ╎0 edit copy to recipe delete . 315 ¦ . ╎add 1, 1 . 316 ¦ . ╎2 . 317 ¦ . ╎─────────────────────────────────────────────────. -318 ¦ . ╎1 edit copy delete . +318 ¦ . ╎1 edit copy to recipe delete . 319 ¦ . ╎add 2, 2 . 320 ¦ . ╎4 . 321 ] @@ -394,7 +394,7 @@ if ('onhashchange' in window) { 332 screen-should-contain [ 333 ¦ . run (F4) . 334 ¦ . ╎─────────────────────────────────────────────────. -335 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy delete . +335 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎0 edit copy to recipe delete . 336 ¦ . ╎add 2, 2 . 337 ¦ . ╎4 . 338 ¦ . ╎─────────────────────────────────────────────────. diff --git a/html/edit/008-sandbox-edit.mu.html b/html/edit/008-sandbox-edit.mu.html index 99fe4400..f55c5f4f 100644 --- a/html/edit/008-sandbox-edit.mu.html +++ b/html/edit/008-sandbox-edit.mu.html @@ -79,7 +79,7 @@ if ('onhashchange' in window) { 17 ¦ . run (F4) . 18 ¦ . ╎ . 19 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 20 ¦ . ╎0 edit copy delete . + 20 ¦ . ╎0 edit copy to recipe delete . 21 ¦ . ╎add 2, 2 . 22 ¦ . ╎4 . 23 ¦ . ╎─────────────────────────────────────────────────. @@ -131,7 +131,7 @@ if ('onhashchange' in window) { 69 ¦ . run (F4) . 70 ¦ . ╎ . 71 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. - 72 ¦ . ╎0 edit copy delete . + 72 ¦ . ╎0 edit copy to recipe delete . 73 ¦ . ╎add 2, 2 . 74 ¦ . ╎4 . 75 ¦ . ╎─────────────────────────────────────────────────. @@ -139,7 +139,7 @@ if ('onhashchange' in window) { 77 ] 78 # click at right edge of 'edit' button (just before 'copy') 79 assume-console [ - 80 ¦ left-click 3, 68 + 80 ¦ left-click 3, 65 81 ] 82 run [ 83 ¦ event-loop screen, console, env, resources @@ -173,7 +173,7 @@ if ('onhashchange' in window) { 111 ¦ break-unless edit? 112 ¦ edit?, env <- try-edit-sandbox click-row, env 113 ¦ break-unless edit? -114 ¦ screen <- render-sandbox-side screen, env, render +114 ¦ screen <- render-sandbox-side screen, env, render 115 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env 116 ¦ loop +next-event 117 } @@ -191,7 +191,7 @@ if ('onhashchange' in window) { 129 assert first-sandbox, [!!] 130 sandbox-left-margin:num <- get *first-sandbox, left:offset 131 sandbox-right-margin:num <- get *first-sandbox, right:offset -132 edit-button-left:num, edit-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin +132 edit-button-left:num, edit-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin 133 edit-button-vertical-area?:bool <- within-range? click-column, edit-button-left, edit-button-right 134 return-unless edit-button-vertical-area?, 0/false 135 # finally, is sandbox editor empty? @@ -235,7 +235,7 @@ if ('onhashchange' in window) { 173 ¦ . run (F4) . 174 ¦ . ╎ . 175 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -176 ¦ . ╎0 edit copy delete . +176 ¦ . ╎0 edit copy to recipe delete . 177 ¦ . ╎print screen, 4 . 178 ¦ . ╎screen: . 179 ¦ . ╎ .4 . . @@ -270,7 +270,7 @@ if ('onhashchange' in window) { 208 assume-resources [ 209 ] 210 env:&:environment <- new-programming-environment resources, screen, [] -211 render-all screen, env, render +211 render-all screen, env, render 212 # create 2 sandboxes and scroll to second 213 assume-console [ 214 ¦ press ctrl-n @@ -285,7 +285,7 @@ if ('onhashchange' in window) { 223 screen-should-contain [ 224 ¦ . run (F4) . 225 ¦ . ╎─────────────────────────────────────────────────. -226 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . +226 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy to recipe delete . 227 ¦ . ╎add 2, 2 . 228 ¦ . ╎4 . 229 ¦ . ╎─────────────────────────────────────────────────. @@ -303,7 +303,7 @@ if ('onhashchange' in window) { 241 ¦ . run (F4) . 242 ¦ . ╎add 2, 2 . 243 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -244 ¦ . ╎0 edit copy delete . +244 ¦ . ╎0 edit copy to recipe delete . 245 ¦ . ╎add 1, 1 . 246 ¦ . ╎2 . 247 ¦ . ╎─────────────────────────────────────────────────. @@ -319,7 +319,7 @@ if ('onhashchange' in window) { 257 assume-resources [ 258 ] 259 env:&:environment <- new-programming-environment resources, screen, [] -260 render-all screen, env, render +260 render-all screen, env, render 261 # create 2 sandboxes 262 assume-console [ 263 ¦ press ctrl-n @@ -333,11 +333,11 @@ if ('onhashchange' in window) { 271 ¦ . run (F4) . 272 ¦ . ╎ . 273 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -274 ¦ . ╎0 edit copy delete . +274 ¦ . ╎0 edit copy to recipe delete . 275 ¦ . ╎add 1, 1 . 276 ¦ . ╎2 . 277 ¦ . ╎─────────────────────────────────────────────────. -278 ¦ . ╎1 edit copy delete . +278 ¦ . ╎1 edit copy to recipe delete . 279 ¦ . ╎add 2, 2 . 280 ¦ . ╎4 . 281 ] @@ -354,11 +354,11 @@ if ('onhashchange' in window) { 292 ¦ . run (F4) . 293 ¦ . ╎ . 294 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -295 ¦ . ╎0 edit copy delete . +295 ¦ . ╎0 edit copy to recipe delete . 296 ¦ . ╎add 1, 1 . 297 ¦ . ╎2 . 298 ¦ . ╎─────────────────────────────────────────────────. -299 ¦ . ╎1 edit copy delete . +299 ¦ . ╎1 edit copy to recipe delete . 300 ¦ . ╎add 2, 2 . 301 ¦ . ╎4 . 302 ] @@ -375,7 +375,7 @@ if ('onhashchange' in window) { 313 screen-should-contain [ 314 ¦ . run (F4) . 315 ¦ . ╎─────────────────────────────────────────────────. -316 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy delete . +316 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎1 edit copy to recipe delete . 317 ¦ . ╎add 2, 2 . 318 ¦ . ╎4 . 319 ¦ . ╎─────────────────────────────────────────────────. diff --git a/html/edit/009-sandbox-test.mu.html b/html/edit/009-sandbox-test.mu.html index 76c915d4..ead5ff9d 100644 --- a/html/edit/009-sandbox-test.mu.html +++ b/html/edit/009-sandbox-test.mu.html @@ -85,7 +85,7 @@ if ('onhashchange' in window) { 22 ¦ . run (F4) . 23 ¦ .recipe foo [ ╎ . 24 ¦ . reply 4 ╎─────────────────────────────────────────────────. - 25 ¦ .] ╎0 edit copy delete . + 25 ¦ .] ╎0 edit copy to recipe delete . 26 ¦ . ╎foo . 27 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎4 . 28 ¦ . ╎─────────────────────────────────────────────────. @@ -118,7 +118,7 @@ if ('onhashchange' in window) { 55 ¦ . run (F4) . 56 ¦ .␣ecipe foo [ ╎ . 57 ¦ . reply 4 ╎─────────────────────────────────────────────────. - 58 ¦ .] ╎0 edit copy delete . + 58 ¦ .] ╎0 edit copy to recipe delete . 59 ¦ . ╎foo . 60 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎4 . 61 ¦ . ╎─────────────────────────────────────────────────. @@ -164,7 +164,7 @@ if ('onhashchange' in window) { 101 } 102 ] 103 -104 before <end-restore-sandbox> [ +104 before <end-restore-sandbox> [ 105 { 106 ¦ filename <- append filename, [.out] 107 ¦ contents <- slurp resources, filename @@ -193,7 +193,7 @@ if ('onhashchange' in window) { 130 ¦ # toggle its expected-response, and save session 131 ¦ sandbox <- toggle-expected-response sandbox 132 ¦ save-sandboxes env, resources -133 ¦ screen <- render-sandbox-side screen, env, render +133 ¦ screen <- render-sandbox-side screen, env, render 134 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env 135 ¦ loop +next-event 136 } @@ -252,11 +252,11 @@ if ('onhashchange' in window) { 189 ¦ response-is-expected?:bool <- equal expected-response, sandbox-response 190 ¦ { 191 ¦ ¦ break-if response-is-expected?:bool -192 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 1/red, row +192 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 1/red, row 193 ¦ } 194 ¦ { 195 ¦ ¦ break-unless response-is-expected?:bool -196 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 2/green, row +196 ¦ ¦ row, screen <- render-text screen, sandbox-response, left, right, 2/green, row 197 ¦ } 198 ¦ jump +render-sandbox-end 199 } diff --git a/html/edit/010-sandbox-trace.mu.html b/html/edit/010-sandbox-trace.mu.html index 5bb31998..5fbc5bb2 100644 --- a/html/edit/010-sandbox-trace.mu.html +++ b/html/edit/010-sandbox-trace.mu.html @@ -85,7 +85,7 @@ if ('onhashchange' in window) { 22 ¦ . run (F4) . 23 ¦ .recipe foo [ ╎ . 24 ¦ . stash [abc] ╎─────────────────────────────────────────────────. - 25 ¦ .] ╎0 edit copy delete . + 25 ¦ .] ╎0 edit copy to recipe delete . 26 ¦ . ╎foo . 27 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. 28 ¦ . ╎ . @@ -104,7 +104,7 @@ if ('onhashchange' in window) { 41 ¦ . run (F4) . 42 ¦ .␣ecipe foo [ ╎ . 43 ¦ . stash [abc] ╎─────────────────────────────────────────────────. - 44 ¦ .] ╎0 edit copy delete . + 44 ¦ .] ╎0 edit copy to recipe delete . 45 ¦ . ╎foo . 46 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎abc . 47 ] @@ -129,7 +129,7 @@ if ('onhashchange' in window) { 66 ¦ . run (F4) . 67 ¦ .␣ecipe foo [ ╎ . 68 ¦ . stash [abc] ╎─────────────────────────────────────────────────. - 69 ¦ .] ╎0 edit copy delete . + 69 ¦ .] ╎0 edit copy to recipe delete . 70 ¦ . ╎foo . 71 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. 72 ¦ . ╎ . @@ -159,7 +159,7 @@ if ('onhashchange' in window) { 96 ¦ . run (F4) . 97 ¦ .recipe foo [ ╎ . 98 ¦ . stash [abc] ╎─────────────────────────────────────────────────. - 99 ¦ . reply 4 ╎0 edit copy delete . + 99 ¦ . reply 4 ╎0 edit copy to recipe delete . 100 ¦ .] ╎foo . 101 ¦ . ╎4 . 102 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. @@ -177,7 +177,7 @@ if ('onhashchange' in window) { 114 ¦ . run (F4) . 115 ¦ .recipe foo [ ╎ . 116 ¦ . stash [abc] ╎─────────────────────────────────────────────────. -117 ¦ . reply 4 ╎0 edit copy delete . +117 ¦ . reply 4 ╎0 edit copy to recipe delete . 118 ¦ .] ╎foo . 119 ¦ . ╎abc . 120 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎8 instructions run . @@ -204,7 +204,7 @@ if ('onhashchange' in window) { 141 ¦ . run (F4) . 142 ¦ . ╎ . 143 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -144 ¦ . ╎0 edit copy delete . +144 ¦ . ╎0 edit copy to recipe delete . 145 ¦ . ╎stash 123456789 . 146 ¦ . ╎123456789 . 147 ] @@ -220,7 +220,7 @@ if ('onhashchange' in window) { 157 ¦ . run (F4) . 158 ¦ . ╎ . 159 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -160 ¦ . ╎0 edit copy delete . +160 ¦ . ╎0 edit copy to recipe delete . 161 ¦ . ╎stash 123456789 . 162 ¦ . ╎123456789 . 163 ] @@ -263,7 +263,7 @@ if ('onhashchange' in window) { 200 ¦ x:bool <- get *sandbox, display-trace?:offset 201 ¦ x <- not x 202 ¦ *sandbox <- put *sandbox, display-trace?:offset, x -203 ¦ screen <- render-sandbox-side screen, env, render +203 ¦ screen <- render-sandbox-side screen, env, render 204 ¦ screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env 205 ¦ loop +next-event 206 } @@ -307,7 +307,7 @@ if ('onhashchange' in window) { 244 ¦ break-unless display-trace? 245 ¦ sandbox-trace:text <- get *sandbox, trace:offset 246 ¦ break-unless sandbox-trace # nothing to print; move on -247 ¦ row, screen <- render-text screen, sandbox-trace, left, right, 245/grey, row +247 ¦ row, screen <- render-text screen, sandbox-trace, left, right, 245/grey, row 248 } 249 <render-sandbox-trace-done> 250 ] diff --git a/html/edit/011-errors.mu.html b/html/edit/011-errors.mu.html index 18baf52f..9faada08 100644 --- a/html/edit/011-errors.mu.html +++ b/html/edit/011-errors.mu.html @@ -72,7 +72,7 @@ if ('onhashchange' in window) { 9 local-scope 10 load-ingredients 11 recipes:&:editor <- get *env, recipes:offset - 12 in:text <- editor-contents recipes + 12 in:text <- editor-contents recipes 13 resources <- dump resources, [lesson/recipes.mu], in 14 recipe-errors:text <- reload in 15 *env <- put *env, recipe-errors:offset, recipe-errors @@ -99,7 +99,7 @@ if ('onhashchange' in window) { 36 { 37 ¦ recipe-errors:text <- get *env, recipe-errors:offset 38 ¦ break-unless recipe-errors - 39 ¦ row, screen <- render-text screen, recipe-errors, left, right, 1/red, row + 39 ¦ row, screen <- render-text screen, recipe-errors, left, right, 1/red, row 40 } 41 ] 42 @@ -171,7 +171,7 @@ if ('onhashchange' in window) { 108 ¦ sandbox-errors:text <- get *sandbox, errors:offset 109 ¦ break-unless sandbox-errors 110 ¦ *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0 # no response -111 ¦ row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row +111 ¦ row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row 112 ¦ # don't try to print anything more for this sandbox 113 ¦ jump +render-sandbox-end 114 } @@ -189,7 +189,7 @@ if ('onhashchange' in window) { 126 ¦ ] 127 ] 128 env:&:environment <- new-programming-environment resources, screen, [foo] -129 render-all screen, env, render +129 render-all screen, env, render 130 screen-should-contain [ 131 ¦ . run (F4) . 132 ¦ .recipe foo [ ╎foo . @@ -308,7 +308,7 @@ if ('onhashchange' in window) { 245 ¦ . run (F4) . 246 ¦ . ╎ . 247 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -248 ¦ . ╎0 edit copy delete . +248 ¦ . ╎0 edit copy to recipe delete . 249 ¦ . ╎add 2, 2 . 250 ¦ . ╎4 . 251 ¦ . ╎─────────────────────────────────────────────────. @@ -340,7 +340,7 @@ if ('onhashchange' in window) { 277 ¦ . errors found (0) run (F4) . 278 ¦ .recipe foo x:_elem -> z:_elem [ ╎ . 279 ¦ . local-scope ╎─────────────────────────────────────────────────. -280 ¦ . load-ingredients ╎0 edit copy delete . +280 ¦ . load-ingredients ╎0 edit copy to recipe delete . 281 ¦ . y:&:num <- copy 0 ╎foo 2 . 282 ¦ . z <- add x, y ╎foo_2: 'add' requires number ingredients, but go↩. 283 ¦ .] ╎t 'y' . @@ -360,7 +360,7 @@ if ('onhashchange' in window) { 297 ¦ . errors found (0) run (F4) . 298 ¦ .recipe foo x:_elem -> z:_elem [ ╎ . 299 ¦ . local-scope ╎─────────────────────────────────────────────────. -300 ¦ . load-ingredients ╎0 edit copy delete . +300 ¦ . load-ingredients ╎0 edit copy to recipe delete . 301 ¦ . y:&:num <- copy 0 ╎foo 2 . 302 ¦ . z <- add x, y ╎foo_3: 'add' requires number ingredients, but go↩. 303 ¦ .] ╎t 'y' . @@ -637,7 +637,7 @@ if ('onhashchange' in window) { 574 ¦ . errors found (0) run (F4) . 575 ¦ . ╎ . 576 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -577 ¦ . ╎0 edit copy delete . +577 ¦ . ╎0 edit copy to recipe delete . 578 ¦ . ╎get 1234:num, foo:offset . 579 ¦ . ╎unknown element 'foo' in container 'number' . 580 ¦ . ╎first ingredient of 'get' should be a container,↩. @@ -701,7 +701,7 @@ if ('onhashchange' in window) { 638 ¦ . errors found (0) run (F4) . 639 ¦ . ╎ . 640 ¦ .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────. -641 ¦ . ╎0 edit copy delete . +641 ¦ . ╎0 edit copy to recipe delete . 642 ¦ . ╎get 1234:num, foo:offset . 643 ¦ . ╎unknown element 'foo' in container 'number' . 644 ¦ . ╎first ingredient of 'get' should be a container,↩. @@ -737,7 +737,7 @@ if ('onhashchange' in window) { 674 ¦ . errors found (0) run (F4) . 675 ¦ .recipe foo [ ╎ . 676 ¦ . { ╎─────────────────────────────────────────────────. -677 ¦ . loop ╎0 edit copy delete . +677 ¦ . loop ╎0 edit copy to recipe delete . 678 ¦ . } ╎foo . 679 ¦ .] ╎took too long! . 680 ¦ . ╎─────────────────────────────────────────────────. @@ -774,7 +774,7 @@ if ('onhashchange' in window) { 711 ¦ . errors found (0) run (F4) . 712 ¦ .recipe foo [ ╎ . 713 ¦ . local-scope ╎─────────────────────────────────────────────────. -714 ¦ . a:num <- next-ingredient ╎0 edit copy delete . +714 ¦ . a:num <- next-ingredient ╎0 edit copy to recipe delete . 715 ¦ . b:num <- next-ingredient ╎foo 4, 0 . 716 ¦ . stash [dividing by], b ╎foo: divide by zero in '_, c:num <- divide-with-↩. 717 ¦ . _, c:num <- divide-with-remainder a, b ╎remainder a, b' . @@ -794,7 +794,7 @@ if ('onhashchange' in window) { 731 ¦ . errors found (0) run (F4) . 732 ¦ .recipe foo [ ╎ . 733 ¦ . local-scope ╎─────────────────────────────────────────────────. -734 ¦ . a:num <- next-ingredient ╎0 edit copy delete . +734 ¦ . a:num <- next-ingredient ╎0 edit copy to recipe delete . 735 ¦ . b:num <- next-ingredient ╎foo 4, 0 . 736 ¦ . stash [dividing by], b ╎dividing by 0 . 737 ¦ . _, c:num <- divide-with-remainder a, b ╎14 instructions run . diff --git a/html/edit/012-editor-undo.mu.html b/html/edit/012-editor-undo.mu.html index 2eb92fd0..3204d6b5 100644 --- a/html/edit/012-editor-undo.mu.html +++ b/html/edit/012-editor-undo.mu.html @@ -1723,7 +1723,7 @@ if ('onhashchange' in window) { 1660 ¦ anchor:&:duplex-list:char <- get deletion, delete-from:offset 1661 ¦ break-unless anchor 1662 ¦ deleted:&:duplex-list:char <- get deletion, deleted-text:offset -1663 ¦ old-cursor:&:duplex-list:char <- last deleted +1663 ¦ old-cursor:&:duplex-list:char <- last deleted 1664 ¦ splice anchor, deleted 1665 ¦ # assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen 1666 ¦ before-cursor <- copy old-cursor diff --git a/html/screen.mu.html b/html/screen.mu.html index 19534abd..7cb5b8b8 100644 --- a/html/screen.mu.html +++ b/html/screen.mu.html @@ -76,11 +76,11 @@ if ('onhashchange' in window) { 19 wait-for-event 0/console 20 cursor-down 0/screen 21 wait-for-event 0/console -22 cursor-right 0/screen +22 cursor-right 0/screen 23 wait-for-event 0/console -24 cursor-left 0/screen +24 cursor-left 0/screen 25 wait-for-event 0/console -26 cursor-up 0/screen +26 cursor-up 0/screen 27 wait-for-event 0/console 28 close-console 29 ] -- cgit 1.4.1-2-gfad0