mu/081print.mu

889 lines
23 KiB
Plaintext
Raw Normal View History

# Wrappers around print primitives that take a 'screen' object and are thus
# easier to test.
container screen [
2016-09-17 17:28:25 +00:00
num-rows:num
num-columns:num
cursor-row:num
cursor-column:num
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
data:&:@:screen-cell # capacity num-rows*num-columns
top-idx:num # index inside data that corresponds to top-left of screen
# modified on scroll, wrapping around to the top of data
2015-05-26 23:15:50 +00:00
]
container screen-cell [
contents:char
2016-09-17 17:28:25 +00:00
color:num
]
2016-09-17 19:55:10 +00:00
def new-fake-screen w:num, h:num -> result:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
result <- new screen:type
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
non-zero-width?:bool <- greater-than w, 0
assert non-zero-width?, [screen can't have zero width]
non-zero-height?:bool <- greater-than h, 0
assert non-zero-height?, [screen can't have zero height]
2016-09-17 17:28:25 +00:00
bufsize:num <- multiply w, h
2016-09-17 20:00:39 +00:00
data:&:@:screen-cell <- new screen-cell:type, bufsize
*result <- merge h/num-rows, w/num-columns, 0/cursor-row, 0/cursor-column, data, 0/top-idx
2015-11-19 05:36:36 +00:00
result <- clear-screen result
]
2016-09-17 19:55:10 +00:00
def clear-screen screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [clear-screen]
{
break-if screen
# real screen
clear-display
return
}
# fake screen
buf:&:@:screen-cell <- get *screen, data:offset
max:num <- length *buf
i:num <- copy 0
{
done?:bool <- greater-or-equal i, max
break-if done?
curr:screen-cell <- merge 0/empty, 7/white
*buf <- put-index *buf, i, curr
i <- add i, 1
loop
}
# reset cursor
*screen <- put *screen, cursor-row:offset, 0
*screen <- put *screen, cursor-column:offset, 0
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
*screen <- put *screen, top-idx:offset, 0
]
2016-09-17 19:55:10 +00:00
def fake-screen-is-empty? screen:&:screen -> result:bool [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [fake-screen-is-empty?]
return-unless screen, 1/true # do nothing for real screens
2016-09-17 20:00:39 +00:00
buf:&:@:screen-cell <- get *screen, data:offset
2016-09-17 17:28:25 +00:00
i:num <- copy 0
len:num <- length *buf
{
2016-09-17 17:32:57 +00:00
done?:bool <- greater-or-equal i, len
2015-07-29 21:37:57 +00:00
break-if done?
curr:screen-cell <- index *buf, i
curr-contents:char <- get curr, contents:offset
2015-07-29 21:37:57 +00:00
i <- add i, 1
loop-unless curr-contents
# not 0
return 0/false
}
return 1/true
]
2016-09-17 19:55:10 +00:00
def print screen:&:screen, c:char -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
2016-09-17 17:32:57 +00:00
color:num, color-found?:bool <- next-ingredient
2015-05-26 23:15:50 +00:00
{
# default color to white
2015-07-29 21:37:57 +00:00
break-if color-found?
color <- copy 7/white
2015-05-26 23:15:50 +00:00
}
2016-09-17 17:32:57 +00:00
bg-color:num, bg-color-found?:bool <- next-ingredient
2015-07-05 03:46:50 +00:00
{
# default bg-color to black
2015-07-29 21:37:57 +00:00
break-if bg-color-found?
bg-color <- copy 0/black
2015-07-05 03:46:50 +00:00
}
2016-09-17 17:28:25 +00:00
c2:num <- character-to-code c
trace 90, [print-character], c2
{
# real screen
break-if screen
print-character-to-display c, color, bg-color
return
}
# fake screen
# (handle special cases exactly like in the real screen)
width:num <- get *screen, num-columns:offset
height:num <- get *screen, num-rows:offset
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
capacity:num <- multiply width, height
row:num <- get *screen, cursor-row:offset
column:num <- get *screen, cursor-column:offset
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
buf:&:@:screen-cell <- get *screen, data:offset
# some potentially slow sanity checks for preconditions {
# eliminate fractions from column and row
row <- round row
column <- round column
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# if cursor is past left margin (error), reset to left margin
{
too-far-left?:bool <- lesser-than column, 0
break-unless too-far-left?
column <- copy 0
*screen <- put *screen, cursor-column:offset, column
}
# if cursor is at right margin, wrap
{
at-right?:bool <- equal column, width
break-unless at-right?
column <- copy 0
*screen <- put *screen, cursor-column:offset, column
row <- add row, 1
*screen <- put *screen, cursor-row:offset, row
}
# if cursor is past right margin (error), reset to right margin
{
too-far-right?:bool <- greater-than column, width
break-unless too-far-right?
column <- subtract width, 1
*screen <- put *screen, cursor-row:offset, row
}
# if row is above top margin (error), reset to top margin
{
too-far-up?:bool <- lesser-than row, 0
break-unless too-far-up?
row <- copy 0
*screen <- put *screen, cursor-row:offset, row
}
# if row is at bottom margin, scroll
{
at-bottom?:bool <- equal row, height
break-unless at-bottom?
scroll-fake-screen screen
row <- subtract height, 1
*screen <- put *screen, cursor-row:offset, row
}
# if row is below bottom margin (error), reset to bottom margin
{
too-far-down?:bool <- greater-than row, height
break-unless too-far-down?
row <- subtract height, 1
*screen <- put *screen, cursor-row:offset, row
}
# }
#? $print [print-character (], row, [, ], column, [): ], c, 10/newline
# special-case: newline
{
newline?:bool <- equal c, 10/newline
break-unless newline?
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
cursor-down-on-fake-screen screen # doesn't modify column
return
}
# special-case: linefeed
{
linefeed?:bool <- equal c, 13/linefeed
break-unless linefeed?
*screen <- put *screen, cursor-column:offset, 0
return
}
# special-case: backspace
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# moves cursor left but does not erase
{
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
backspace?:bool <- equal c, 8/backspace
break-unless backspace?
{
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
break-unless column
column <- subtract column, 1
*screen <- put *screen, cursor-column:offset, column
}
return
}
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# save character in fake screen
top-idx:num <- get *screen, top-idx:offset
index:num <- data-index row, column, width, height, top-idx
cursor:screen-cell <- merge c, color
*buf <- put-index *buf, index, cursor
# move cursor to next character
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# (but don't bother making it valid; we'll do that before the next print)
column <- add column, 1
*screen <- put *screen, cursor-column:offset, column
]
def cursor-down-on-fake-screen screen:&:screen -> screen:&:screen [
local-scope
load-ingredients
#? stash [cursor-down]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
row:num <- get *screen, cursor-row:offset
height:num <- get *screen, num-rows:offset
bottom:num <- subtract height, 1
at-bottom?:bool <- greater-or-equal row, bottom
{
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
break-if at-bottom?
row <- add row, 1
*screen <- put *screen, cursor-row:offset, row
}
{
break-unless at-bottom?
scroll-fake-screen screen # does not modify row
}
]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
def scroll-fake-screen screen:&:screen -> screen:&:screen [
local-scope
load-ingredients
#? stash [scroll-fake-screen]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
width:num <- get *screen, num-columns:offset
height:num <- get *screen, num-rows:offset
buf:&:@:screen-cell <- get *screen, data:offset
# clear top line and 'rotate' it to the bottom
top-idx:num <- get *screen, top-idx:offset # 0 <= top-idx < len(buf)
next-top-idx:num <- add top-idx, width # 0 <= next-top-idx <= len(buf)
empty-cell:screen-cell <- merge 0/empty, 7/white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
{
done?:bool <- greater-or-equal top-idx, next-top-idx
break-if done?
put-index *buf, top-idx, empty-cell
top-idx <- add top-idx, 1
# no modulo; top-idx is always a multiple of width,
# so it can never wrap around inside this loop
loop
}
# top-idx now same as next-top-idx; wrap around if necessary
capacity:num <- multiply width, height
_, top-idx <- divide-with-remainder, top-idx, capacity
*screen <- put *screen, top-idx:offset, top-idx
]
# translate from screen (row, column) coordinates to an index into data
# while accounting for scrolling (sliding top-idx)
def data-index row:num, column:num, width:num, height:num, top-idx:num -> result:num [
local-scope
load-ingredients
result <- multiply width, row
result <- add result, column, top-idx
capacity:num <- multiply width, height
_, result <- divide-with-remainder result, capacity
]
scenario print-character-at-top-left [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
run [
a:char <- copy 97/a
fake-screen <- print fake-screen, a:char
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
1:@:screen-cell/raw <- copy *cell
]
memory-should-contain [
1 <- 6 # width*height
2 <- 97 # 'a'
3 <- 7 # white
# rest of screen is empty
4 <- 0
]
]
scenario print-character-at-fractional-coordinate [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
a:char <- copy 97/a
run [
move-cursor fake-screen, 0.5, 0
fake-screen <- print fake-screen, a:char
cell:&:@:screen-cell <- get *fake-screen, data:offset
1:@:screen-cell/raw <- copy *cell
]
memory-should-contain [
1 <- 6 # width*height
2 <- 97 # 'a'
3 <- 7 # white
# rest of screen is empty
4 <- 0
]
]
scenario print-character-in-color [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
2015-05-27 02:30:27 +00:00
run [
a:char <- copy 97/a
fake-screen <- print fake-screen, a:char, 1/red
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
1:@:screen-cell/raw <- copy *cell
2015-05-27 02:30:27 +00:00
]
memory-should-contain [
1 <- 6 # width*height
2 <- 97 # 'a'
3 <- 1 # red
# rest of screen is empty
4 <- 0
2015-05-27 02:30:27 +00:00
]
]
scenario print-backspace-character [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
a:char <- copy 97/a
fake-screen <- print fake-screen, a
run [
backspace:char <- copy 8/backspace
fake-screen <- print fake-screen, backspace
2016-09-17 17:28:25 +00:00
10:num/raw <- get *fake-screen, cursor-column:offset
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
11:@:screen-cell/raw <- copy *cell
]
memory-should-contain [
10 <- 0 # cursor column
11 <- 6 # width*height
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
12 <- 97 # still 'a'
13 <- 7 # white
# rest of screen is empty
14 <- 0
]
]
2015-06-16 22:30:43 +00:00
scenario print-extra-backspace-character [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
a:char <- copy 97/a
fake-screen <- print fake-screen, a
2015-06-16 22:30:43 +00:00
run [
backspace:char <- copy 8/backspace
fake-screen <- print fake-screen, backspace
fake-screen <- print fake-screen, backspace # cursor already at left margin
2016-09-17 17:28:25 +00:00
1:num/raw <- get *fake-screen, cursor-column:offset
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
3:@:screen-cell/raw <- copy *cell
2015-06-16 22:30:43 +00:00
]
memory-should-contain [
1 <- 0 # cursor column
3 <- 6 # width*height
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
4 <- 97 # still 'a'
5 <- 7 # white
# rest of screen is empty
6 <- 0
2015-06-16 22:30:43 +00:00
]
]
scenario print-character-at-right-margin [
# fill top row of screen with text
local-scope
fake-screen:&:screen <- new-fake-screen 2/width, 2/height
a:char <- copy 97/a
fake-screen <- print fake-screen, a
b:char <- copy 98/b
fake-screen <- print fake-screen, b
2015-06-16 22:30:43 +00:00
run [
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# cursor now at next row
c:char <- copy 99/c
fake-screen <- print fake-screen, c
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
10:num/raw <- get *fake-screen, cursor-row:offset
11:num/raw <- get *fake-screen, cursor-column:offset
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
12:@:screen-cell/raw <- copy *cell
2015-06-16 22:30:43 +00:00
]
memory-should-contain [
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
10 <- 1 # cursor row
11 <- 1 # cursor column
12 <- 4 # width*height
13 <- 97 # 'a'
14 <- 7 # white
15 <- 98 # 'b'
16 <- 7 # white
17 <- 99 # 'c'
18 <- 7 # white
19 <- 0 # ' '
20 <- 7 # white
2015-06-16 22:30:43 +00:00
]
]
scenario print-newline-character [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
a:char <- copy 97/a
fake-screen <- print fake-screen, a
run [
newline:char <- copy 10/newline
fake-screen <- print fake-screen, newline
2016-09-17 17:28:25 +00:00
10:num/raw <- get *fake-screen, cursor-row:offset
11:num/raw <- get *fake-screen, cursor-column:offset
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
12:@:screen-cell/raw <- copy *cell
]
memory-should-contain [
10 <- 1 # cursor row
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
11 <- 1 # cursor column
12 <- 6 # width*height
13 <- 97 # 'a'
14 <- 7 # white
# rest of screen is empty
15 <- 0
]
]
2015-06-16 22:30:43 +00:00
scenario print-newline-at-bottom-line [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
newline:char <- copy 10/newline
fake-screen <- print fake-screen, newline
fake-screen <- print fake-screen, newline
2015-06-16 22:30:43 +00:00
run [
# cursor now at bottom of screen
fake-screen <- print fake-screen, newline
2016-09-17 17:28:25 +00:00
10:num/raw <- get *fake-screen, cursor-row:offset
11:num/raw <- get *fake-screen, cursor-column:offset
2015-06-16 22:30:43 +00:00
]
# doesn't move further down
2015-06-16 22:30:43 +00:00
memory-should-contain [
10 <- 1 # cursor row
11 <- 0 # cursor column
2015-06-16 22:30:43 +00:00
]
]
scenario print-character-at-bottom-right [
local-scope
fake-screen:&:screen <- new-fake-screen 2/width, 2/height
a:char <- copy 97/a
fake-screen <- print fake-screen, a
b:char <- copy 98/b
fake-screen <- print fake-screen, b
c:char <- copy 99/c
fake-screen <- print fake-screen, c
2015-06-16 22:30:43 +00:00
run [
# cursor now at bottom right
d:char <- copy 100/d
fake-screen <- print fake-screen, d
2016-09-17 17:28:25 +00:00
10:num/raw <- get *fake-screen, cursor-row:offset
11:num/raw <- get *fake-screen, cursor-column:offset
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
12:num/raw <- get *fake-screen, top-idx:offset
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
20:@:screen-cell/raw <- copy *cell
2015-06-16 22:30:43 +00:00
]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# cursor column overflows the screen but is not wrapped yet
2015-06-16 22:30:43 +00:00
memory-should-contain [
10 <- 1 # cursor row
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
11 <- 2 # cursor column -- outside screen
12 <- 0 # top-idx -- not yet scrolled
20 <- 4 # screen size (width*height)
21 <- 97 # 'a'
22 <- 7 # white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
23 <- 98 # 'b'
24 <- 7 # white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
25 <- 99 # 'c'
26 <- 7 # white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
27 <- 100 # 'd'
28 <- 7 # white
2015-06-16 22:30:43 +00:00
]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
run [
e:char <- copy 101/e
print fake-screen, e
10:num/raw <- get *fake-screen, cursor-row:offset
11:num/raw <- get *fake-screen, cursor-column:offset
12:num/raw <- get *fake-screen, top-idx:offset
cell:&:@:screen-cell <- get *fake-screen, data:offset
20:@:screen-cell/raw <- copy *cell
]
memory-should-contain [
# text scrolls by 1, we lose the top line
10 <- 1 # cursor row
11 <- 1 # cursor column -- wrapped
12 <- 2 # top-idx -- scrolled
20 <- 4 # screen size (width*height)
# screen now checked in rotated order
25 <- 99 # 'c'
26 <- 7 # white
27 <- 100 # 'd'
28 <- 7 # white
# screen wraps; bottom line is cleared of old contents
21 <- 101 # 'e'
22 <- 7 # white
23 <- 0 # unused
24 <- 7 # white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
]
]
# even though our screen supports scrolling, some apps may want to avoid
# scrolling
# these helpers help check for scrolling at development time
def save-top-idx screen:&:screen -> result:num [
local-scope
load-ingredients
return-unless screen, 0 # check is only for fake screens
result <- get *screen, top-idx:offset
]
def assert-no-scroll screen:&:screen, old-top-idx:num [
local-scope
load-ingredients
return-unless screen
new-top-idx:num <- get *screen, top-idx:offset
no-scroll?:bool <- equal old-top-idx, new-top-idx
assert no-scroll?, [render should never use screen's scrolling capabilities]
2015-06-16 22:30:43 +00:00
]
2016-09-17 19:55:10 +00:00
def clear-line screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [clear-line]
space:char <- copy 0/nul
{
break-if screen
# real screen
clear-line-on-display
return
}
# fake screen
width:num <- get *screen, num-columns:offset
column:num <- get *screen, cursor-column:offset
original-column:num <- copy column
# space over the entire line
{
right:num <- subtract width, 1
done?:bool <- greater-or-equal column, right
break-if done?
print screen, space
column <- add column, 1
loop
}
# now back to where the cursor was
*screen <- put *screen, cursor-column:offset, original-column
]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
# only for non-scrolling apps
2016-09-17 19:55:10 +00:00
def clear-line-until screen:&:screen, right:num/inclusive -> screen:&:screen [
local-scope
load-ingredients
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
row:num, column:num <- cursor-position screen
#? stash [clear-line-until] row column
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
height:num <- screen-height screen
past-bottom?:bool <- greater-or-equal row, height
return-if past-bottom?
space:char <- copy 32/space
2016-09-17 17:32:57 +00:00
bg-color:num, bg-color-found?:bool <- next-ingredient
{
# default bg-color to black
break-if bg-color-found?
bg-color <- copy 0/black
}
{
2016-09-17 17:32:57 +00:00
done?:bool <- greater-than column, right
break-if done?
screen <- print screen, space, 7/white, bg-color # foreground color is mostly unused except if the cursor shows up at this cell
column <- add column, 1
loop
}
]
2016-09-17 19:55:10 +00:00
def cursor-position screen:&:screen -> row:num, column:num [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
{
break-if screen
# real screen
row, column <- cursor-position-on-display
return
}
# fake screen
row:num <- get *screen, cursor-row:offset
column:num <- get *screen, cursor-column:offset
]
2016-09-17 19:55:10 +00:00
def move-cursor screen:&:screen, new-row:num, new-column:num -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [move-cursor]
{
break-if screen
# real screen
move-cursor-on-display new-row, new-column
return
}
# fake screen
*screen <- put *screen, cursor-row:offset, new-row
*screen <- put *screen, cursor-column:offset, new-column
]
2015-04-30 17:12:36 +00:00
scenario clear-line-erases-printed-characters [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
# print a character
a:char <- copy 97/a
fake-screen <- print fake-screen, a
# move cursor to start of line
fake-screen <- move-cursor fake-screen, 0/row, 0/column
2015-04-30 17:12:36 +00:00
run [
fake-screen <- clear-line fake-screen
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
10:@:screen-cell/raw <- copy *cell
2015-04-30 17:12:36 +00:00
]
# screen should be blank
memory-should-contain [
10 <- 6 # width*height
11 <- 0
12 <- 7
13 <- 0
14 <- 7
15 <- 0
16 <- 7
17 <- 0
18 <- 7
19 <- 0
20 <- 7
21 <- 0
22 <- 7
2015-04-30 17:12:36 +00:00
]
]
2016-09-17 19:55:10 +00:00
def cursor-down screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [cursor-down]
{
break-if screen
# real screen
move-cursor-down-on-display
return
}
# fake screen
cursor-down-on-fake-screen screen
]
scenario cursor-down-scrolls [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
# print something to screen and scroll
run [
print fake-screen, [abc]
cursor-to-next-line fake-screen
cursor-to-next-line fake-screen
data:&:@:screen-cell <- get *fake-screen, data:offset
10:@:screen-cell/raw <- copy *data
]
# screen is now blank
memory-should-contain [
10 <- 6 # width*height
11 <- 0
12 <- 7 # white
13 <- 0
14 <- 7 # white
15 <- 0
16 <- 7 # white
17 <- 0
18 <- 7 # white
19 <- 0
20 <- 7 # white
21 <- 0
22 <- 7 # white
]
]
2016-09-17 19:55:10 +00:00
def cursor-up screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [cursor-up]
{
break-if screen
# real screen
move-cursor-up-on-display
return
}
# fake screen
row:num <- get *screen, cursor-row:offset
at-top?:bool <- lesser-or-equal row, 0
return-if at-top?
row <- subtract row, 1
*screen <- put *screen, cursor-row:offset, row
]
2016-09-17 19:55:10 +00:00
def cursor-right screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [cursor-right]
{
break-if screen
# real screen
move-cursor-right-on-display
return
}
# fake screen
width:num <- get *screen, num-columns:offset
column:num <- get *screen, cursor-column:offset
max:num <- subtract width, 1
at-bottom?:bool <- greater-or-equal column, max
return-if at-bottom?
column <- add column, 1
*screen <- put *screen, cursor-column:offset, column
]
2016-09-17 19:55:10 +00:00
def cursor-left screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [cursor-left]
{
break-if screen
# real screen
move-cursor-left-on-display
return
}
# fake screen
column:num <- get *screen, cursor-column:offset
at-top?:bool <- lesser-or-equal column, 0
return-if at-top?
column <- subtract column, 1
*screen <- put *screen, cursor-column:offset, column
]
2016-09-17 19:55:10 +00:00
def cursor-to-start-of-line screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [cursor-to-start-of-line]
2016-09-17 17:28:25 +00:00
row:num <- cursor-position screen
screen <- move-cursor screen, row, 0/column
]
2016-09-17 19:55:10 +00:00
def cursor-to-next-line screen:&:screen -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [cursor-to-next-line]
2015-07-29 21:37:57 +00:00
screen <- cursor-down screen
screen <- cursor-to-start-of-line screen
]
2016-09-17 19:55:10 +00:00
def move-cursor-to-column screen:&:screen, column:num -> screen:&:screen [
local-scope
load-ingredients
2016-09-17 17:28:25 +00:00
row:num, _ <- cursor-position screen
#? stash [move-cursor-to-column] row
move-cursor screen, row, column
]
2016-09-17 19:55:10 +00:00
def screen-width screen:&:screen -> width:num [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [screen-width]
{
2015-11-19 05:36:36 +00:00
break-unless screen
# fake screen
2015-11-19 05:36:36 +00:00
width <- get *screen, num-columns:offset
return
}
# real screen
2015-11-19 05:36:36 +00:00
width <- display-width
]
2016-09-17 19:55:10 +00:00
def screen-height screen:&:screen -> height:num [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
#? stash [screen-height]
{
2015-11-19 05:36:36 +00:00
break-unless screen
# fake screen
2015-11-19 05:36:36 +00:00
height <- get *screen, num-rows:offset
return
}
# real screen
2015-11-19 05:36:36 +00:00
height <- display-height
]
2016-09-17 19:55:10 +00:00
def print screen:&:screen, s:text -> screen:&:screen [
local-scope
2015-11-19 05:36:36 +00:00
load-ingredients
2016-09-17 17:32:57 +00:00
color:num, color-found?:bool <- next-ingredient
{
# default color to white
2015-07-29 21:37:57 +00:00
break-if color-found?
color <- copy 7/white
}
2016-09-17 17:32:57 +00:00
bg-color:num, bg-color-found?:bool <- next-ingredient
2015-07-05 03:46:50 +00:00
{
# default bg-color to black
2015-07-29 21:37:57 +00:00
break-if bg-color-found?
bg-color <- copy 0/black
2015-07-05 03:46:50 +00:00
}
2016-09-17 17:28:25 +00:00
len:num <- length *s
i:num <- copy 0
{
2016-09-17 17:32:57 +00:00
done?:bool <- greater-or-equal i, len
2015-07-29 21:37:57 +00:00
break-if done?
c:char <- index *s, i
print screen, c, color, bg-color
2015-07-29 21:37:57 +00:00
i <- add i, 1
loop
}
]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
scenario print-text-wraps-past-right-margin [
local-scope
fake-screen:&:screen <- new-fake-screen 3/width, 2/height
2015-06-16 21:21:00 +00:00
run [
fake-screen <- print fake-screen, [abcd]
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
5:num/raw <- get *fake-screen, cursor-row:offset
6:num/raw <- get *fake-screen, cursor-column:offset
7:num/raw <- get *fake-screen, top-idx:offset
2016-09-17 20:00:39 +00:00
cell:&:@:screen-cell <- get *fake-screen, data:offset
10:@:screen-cell/raw <- copy *cell
2015-06-16 21:21:00 +00:00
]
memory-should-contain [
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
5 <- 1 # cursor-row
6 <- 1 # cursor-column
7 <- 0 # top-idx
10 <- 6 # width*height
11 <- 97 # 'a'
12 <- 7 # white
13 <- 98 # 'b'
14 <- 7 # white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
15 <- 99 # 'c'
16 <- 7 # white
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
17 <- 100 # 'd'
18 <- 7 # white
# rest of screen is empty
3860 - stop buffering the screen in termbox To achieve this we have to switch to a model of the screen in termbox that is closer to the underlying terminal. Before: a screen is a grid of characters writing out of bounds does nothing After: a screen is a scrolling raster of characters writing out of bounds wraps to next line and scrolls if necessary To move to the new model, it was essential that I migrate my fake screen at the same time to mimic it. This is why the first attempt (commit 3824) failed (commit 3858). This is also why this commit can't be split into smaller pieces. The fake screen now 'scrolls' by rotating screen lines from top to bottom. There's still no notion of a scrollback buffer. The newer model is richer; it permits repl-like apps that upstream termbox can't do easily. It also permits us to simply use `printf` or `cout` to write to the screen, and everything mostly works as you would expect. Exceptions: a) '\n' won't do what you expect. You need to explicitly print both '\n' and '\r'. b) backspace won't do what you expect. It only moves the cursor back, without erasing the previous character. It does not wrap. Both behaviors exactly mimic my existing terminal's emulation of vt100. The catch: it's easy to accidentally scroll in apps. Out-of-bounds prints didn't matter before, but they're bugs now. To help track them down, use the `save-top-idx`, `assert-no-scroll` pair of helpers. An important trick is to wrap the cursor before rather after printing a character. Otherwise we end up scrolling every time we print to the bottom-right character. This means that the cursor position can be invalid at the start of a print, and we need to handle that. In the process we also lose the ability to hide and show the screen. We have to show the prints happening. Seems apt for a "white-box" platform like Mu.
2017-05-18 16:44:37 +00:00
19 <- 0
2015-06-16 21:21:00 +00:00
]
]
def print screen:&:screen, n:num -> screen:&:screen [
local-scope
load-ingredients
2016-09-17 17:32:57 +00:00
color:num, color-found?:bool <- next-ingredient
{
# default color to white
2015-07-29 21:37:57 +00:00
break-if color-found?
color <- copy 7/white
}
2016-09-17 17:32:57 +00:00
bg-color:num, bg-color-found?:bool <- next-ingredient
2015-07-05 03:46:50 +00:00
{
# default bg-color to black
2015-07-29 21:37:57 +00:00
break-if bg-color-found?
bg-color <- copy 0/black
2015-07-05 03:46:50 +00:00
}
# todo: other bases besides decimal
s:text <- to-text n
screen <- print screen, s, color, bg-color
]
2017-01-22 20:10:38 +00:00
def print screen:&:screen, n:bool -> screen:&:screen [
local-scope
load-ingredients
color:num, color-found?:bool <- next-ingredient
{
# default color to white
break-if color-found?
color <- copy 7/white
}
bg-color:num, bg-color-found?:bool <- next-ingredient
{
# default bg-color to black
break-if bg-color-found?
bg-color <- copy 0/black
}
n2:num <- copy n
screen <- print screen, n2, color, bg-color
]
2016-09-17 19:55:10 +00:00
def print screen:&:screen, n:&:_elem -> screen:&:screen [
local-scope
load-ingredients
2016-09-17 17:32:57 +00:00
color:num, color-found?:bool <- next-ingredient
{
# default color to white
break-if color-found?
color <- copy 7/white
}
2016-09-17 17:32:57 +00:00
bg-color:num, bg-color-found?:bool <- next-ingredient
{
# default bg-color to black
break-if bg-color-found?
bg-color <- copy 0/black
}
2016-09-17 17:28:25 +00:00
n2:num <- copy n
screen <- print screen, n2, color, bg-color
]