1. 23
  1. 8

    This is a good talk, and I think it’s a positive that we’re getting more features in terminals. Far from being bloat, I find that better font handling helps me avoid eye strain; viewing non-ASCII text is actually possible (although sometimes still ugly); and I can eliminate tmux/screen, which I have always found annoying to configure and never perfectly ergonomic. Even frivolous-seeming features like ligatures can help make symbol-heavy languages like Rust more readable.

    1. 4

      The bloat crowd want to bloat terminals, too.

      No refuge for suckless types.

      1. 9

        What do you mean? In the open source world, there is pretty much always a refuge. And it’s not really the foundation for everything like say, the kernel or the init daemon ;)

        1. 6

          Minimal terminal programs continue to exist, so I don’t know why there is “no refuge”.

          In any case, the terminal is more than just a tool – it defines the range of possible interfaces available to command-line applications. Insisting that that range should remain narrow is more old-man-yells-at-cloud than it is a design philosophy, because it ultimately forces more program to drop into GUIs when the interaction they need exceeds what a VT220 provides.

          1. 3

            If you just require a minimum of VT240 support instead of VT220, you can have ReGIS graphics. So even sticking with 80es tech, you can do quite a lot.

        2. 3

          I was going to complain about the use of a video to show off text terminal emulators but this is well done!

          1. 2

            Some slides/similar would had been great, as I was too lazy to scroll back to double check some things, like the true color configuration & Emacs.

          2. 3

            This is a good presentation, but I find it funny how terminals want to shoehorn in what has been available in GUIs for a while.

            1. 9

              The terminal is still my most productive environment. Typing commands and little loops and globs and pipelines and whatever is inherently faster for me than any sort of GUI manipulation.

              This is especially true if you work across machines (again, for me). X and Plan 9 almost got remote graphical applications right, but it never quite worked seamlessly and it got to the point where it seems like people only ever use remote command lines and now most of the major OS’s have done away with seamless remote GUIs if they ever had them to begin with.

              Something that also would’ve improved my GUI experience, and which I hacked in to dwm years ago, is window swallowing. When I’m working in the terminal, writing my little loops and pipelines and availing myself of the power of the command line, when I launch a graphical text editor my attention is popped to another window.

              I realize this is what a lot of people want, but for me, the concept of the editor taking over the window I’m in makes so much more sense to me intuitively and makes context switching so much easier. Plan 9 did it and a few other GUIs did it but no mainstream ones do, and certainly not when dealing with remote graphical applications.

              1. 2

                I think it’s interesting to debate if this is right or not. I’m not a fan of using technologies in a way that it wasn’t indented, because I feel like it might always come back and bite you. People do crazy things with terminals, and even though it’s usually mostly aestethic, it breaks stuff for specifc users. I like to use the Emacs terminal, and therefore stick to non-interactive tools that avoid taking over the whole terminal or jumping around. It’s a minority, but good design shouldn’t be at anyone’s disadvantage. The concept of graceful degradation, as sometimes seen applied to websites, might be relevant here too. Not everything should have to work everywhere (most modern terminal emulators can’t plot graphics either), but assuming everything is a vt100 shouldn’t be the default either.

                1. 1

                  As a GNU Emacs user, I find it funny that I have way better control over my preferred OpenType font (JetBrains Mono) in my terminal than I do using the GUI version of the editor. I hate wide spacing between letters in monospace fonts, so I like to adjust the kerning to scrunch the letters together. Try this in Emacs, you’ll find you can’t, regardless if you set the :width to condensed, semi-condensed, or ultra-super-mega-condensed. Also try configuring ligatures, sylistic sets, or the fallback behavior – those kind of detailed font tweaks aren’t exposed by Emacs, yet they are in certain terminal emulators.

                  1. 3

                    There is something to be said for having a minimal protocol between the “GUI Server” (frontend) and the backend ;) But doesn’t seem like Display PostScript is coming back, so we’re stuck with the terminal.

                    1. 2

                      Not with that attitude. I’ve been seriously considering using a DPS derivative to solve the problem of the hideous and useless terminal (but don’t hold your breath).

                      I still don’t understand why there’s been so little (re)invention in this area, save for game engines. Once you gain some basic understanding of how GUI libraries are put together, it is fairly straight-forward to reimplement them given a text shaping/rendering engine and a rasterizer, such as Pango with Cairo (the latter itself a derivative of Postscript, just like HTML canvas’ 2D context).

                      Misusing a Unix terminal as a GUI server doesn’t make it easy to create user interfaces, despite expectations.

                      1. 1

                        Years ago I wrote an experiment where the terminal could be flipped into a special mode via escape sequence that would then accept a Lua script, and would flip the window to a Cairo-based canvas that was manipulable via Lua.

                        The experiment “worked” but it turns out I’m really bad at GUI programming, especially at such a low level. But it was a neat experiment.

                        I’m curious what your DPS derivative would look like? DPS is neat.

                        1. 1

                          It’s a shame that no such experiment has really “seen the light of day”, except for one web-based prototype.

                          There are quite a few choices in this area, so me saying “derivative” mostly hints at there being a possible need for divergence. I haven’t really had a close look at DPS, so I take it mostly as a concept, as I have intimate knowledge of Cairo and the two are nearly the same thing.

                          If you have some sort of canvas, you can start with a Widget:

                          • abstract get_size()
                          • abstract render(context)
                          • abstract on_key(key, state)
                          • abstract on_mouse*(x, y, state)

                          Define a container such as VerticalBox:

                          • children[]
                          • heights[]
                          • private recalc(): ask each children for how high they want to be etc.
                          • render(): iterate through children, translate origin, possibly clip, save state, call their render method, restore state
                          • on_key(): find which child has keyboard focus and forward the event, possibly bubble up
                          • on_mouse*(): see what child could contain the given point

                          Perhaps a Button:

                          • text
                          • private depressed
                          • abstract on_click()
                          • get_size(): measure the text, add padding
                          • render(): clear with background colour, draw ridge, measure the text, render it in the center, adjust if depressed
                          • on_key(): call on_click() if the key is Enter/Space
                          • on_mouse(): toy with depressed, maybe call on_click(), invalidate the widget’s region

                          It’s all rather simple like this. It will take some time but it doesn’t require deep thought to get it working.

                          The context passed to the render method just queues/forwards DPS commands. Fonts can either be rendered on the client and glyphs cached on the server (XRender method, undesirable here), or you need to have a backwards channel to query font properties–if you ban scaling or rotation transformations and stick to translations only, it won’t depend on DPS state, and if you disregard ligatures and other nice-to-haves, you can shape it yourself trivially.

                          What’s hard is how to make this work in a non-hierarchical way, which I don’t think I need–a vector graphics alternate screen is fine for me, and it is possible to make a graphical shell with this–you can have parts of the screen emulating a vt100 and parts of it either retaining some DPS output or running an application–a graphical tmux is quite possible. It should also be possible to do things like embed text editors–this is extremely desirable. In general, most issues are about conceptual design.

                          What’s nice is that if these GUIs run in a mode, you can throw terminfo and other terrible legacy burden over the wall.

                          1. 1

                            What do you think about having the terminal be a Wayland compositor, that will place windows below where you started them? Then you won’t have the problem of having to integrate with every graphics API.

                            1. 1

                              Wayland adds ridiculous levels of complexity and the subwindows become completely opaque.

                              With DPS you can impose arbitrary high-detail scaling and even have a universal text selection mechanism.

                              It could be added as an optional feature, though.

                2. 1

                  The terminal in Google Chrome(OS) supports some modern features too, including the iTerm2 OSC 1337 sequence for images: https://chromium.googlesource.com/apps/libapps/+/master/nassh/doc/FAQ.md#how-do-i-view-images

                  1. 1

                    Here are two (canonical) traits that (among others) make up a terminal:

                    • It can only display characters.
                    • All characters have the same width.

                    These traits are regarded as strengths rather than shortcomings because they lower complexity. The lower complexity should turn out as qualities like reliability, longevity, (cross platform) compatibility, small bandwidth (characters not pixels), insignificant rendering delays, reduced effort for implementing a user interface, manageability of user interface code by a single/few person(s) even for complicated use cases…

                    … all while covering a fair amount of all possible application use cases and enabling automation on top.

                    The more you disregard these traits, the more you loose the qualities. Letting the terminal be the terminal is (at least in my view) not some obsession with a glamourised past but a commitment to a functioning future.

                    1. 1

                      A few case by case examples to my statement from above:

                      • Do ligatures belong in terminals: Yes, seems legit.
                      • Should terminals enable UTF-8 PUA (Private User Are) for icons: I… don’t know ? Maybe yes. But any software should work well without it.
                      • Scrolling with the mouse wheel: Yes, as long as keyboard based scrolling works well too.
                      • Coloring and inline styling (italic, bold etc.): Sure, but again, any software should work well without it.
                      • Terminals with GPU rendering: If the aim is to display motion more fluid then I’m in. If on the other hand software starts to require a GPU-based terminal (something like an ASCII-video player), then no.
                      • Images/pixel graphics capabilities in terminals: No. Use a GUI program for that.
                      • Non fixed width font rendering: No. Use a GUI program for that.
                      1. 1

                        All characters have the same width.

                        If only. What’s more, wcwidth() can differ between the application, the terminal and the font.

                        1. 1

                          Yeah, you’re absolutely right. And that’s exactly where the complexity starts to increase :-)

                          At least the monospaced fonts are not as complicated as proportional fonts. AFAIK monospaced fonts keep the main grid of regular characters, right ? So all wider than regular characters use a multiple of the space of a regular character. Or doesn’t even this ideal hold true ?

                          Out of curiosity: how serious is the wcwidth problem ? Do you know an insightful resource on the topic by any chance ?

                          1. 2

                            Monospace fonts should use the same width for all glyphs, or twice that width.

                            New additions to Unicode, i.e., what hasn’t been covered by older tables, can cause problems. E.g., if you add emoji to the private use area, you will be disappointed. Also, I’m not sure if some characters haven’t switched category.

                            There is a set of characters that may take either a single cell or two cells (also called half-width or full-width, just to mess with you), see https://www.unicode.org/reports/tr11/tr11-36.html

                            These are mostly corner cases. Low likelihood of running into this.

                            In general, monospace fonts are a bit simpler but not by far. Asians and Unicode will destroy your assumptions.

                            To retain some sanity, you can limit yourself to languages using the latin, cyrillic or greek alphabet.

                            1. 1


                              I proxy learned some Unicode lingo too:

                              • characters (refers to meaning) vs. glyphs (refers to appearance)
                              • half-width (means 1 cell) vs. full-width (means 2 cells)