# Readline subsystem

Prerequisites: sys/io

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.

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).

To install it, you only have to call "rdln$", which installs itself at the
appropriate places:

1. Set the "abort" alias to its regular "(abort)" target (rdln is usually
   installed during boot, at which time "abort" points to a word that spits
   "boot failure" and halts the machine)
2. Change "main" to its own implementation, which resets the rdln buffer before
   starting the endless loop. This way, when we run "quit", the rest of the rdln
   buffer will not be ran.
3. Set "console readio" to the "rdln" structbind

After the "rdln$" call, the readline subsystem is active and you'll be prompted
for the first time.

## Rdln API

The Rdln structure extends MemIO to wrap the realine buffer. The sys/rdln unit
also defines a "rdln" structbind to it.

This structure overrides :readbuf so that when it's at EOF, it calls :readline
so that EOF condition is never actually reached.

Methods:

: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.
  Also, ensure that :readbuf is properly set (:interpret changes :readbuf
  binding temporarily, we want to change it back afterwards, or if an abort
  occurred during :interpret).

:interpret ( self -- )
  This is an override of IO :interpret. It temporarily changes :readbuf to
  MemIO's _readbuf so that we don't trigger :readline at EOF and thus allow
  :interpret to end at some point. This override also changes the
  ( self -- self ) signature to ( self -- ) because it's unlikely that "self"
  is still needed after a call to this version of :interpret, so we don't need
  that weirdness to propagate.
