Building a Better Terminal

2015-08-12 10:22

Building a Better Terminal

First, let's start with a bit of background.

I like using a terminal / console. The direct interaction and expressiveness that a command line gives me is very powerful, and efficient. I'm writing this post in vim, using restructured text. I do all my file management in a console window, directly in the shell.

So when I think about what a 'better' terminal would be, I don't mean to replace it with something that fundamentally changes the interaction model. For some, a better terminal would be more like a notebook, with rerunable, editable commands, able to embed images, links, and videos. Interactable with a mouse. That escapes the bounds of what I believe to be generally useful as a replacement for existing terminals. (The IPython Notebook is a very good example of something that is 'like' a terminal, or interactive console, but serves a different purpose and audience.)

All that being said, there are definitely limitations of current terminal emulators that I believe are worth addressing. They fall into a couple of broad categories, with some basic requirements:

  • Robust multilingual / Unicode support
    • Support of the entire range of Unicode codepoints, not just the BMP.
    • Gridded / Monospace rendering, but with the ability to have graphemes span grid spaces (or potentially subdivide them) for legible rendering of different languages mixed together. (Full/half-width katakana, etc.)
    • Normalization of input code points and predictable editing behavior (backspace by grapheme, not code point, input/backspace of combining characters)
    • Configurable font support, including selection of alternate glyphs (important for legible mixing of unified Han ideographs used by multiple languages)
  • Escape sequences / Keyboard shortcut limitations
    • All commands to the terminal must be recognizable without timeouts.
    • All commands must be unambiguous.
    • All commands must leave the terminal in a usable state on failures.
    • Every keyboard sequence of the system must be detectable and usable by the software running on the terminal, they cannot be mistaken for commands to the terminal itself (unless the terminal is specifically configured to use the shortcut, in which case the shortcut must be entirely absorbed by the terminal and not passed to the software running on it.)
    • If a mouse is supported by the input system the terminal is connected to, then the mouse must be either completely unable to interact with the software on the terminal (only with the terminal itself), or the mouse is only able to interact with the software on the terminal, not able to control the terminal itself (when the terminal is focused, in the case of a window manager).
  • Formatting / Fonts / Color / etc.
    • Suport of color, including background color, must be capable of representing a full modern display, 24-bit color, with alpha. (Alpha may not be always useful, but it should be possible, as some compositing window managers can usefully apply it.)
    • Formatting must include normal font variants like oblique, bold, italic, small caps, etc. and not substitute 'bright' colors for these unless desired.
    • Kerning that respects the gridded nature of the terminal may be applied to enhance legibility, especially for symbols or in the case of languages with mandatory ligatures.

Note

These requirements are based on my usage, which is from the perspective of a software developer, with a native language of English, but an interest in correct and pleasant typography, linguistics, and mathematics.

Many of these requirements are born out of the usage of a modern terminal emulator and its environment, given the differences between the current usage and the historical context in which the terminals were developed.

A modern terminal emulator is a piece of software responsible for interacting with the I/O system in some fashion (either through a graphical environment like X, through a kernel primitive like Linux's CONFIG_VT, etc.) and interacting in a specified way with software run on that terminal. It functions as a basic API layer for certain kinds of software.

This is different than the historical usage, which was that a terminal was a device attached to a computer (generally over a serial line) that provided access to the computer, generally a multi-user machine. As such, the I/O system was only able to communicate in-band over a stream of bytes, generally, and many of the limitations of current terminal emulators are a direct result of this arrangement.

Even in the case of a remote terminal, we now have much higher bandwidth in most cases, so a more robust terminal protocol, between software and the I/O system is desirable. Additionally, given no compatibility constraints, we can define an out-of-band mechanism for control of the terminal, rather than needing to rely on a complex and ambiguous stream of bytes for all communications.

I don't have a clear idea of a design, I am only outlining what I feel are the requirements of a 'better' terminal.

Thanks for reading.