1. 52
    1. 24

      I’m the author of a terminal emulator so I regret to say that I know far too much about this cursed subject.

      I’ll start with saying this article is excellent. There is no “but” to that, I just want to add some extra information in case Julia (big fan, by the way) or anyone else is interested. I’d also like to ask for feedback: as the author of a terminal emulator, I’d love to hear from anyone on ideas to improve things. One thing I’m immediately thinking based on this article is: I need to make minimum contrast better and more obvious that it exists. I’m noodling on it. But happy to hear anything else.

      A note on TERM: by setting it to xterm (or frequently xterm-256color), you’re effectively telling whatever is running that the terminal running supports all the features of xterm. This does get you pretty colors usually but you will also sacrifice some modern features that programs MAY (but shouldn’t) use “TERM” for: Kitty keyboard protocol, synchronized output, styled/colored underlines, and more. Admittedly, if you’re SSHing into a machine, these may not be very useful anyways so it’s fine but just so you know if you’re using a modern terminal some stuff may stop working.

      I said above “MAY (but shouldn’t)”, so what should they do? The most modern well supported thing to do is XTGETTCAP. This is more or less terminfo but via VT sequences instead of an environment variable and local database. As a result, it works over SSH and without any SSH config madness. Besides XTGETTCAP, some sequences (like Kitty keyboard protocol and synchronized output) have feature test sequences that noop on unsupported terminals.

      Did I say cursed subject? Cursed subject.

      Beyond that, I’m trying to help this subject slightly: my terminal provides a terminal inspector (grep “inspector”) which is like a “web inspector.” You can hover over cells and see exactly what color they are set to (both RGB and palette numbers). You can also see things like the active palette. I mainly want to help answer the question “why the #&!* is this cell this way?” (amongst other questions).

      So to close it out: I’d love to hear any ideas people have for improving this. I too want people to more easily get things “zero config” out of the box that just works. I think finding a way to make minimum contrast work by default without being jarring is one thing I’m thinking about. But I’m open to other ideas, too.

      And again, big fan of Julia Evans!

      1. 12

        Thanks for the kind words – the Ghostty terminal inspector feature looks so useful! Having it be read-write in the future really feels like a gamechanger for understanding how the terminal works, it really makes me want to check out Ghostty.

        One thing I’ve noticed while trying to debug my colorschemes over the last couple of days is that I use a lot of different terminal applications, and it’s very hard to keep track of which ANSI colours all of those applications use – a common pattern for me in the past is that I’ll try a new colorscheme, and then I’ll be unpleasantly surprised a week later when I realize that some important terminal application clashes with that colorscheme.

        An idea for how to address that is to have the terminal somehow monitor all of the ANSI colours that I use over time in various applications, and when I’m considering a new colorscheme then somehow generate for me a theme preview for that colorscheme that actually matches my real-world terminal usage. Or maybe it could flag “hey, FYI if you switch to this colorscheme then you’ll end up with some extremely bad contrast in htop”. No idea if that’s practical or worthwhile to implement, just brainstorming.

        1. 5

          If you’re interested in trying Ghostty, please feel free to email me (m@mitchellh.com). I prefer for now for any beta tester to join Discord (https://discord.gg/ghostty) since all development discussion currently happens there but totally understand if that’s something you’re not comfortable with, so just email me and I’ll get you added. It’ll be public and FOSS by the end of the year.

          And thanks for the rest of the input. I’ll think about this…

        2. 3

          Something that’s puzzled me, and I may get terms a little wrong here due to unfamiliarity: Would it be possible for a remote terminal connection to carry its terminfo with it? I often ssh to stripped-down/old boxes that won’t have info for a (not so) recent terminal. Right now the process is that I carry or set an env var on the remote system to hope it has a file installed that works correctly with my terminal. I can see that choice a few decades ago when a ~4k terminfo file would take a noticeable amount of time to transfer and the user was likely using a slowly-revised terminal managed by the same sysadmins, but now it seems a bit backwards to expect the remote machine to know about client software.

          1. 5

            Sorry for the super late reply, I was on vacation with my family. What you’re asking for is exactly what XTGETTCAP does: it introduces a new sequence that asks the terminal emulator over the pty for terminfo values. Since its over the pty, it works over remote connections. This is why it was made. That’s the correct solution nowadays for programs to use and it’s relatively well supported. I linked more information about it in my original response.

            1. 1

              There’s no rush on these things. :) Thanks for explaining XTGETTCAP, I didn’t get it from your first explanation.

            2. 4

              I was a long term user of rxvt-unicode, which has the fun quirk of not shipping an entry in the usual terminfo database. Combining this with a need to log in to embedded and/or not-managed-by-me remote hosts, I’m familiar with that annoyance.

              As a quick fix, you can clone your client machine’s entry to the remote with an obscure one-liner:

              infocmp -a | ssh the_remote_host tic -
              

              Arguably, it’d be nicer for it to happen automagically, but I suspect it’s in an uncanny valley of features. It’s probably very rarely hit, and most people with the arcane knowledge to go and plumb such a thing in also know about the weird ncurses commands. It’s pretty easy to shrug, chant the magic spell, and get on with what they were really trying to accomplish. (Or in a pinch, the common export TERM=xterm mostly Just Works, right?)

            3. 2

              It naïvely seems to me that some of the trouble arises from using the same tones for foreground and background colors. Given that ANSI codes contain separate codes for setting the foreground and background, I wonder if it may be practical and fruitful for a terminal to allow specification of distinct colors for each. I don’t know how this would play out for TUIs like midnight commander, though.

              As for defaults, there are a number of resources that are available for testing the readability of various foreground+background combinations. I personally have found the APCA contrast calculations useful, especially for dark backgrounds: https://git.myndex.com

              1. 1

                I currently happily use kitty, but I recall its author writing about tmux with some degree of antipathy. That worries me, because kitty does not AFAIK meet my needs absent tmux. Beautiful terminals on the local machine are cool, but as long as those features are available only locally, I’ll do without in order to maintain a development environment that works equally well regardless of whether I’m physically sitting at the development machine(s).

                Like I said, I use kitty (mostly on Linux, but also a bit on MacOS), always with one or two levels of tmux (with windows of the outer level corresponding to machines/VMs), wherein I spend most of my time in the kakoune text editor (usually with many tmux panes) and at the command line (usually with many tmux windows). I’m ignorant of the challenges involved in making new terminal features work well over the network, but even if it’s Hard™, supporting multiplexed remote terminal sessions remains an important use case.

                1. 3

                  The reason the Kitty maintainer is vocally against multiplexers like tmux is because it introduces layers of terminal emulators (tmux itself is a terminal emulator but instead of a GUI it ships its UI as a TUI across a pty into another terminal emulator). Each layer may have different capabilities and behavioral quirks.

                  So for example, when the Kitty maintainer introduces a new feature such as styled underlines, tmux users can’t use them until tmux also understands and parses them. He’s even gone so far as to create extremely creative mechanisms in his protocols (i.e. the Unicode placeholder subsection of the Kitty graphics protocol) in order to “smuggle” protocols through tmux without tmux having to support them.

                  As a terminal emulator author, that’s frustrating, because you can’t improve your ecosystem without these nested layers hopping on board. Some may argue that’s a feature not a bug. I’m just stating it as it is.

              2. 7

                Ignoring all the instruction encoding idiocy abound – The fundamental problem is that colouring already starts with the developer side saying ‘ok I think this should be red’ and then the emulator side going, nah, ‘red is green’ rather than semantically tagging ‘text is red, line-drawing is white, …’.

                Then you side-step all of this with the three or four added instructions for setting colours from a (possibly downsampled) 8 bit r/g/b or sixel encoded ‘can we embed an image in a way that makes dot matrix printers feel accurate by comparison’ way where applying a scheme suddenly become the equivalent of tone mapping.

                1. 6

                  I’m not sure why the iTerm Solarized theme is designed this way (there must be a reason!) but I’m pretty sure I prefer the version where the “bright” colours are actually colours instead of all being shades of gray.

                  This is actually as originally specified by Ethan Schoonover, the designer of Solarized, who used it as a way of fitting the larger set of “base” tones into the 16 slots afforded by ANSI colors. See the table entitled “The Values” on the website: https://ethanschoonover.com/solarized/#the-values


                  I used to use base16-shell + base16-vim, but I didn’t like the actual syntax aspect of the color scheme – in terms of what colors were chosen for different highlight groups. (See https://github.com/tinted-theming/home/issues/10). For the curious, there’s also been a community fork of Chris Kempson’s original base16 work, since he seemed to have gone inactive: https://github.com/tinted-theming

                  I finally ended up going off the deep end of color scheme nerdery, formulated my own from scratch, set up neovim and iTerm to use it, and have thankfully resisted the urge to fiddle with it much further. (https://github.com/e-q/okcolors.nvim)

                  1. 2

                    Thanks for sharing your creation.

                    set up neovim and iTerm to use it

                    Can you explain / share how you use okcolors.nvim with iTerm please?

                    1. 3

                      To be more precise, I manually created an iTerm2 color scheme to use the colors as the terminal ANSI colors. I’ve uploaded it here: https://gist.github.com/e-q/24a4d04e88a727bf81407f9c831efff3

                      1. 2

                        Thank you!

                  2. 5

                    As an every day terminal user for 25+ years, my approach is to simply stick to the default 16 colors.

                    If an app shows me yellow text on a white background, I consider this an issue with the app, not something to fix by reconfiguring my terminal and breaking other apps in the process.

                    If the terminal’s default colors deviate too much from the standard VGA (looking at you, Gnome Terminal), THEN I consider this an issue with the terminal. But my solution is to switch to a different one, instead of tinkering with the config.

                    The reason is that I use several different machines, with a few different operating systems, from which I ssh to several dozens of remote instances, some of them shared with other developers. Hence I prefer to adjust myself to a set of default shells, editors and colors, rather than spend time perfecting my configs on every machine.

                    To be honest I also find the 16 default colors just enough for nice and clear TUIs, and personally never really felt the need for more of them. At least I can see much more important usability issues with terminal apps than colors.

                    1. 4

                      This is my favorite way to visualize the 16 colors:

                      #!/usr/bin/env perl
                      
                      for ( [ 0 .. 7 ], [ 8 .. 15 ] ) {
                          printf "\x1b[48;5;${_}m %2d ", $_ for @$_;
                          print "\x1b[0m\n";
                      }
                      
                      1. [Comment removed by author]

                        1. 1

                          I’ve recently started setting my system to greyscale (for sort of unrelated reasons), and it’s very nice that it solves the problem of aesthetically-clashing colours. It doesn’t solve the problem of colour combos with insufficient contrast, but it might help a bit because it means that any old solution will do.

                          1. 1

                            Problem one listed there, blue on black and yellow on white, annoyed me enough to write my own terminal emulator. Mine uses a classic palette, but when drawing, if a cell has poor contrast, it adapts the colors to make it legible again Screenshot to show: https://arsdnet.net/terminal-colors.png I also special case white on white and black on black to make them grey instead, still fairly low contrast, but it is readable (sorry i messed up the label once in the screenshot but you can still see the idea).

                            It arguably could still be better, but this is an approach I’m surprised more terminal emulators don’t adopt.

                            1. 4

                              If you read further down the article, she details a number of terminal emulators that have a “Minimum contrast” setting that you can tweak so that the contrast never gets too close for comfortable reading. iTerm2 and kitty both support this. It sounds like something I’d like for terminator or GNOME-vte, but it also sounds like a bunch of work…

                              1. 2

                                Oh nice, yeah, I started skimming pretty quickly since none of these problems affect me any more. But I see at the end she actually agrees with me that this is a nice solution that should be used more. It should be implemented and enabled by default everywhere!

                            2. 1

                              I hit a bunch of these problems, and after trying pretty much every color scheme I could find, I ended up making my own color scheme that fixes some of these issue. It’s likely to be impossible to fix all of them though. We use that theme (Aardvark Blue) for most of the Ratatui demos. In particular it solves the blue on black, blue on default background, light yellow on gray (but not bright white).

                              Originally added to the iTerm2 color schemes library in https://github.com/mbadolato/iTerm2-Color-Schemes/pull/417

                              The goal of this theme was:

                              • colors are fairly natural (i.e. blue is blue, red is red)
                              • background and black are distinct
                              • grays are naturally ordered avoiding full black
                              • light and dark colors are distinct from each other
                              • all colors look good on background, black, dark gray, gray, white

                              Demo screenshot in https://ratatui.rs/examples/style/colors/ (which btw is a pretty nice utility for checking out contrast themes when you’re going through the process of choosing them)