Chasing the dream of a terminal-free CLI

TLDR; Crazy person is trying to do something about how nightmarishly bad the interface between you and the command-line/command-line utilities really is, i.e. getting rid of terminal protocols. 

 To start with ‘why’? If you have never had the pleasant experience of writing a terminal emulator, you might not have run into the details on how these actually work. As a user, maybe you have experienced a spurious ‘cat’ command with wrong input file turning your screen into unreadable garbage, or tried to resize a terminal window and wondered why it is so slow to react or being temporarily drawn with severe artifacts – but discarded such observations as mere annoyances. In fact, there are quite a lot of problems hiding under the surface that makes the command-line interface in unix- inspired systems less than optimal- and even unpleasant- to use. Instead of going into those details here, I’ll refer to this thread on reddit to save some time. Incidentally, this thread also happened to remind me that I did the grunt work for this already some two months ago; then forgot to tell anyone.

Context/Recap (feel free to skip): As part of the Arcan 0.5.2 work, the terminal frameserver was refactored and split into two parts: the terminal frameserver and arcan-shmif-tui. TUI here does not just refer to the common acronym ‘Text-based User Inteface’ but also the last part of the onomatopoetic form of the action of spitting saliva (rrrrrrpppptui, excluding any adjustments for locale). Frameservers in Arcan are a set of partially-trusted clients where each distinct one fulfills a specific role (archetype). There’s one for encoding/translating, another for decoding and so on. The idea was to have the engine be able to outsource tasks that are crash-prone or easy targets for reliable exploitation. One of the many goals with this design is to remove all media parsers from the main Arcan process, but also to allow these to be interchangeable (swap the default set out for ones that fit your particular needs) and act as services for other processes in a microkernel- like architecture in order to reduce the system-wide spread of dangerous and irresponsive parser use.

Back to business: The terminal frameserver was heavily based on David Herrmans libtsm, adding a handful of additional escape codes and integrating with font transmission/tuning/rendering, clipboard management, and the myriad of other features hidden inside the internal shmif- API.

Thankfully enough, libtsm neatly separates between the insanely convoluted state-machine required in order to act as a good little terminal emulator, and a virtual display which perform the whole cells/lines/metadata management that is sometimes rendered and queried.

Keeping the virtual display part around, the formula thus becomes:

TUI = [shiny new API] + [shmif- integration || XXX] + [tsm(display)] + [???]

This provides a building block for command-line driven applications that are not bound to the restrictions of the normal [terminal-emulator + sHell + application] threesome. Think of it as removing the middle man between the command line and the display server, but not being burdened by a full GUI toolkit. The core concept – text output, keyboard input – is maintained and lines or uniform ‘cells’ in a tight grid is still kept. You get the benefits of integrating with the outer system (window manager, …) when it comes to clipboard, multiple windows and so on, but not the complexity from toolkits or from implementing VT100 or other terminal protocols. It will also be possible to ‘hand the connection over’ to any program the shell would be running, providing a Plan9 like multiplex CLI style.

Wait, I hear you ask, won’t this actually introduce a gentle-push-off-a-cliff dependency to Arcan-as-a-Display-Server, break backwards compatibility with just about everything and in the process undermine-the-holiness-of-our-lord-and-saviour-UNIX-and-how-dare-you-I-love-my tscreenmux-bandaid-f-you-very-much-Hitler

Well, that’s something to avoid – don’t be evil and all that. That’s why there’s a “|| XXX” and a [???] in the formula above. The XXX can be substituted for some other rendering/display system integration API and the [???] to some ‘to be written’ backend that can output to the curses/terminal-esc-termcap war zone. It won’t be that hard and it’s not that many lines of code. It is much easier to multiplex metadata and data into holy output-stream matrimony again, than it would ever be to safely divorce the two.

To step back and be a bit critical to the while concept (but not really) – “is this actually something we need? We have a ton of awesome sparkling crisp UI toolkits and even that sweet Electr…”. What some of us (not necessarily all of us or even the majority of us) need is to get the f’ away from a world where everything needs GPU access and half a gigabytes of dependencies to download and draw a picture. That said, clinging to a world where you have to think “hmm was it -v as in ls, or as in pkill” may be a bit too conservative.

Anyhow, the current state is more than usable, although the API is still in the middle of its first iteration. Hey look, a header file! The terminal frameserver has been rewritten to use this API, so the features that was previously present in there (dynamic font switching, multi-DPI aware rendering, clipboard, unicode, and so on) are exposed. The code is kept as part of the main Arcan git for the time being,  but when things have stabilized, it will be split into a project of its own.

Small gains:

  1. Integration with window management: making life easier for keyboard cowboys and screen-readers alike, you no longer have to interpret a series of +-=/_+ (if the glyphs are even in the current font) as a popup or separator.
  2. Reliably copy and pasting things.
  3. Saving / Restoring State, Switching Locale, Modifying Environment – at runtime.
  4. Common interface for Open/Save/Pipe between otherwise isolated sessions.
  5. Audio Playback without /dev/dsp or worse.
  6. Drawing custom rasters into cells without Sixel.
  7. Emoji, free of charge – though debatable if that’s really a good thing.
  8. UI manageable alerts, not blinky-flashy-beepy-beepy.

(the list is really much longer but I’ll just stop here)


  1. Empower/Inspire people to find a new terminal-emulator liberated, efficient model for a future-ready shell, like NOTTY is doing.
  2. That the emergent patterns may one day be cleaned up and spit-polished into a protocol — pure, free and not relying on any code that I’ve touched.
  3. Peace on earth and good will towards men.
  4. That children never again have to lose their innocence by learning what setterm -reset is, or why it is, at times, needed.

Personal plans:

  1. Migrate Senseye translators to this.
  2. One day make a text/command-line oriented UI to gdb/lldb that doesn’t suck.
  3. Slowly forget what ESC, OSC, DSC,CSI etc. actually did.
  4. Make bindings for the more sensible of programming languages.
  5. Tricking someone else into maintaining it.
  6. TrueColor 60fps version of sl.

Intrigued?  Excited? Aroused? Care to Join in?

Bring out the KY, pour a stiff drink, swing by IRC, fork on Github – and have a Happy New Year.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s