6794 - cleaner interface for keyboard
So far I've been assuming that read-key only works for ascii, and that I'd need to get more sophisticated both for multi-byte utf-8 and multi-byte terminal escape codes like arrow keys. Rather to my surprise, both work fine. We just need to adjust the types to reflect this fact.
This commit is contained in:
parent
797c93e054
commit
e403d15732
|
@ -119,15 +119,22 @@ $enable-keyboard-type-mode:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
read-key-from-real-keyboard: # -> result/eax: byte
|
||||
# read keys or escapes up to 4 bytes
|
||||
#
|
||||
# fun fact: terminal escapes and graphemes in utf-8 don't conflict!
|
||||
# - in graphemes all but the first/lowest byte will have a 1 in the MSB (be
|
||||
# greater than 0x7f)
|
||||
# - in escapes every byte will have a 0 in the MSB
|
||||
# the two categories overlap only when the first/lowest byte is 0x1b or 'esc'
|
||||
read-key-from-real-keyboard: # -> result/eax: grapheme
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
51/push-ecx
|
||||
# var buf/ecx: (stream byte 1)
|
||||
# var buf/ecx: (stream byte 4)
|
||||
68/push 0/imm32/data
|
||||
68/push 1/imm32/size # 3 bytes of data unused
|
||||
68/push 4/imm32/size
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
|
2
400.mu
2
400.mu
|
@ -161,7 +161,7 @@ sig hide-cursor-on-real-screen
|
|||
sig show-cursor-on-real-screen
|
||||
sig enable-keyboard-immediate-mode
|
||||
sig enable-keyboard-type-mode
|
||||
sig read-key-from-real-keyboard -> result/eax: byte
|
||||
sig read-key-from-real-keyboard -> result/eax: grapheme
|
||||
sig read-line-from-real-keyboard in: (addr stream byte)
|
||||
sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file)
|
||||
sig populate-buffered-file-containing contents: (addr array byte), out: (addr handle buffered-file)
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
init-screen-position-state screen-position-state, nrows, ncols
|
||||
{
|
||||
render file, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
compare done?, 0
|
||||
break-if-=
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
init-screen-position-state screen-position-state
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
}
|
||||
enable-keyboard-type-mode
|
||||
enable-screen-type-mode
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
init-screen-position-state screen-position-state
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
}
|
||||
enable-keyboard-type-mode
|
||||
enable-screen-type-mode
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
init-screen-position-state screen-position-state
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
}
|
||||
enable-keyboard-type-mode
|
||||
enable-screen-type-mode
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
init-screen-position-state screen-position-state
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
}
|
||||
enable-keyboard-type-mode
|
||||
enable-screen-type-mode
|
||||
|
|
|
@ -13,7 +13,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
init-screen-position-state screen-position-state
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
normal-text
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
normal-text
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
normal-text
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
normal-text
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
normal-text
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
normal-text
|
||||
{
|
||||
render fs, screen-position-state
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-screen-grid-mode
|
||||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, 5, 5, 30, 30
|
||||
var key/eax: byte <- read-key
|
||||
render file, 5, 5, 0x30, 0x30
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-screen-grid-mode
|
||||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, 5, 5, 30, 30
|
||||
var key/eax: byte <- read-key
|
||||
render file, 5, 5, 0x30, 0x30
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, 0x20, 0x30 # nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ fn main args: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
enable-keyboard-immediate-mode
|
||||
{
|
||||
render file, nrows, ncols
|
||||
var key/eax: byte <- read-key
|
||||
var key/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare key, 0x71 # 'q'
|
||||
loop-if-!=
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main -> exit-status/ebx: int {
|
|||
move-cursor 0, 5, 5
|
||||
print-string 0, "_________"
|
||||
enable-keyboard-immediate-mode
|
||||
var dummy/eax: byte <- read-key
|
||||
var dummy/eax: grapheme <- read-key-from-real-keyboard
|
||||
var row/eax: int <- copy 5
|
||||
{
|
||||
compare row, 0xe # 15
|
||||
|
@ -24,7 +24,7 @@ fn main -> exit-status/ebx: int {
|
|||
sleep 0 0x5f5e100 # 100ms
|
||||
loop
|
||||
}
|
||||
var dummy/eax: byte <- read-key
|
||||
var dummy/eax: grapheme <- read-key-from-real-keyboard
|
||||
enable-keyboard-type-mode
|
||||
clear-screen 0
|
||||
exit-status <- copy 0
|
||||
|
|
|
@ -63,14 +63,14 @@ fn interactive -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
}
|
||||
# render tree
|
||||
var _root-addr/eax: (addr cell) <- lookup root-handle
|
||||
var root-addr/ecx: (addr cell) <- copy _root-addr
|
||||
root-addr <- copy _root-addr
|
||||
var cursor-addr/eax: (addr cell) <- lookup *cursor
|
||||
render root-addr, cursor-addr
|
||||
loop
|
||||
|
@ -84,7 +84,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
$process:body: {
|
||||
# if c == 'h' move cursor to its parent if possible
|
||||
{
|
||||
|
|
|
@ -63,7 +63,7 @@ fn interactive -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
|
@ -84,7 +84,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
$process:body: {
|
||||
# if c == 'h' move cursor to its parent if possible
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ fn main -> exit-status/ebx: int {
|
|||
# wait for a key
|
||||
{
|
||||
enable-keyboard-immediate-mode
|
||||
var dummy/eax: byte <- read-key
|
||||
var dummy/eax: grapheme <- read-key-from-real-keyboard
|
||||
enable-keyboard-type-mode
|
||||
}
|
||||
# clean up
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
fn main -> exit-status/ebx: int {
|
||||
clear-screen 0
|
||||
enable-keyboard-immediate-mode
|
||||
var dummy/eax: byte <- read-key
|
||||
var dummy/eax: grapheme <- read-key-from-real-keyboard
|
||||
draw-box 5, 5, 0x23, 0x23 # 35, 35
|
||||
sleep 0 0x5f5e100 # 100ms
|
||||
sleep 0 0x5f5e100 # 100ms
|
||||
|
@ -17,7 +17,7 @@ fn main -> exit-status/ebx: int {
|
|||
sleep 0 0x5f5e100 # 100ms
|
||||
sleep 0 0x5f5e100 # 100ms
|
||||
draw-box 5, 5, 0x23, 0xaf # 35, 175
|
||||
var dummy/eax: byte <- read-key
|
||||
var dummy/eax: grapheme <- read-key-from-real-keyboard
|
||||
enable-keyboard-type-mode
|
||||
clear-screen 0
|
||||
exit-status <- copy 0
|
||||
|
|
|
@ -31,7 +31,7 @@ fn main -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
|
@ -50,7 +50,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
var c1/eax: (addr handle cell) <- copy cursor
|
||||
var c2/eax: (addr cell) <- lookup *c1
|
||||
create-child c2
|
||||
|
|
|
@ -58,7 +58,7 @@ fn interactive -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
|
@ -77,7 +77,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
# increase depth by 1
|
||||
var c1/ecx: (addr handle cell) <- copy cursor
|
||||
var c2/eax: (addr cell) <- lookup *c1
|
||||
|
|
|
@ -62,7 +62,7 @@ fn interactive -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
|
@ -81,7 +81,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
var c1/ecx: (addr handle cell) <- copy cursor
|
||||
var c2/eax: (addr cell) <- lookup *c1
|
||||
create-child c2
|
||||
|
|
|
@ -62,7 +62,7 @@ fn interactive -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
|
@ -81,7 +81,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
var c1/ecx: (addr handle cell) <- copy cursor
|
||||
var c2/eax: (addr cell) <- lookup *c1
|
||||
create-child c2
|
||||
|
|
|
@ -60,14 +60,15 @@ fn interactive -> exit-status/ebx: int {
|
|||
$main:loop: {
|
||||
# process key
|
||||
{
|
||||
var c/eax: byte <- read-key
|
||||
var c/eax: grapheme <- read-key-from-real-keyboard
|
||||
compare c, 4 # ctrl-d
|
||||
break-if-= $main:loop
|
||||
process c, root, cursor
|
||||
}
|
||||
# render tree
|
||||
root-addr <- lookup root-handle
|
||||
cursor-addr <- lookup *cursor
|
||||
var _root-addr/eax: (addr cell) <- lookup root-handle
|
||||
root-addr <- copy _root-addr
|
||||
var cursor-addr/eax: (addr cell) <- lookup *cursor
|
||||
render root-addr, cursor-addr
|
||||
loop
|
||||
}
|
||||
|
@ -80,7 +81,7 @@ $main:loop: {
|
|||
# Tree mutations
|
||||
#######################################################
|
||||
|
||||
fn process c: byte, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
fn process c: grapheme, root: (addr handle cell), cursor: (addr handle cell) {
|
||||
$process:body: {
|
||||
# if c == 'h' move cursor to its parent if possible
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue