duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 08a37e59b842ffd9f80b9aaab6e6e0cefeaf8168
parent 3e6f4fbd3c0e9017ba8ed76216bcf2970fcc02c0
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 27 Jan 2023 22:43:47 -0500

sys/rdln: make ESC flush line without interpreting

Diffstat:
Mfs/doc/sys/rdln.txt | 25+++++++++++++++++--------
Mfs/sys/rdln.fs | 23+++++++++++++----------
Mfs/text/ged.fs | 3++-
3 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/fs/doc/sys/rdln.txt b/fs/doc/sys/rdln.txt @@ -6,9 +6,19 @@ Dusk's main loop endlessly consumes text coming from "console". If you plug your input (for example the keyboard device) directly on it, words will be executed as soon as you type a whitespace. This behavior is generally uncomfortable because we expect the system to consume what we type in a line-by-line manner. -We also want to have the opportunity to correct mistakes on that line before we -send it for interpretation. We also usually want to have some kind of prompt -(the "ok" prompt). That's what sys/rdln does. + +sys/rdln makes the console input have the following behavior: + +1. Buffer input without interpreting it immediately. +2. When we begin buffering a line, prompt with "ok\n". +3. Echo every character received. +4. When backspace (ASCII $08) is received, go back one character in the buffer + and emit backspace+space (unless of course we're at the beginning of the + buffer). +5. Replace CR (ASII $0d) keys with LF (ASCII $0a). +6. If ESC is pressed (ASCII $1b), flush the line and don't interpret it. +7. If any other ASCII control character is received (< $20), flush the line and + interpret it. It defines a Rdln structure as well as a re-implementation of the "main" routine (the routine that endlessly consumes words). @@ -37,11 +47,10 @@ so that EOF condition is never actually reached. Methods: -:readline ( self -- ) - Clear the buffer and type into it through sys/kbd's "key". When BS is - received and if we're not at the beginning of the buffer, we go back one - character emit SPC+BS. If we receive any other ASCII control char, typing - ends. After a :readline, "ptr" = "buf(". +:typeline ( self -- f ) + Clear the buffer and type into it through sys/kbd's "key", applying buffering + rules outlined above. f=1 if resulting line should be interpreted. f=0 if not + (ESC was pressed). After a :readline, "ptr" = "buf(". :reset ( self -- ) Set "ptr" to ")buf" so that the next "readbuf" call triggers :readline. diff --git a/fs/sys/rdln.fs b/fs/sys/rdln.fs @@ -6,21 +6,24 @@ create in( LNSZ allot here const in) : bs? BS over = swap $7f = or ; +: cr>lf dup CR = if drop LF then ; \ only emit c if it's within the visible ascii range : emitv ( c -- ) dup SPC - $5f < if emit else drop then ; -: lntype ( ptr c -- ptr+1 f ) - dup bs? if ( ptr c ) - drop dup in( > if 1- BS emit then spc> BS emit 0 - else ( ptr c ) \ non-BS - dup emitv dup rot c!+ ( c ptr+1 ) dup in) = rot SPC < or ( ptr+1 f ) - then ; extends MemIO struct[ Rdln - : :readline ( self -- ) >r \ V1=self - in( begin key lntype until ( a ) - dup V1 to )buf 1- LF swap c! in( r> to ptr ; + : :lntype ( c self -- f ) >r \ V1=self + dup bs? if ( c ) + drop V1 ptr V1 buf( > if -1 V1 to+ ptr BS emit then spc> BS emit 0 + else ( c ) \ non-BS + cr>lf V1 )buf V1 ptr - 1 = if drop LF then + dup emitv dup V1 :putc SPC < + then rdrop ( f ) ; + : :typeline ( self -- f ) >r \ V1=self + V1 buf( LNSZ + V1 to )buf V1 :rewind + begin key V1 :lntype until + V1 ptr V1 to )buf V1 :rewind r> )buf 1- c@ ESC <> ; : _readbuf2 ( n hdl -- a? read-n ) - dup :eof? if ." ok\n" dup :readline nl> then _readbuf ; + dup :eof? if begin ." ok\n" dup :typeline until nl> then _readbuf ; : :reset ['] _readbuf2 over ['] :readbuf sfield! dup )buf swap to ptr ; : :interpret ['] _readbuf over ['] :readbuf sfield! diff --git a/fs/text/ged.fs b/fs/text/ged.fs @@ -43,7 +43,8 @@ KEYS c@ wordtbl handlers :w $ffff edbuf :goright ; :w pagesz edbuf :goup ; :w pagesz edbuf :godown ; -:w _statusline rdln :readline _statusline rdln :interpret _top _top! ; +:w _statusline rdln :typeline _statusline + if rdln :interpret then _top _top! ; : ged 0 to _top begin _refresh key KEYS c@+ [c]? ( idx )