From b2a2dc9593bd8a06977830f228ee86bb80c6a36e Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 16 Apr 2017 15:16:22 -0700 Subject: 3825 --- html/edit/001-editor.mu.html | 902 ++++++++++++++++++++++--------------------- 1 file changed, 453 insertions(+), 449 deletions(-) (limited to 'html/edit/001-editor.mu.html') diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html index 48044ef8..f9282fcc 100644 --- a/html/edit/001-editor.mu.html +++ b/html/edit/001-editor.mu.html @@ -69,468 +69,472 @@ if ('onhashchange' in window) { 6 local-scope 7 load-ingredients 8 open-console - 9 hide-screen 0/screen - 10 e:&:editor <- new-editor text, 0/left, 5/right - 11 render 0/screen, e - 12 show-screen 0/screen - 13 wait-for-event 0/console - 14 close-console - 15 ] - 16 - 17 scenario editor-renders-text-to-screen [ - 18 local-scope - 19 assume-screen 10/width, 5/height - 20 e:&:editor <- new-editor [abc], 0/left, 10/right - 21 run [ - 22 ¦ render screen, e - 23 ] - 24 screen-should-contain [ - 25 ¦ # top line of screen reserved for menu + 9 e:&:editor <- new-editor text, 0/left, 5/right + 10 render 0/screen, e + 11 wait-for-event 0/console + 12 close-console + 13 ] + 14 + 15 scenario editor-renders-text-to-screen [ + 16 local-scope + 17 assume-screen 10/width, 5/height + 18 e:&:editor <- new-editor [abc], 0/left, 10/right + 19 run [ + 20 ¦ render screen, e + 21 ] + 22 screen-should-contain [ + 23 ¦ # top line of screen reserved for menu + 24 ¦ . . + 25 ¦ .abc . 26 ¦ . . - 27 ¦ .abc . - 28 ¦ . . - 29 ] - 30 ] - 31 - 32 container editor [ - 33 # editable text: doubly linked list of characters (head contains a special sentinel) - 34 data:&:duplex-list:char - 35 top-of-screen:&:duplex-list:char - 36 bottom-of-screen:&:duplex-list:char - 37 # location before cursor inside data - 38 before-cursor:&:duplex-list:char - 39 - 40 # raw bounds of display area on screen - 41 # always displays from row 1 (leaving row 0 for a menu) and at most until bottom of screen - 42 left:num - 43 right:num - 44 bottom:num - 45 # raw screen coordinates of cursor - 46 cursor-row:num - 47 cursor-column:num - 48 ] - 49 - 50 # creates a new editor widget - 51 # right is exclusive - 52 def new-editor s:text, left:num, right:num -> result:&:editor [ - 53 local-scope - 54 load-ingredients - 55 # no clipping of bounds - 56 right <- subtract right, 1 - 57 result <- new editor:type - 58 # initialize screen-related fields - 59 *result <- put *result, left:offset, left - 60 *result <- put *result, right:offset, right - 61 # initialize cursor coordinates - 62 *result <- put *result, cursor-row:offset, 1/top - 63 *result <- put *result, cursor-column:offset, left - 64 # initialize empty contents - 65 init:&:duplex-list:char <- push 167/§, 0/tail - 66 *result <- put *result, data:offset, init - 67 *result <- put *result, top-of-screen:offset, init - 68 *result <- put *result, before-cursor:offset, init - 69 result <- insert-text result, s - 70 <editor-initialization> - 71 ] - 72 - 73 def insert-text editor:&:editor, text:text -> editor:&:editor [ - 74 local-scope - 75 load-ingredients - 76 # early exit if text is empty - 77 return-unless text - 78 len:num <- length *text - 79 return-unless len - 80 idx:num <- copy 0 - 81 # now we can start appending the rest, character by character - 82 curr:&:duplex-list:char <- get *editor, data:offset - 83 { - 84 ¦ done?:bool <- greater-or-equal idx, len - 85 ¦ break-if done? - 86 ¦ c:char <- index *text, idx - 87 ¦ insert c, curr - 88 ¦ # next iter - 89 ¦ curr <- next curr - 90 ¦ idx <- add idx, 1 - 91 ¦ loop - 92 } - 93 ] - 94 - 95 scenario editor-initializes-without-data [ - 96 local-scope - 97 assume-screen 5/width, 3/height - 98 run [ - 99 ¦ e:&:editor <- new-editor 0/data, 2/left, 5/right -100 ¦ 2:editor/raw <- copy *e -101 ] -102 memory-should-contain [ -103 ¦ # 2 (data) <- just the § sentinel -104 ¦ # 3 (top of screen) <- the § sentinel -105 ¦ 4 <- 0 # bottom-of-screen; null since text fits on screen -106 ¦ # 5 (before cursor) <- the § sentinel -107 ¦ 6 <- 2 # left -108 ¦ 7 <- 4 # right (inclusive) -109 ¦ 8 <- 0 # bottom (not set until render) -110 ¦ 9 <- 1 # cursor row -111 ¦ 10 <- 2 # cursor column -112 ] -113 screen-should-contain [ + 27 ] + 28 ] + 29 + 30 container editor [ + 31 # editable text: doubly linked list of characters (head contains a special sentinel) + 32 data:&:duplex-list:char + 33 top-of-screen:&:duplex-list:char + 34 bottom-of-screen:&:duplex-list:char + 35 # location before cursor inside data + 36 before-cursor:&:duplex-list:char + 37 + 38 # raw bounds of display area on screen + 39 # always displays from row 1 (leaving row 0 for a menu) and at most until bottom of screen + 40 left:num + 41 right:num + 42 bottom:num + 43 # raw screen coordinates of cursor + 44 cursor-row:num + 45 cursor-column:num + 46 ] + 47 + 48 # creates a new editor widget + 49 # right is exclusive + 50 def new-editor s:text, left:num, right:num -> result:&:editor [ + 51 local-scope + 52 load-ingredients + 53 # no clipping of bounds + 54 right <- subtract right, 1 + 55 result <- new editor:type + 56 # initialize screen-related fields + 57 *result <- put *result, left:offset, left + 58 *result <- put *result, right:offset, right + 59 # initialize cursor coordinates + 60 *result <- put *result, cursor-row:offset, 1/top + 61 *result <- put *result, cursor-column:offset, left + 62 # initialize empty contents + 63 init:&:duplex-list:char <- push 167/§, 0/tail + 64 *result <- put *result, data:offset, init + 65 *result <- put *result, top-of-screen:offset, init + 66 *result <- put *result, before-cursor:offset, init + 67 result <- insert-text result, s + 68 <editor-initialization> + 69 ] + 70 + 71 def insert-text editor:&:editor, text:text -> editor:&:editor [ + 72 local-scope + 73 load-ingredients + 74 # early exit if text is empty + 75 return-unless text + 76 len:num <- length *text + 77 return-unless len + 78 idx:num <- copy 0 + 79 # now we can start appending the rest, character by character + 80 curr:&:duplex-list:char <- get *editor, data:offset + 81 { + 82 ¦ done?:bool <- greater-or-equal idx, len + 83 ¦ break-if done? + 84 ¦ c:char <- index *text, idx + 85 ¦ insert c, curr + 86 ¦ # next iter + 87 ¦ curr <- next curr + 88 ¦ idx <- add idx, 1 + 89 ¦ loop + 90 } + 91 ] + 92 + 93 scenario editor-initializes-without-data [ + 94 local-scope + 95 assume-screen 5/width, 3/height + 96 run [ + 97 ¦ e:&:editor <- new-editor 0/data, 2/left, 5/right + 98 ¦ 2:editor/raw <- copy *e + 99 ] +100 memory-should-contain [ +101 ¦ # 2 (data) <- just the § sentinel +102 ¦ # 3 (top of screen) <- the § sentinel +103 ¦ 4 <- 0 # bottom-of-screen; null since text fits on screen +104 ¦ # 5 (before cursor) <- the § sentinel +105 ¦ 6 <- 2 # left +106 ¦ 7 <- 4 # right (inclusive) +107 ¦ 8 <- 0 # bottom (not set until render) +108 ¦ 9 <- 1 # cursor row +109 ¦ 10 <- 2 # cursor column +110 ] +111 screen-should-contain [ +112 ¦ . . +113 ¦ . . 114 ¦ . . -115 ¦ . . -116 ¦ . . -117 ] -118 ] -119 -120 # Assumes cursor should be at coordinates (cursor-row, cursor-column) and -121 # updates before-cursor to match. Might also move coordinates if they're -122 # outside text. -123 def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, screen:&:screen, editor:&:editor [ -124 local-scope -125 load-ingredients -126 return-unless editor, 1/top, 0/left -127 left:num <- get *editor, left:offset -128 screen-height:num <- screen-height screen -129 right:num <- get *editor, right:offset -130 # traversing editor -131 curr:&:duplex-list:char <- get *editor, top-of-screen:offset -132 prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev -133 curr <- next curr -134 # traversing screen -135 color:num <- copy 7/white -136 row:num <- copy 1/top -137 column:num <- copy left -138 cursor-row:num <- get *editor, cursor-row:offset -139 cursor-column:num <- get *editor, cursor-column:offset -140 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset -141 screen <- move-cursor screen, row, column -142 { -143 ¦ +next-character -144 ¦ break-unless curr -145 ¦ off-screen?:bool <- greater-or-equal row, screen-height -146 ¦ break-if off-screen? -147 ¦ # update editor.before-cursor -148 ¦ # Doing so at the start of each iteration ensures it stays one step behind -149 ¦ # the current character. -150 ¦ { -151 ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row -152 ¦ ¦ break-unless at-cursor-row? -153 ¦ ¦ at-cursor?:bool <- equal column, cursor-column -154 ¦ ¦ break-unless at-cursor? -155 ¦ ¦ before-cursor <- copy prev -156 ¦ } -157 ¦ c:char <- get *curr, value:offset -158 ¦ <character-c-received> -159 ¦ { -160 ¦ ¦ # newline? move to left rather than 0 -161 ¦ ¦ newline?:bool <- equal c, 10/newline -162 ¦ ¦ break-unless newline? -163 ¦ ¦ # adjust cursor if necessary -164 ¦ ¦ { -165 ¦ ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row -166 ¦ ¦ ¦ break-unless at-cursor-row? -167 ¦ ¦ ¦ left-of-cursor?:bool <- lesser-than column, cursor-column -168 ¦ ¦ ¦ break-unless left-of-cursor? -169 ¦ ¦ ¦ cursor-column <- copy column -170 ¦ ¦ ¦ before-cursor <- prev curr -171 ¦ ¦ } -172 ¦ ¦ # clear rest of line in this window -173 ¦ ¦ clear-line-until screen, right -174 ¦ ¦ # skip to next line -175 ¦ ¦ row <- add row, 1 -176 ¦ ¦ column <- copy left -177 ¦ ¦ screen <- move-cursor screen, row, column -178 ¦ ¦ curr <- next curr -179 ¦ ¦ prev <- next prev -180 ¦ ¦ loop +next-character -181 ¦ } -182 ¦ { -183 ¦ ¦ # at right? wrap. even if there's only one more letter left; we need -184 ¦ ¦ # room for clicking on the cursor after it. -185 ¦ ¦ at-right?:bool <- equal column, right -186 ¦ ¦ break-unless at-right? -187 ¦ ¦ # print wrap icon -188 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left -189 ¦ ¦ print screen, wrap-icon, 245/grey -190 ¦ ¦ column <- copy left -191 ¦ ¦ row <- add row, 1 -192 ¦ ¦ screen <- move-cursor screen, row, column -193 ¦ ¦ # don't increment curr -194 ¦ ¦ loop +next-character -195 ¦ } -196 ¦ print screen, c, color -197 ¦ curr <- next curr -198 ¦ prev <- next prev -199 ¦ column <- add column, 1 -200 ¦ loop -201 } -202 # save first character off-screen -203 *editor <- put *editor, bottom-of-screen:offset, curr -204 # is cursor to the right of the last line? move to end -205 { -206 ¦ at-cursor-row?:bool <- equal row, cursor-row -207 ¦ cursor-outside-line?:bool <- lesser-or-equal column, cursor-column -208 ¦ before-cursor-on-same-line?:bool <- and at-cursor-row?, cursor-outside-line? -209 ¦ above-cursor-row?:bool <- lesser-than row, cursor-row -210 ¦ before-cursor?:bool <- or before-cursor-on-same-line?, above-cursor-row? -211 ¦ break-unless before-cursor? -212 ¦ cursor-row <- copy row -213 ¦ cursor-column <- copy column -214 ¦ before-cursor <- copy prev -215 } -216 *editor <- put *editor, bottom:offset, row -217 *editor <- put *editor, cursor-row:offset, cursor-row -218 *editor <- put *editor, cursor-column:offset, cursor-column -219 *editor <- put *editor, before-cursor:offset, before-cursor -220 return row, column -221 ] -222 -223 def clear-screen-from screen:&:screen, row:num, column:num, left:num, right:num -> screen:&:screen [ -224 local-scope -225 load-ingredients -226 # if it's the real screen, use the optimized primitive -227 { -228 ¦ break-if screen -229 ¦ clear-display-from row, column, left, right -230 ¦ return -231 } -232 # if not, go the slower route -233 screen <- move-cursor screen, row, column -234 clear-line-until screen, right -235 clear-rest-of-screen screen, row, left, right -236 ] -237 -238 def clear-rest-of-screen screen:&:screen, row:num, left:num, right:num -> screen:&:screen [ -239 local-scope -240 load-ingredients -241 row <- add row, 1 -242 screen <- move-cursor screen, row, left -243 screen-height:num <- screen-height screen -244 { -245 ¦ at-bottom-of-screen?:bool <- greater-or-equal row, screen-height -246 ¦ break-if at-bottom-of-screen? -247 ¦ screen <- move-cursor screen, row, left -248 ¦ clear-line-until screen, right -249 ¦ row <- add row, 1 -250 ¦ loop -251 } -252 ] -253 -254 scenario editor-prints-multiple-lines [ -255 local-scope -256 assume-screen 5/width, 5/height -257 s:text <- new [abc -258 def] -259 e:&:editor <- new-editor s, 0/left, 5/right -260 run [ -261 ¦ render screen, e -262 ] -263 screen-should-contain [ -264 ¦ . . -265 ¦ .abc . -266 ¦ .def . -267 ¦ . . -268 ] -269 ] -270 -271 scenario editor-handles-offsets [ -272 local-scope -273 assume-screen 5/width, 5/height -274 e:&:editor <- new-editor [abc], 1/left, 5/right -275 run [ -276 ¦ render screen, e -277 ] -278 screen-should-contain [ -279 ¦ . . -280 ¦ . abc . -281 ¦ . . -282 ] -283 ] -284 -285 scenario editor-prints-multiple-lines-at-offset [ -286 local-scope -287 assume-screen 5/width, 5/height -288 s:text <- new [abc -289 def] -290 e:&:editor <- new-editor s, 1/left, 5/right -291 run [ -292 ¦ render screen, e -293 ] -294 screen-should-contain [ -295 ¦ . . -296 ¦ . abc . -297 ¦ . def . -298 ¦ . . -299 ] -300 ] -301 -302 scenario editor-wraps-long-lines [ -303 local-scope -304 assume-screen 5/width, 5/height -305 e:&:editor <- new-editor [abc def], 0/left, 5/right -306 run [ -307 ¦ render screen, e -308 ] -309 screen-should-contain [ -310 ¦ . . -311 ¦ .abc ↩. -312 ¦ .def . -313 ¦ . . -314 ] -315 screen-should-contain-in-color 245/grey [ -316 ¦ . . -317 ¦ . ↩. -318 ¦ . . -319 ¦ . . -320 ] -321 ] -322 -323 scenario editor-wraps-barely-long-lines [ -324 local-scope -325 assume-screen 5/width, 5/height -326 e:&:editor <- new-editor [abcde], 0/left, 5/right -327 run [ -328 ¦ render screen, e -329 ] -330 # still wrap, even though the line would fit. We need room to click on the -331 # end of the line -332 screen-should-contain [ -333 ¦ . . -334 ¦ .abcd↩. -335 ¦ .e . -336 ¦ . . -337 ] -338 screen-should-contain-in-color 245/grey [ -339 ¦ . . -340 ¦ . ↩. -341 ¦ . . -342 ¦ . . -343 ] -344 ] -345 -346 scenario editor-with-empty-text [ -347 local-scope -348 assume-screen 5/width, 5/height -349 e:&:editor <- new-editor [], 0/left, 5/right -350 run [ -351 ¦ render screen, e -352 ¦ 3:num/raw <- get *e, cursor-row:offset -353 ¦ 4:num/raw <- get *e, cursor-column:offset -354 ] -355 screen-should-contain [ -356 ¦ . . -357 ¦ . . -358 ¦ . . -359 ] -360 memory-should-contain [ -361 ¦ 3 <- 1 # cursor row -362 ¦ 4 <- 0 # cursor column +115 ] +116 ] +117 +118 # Assumes cursor should be at coordinates (cursor-row, cursor-column) and +119 # updates before-cursor to match. Might also move coordinates if they're +120 # outside text. +121 def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, screen:&:screen, editor:&:editor [ +122 local-scope +123 load-ingredients +124 return-unless editor, 1/top, 0/left +125 left:num <- get *editor, left:offset +126 screen-height:num <- screen-height screen +127 right:num <- get *editor, right:offset +128 # traversing editor +129 curr:&:duplex-list:char <- get *editor, top-of-screen:offset +130 prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev +131 curr <- next curr +132 # traversing screen +133 color:num <- copy 7/white +134 row:num <- copy 1/top +135 column:num <- copy left +136 cursor-row:num <- get *editor, cursor-row:offset +137 cursor-column:num <- get *editor, cursor-column:offset +138 before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset +139 screen <- move-cursor screen, row, column +140 { +141 ¦ +next-character +142 ¦ break-unless curr +143 ¦ off-screen?:bool <- greater-or-equal row, screen-height +144 ¦ break-if off-screen? +145 ¦ # update editor.before-cursor +146 ¦ # Doing so at the start of each iteration ensures it stays one step behind +147 ¦ # the current character. +148 ¦ { +149 ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row +150 ¦ ¦ break-unless at-cursor-row? +151 ¦ ¦ at-cursor?:bool <- equal column, cursor-column +152 ¦ ¦ break-unless at-cursor? +153 ¦ ¦ before-cursor <- copy prev +154 ¦ } +155 ¦ c:char <- get *curr, value:offset +156 ¦ <character-c-received> +157 ¦ { +158 ¦ ¦ # newline? move to left rather than 0 +159 ¦ ¦ newline?:bool <- equal c, 10/newline +160 ¦ ¦ break-unless newline? +161 ¦ ¦ # adjust cursor if necessary +162 ¦ ¦ { +163 ¦ ¦ ¦ at-cursor-row?:bool <- equal row, cursor-row +164 ¦ ¦ ¦ break-unless at-cursor-row? +165 ¦ ¦ ¦ left-of-cursor?:bool <- lesser-than column, cursor-column +166 ¦ ¦ ¦ break-unless left-of-cursor? +167 ¦ ¦ ¦ cursor-column <- copy column +168 ¦ ¦ ¦ before-cursor <- prev curr +169 ¦ ¦ } +170 ¦ ¦ # clear rest of line in this window +171 ¦ ¦ clear-line-until screen, right +172 ¦ ¦ # skip to next line +173 ¦ ¦ row <- add row, 1 +174 ¦ ¦ column <- copy left +175 ¦ ¦ screen <- move-cursor screen, row, column +176 ¦ ¦ curr <- next curr +177 ¦ ¦ prev <- next prev +178 ¦ ¦ loop +next-character +179 ¦ } +180 ¦ { +181 ¦ ¦ # at right? wrap. even if there's only one more letter left; we need +182 ¦ ¦ # room for clicking on the cursor after it. +183 ¦ ¦ at-right?:bool <- equal column, right +184 ¦ ¦ break-unless at-right? +185 ¦ ¦ # print wrap icon +186 ¦ ¦ wrap-icon:char <- copy 8617/loop-back-to-left +187 ¦ ¦ print screen, wrap-icon, 245/grey +188 ¦ ¦ column <- copy left +189 ¦ ¦ row <- add row, 1 +190 ¦ ¦ screen <- move-cursor screen, row, column +191 ¦ ¦ # don't increment curr +192 ¦ ¦ loop +next-character +193 ¦ } +194 ¦ print screen, c, color +195 ¦ curr <- next curr +196 ¦ prev <- next prev +197 ¦ column <- add column, 1 +198 ¦ loop +199 } +200 # save first character off-screen +201 *editor <- put *editor, bottom-of-screen:offset, curr +202 # is cursor to the right of the last line? move to end +203 { +204 ¦ at-cursor-row?:bool <- equal row, cursor-row +205 ¦ cursor-outside-line?:bool <- lesser-or-equal column, cursor-column +206 ¦ before-cursor-on-same-line?:bool <- and at-cursor-row?, cursor-outside-line? +207 ¦ above-cursor-row?:bool <- lesser-than row, cursor-row +208 ¦ before-cursor?:bool <- or before-cursor-on-same-line?, above-cursor-row? +209 ¦ break-unless before-cursor? +210 ¦ cursor-row <- copy row +211 ¦ cursor-column <- copy column +212 ¦ before-cursor <- copy prev +213 } +214 *editor <- put *editor, bottom:offset, row +215 *editor <- put *editor, cursor-row:offset, cursor-row +216 *editor <- put *editor, cursor-column:offset, cursor-column +217 *editor <- put *editor, before-cursor:offset, before-cursor +218 return row, column +219 ] +220 +221 def clear-screen-from screen:&:screen, row:num, column:num, left:num, right:num -> screen:&:screen [ +222 local-scope +223 load-ingredients +224 # if it's the real screen, use the optimized primitive +225 { +226 ¦ break-if screen +227 ¦ clear-display-from row, column, left, right +228 ¦ return +229 } +230 # if not, go the slower route +231 screen <- move-cursor screen, row, column +232 clear-line-until screen, right +233 clear-rest-of-screen screen, row, left, right +234 ] +235 +236 def clear-rest-of-screen screen:&:screen, row:num, left:num, right:num -> screen:&:screen [ +237 local-scope +238 load-ingredients +239 row <- add row, 1 +240 # if it's the real screen, use the optimized primitive +241 { +242 ¦ break-if screen +243 ¦ clear-display-from row, left, left, right +244 ¦ return +245 } +246 screen <- move-cursor screen, row, left +247 screen-height:num <- screen-height screen +248 { +249 ¦ at-bottom-of-screen?:bool <- greater-or-equal row, screen-height +250 ¦ break-if at-bottom-of-screen? +251 ¦ screen <- move-cursor screen, row, left +252 ¦ clear-line-until screen, right +253 ¦ row <- add row, 1 +254 ¦ loop +255 } +256 ] +257 +258 scenario editor-prints-multiple-lines [ +259 local-scope +260 assume-screen 5/width, 5/height +261 s:text <- new [abc +262 def] +263 e:&:editor <- new-editor s, 0/left, 5/right +264 run [ +265 ¦ render screen, e +266 ] +267 screen-should-contain [ +268 ¦ . . +269 ¦ .abc . +270 ¦ .def . +271 ¦ . . +272 ] +273 ] +274 +275 scenario editor-handles-offsets [ +276 local-scope +277 assume-screen 5/width, 5/height +278 e:&:editor <- new-editor [abc], 1/left, 5/right +279 run [ +280 ¦ render screen, e +281 ] +282 screen-should-contain [ +283 ¦ . . +284 ¦ . abc . +285 ¦ . . +286 ] +287 ] +288 +289 scenario editor-prints-multiple-lines-at-offset [ +290 local-scope +291 assume-screen 5/width, 5/height +292 s:text <- new [abc +293 def] +294 e:&:editor <- new-editor s, 1/left, 5/right +295 run [ +296 ¦ render screen, e +297 ] +298 screen-should-contain [ +299 ¦ . . +300 ¦ . abc . +301 ¦ . def . +302 ¦ . . +303 ] +304 ] +305 +306 scenario editor-wraps-long-lines [ +307 local-scope +308 assume-screen 5/width, 5/height +309 e:&:editor <- new-editor [abc def], 0/left, 5/right +310 run [ +311 ¦ render screen, e +312 ] +313 screen-should-contain [ +314 ¦ . . +315 ¦ .abc ↩. +316 ¦ .def . +317 ¦ . . +318 ] +319 screen-should-contain-in-color 245/grey [ +320 ¦ . . +321 ¦ . ↩. +322 ¦ . . +323 ¦ . . +324 ] +325 ] +326 +327 scenario editor-wraps-barely-long-lines [ +328 local-scope +329 assume-screen 5/width, 5/height +330 e:&:editor <- new-editor [abcde], 0/left, 5/right +331 run [ +332 ¦ render screen, e +333 ] +334 # still wrap, even though the line would fit. We need room to click on the +335 # end of the line +336 screen-should-contain [ +337 ¦ . . +338 ¦ .abcd↩. +339 ¦ .e . +340 ¦ . . +341 ] +342 screen-should-contain-in-color 245/grey [ +343 ¦ . . +344 ¦ . ↩. +345 ¦ . . +346 ¦ . . +347 ] +348 ] +349 +350 scenario editor-with-empty-text [ +351 local-scope +352 assume-screen 5/width, 5/height +353 e:&:editor <- new-editor [], 0/left, 5/right +354 run [ +355 ¦ render screen, e +356 ¦ 3:num/raw <- get *e, cursor-row:offset +357 ¦ 4:num/raw <- get *e, cursor-column:offset +358 ] +359 screen-should-contain [ +360 ¦ . . +361 ¦ . . +362 ¦ . . 363 ] -364 ] -365 -366 # just a little color for Mu code -367 -368 scenario render-colors-comments [ -369 local-scope -370 assume-screen 5/width, 5/height -371 s:text <- new [abc -372 # de -373 f] -374 e:&:editor <- new-editor s, 0/left, 5/right -375 run [ -376 ¦ render screen, e -377 ] -378 screen-should-contain [ -379 ¦ . . -380 ¦ .abc . -381 ¦ .# de . -382 ¦ .f . +364 memory-should-contain [ +365 ¦ 3 <- 1 # cursor row +366 ¦ 4 <- 0 # cursor column +367 ] +368 ] +369 +370 # just a little color for Mu code +371 +372 scenario render-colors-comments [ +373 local-scope +374 assume-screen 5/width, 5/height +375 s:text <- new [abc +376 # de +377 f] +378 e:&:editor <- new-editor s, 0/left, 5/right +379 run [ +380 ¦ render screen, e +381 ] +382 screen-should-contain [ 383 ¦ . . -384 ] -385 screen-should-contain-in-color 12/lightblue, [ -386 ¦ . . +384 ¦ .abc . +385 ¦ .# de . +386 ¦ .f . 387 ¦ . . -388 ¦ .# de . -389 ¦ . . +388 ] +389 screen-should-contain-in-color 12/lightblue, [ 390 ¦ . . -391 ] -392 screen-should-contain-in-color 7/white, [ +391 ¦ . . +392 ¦ .# de . 393 ¦ . . -394 ¦ .abc . -395 ¦ . . -396 ¦ .f . +394 ¦ . . +395 ] +396 screen-should-contain-in-color 7/white, [ 397 ¦ . . -398 ] -399 ] -400 -401 after <character-c-received> [ -402 color <- get-color color, c +398 ¦ .abc . +399 ¦ . . +400 ¦ .f . +401 ¦ . . +402 ] 403 ] 404 -405 # so far the previous color is all the information we need; that may change -406 def get-color color:num, c:char -> color:num [ -407 local-scope -408 load-ingredients -409 color-is-white?:bool <- equal color, 7/white -410 # if color is white and next character is '#', switch color to blue -411 { -412 ¦ break-unless color-is-white? -413 ¦ starting-comment?:bool <- equal c, 35/# -414 ¦ break-unless starting-comment? -415 ¦ trace 90, [app], [switch color back to blue] -416 ¦ return 12/lightblue -417 } -418 # if color is blue and next character is newline, switch color to white -419 { -420 ¦ color-is-blue?:bool <- equal color, 12/lightblue -421 ¦ break-unless color-is-blue? -422 ¦ ending-comment?:bool <- equal c, 10/newline -423 ¦ break-unless ending-comment? -424 ¦ trace 90, [app], [switch color back to white] -425 ¦ return 7/white -426 } -427 # if color is white (no comments) and next character is '<', switch color to red -428 { -429 ¦ break-unless color-is-white? -430 ¦ starting-assignment?:bool <- equal c, 60/< -431 ¦ break-unless starting-assignment? -432 ¦ return 1/red -433 } -434 # if color is red and next character is space, switch color to white -435 { -436 ¦ color-is-red?:bool <- equal color, 1/red -437 ¦ break-unless color-is-red? -438 ¦ ending-assignment?:bool <- equal c, 32/space -439 ¦ break-unless ending-assignment? -440 ¦ return 7/white -441 } -442 # otherwise no change -443 return color -444 ] -445 -446 scenario render-colors-assignment [ -447 local-scope -448 assume-screen 8/width, 5/height -449 s:text <- new [abc -450 d <- e -451 f] -452 e:&:editor <- new-editor s, 0/left, 8/right -453 run [ -454 ¦ render screen, e -455 ] -456 screen-should-contain [ -457 ¦ . . -458 ¦ .abc . -459 ¦ .d <- e . -460 ¦ .f . +405 after <character-c-received> [ +406 color <- get-color color, c +407 ] +408 +409 # so far the previous color is all the information we need; that may change +410 def get-color color:num, c:char -> color:num [ +411 local-scope +412 load-ingredients +413 color-is-white?:bool <- equal color, 7/white +414 # if color is white and next character is '#', switch color to blue +415 { +416 ¦ break-unless color-is-white? +417 ¦ starting-comment?:bool <- equal c, 35/# +418 ¦ break-unless starting-comment? +419 ¦ trace 90, [app], [switch color back to blue] +420 ¦ return 12/lightblue +421 } +422 # if color is blue and next character is newline, switch color to white +423 { +424 ¦ color-is-blue?:bool <- equal color, 12/lightblue +425 ¦ break-unless color-is-blue? +426 ¦ ending-comment?:bool <- equal c, 10/newline +427 ¦ break-unless ending-comment? +428 ¦ trace 90, [app], [switch color back to white] +429 ¦ return 7/white +430 } +431 # if color is white (no comments) and next character is '<', switch color to red +432 { +433 ¦ break-unless color-is-white? +434 ¦ starting-assignment?:bool <- equal c, 60/< +435 ¦ break-unless starting-assignment? +436 ¦ return 1/red +437 } +438 # if color is red and next character is space, switch color to white +439 { +440 ¦ color-is-red?:bool <- equal color, 1/red +441 ¦ break-unless color-is-red? +442 ¦ ending-assignment?:bool <- equal c, 32/space +443 ¦ break-unless ending-assignment? +444 ¦ return 7/white +445 } +446 # otherwise no change +447 return color +448 ] +449 +450 scenario render-colors-assignment [ +451 local-scope +452 assume-screen 8/width, 5/height +453 s:text <- new [abc +454 d <- e +455 f] +456 e:&:editor <- new-editor s, 0/left, 8/right +457 run [ +458 ¦ render screen, e +459 ] +460 screen-should-contain [ 461 ¦ . . -462 ] -463 screen-should-contain-in-color 1/red, [ -464 ¦ . . +462 ¦ .abc . +463 ¦ .d <- e . +464 ¦ .f . 465 ¦ . . -466 ¦ . <- . -467 ¦ . . +466 ] +467 screen-should-contain-in-color 1/red, [ 468 ¦ . . -469 ] -470 ] +469 ¦ . . +470 ¦ . <- . +471 ¦ . . +472 ¦ . . +473 ] +474 ] -- cgit 1.4.1-2-gfad0