The basic listener is very minimalistic. There are a few reasons for this.
• I don't use it often (I generally code in files or blocks,
using the listener only for brief tests)
• A complex listener adds surface for bugs and incompatibilites
due to terminal and host configurations
• It's harder to pipe data in and out of a more complex listener
This can be worked around in a number of ways. Tools like rlwrap can be used to provide a line editor and history, and one can always write their own custom listener...
But sometimes it's nice to experiment a bit. This is a modestly expanded version of the listener, adding some new functionality and providing a more flexible base to build on.
• character breaking input
• suggestions on hitting TAB
• show stack on hitting ESC
• use retro-describe to get help on CTRL+K
retro -i -f alternate-listener.forth new-listener
The listener needs to determine what to treat as the end of the token. I define end-of-token? for this.
It's possible to get an empty string as an input. This isn't any good, so I define s:blank? for this.
There are certain keys I want to handle differently from others. The initial ones are backspace, tab, escape, and CTRL+K. I am defining handlers for these.
First is backspace. I trap ASCII:BS and ASCII:DEL for this.
Tab is used to display suggestions, based on the token input so far.
Control + k (ASCII:VT) will display help for the word being typed. This assumes that retro-describe is in your $PATH and that the typed text is a complete word name (without a sigil).
The escape key will be used to display the stack.
To control the checks, I define two words. The first returns an array of handlers, the second processes them.
And with these, I can quickly implement the new-listener.
All of the exposed words are hooks: your code can patch in and replace them as you see fit, making this much more mallable at runtime.
Future things to (maybe) explore:
• tab completion
• line editing
• input history