mu/081print.mu

915 lines
24 KiB
Plaintext
Raw Normal View History

# Wrappers around print primitives that take a 'screen' object and are thus
# easier to test.
#
# Screen objects are intended to exactly mimic the behavior of traditional
# terminals. Moving a cursor too far right wraps it to the next line,
# scrolling if necessary. The details are subtle:
#
# a) Rows can take unbounded values. When printing, large values for the row
# saturate to the bottom row (because scrolling).
#
# b) If you print to a square (row, right) on the right margin, the cursor
# position depends on whether 'row' is in range. If it is, the new cursor
# position is (row+1, 0). If it isn't, the new cursor position is (row, 0).
# Because scrolling.
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
pending-scroll?:bool
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
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
2017-12-04 07:25:40 +00:00
load-inputs
2015-11-19 05:36:36 +00:00
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, false/pending-scroll?, 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? stash [fake-screen-is-empty?]
return-unless screen, 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 false
}
return true
]
2016-09-17 19:55:10 +00:00
def print screen:&:screen, c:char -> screen:&:screen [
local-scope
2017-12-04 07:25:40 +00:00
load-inputs
color:num, color-found?:bool <- next-input
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
}
2017-12-04 07:25:40 +00:00
bg-color:num, bg-color-found?:bool <- next-input
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 or past right margin, wrap
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
{
at-right?:bool <- greater-or-equal column, width
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 at-right?
column <- copy 0
*screen <- put *screen, cursor-column:offset, column
row <- add row, 1
*screen <- put *screen, cursor-row:offset, row
}
# }
# if there's a pending scroll, perform it
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
{
pending-scroll?:bool <- get *screen, pending-scroll?:offset
break-unless pending-scroll?
#? stash [scroll]
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
scroll-fake-screen screen
*screen <- put *screen, pending-scroll?:offset, false
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
}
#? $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, wrapping as necessary
# however, don't scroll just yet
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
column <- add column, 1
{
past-right?:bool <- greater-or-equal column, width
break-unless past-right?
column <- copy 0
row <- add row, 1
past-bottom?:bool <- greater-or-equal row, height
break-unless past-bottom?
# queue up a scroll
#? stash [pending scroll]
*screen <- put *screen, pending-scroll?:offset, true
row <- subtract row, 1 # update cursor as if scroll already happened
}
*screen <- put *screen, cursor-row:offset, 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
*screen <- put *screen, cursor-column:offset, column
]
def cursor-down-on-fake-screen screen:&:screen -> screen:&:screen [
local-scope
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
{
overflow?:bool <- greater-or-equal row, height
break-unless overflow?
row <- subtract height, 1
}
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
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
13:bool/raw <- get *fake-screen, pending-scroll?: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
]
2017-06-24 14:45:35 +00:00
# cursor column wraps but the screen doesn't scroll yet
2015-06-16 22:30:43 +00:00
memory-should-contain [
10 <- 1 # cursor row
2017-06-24 14:45:35 +00:00
11 <- 0 # cursor column -- outside 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
12 <- 0 # top-idx -- not yet scrolled
2017-06-24 14:45:35 +00:00
13 <- 1 # pending-scroll?
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
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
2017-12-04 07:25:40 +00:00
load-inputs
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
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
2017-12-04 07:25:40 +00:00
load-inputs
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
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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
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
2017-12-04 07:25:40 +00:00
bg-color:num, bg-color-found?:bool <- next-input
{
# 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
2017-12-04 07:25:40 +00:00
load-inputs
{
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
2017-12-04 07:25:40 +00:00
load-inputs
#? stash [move-cursor] new-row new-column
{
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
# if cursor column is within bounds, reset 'pending-scroll?'
{
width:num <- get *screen, num-columns:offset
scroll?:bool <- greater-or-equal new-column, width
break-if scroll?
2017-06-24 14:45:35 +00:00
#? stash [resetting pending-scroll?]
*screen <- put *screen, pending-scroll?:offset, false
}
]
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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
#? 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
2017-12-04 07:25:40 +00:00
load-inputs
color:num, color-found?:bool <- next-input
{
# default color to white
2015-07-29 21:37:57 +00:00
break-if color-found?
color <- copy 7/white
}
2017-12-04 07:25:40 +00:00
bg-color:num, bg-color-found?:bool <- next-input
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
2017-12-04 07:25:40 +00:00
load-inputs
color:num, color-found?:bool <- next-input
{
# default color to white
2015-07-29 21:37:57 +00:00
break-if color-found?
color <- copy 7/white
}
2017-12-04 07:25:40 +00:00
bg-color:num, bg-color-found?:bool <- next-input
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
2017-12-04 07:25:40 +00:00
load-inputs
color:num, color-found?:bool <- next-input
2017-01-22 20:10:38 +00:00
{
# default color to white
break-if color-found?
color <- copy 7/white
}
2017-12-04 07:25:40 +00:00
bg-color:num, bg-color-found?:bool <- next-input
2017-01-22 20:10:38 +00:00
{
# default bg-color to black
break-if bg-color-found?
bg-color <- copy 0/black
}
{
break-if n
screen <- print screen, [false], color, bg-color
}
{
break-unless n
screen <- print screen, [true], color, bg-color
}
2017-01-22 20:10:38 +00:00
]
2016-09-17 19:55:10 +00:00
def print screen:&:screen, n:&:_elem -> screen:&:screen [
local-scope
2017-12-04 07:25:40 +00:00
load-inputs
color:num, color-found?:bool <- next-input
{
# default color to white
break-if color-found?
color <- copy 7/white
}
2017-12-04 07:25:40 +00:00
bg-color:num, bg-color-found?:bool <- next-input
{
# default bg-color to black
break-if bg-color-found?
bg-color <- copy 0/black
}
2018-06-17 18:20:53 +00:00
n2:num <- deaddress n
screen <- print screen, n2, color, bg-color
]