Terminal Vs Tui

21 Jan 2024 - Ben

For a long time I’ve loved using the terminal, but couldn’t quite figure out what I liked about it. Things I did all the time I could make faster relatively easily, mostly. Not all software was that way though, even on the terminal. What was the difference between the software that I could automate away for my daily tasks and the ones I couldn’t? The ones that had Command Line Interfaces (CLIs) vs Text-based User Interfaces (TUIs). I wanted to like Text-based User Interfaces (TUIs) because they were on the terminal, and the terminal made things easier for me, past the initial learning curve. But the two have very different user philosophies, even though they both run in the same place. The largest different, I’ve decided, is the captive interface.

Command Line Interface

A CLI has no captive interface. It takes your command as input and spits out output. This allows it to be easily used in scripting and extended to a users content. Add goodies like aliases in there, and you can redefine how most of these work for you, simplifying and streamlining common workflows for yourself. The “for yourself” is important. Designers didn’t have to create the perfect experience for you. They gave you tools that made it easy to create the perfect experience for yourself.

My favorite types of CLI tools? Non interactive, plain text (easily parsable) output, and the most useful ones conform to the Unix philosophy Point 2:

Expect the output of every program to become the input to another, as yet unknown, program. Don’t clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don’t insist on interactive input.

A great example of this that I use every day is a git alias: git logo which expands to git log --oneline; it’s 8 characters instead of 17 and for the amount I type it every day, probably saves me hundreds of key strokes a month (and many typos, --oneline is tough for me for some reason). Another example is git delete-gone; it strings together a few git commands and grep to delete branches that have been deleted from the origin remote. I don’t even know what command it exactly runs without looking at it, but it’s a task I know how to do.

Text-based User Interface

On the other hand, TUIs, or CUIs (captive user interfaces), are typically keyboard and menu driven experiences that don’t script well. It’s meant for user interaction, often offering fewer keystrokes to accomplish a goal (maybe reading email), but makes it less extensible. Keybindings can usually be reconfigured, but you can’t connect it with other applications.

The Inbetween

There are a few tools that change how they behave in respoinse to their environment. Don’t supply the flag, but the tool needs that information? It will ask for it interactively. An old example is apt install, where you are then prompted if you want to install the found software, but you can pass a -y flag to ignore this prompt and run the whole command noninteractively.

A better example is ripgrep, where it will default to pretty printing in your terminal, but has a plain text mode and other formatting options that make it more suitable for scripting. It does some checks to pick the best method by default and provides flags to override.

Github’s cli tool is another good example, supply the -b flag and a body and it won’t ask for one. Don’t supply one and you get an interactive question in your terminal. I haven’t poked around enough to know if you can turn off all the questions, even without supplying the flags, but it’s a very lightweight interface I appreciate when opening PRs.

Possibly somewhere inbetween are server-client memory models like tmux or kakoune which are used interactively but have detached modes where commands can be sent via a CLI. I like these best because they offer the interactivity of a CUI with the scriptablitly of a CLI. How are these systems built? I have no idea, but it’s something I plan on exploring.

These “inbetween” softwares demonstrate that software transcends a single philosophy and can pragmatically support multiple, which can provide more users a better experience while keeping the familiarity between modalities. Software that works best for all users is the best kind of software.