Building Rich Terminal Dashboards
willmcgugan.com
willmcgugan.com
This is sad because Will writes great posts[1] and great software[2], but somehow his submissions mentioning Rich tend to end up dead. Would it be a case of bad project name for HN titles?
[0] https://news.ycombinator.com/item?id=26147831
(Bit of a bee in my bonnet because I never like Title Case In Submissions Even If The Article Itself Uses It anyway, but it's especially unfortunate here.)
Rich is really great. It didn't actually need us to add much to make it work as a terminal layout manager too - all the pieces were really there already for us to build on.
Let me know if you have any questions about our experiences with Rich and ghtop.
Except for CAD applications and some games, almost everything we do online today could be accomplished via textual UI. Almost the entire internet could be replaced with TUIs and a lot of things would be better and more straightforward, and nearly everyone would be able to do what they need to do online.
TUIs are fast, they are light, they are ultra responsive and ... Yeah. They're definitely underrated. They're probably a lot easier for screen-readers, too.
I'm not suggesting that we undo everything and make a TUI web, but I do want to point out that we do a hell of a lot on today's UIs that we don't need to do, solely because some designer who wants to make pretty things that function poorly said so.
But like you, I wish we had more options to fully exercise the power of a TUI much closer to the metal, like the old days. Apps where almost every keystroke completes an operation faster than the fastest typist can move from key to key....
Of course, beyond a certain speed, more speed wouldn't matter, so maybe I could get it by installing a (local, not remote) desktop Linux without any GUI and using only CLI dev tools. Is anyone doing this?
After I get bored, I do either `sudo init 7` to be sure, but mostly just Ctrl-Alt-F1, which brings me back to my graphical shell.
This method has the advantage that you are always on the same system, not needing anything else. Oh, also the music works, if you don't kill the GUI with the first `init` call.
Coupled with tmux, emacs/vim, nvlc, lynx, and coreutils, you can really be more productive there, from the extra speed, less memory requirements, and less available distractions.
EDIT: I could not find the actual link to the library either on HN or in the OP, so I am linking it here [1], for the convenience of myself and others.
The modern systemd equivalent is:
systemctl isolate multi-user
> sudo init 7 […] which brings me back to my graphical shell. systemctl isolate graphical
or systemctl isolate defaultThe way people just replace things instead of addressing the issues in the old things bothers me.
init.d wasn't multithreaded. Ok, so give it threads. Etc.
My workstation defaults to booting into the equivalent of run-level 3 (no display manager) and when I get tired of being in text mode, I just run `startx` for the graphical interface.
In it, Mr Murray live-codes a simple program to display all 256 characters in the C64's character set, by directly poking them into video memory (that's close to the metal, right?).
Once in BASIC, and once in machine code, to show the contrast in speed. It's pretty impressive even now, and that's running on a 1-MHz 8-bit processor. :)
As an application developer, you'd certainly be much more in tune with how well your application is performing if you could feel a dip in performance the way I remember feeling it when a TUI wasn't responding quite as quickly as it was a few seconds earlier. Giving users insight into your application's performance is a good thing, because I think we put out and put up with unreasonably slow software far too often these days.
TUIs (as currently designed) have no structure, so it's very difficult to move around from section to section. A website with headers and auto-wrapping text is much easier to move around and read with a screen reader.
And I might add, it's the oldest web browser still being maintained. Since 1992.
The irony is of course that Unix-like OS vendors spend so much time fighting each other that it was basically mutually assured destruction, and proprietary Unix systems went the way of the dinosaur after the dot com crash.
I call bullshit on this.
Using fixed character cell grid for UI absolutely wastes ton of space. First of all just basic text takes more space in fixed-width than variable width. But the biggest offender is any layout or ui elements that would not need whole cell. Even basic 1px horizontal line takes 10px of height or whatever. Places where 1 or 2 px padding could do will use full cell instead.
And then there is of course the space waste from forcing all text to be same size. For tons of applications the UI elements could do with smaller font than content, but none of that is possible with TUI.
I find your example of hiding scrollbars hilarious, considering that TUIs are in general far worse offenders in that area specifically. For example none of the examples for Rich here show scrollbars..
I do also believe that in terms of performance TUIs leave lot on the table, because they are forced to go through all sort of weird legacy layers. Pushing pixels on screen and receiving key events directly almost certainly should be faster/more efficient than going through tty layer and terminal emulation.
Why do you think it needs to be faster? Do you currently have issues with complexity or latency? Have you measured it? Do you think that replacing the current abstractions with new abstractions will really be a net improvement?
A terminal emulator is pretty much the least non-trivial resource-intensive graphical application I can think of. I've been running Linux on the desktop for over two decades and can't think of a single time I thought the terminal emulator I was using at the time was too slow. (Which is why I don't really understand the need for CPU-accelerated terminal emulators, but that's a different kettle of worms.)
This is not true; there is an underline attribute which can add a ~1px horizontal line without taking up any additional space.
That might be true for more minimal TUIs, but I don't think most screen-readers can handle the multi-paneled ones like OP.
Emacs as a platform is a good example here - the TUI that you can achieve in it is similar to web GUIs made of standard components - in the the UI isn't just pixels on a 256-bit canvas, but it's made of building blocks that you can inspect, select, copy, and that gracefully enhance/degrade when you switch between graphical and terminal modes.
It's reinventing the wheel, but a car tire is a welcome improvement to a wooden wagon wheel.
https://github.com/magiblot/turbo
Applications like tvedit were designed for MS-DOS, which offered full interaction with the mouse and keyboard, and many of them were commercial products aimed at a general audience. TUI applications from the Unix tradition, however, were designed for use in terminals with limited capabilities, and were aimed at more technical users (or were created by the users themselves).
User-friendly TUI applications in MS-DOS were succeeded by Windows applications, while the largest revolution in the last 20 years in Unix TUIs has been the widespread support of 256/24-bit colors and UTF-8. Hence the gap in usability between the two worlds.
I certainly get that a good library yesterday might not be good today or that an existing library's style might not meet this language's style but I doubt the need to rewrite existing libraries so often. Even with the much-maligned PHP, libraries were frequently bindings to other libraries.
A unix command named 'topify' which allows you to create a pipeline of stdio into a top-like, updating, single screen output.
So, let's say you have a command with multiple lines of output - like netstat or certain airport commands - but instead of doing silly things like I do now:
while true ; do airport -s ; sleep 10 ; tput clear ; done
... I could `topify airport -s` and I would just get a nice, single page, constantly refreshing output summary.There are a LOT of commands I wish I could 'topify' from time to time ...
Thank you!
I used to have an IBM 3151 terminal on my desk (I wish I could afford a 3278/9 or 3290) connected over 9600 bps to my workstation. It's a great to remind me to keep things simple.
Also, not all terminals have uniform coverage for ANSI codes. Apple's Terminal.App does a good job with double-width and double-height, but lacks the SGR 53 overline that VTE, Konsole and Microsoft Windows Terminal have (and that makes status lines so much better).
Nowadays, terminals have no problem with mouse support, which everyone can test by starting htop in a terminal and clicking with a mouse on a column title to sort by it.
https://github.com/reflex-frp/reflex-vty#reflex-vty
One thing neither of these libraries appear to have done yet that I would really like is create a more compact window rendering. Currently each window gets a 1-character border. What I would like is something that saves space by collapsing adjacent windows' borders into a single character instead of having two redundant borders next to each other. Of course I get why they do it the way they do, but terminals are often more constrained for space and with complex UIs you can lose a fair amount due to these unnecessary borders. That would be the next thing I'd hack on to improve these kinds of libraries. But alas...too many fun projects to hack on and not enough hours in the day.
However, they could be implemented as an extension to Rich in another library.
Did you have something in mind?
[1] https://news.ycombinator.com/item?id=14405186
[2] https://github.com/chjj/blessed
[3] http://web.archive.org/web/20091011010412/http://www.vtsoft....
At some point, I used ImTui to create a more convenient way to create these .yml configuration files: wtf-tui [1]. I also made an emscripten port of wtf-tui for easy testing in the browser [2]
[0] - https://wtfutil.com
Being this simple looks enticing
Another option for full-screen apps is Python Prompt Toolkit[1], which also handles keyboard and mouse input and can be used to implement editors[2].
> prompt_toolkit 3.0 is completely type annotated and uses asyncio natively.
The rich source is also type annotated and very clean and readable.
[0] https://github.com/chjj/blessed
https://vadimdemedes.com/posts/ink-3
It lets you write React CLI apps using a flexbox layout engine, and is used by a number of high-profile node projects.
And, terminal emulators such as iTerm can nowadays display images. And vector or bitmapped graphics were actually a thing once. E.g. I believe xterm can still understand and display https://en.wikipedia.org/wiki/ReGIS graphics. Surely there must be better and simpler alternatives that I may be missing. Having an empty canvas and drawing to it without too much hassle is reminiscent of the era when this was done with a few lines of BASIC.
If you want to create charts quickly there's also: https://github.com/FedericoCeratto/dashing
Would you consider adding an integration for Rich?
In theory it should be possible to have your charts object also work within a Rich layout, using the Console Protocol.
(Thanks to @joseluis who posted about notcurses here)
Architecturally however, I think terminal primitives and widgets should be separate layers/packages.
That being said, working in the CLI with a GUI does not work very well.
Having the option to search for strings logged in some pages ago is really handy.
[1] https://www.npmjs.com/package/pkg [2] https://github.com/marcelotduarte/cx_Freeze
#!/usr/bin/fades
https://github.com/PyAr/fades#what-is-fadesBut similarly to with Python, it still requires you have the runtime installed along with any packages your thing depends on
Check https://github.com/fdehau/tui-rs for example.
As a user I’m just encouraging people not to use an interpreted language to build tools you plan to distribute.
I've always wanted to create something like vtop but for network and disk io, this might finally let me do it myself.