Hacker News new | past | comments | ask | show | jobs | submit login
Terminal colours are tricky (jvns.ca)
371 points by chmaynard 65 days ago | hide | past | favorite | 142 comments



I came across all of these issues and many more trying to make a good light color scheme for my systems. Two interesting findings I did not see discussed:

1. It makes sense in retrospect, but I was very surprised at how much more subtle light themes are compared to dark when viewed on different screens; of course their hardware and software configs lead to variations on the color output, but light dominant changes are perceived so much more drastically than dark ones. This is a serious issue if you will be porting your theme to computers with a variety of screens and configurations.

2. Occasionally, you need to drop to a linux or bsd console with very limited support for fonts and fancy colors. Then your `fd` and `exa/lsd/whatever` may be unusable and annoying, especially if you have mapped the latter to `ls`. I managed, after a long struggle, to get a working fbterm in my system to get decent terminal features without X, but fbterm has its own issues. You need to account for this use-case, especially when configuring vim colorschemes: make sure that you have a fallback theme for a feature-poor console or you have really practiced typing vim commands blind :D

Edit: here is a screenshot of my stylized fbterm screen, obviously not for serious work, but meant to demonstrate what you can do without X: https://i.imgur.com/RbDRgtD.png


> I was very surprised at how much more subtle light themes are compared to dark when viewed on different screens.

This does not surprise me. I do analog black and white printing (from film) and it's a well known thing that our eye is much better at detecting subtle tonal changes in light areas of a print than darker ones. For this reason, a lot of the time in tweaking the right exposure and contrast for a print is spent to make those hightlights look "just right". I don't print digitally, but I am sure the same principles will apply there too.


This is why, as policy, I don’t judge negatives any more. I always print contact sheets and make my initial judgments there.


> Occasionally, you need to drop to a linux or bsd console with very limited support for fonts and fancy colors. Then your `fd` and `exa/lsd/whatever` may be unusable and annoying, especially if you have mapped the latter to `ls`.

Normally you should be able to rely on a properly set TERM variable [1], and CLI utilities should respect the capabilities they can gain from the TERM variable.

Sadly, a lot of "modern" CLI tool frameworks - particularly those written in JavaScript - tend to ignore this.

[1] https://www.gnu.org/software/gettext/manual/html_node/The-TE...


Was going to say "hey just set $TERM", then saw your comment and actually read the article which covers all of this pretty well. But, not only am I annoyed about this, but I feel that being annoyed about this confirms I am definitely getting old. yells at cloud

Starting using Linux at 15 in 2002. Didn't realise how "early" that was then (especially compared to now, seemed old then). Been working professionally in the space since 2006. Now I'm 37. Yikes.

On the plus side it definitely works for your more basic tools.. for most of the non-basic ones, as a hack you could pipe the output to "cat" as most tools try to detect if the terminal is interactive or not to remove colors from output being piped. It also annoys me we don't have a better way to signal that, and I have to pass --colors and hope it's supported to every command where I want the colors but just to filter the output by line with grep.

Anyway...


I'm also 37. Two younger colleagues were complaining this week that something like `os.MkDir(..., 0755)` is extremely confusing and that they don't like and can't make sense of octal file permissions. I felt really old :)


I had a recent experience trying to show a large number of data series by different colours on a plot in Excel.

I found the best option for easily distinguishing a large number of colours was the monochromatic spectral "rainbow" colours on a black background (there's also a setting to make the data points have a bit of "bloom" aura in the same colour so they look like dots of light).

It makes sense from a colour saturation perspective (i.e. signal to noise ratio across the spectrum) that a black background is better.

You can pretty much have 10 different colours

EDIT: Another benefit is it conveys "sequence/order/distance" information: yellow is between red and green; orange is between red and yellow, etc. It's easy to subdivide and interpret how "close together" two colours are.


That sounds reasonable. But sometimes I have a bunch of signals with some of them being pairs, so having a dark and light version of the same color helps to see them together. Does this work with adjacent rainbow colors as well?


You can use the same hue with different luminance.


All those nice fonts and pleasant color theme... ruined by a background that makes some characters hard to read :)


Oh, you mean the picture I linked? That's just to look cool on a screenshot, obviously you won't work with a background picture getting in the way! :D


Nah, the background picture is based xD


Your stylized fbterm screen is awesome, always good to have a cute anime girl lol.

Really good colors and organization of the terminals, it would be great for serious work too in my view =p


Would you share how you configured your fbterm?


Here is a pastebin of my config, adapted from Lu Xu's dotfiles [0]

https://pastebin.com/RgbgLUTq

[0] https://github.com/xlucn/dotfiles

It is Lu Xu's dotfiles you should focus on if you want to understand how fb* tools work.

I invoke fbterm via this script to set the bg image:

  #!/bin/sh
  # fbterm-bi: a wrapper script to enable background image with fbterm
  # usage: fbterm-bi /path/to/image fbterm-options
  
  printf '\033[?25l' # hide cursor
  fbv -ciuker "$1" << EOF
  q
  EOF
  shift
  export FBTERM_BACKGROUND_IMAGE=1
  exec /bin/fbterm "$@"


Oh nice, I will give it a try. Thank you so much!


> Occasionally, you need to drop to a linux or bsd console with very limited support for fonts and fancy colors. Then your `fd` and `exa/lsd/whatever` may be unusable and annoying, especially if you have mapped the latter to `ls`.

I just did a check on my NixOS system there and the console seems fine? The ANSI blue on black for directories in eza is a bit... meh, but it's perfectly readable and the same is true for the default colour scheme for ls on MacOS terminal


I actually don't think it's that hard:

Step 1:

Most terminal emulators ship with a garbage default colour scheme. So change that.

Personally I'm a fan of Solarized (specifically dark, but I like their light theme too). However even if you don't like Solarized, there are plenty of other themes that are readable with any colour against the default backgrounds.

Step 2:

Avoid any CLI tool that uses escape sequences for 8bit or 24bit colours by default. This might be an unpopular opinion, but I actually consider that as user hostile. Reason being: I've already chosen a the best terminal colour scheme for my readability requirements (remember, this will differ for different people). Having a developer override that because they fancy themselves as a pseudo-designer is not helpful. By all means, they can have an option to enable themes in their tool if they wish, but that should be opt-in, not the default.

As someone who spends most of their life in the terminal, following those two rules is enough to provide a consistent and easy terminal reading environment with almost-zero configuration overhead.

I think the real problem is that we indulge developers using 8bit and 24bit colour escape codes.


> By all means, they can have an option to enable themes in their tool if they wish, but that should be opt-in, not the default.

This touches on the problem of good defaults. If the user has to configure it then the user must know that it is configurable and then do it. This is a serious hurdle and only a tiny fraction of users will do it.

Over the years I've come to the conclusion that you must throw your new features into the face and shove good defaults down the throats of users, otherwise these feature are hardly used.

8bit and 24bit colors are already opt-in and you can configure it. Your TERM and COLORTERM environmental variables determine if a (well behaved) terminal program will use those colors.


> Over the years I've come to the conclusion that you must throw your new features into the face and shove good defaults down the throats of users, otherwise these feature are hardly used.

Agreed to an extent. I wouldn't call ignoring the systems colour preferences as "good defaults". But I do agree with your more general point.

> 8bit and 24bit colors are already opt-in and you can configure it. Your TERM and COLORTERM environmental variables determine if a (well behaved) terminal program will use those colors.

Unfortunately it's not that simple. Both the "256color" suffix to $TERM and $COLORTERM env vars report terminal compatibility -- not user preference.

Neither are standards either. It's a push to even call them a de facto standard because they're often not used by either terminal emulators nor application developer alike.

There is another env var that does report user preferences: $COLORFGBG, but that receives even less support than the former two vars.

There's also $NO_COLOR (or is $NOCOLOR?), which seems to be honored a little better. However the problem with this is it turns colour off completely. ie you cannot specify "use 4bit but not 8bit nor 24bit colour".

Like all things terminal detection wise, it's all a big fat steaming mess of inconsistencies. Which is why I think the best default is 3/4bit or no colour at all if $NO_COLOR / not a TTY. And have all the cool 24bit themes as an optional extra.


It's also the case that a lot of modern CLI tools will absolutely ignore your termcap and your $TERM env var and barf out whatever extension to ANSI is used by the currently most popular terminal emulators.

Unless it's a TUI app that I'm going to spend a lot of time in (e.g., Emacs), I do not want it theming itself. I want it to look at my termcap to see if it has ANSI color support, and if it does, then emit ANSI color codes. I use base16-shell to set my terminal colors and I want CLI and TUI apps to respect them.


> Unfortunately it's not that simple. Both the "256color" suffix to $TERM and $COLORTERM env vars report terminal compatibility -- not user preference.

Terminal compatibility that is expected to be used. If you only want the 16 base colors then this is the way to go. This is the most reliable and best supported way to get that in the terminal.

If you want some tools to still output 256 colors, you can change the TERM variable on the fly: "TERM=$TERM-256color infocmp -L".

You also should unset COLORTERM. It's for specifying that this terminal supports 24bit colors.


You’re basically just demonstrating my point that this gets very complicated very quickly and thus the polite way to handle this is tool authors to default to 4bit.


A lot of the complexity comes not only from technology that has been dragged along for almost 50 years now but also that the maintainer of ncurses/terminfo has been stubbornly refusing to add new capabilities to the terminfo library.

Using terminfo will give you at least a standard approach to what defaults to use. If you don't want to configure your terminal then you are asking others to do something you are not willing to do.

If we are supposed to go with the lowest common denominator without terminfo capabilities, we would even lose 4bit colors. Then only the basic 8 colors are safe because there a lot of terminals now that don't support the workaround of "bold plus basic color gives bright color" anymore.


That is a massive over simplification and you're pointing the fingers at the wrong culprits.

I've talked a lot recently about the problems with env vars for terminal detection and the problems with developers not understanding how to correctly query terminal capabilities. Heck, some don't even correctly support non-TTY outputs (ie pipes). And then there's the issue that terminfo is a C library so a lot of languages with average to no-C FFI support cannot use it without fork()ing -- which is slow. Plus terminfo is POSIX only which eliminates platforms like Windows -- which is increasingly a target now that Windows Terminal supports ANSI escape sequences.

It's a mess and blaming that on history and terminfo really misunderstands that the real problem is modern tools not respecting or having compatibility with that history, rather than the history breaking things.

> If we are supposed to go with the lowest common denominator without terminfo capabilities, we would even lose 4bit colors. Then only the basic 8 colors are safe because there a lot of terminals now that don't support the workaround of "bold plus basic color gives bright color" anymore.

You're missing the point. It's not about supporting the lowest common denominator -- though I'd love you to give some example of terminal emulators in common use that don't support 4-bit colours ;)

It's about supporting user defaults. Themes based on 8-bit and 24-bit colour pallets are defined by the developer. Whereas themes based on 3 and 4-bit colour pallets are defined by the terminal user.

Hence why I say applications should default to the terminal defaults (defined by the user)

There's times when applications should support 24-bit regardless of the user preferences. Such as image rendering in the terminal. But those are exceptions rather than the norm. And precisely why things like `256-color` and $COlORTERM need to be defining terminal support not user preference.


> And then there's the issue that terminfo is a C library so a lot of languages with average to no-C FFI support cannot use it without fork()ing -- which is slow. Plus terminfo is POSIX only which eliminates platforms like Windows -- which is increasingly a target now that Windows Terminal supports ANSI escape sequences.

export TERM=ms-terminal

Windows is POSIX. Windows NT always had a POSIX layer.

Terminfo is mostly a file based database collection. You don't need to link to the C library, you just must be able to read the terminal infos.

> You're missing the point. It's not about supporting the lowest common denominator -- though I'd love you to give some example of terminal emulators in common use that don't support 4-bit colours ;)

The question is not about support but about how to get them to be display. Which escape sequences produces colors 8-15? The answer is different from terminal to terminal and that's the problem.


> export TERM=ms-terminal

A few problems with that:

1. That then breaks any applications that look for either `xterm` or `256-colors` in the TERM string. Unfortunately these days $TERM behaves more like a User-Agent string in HTTP-land so most terminal emulators are forced to pretend to be `xterm` even when they're not.

2. `export` is a Bourne Shell-ism. Powershell's syntax looks a little more like:

    $Env:<variable-name> = "<new-value>"
https://learn.microsoft.com/en-us/powershell/module/microsof...

> Windows is POSIX. Windows NT always had a POSIX layer.

Windows is not POSIX. Windows has POSIX compatibilities in some places but POSIX defines a plethora of different things beyond just C-APIs.

For example: Windows doesn't have a lot of the command line utilities defined by POSIX: https://en.wikipedia.org/wiki/List_of_POSIX_commands

> Terminfo is mostly a file based database collection. You don't need to link to the C library, you just must be able to read the terminal infos.

mostly is doing a lot of heavy lifting there.

Also reading those databases without C is non-trivial as well. For example try manually parsing the output of /usr/share/terminfo/74/tmux-256color on macOS.

It's also worth noting here that there's two different database formats: terminfo and termcap. And different locations each platform (and users!) might configure those databases to reside.

Also tools like `tput` do more than just look up $TERM against terminfo. There are actually a few different places where terminal capabilities are hidden. Including ANSI escape codes, which was originally used in the hardware terminal days before $TERM existed and are still expected to be supported by modern terminal emulators.

Let's not forget that you also need to check if you're reading from, or writing to, a TTY. It might actually be a pipe, or even just a regular file. And while there is a standard C API for checking if a file descriptor is a TTY, `isatty()`, that itself is just a hack because there's no ABI in TTYs to return true/false if they are a TTY. So instead isatty() has to send ioctl calls to alter the state of the TTY, but a state that's only supported by TTYs (ie incompatible with pipes and regular files). It's a hack that's worked well for decades, but it's yet another class of edge cases that people take for granted.

> The question is not about support but about how to get them to be display. Which escape sequences produces colors 8-15? The answer is different from terminal to terminal and that's the problem.

The escape codes don't differ. There is one standard set of escape sequences for 4-bit (8->15). https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-b...

What differs is the shade of colours that are produced with those escape codes. And that's exactly why I advocate that developers should stick to 3/4-bit code.

The point I'm making is that those colours are defined by the terminal and configurable by the user. Which means individuals can set a colour profile that is readable for them. This is why CLI and TUI developers should default to, and respect, those preferences.

Take a read through my comment history. I'm an author of a multitude of advanced CLI and TUI applications as well as terminal emulator and thus I've discussed these topics at great lengths with other people.


Solarized Dark, specifically, is not well-suited for terminal use, because the author has assigned "bright black" to nearly the same color as the background. Many applications expect that 'bright black' text will be visible against the background. See here for many examples: https://github.com/altercation/solarized/issues/220

Nearly all other colorschemes represent 'bright black' as a gray color, which is readable against the black background.


> themes that are readable with any colour against the default backgrounds.

Yes, but then there are applications that set both the text and background colour. For example pamix sets the background to black, or tmux's statusline, or ngrok. And you end up in a rabbit hole trying to deal with that.


I don't know what pamix is but my rule of thumb is to use only apps that supports themes that are common in most terminals, text/code editor like solarized, gruvbox...


>> Step 2:

>> Avoid any CLI tool that uses escape sequences for 8bit or 24bit colours by default.

I was going to point out that the author never takes a step back and asks "What would be the best way to handle this?" The problem there is we have to define what "best" is. IMHO that involves a number of principles. My preferences are:

1) Any user customization should be in one place.

2) The impact on programs should be minimal (in LoC for example).

Both of those suggest the solution belongs in the terminal.

IMHO it starts with terminal programs having sane default colors. What that means is fuzzy, but so is this whole discussion. IMHO colors should follow the "standard" so that blue is still recognizably blue. But consideration should be given to the common forms of color blindness - for example I have a hard time reading pure red on black (adding a bit of anything helps this, don't just use ff0000).

Once terminals get fixed to have sane defaults, CLI programs should use those 16 standard colors. Any attempt to use 24bit here is either saying "I give up on getting those terminal folks to offer sanity" or it's saying something like "I know best", but either way users end up with N programs they have to configure. Lets not define themes in cli apps OK? Remember, this is my answer to "what would be the best way to handle this?"

I have similar thoughts when it comes to web sites and fonts. Present content in HTML so users can configure how they want to see it. Similar for page formatting - it's not a magazine layout, let it flow.

Also stuff in desktop software. IMHO Wayland compositors should remember window placement. It was stupid for every X program to store and restore its window position. Wayland says knowing about the environment is a security issue (and I agree) but then it becomes the DEs job to handle this memory. It also unburdens ALL the apps from having code for this.

There are other areas where that question comes up "Where in the software stack should this thing be handled?" Whatever your opinion, I believe you should start by answering the questions around that word "should". What are the goals in selecting where a thing gets handled? My answers always lean toward simplicity and maintainability. What other principles might I adopt to answer these questions?


> What would be the best way to handle this?

A styling service from systemd.


Avoid any CLI tool that uses escape sequences for 8bit or 24bit colours by default.

How difficult is this in practice? (Julia's article mentions this idea too without going deeper into the struggles)

A related topic is: Do terminal color schemes only concern themselves with the 16 base colors or do they also meddle with the RGB and greyscale parts. I mean you could also adapt the 8bit and 16bit colors to your readability requirements.


There is no 16bit. You cannot alter the 24bit (at least not on your average terminal emulator).

Same is true for 8bit. Most terminal emulators tend not to support altering those colours either.

In practice, the only application I use that I've had to configure the colours for was tmux. But I tend to forget about tmux because its one of those applications that needs a lot of a configuration from the outset anyway (in my opinion at least).

There might be other "must have" tools that set the background colours too. I've either not needed them personally, or have completely forgotten about them


Step2: do agree with the fact someone making a CLI tool should respect user preferences. it's also much easier just not to use the sequences in the tool so I don't get why people would do that in the first place :S.

Step 1: I think here maybe the default setting should be solarized-dark/light on terminals. It's honestly a good and sane default. It's purpose built to be less hostile on the eyes in my opinion, which should likely be what's aimed for in a default setting... the themes and colors are there for people who like to stare at their terminal all day (if you only use it once or twice then you don't care about what color it has) so it should be eye-friendly defaults. if people want to muck about changing it to their own custom theme they won't be bothered about defaults anyway since they will immediately customize it.

I personally hate the fact I even need to swap a theme, or download and reformat some Xresources file tediously (while looking at godawful colors in the process!). I just want my eyes not to burn.. don't care what colors yield that result.


I would disagree that solarized is a good default, the colour it uses for blue (which is used by `ls' to show directories) is so low contrast it wears my eyes out.


Seconded. By all means, people should use what they personally like, but solarized is really not designed to be a terminal mapping. Half the brights get mapped to totally different hues and the other half get mapped to indistinguishable shades of gray. Yes, the standard terminal color values are hideous, but we can do better than solarized.


What would you recommend?

Same questions to others who've posted qualms with Solarized.

I tend not to spend much time configuring things these days so have always landed on Solarized out of laziness.


To reiterate, I'm not here to say anyone is wrong for using solarized, only that as a terminal default it would eliminate the ability of terminal applications to assume that bright green, bright blue, bright cyan, and bright yellow are anything other than shades of gray. If that's fine for your use case, then no harm. And plenty of people tweak solarized to make these colors usable and distinguishable, but of course this obviates the whole light mode/dark mode party trick that is solarized's raison d'etre.

There are lots of websites out there where people have shared their terminal color schemes, I would recommend seeking one out and looking for a screenshot of one that catches your eye.


Don’t worry, I wasn’t taking your comment as personal critique. :)

And to be fair to Solarized, it was really novel when it came out. But we’ve had years to improve upon it since.

So I’m genuinely interested to hear some recommendations. Ideally themes that are “standardised” (for lack of a better phrase) so that I’m likely to find a VSCode theme as well as iTerm2 etc.

I know I could just look online myself but customisation can quickly end up becoming an “addiction” (again, for want a better phrase) where you spend more time “configuring” than “doing”. A procrastination trap I’ve fallen into many times before. The appeal of Solarized is its better than most defaults and it’s easy to find so that stops me from spending too much time playing. And the appeal of having someone else tell me to use something else is that I also don’t fall into that proverbial rabbit hole.


Totally fair. In truth, modern terminal emulators have come a long way since the days of opening up CMD.exe or Putty and cringing at their peaked RGB sliders. Nowadays when I install a new terminal it tends to come with a decent color scheme out of the box. But if you insist, I could extract the color scheme that I made for myself a decade ago, though I decline to give it its own name or website. :P



For some reason that blue is a problem in a lot of color schemes. It's a good test for me though. If I can't read the output of ls, I dump the color scheme.


Solarized it too low-contrast for my eyes. For some people low-contrast means easy on the eyes, for others it is the opposite.


I completely agree. And for what it's worth, I set Solarized dark as the default theme on the terminal emulator I've written. Though it's not quite ready to be used as anyone's primary TERM just yet.


Would be good to check colours (if you're someone who picks colours) against the new APCA algorithm (Advanced Perception of Colour), which will supersede the existing x:y one in the upcoming WCAG 3.0 (which may take a few years yet). APCA takes font size, weight, foreground/background, and even apparently ambient light/surroundings and intended purpose into consideration. It would be neat if terminal emulators could use the device's light sensor to optimize the contrast based on environmental factors.


I've actually done this manually for my current terminal color scheme, because I could not find a single premade theme that satisfied my personal contrast requirements for all the ANSI colors.


Oh, that is fascinating.


The creator has a huge amount of docs surrounding the project that are quirky and very informative https://linktr.ee/Myndex


And then we have the absolute mad men that just want to disable colors altogether[0]. I am tempted to try it myself, but I also like the pretty colors.

[0] https://no-color.org/


   :syntax off
is my only vim configuration because terminal color sets were designed by computer programmers and electrical engineers and other people who don’t understand that the important thing about colors is not the colors but the brightness.


If you get used to monochrome terminals, you'll start to find that most colours are distracting and attention-getting. I wonder if there's a correlation between those who don't want colour in their terminal and those who have a very strong adblocker and/or extensively use reader mode in their browsers.


I take the Incredibles approach: When everything is coloured, nothing is.


Color sequences are not portable and known to break things (e.g. Jupyter sessions crashing due to colored pytest reports) and nothing but a liability if you're just piping the output. I think it's more about having the option.


Sounds like those pieces of software should also work on being more resilient to color sequences.


Me, for one.

Especially coding, I find almost all coloring to be distracting and counterproductive. Doubly so when I'm bouncing back and forth between Linux ans Windows. Many tools' default use of color borders on (or crashes head on into) unusable.

Some tools offer a --color=never option, and a good number respect NO_COLOR. Unfortunately, not all do, and even those that purport to assume that those modes will only be used for use in pipelines, programmatic interfaces, and such. That leads to all sorts of unfortunate behavior.


I'm moving in that direction. See zenbones. I ended up with https://github.com/savq/melange-nvim

They have a consistent color scheme concept of semantically significant color temperature, while leaning warm to save your eyes from staring at so much blue light. Comes with alacritty colorscheme


I'd rather see this than colorful anime backgrounds and emojis in shell prompts.


Same. There are few things that annoy me more when working in the shell than unexpected emojis in outputs to be cute or more accessible or whatever. I'll take the occasional readline and curses shenanigans but even then there's usually a way to disable those to have pure character outputs and no control chars.


I was using "script" command to record my interactions on the terminal and with colors, it was a mess. Pretty sure there are other legitimate use cases.


These are presumably the same people 'raw dogging' trans-oceanic flights.


I've wanted to use a light theme for my terminal for a long time, but I've always given up since there are just too many programs that use custom (non-ANSI) colors that are optimized for a dark terminal background. For some of those programs, the colors are configurable, but it seemed too much of a hassle to configure every single program. So now I'm just using a dark terminal background, but with a hand-picked ANSI theme where all the colors have a sufficient contrast ratio for me and also get a pass on APCA / WCAG 3 contrast checkers. I'm happy with it. :)


For some of us with higher-order visual aberrations, dark mode is a non-starter. (The converse holds for some people with cataracts.) The OSC 11 control sequence lets a program determine the background color, but few bother. Usually, someone just thinks yellow warning messages look cool, and that's the end of it.

That also leads to problem 12: Certain popular terminals that default to setting TERM=xterm256-color while not being xterm-compatible.

Edit: I just came across `xtermcontrol`, which can abstract the background check in scripts, and is in all the major package managers.


It doesn't have to be cataracts, my eyes are just unusually sensitive to light. I find the hacker news theme borderline during the daytime, and can only handle it for short bursts at night with the brightness on my monitor set to the lowest setting.

It's probably too late for terminals to add a concept of semantic color, other than "default foreground" and "default background", but the situation as it is forces TUI authors to either stick to the basic eight or make colors completely user-configurable, if they don't want to leave anybody out.

By semantic color I mean what editors do, where the presentation is separated from the intention. Unclear how to even start with that for terminals though.

(To someone out there about to tell me about how I can custom theme HN: please consider that I might spend too much time here already and don't need it to be easy to use in the dark. Cheers)


I was for a while faking a 16-color terminal without support for 256 colors just to avoid this configuration hell. I also tried https://no-color.org/ because I’d rather have no colors than bad colors.

These days I just gave up and manually configure most apps to use ANSI colors (e.g. fzf etc have command switches for that), and let Vim and Emacs be the only non-ANSI apps which are instead set to match the colorscheme I use in the rest of the terminal. (Although stuff like vim-dim let’s you go one step further if you want.)


Many terminals (konsole from trinity/tde3) allow you to customize the colour of the primary colours, which helps.


I'm not having issues with macOS's iTerm, and the programs that I use, like neovim, looked good out of the box.


Emacs has its not super discoverable frame-background mode[0] which is effectively either 'light' or 'dark'.

When you're wondering why Emacs chose poor colors for something, it's often frame-background-mode being wrong.

[0]https://doc.endlessparentheses.com/Var/frame-background-mode...


Often the underlying problem is a failure of the terminal to set the `COLORFGBG` variable.

For dark-background terminals with white text:

  export COLORFGBG='15;0'
For light-background terminals with black text:

  export COLORFGBG='0;15'



I've been using a lightly customised version of the FlatUI colour scheme for around a decade and really haven't run into any situations where it's caused issues:

png file: https://drive.google.com/file/d/1mkMESeGf7MNdKa-rPDx7Yf9BDit...

imgur link: https://imgur.com/a/flatui-7mqVZAY

Based on: https://flatuicolors.com/palette/defo


Looks similar to the One Dark theme which was originally from the Atom editor iirc.

I've been using mine for about a decade too. It works well for iTerm, vim, Emacs, vscode etc etc


I've used Apple's Terminal for a long time, way back when there was a set of color schemes called "Terminal Fructose" that was nice, I would have different colored backgrounds for different tasks. Apple at some point built that in with their themes.

However, Apple have languished with their Terminal support, they don't to >256 colors and some of the other more modern stuff is lacking and it doesn't really work with a Neovim+LazyVim setup.

I've been trying to find a "better" terminal and have bounced around between iTerm2, Kitty, Alacritty and Wezterm, but while they all are more "modern", I find that none of them seem to have that basic "New Window with Profile ..." option that lets me quickly open windows with different background colors/themes (at least without some screwing around).

Currently settled on Wezterm, mostly because it also works on Windows and I can share my wezterm.lua configuration (I should note that Windows Terminal is actually pretty good too). I still do find my self running Apple Terminal for quick things (e.g. using python3 as a REPL to do math or testing hex/binary stuff out etc).


> none of them seem to have that basic "New Window with Profile ..."

iTerm has exactly that.


Yes, you are right! iTerm2 does -- as long as you have more than the default profile set up (and you have to set them up yourself, which is easy enough).


That's weird, as I dumped Apple's terminal very quickly in favor of iTerm2 specifically because it support "new tab with profile".


I stuck with Wezterm for two reasons: 1) I can share the config across multiple platforms easily 2) Lua for configuration.

There are a few things I miss from iTerm2 (mostly mouse related), but otherwise it took me a few evenings to configure it to my liking (cmd-n opens a new window at the default dir, not the current one) and I've been a happy user since.


If you want to add "New Window with Profile..." to WezTerm, you can probably hack something into either `launch_menu` [1] (for starting different shells), or `augment-command-palette` [2] (for adding items to the command palette).

1. https://wezfurlong.org/wezterm/config/lua/config/launch_menu...

2. https://wezfurlong.org/wezterm/config/lua/window-events/augm...

Yeah, it takes some screwing around, but programming extremely specific features just the way you want them is peak WezTerm experience.


Konsole (the KDE terminal) does this (either from the manu or click and hold on the new tab icon) and I believe it is available for MacOS.


Not just terminal, but be it Neon signs or LED name boards, blue is the toughest on eyes during night time. It's always blurry from a distance, and can't even focus on it. I have seen big businesses putting up huge name boards in blue lights, and I think how they can spend a lot of money without even realizing that people can't read it.


I have automatic light/dark mode tied to the daylight cycle on my laptop and the amount of colour emitting applications which break when I turn on light-on-dark mode is astounding.

If you are writing a command line tool and you absolutely insist it must have colours then stick to the ANSI 16 colours or allow end users to customize the colour scheme.


I've reached a point where having well-coordinated colors in my terminal just doesn't concern me, I find it to be a waste of time now. I used to be all about finding the perfect scheme, with the perfect terminal font, cool transparency and whatnot, now I just don't really care. I have more interesting things to work on. Whatever, if you want to, you do you.

Maybe because I've had to work on enough remote consoles without any, or limited, color support where I'm more concerned about the problem at hand than which shade of blue is being output for directories. Ok, I'll admit I adjust the default apple terminal 'pro' scheme colors a bit, adding a bit of contrast to the background because I'm in it all day, but beyond that, nothing. I find coloring has little to no positive effect on my productivity, and in some instances, hinders it. No colors on ls, I actually get a bit annoyed when color escapes reach stdout via logs now, hah. Hell, that extends even to my $PS1. I've never bothered to update it on this system. Crotchety, grizzled ops person perspective maybe?


For me it’s about utility. I don’t buy any arguments saying don’t use aliases or colors because others won’t have them. 90% of my terminal interaction is on my terminal so I’m not too bothered.

It takes me maybe 10min when I get a new computer (usually Mac) to have Oh My Zsh and Powerlevel10k installed on my machine, configure p10k with the awesome setup wizard, change to my coding font, and tweak my background and foreground to dark teal/off-white. After that I never have to touch it again and it looks amazing for the rest of my working days. The default PS1 mods from p10k giving me directory context, info on k8s, docker, and python venv, along with info on last run cmd like exit code and runtime, are all just so valuable and I got them for basically free.

I can understand not wanting to constantly tweak it and I agree with that but I would have to disagree that making any customization is a waste of time.


I agree and disagree with you. Same 'grumpy old sysop' energy. Same as you I, ssh into 100 different servers on dozens of client networks. Too many have a stupid amount of restrictions in the name of security that prevent changes or enforce settings. i.e. One client has a 'forced' PS1 output that shows: RAM free/total HD space free/total CPU load TOP cpu item Previous command

All with obnoxious colours AND blinking if a threshold gets met. .bashrc (and associated)is read-only (and) overwritten at every login.

But, I can `source .my-env` And bring sanity to my session.

I'd rather have a 'default-plain' then some forced-bling that a dev thought was cool 20 years ago.


I don't bother about the colors because white on black is excellent for me and I prefer not to have the output colorized. Makes things easy. :)

I lie a little... I do disable colorization when possible, or set everything to be white on black when I can't just turn it off.


Pretty much same, but over time I've switched to dark on light in terminal. Easier for me to read these days. Still use "night mode" often on my phone, mostly to save battery (OLED).


This is how I feel about virtually all "personalize your environment" discussions. The sheer level of effort to ship preferred shells and tools and aliases and dotfiles and color schemes around the thousands of nodes I touch in a given year makes it all feel like a losing bet. It means every little change feels like a new insurmountable chore I just placed on myself.

Now, yeah, in the case of the terminal, it's probably not so bad because the remote system _probably_ won't override my settings, or it's probably relatively easy to force my side to take priority, but it still falls into the bucket of "huge chores with minimal payoff".

Also crotchety, grizzled ops person who invests too much time into solving the problem right in front of them and not enough time into stepping back and engaging in possibly-fruitful sidequests.


A big problem is that, even when you ignore 256 and true color support, and limit yourself to the 16 color palette, there’s no consensus on whether the 16 colors are backgrounds or foregrounds. Some CLI write text in foreground color over color_x, while others do it with background color.


If you’re a CLI, you should never (a) set background colours, or (b) use more than the 16 colours range¹, unless the user configures it so.

If you’re a TUI (as in, full-screen terminal app), you should probably not (a) set background colours, or (b) use more than the 16 colours range¹, unless the user configures it so.

—⁂—

¹ And you can’t even wisely use most of the 16 colour range—the intense colours might be higher or lower contrast, so they’re not useful how people want to use them, and black and white could both be either the higher contrast or literally invisible, when used against the default background; and blue, yellow, bright yellow, bright cyan are each very difficult to see on some common themes, those that’s becoming less common.


Sadly, the state of CLI and TUI tools is that background colors _will_ be encountered soon or later, if you use a wide range of software. And I struggle quite a bit sometimes to make everything in my terminal legible.


I'm genuinely unsure what you mean here. In SGR, 30-37 are foreground colors, 40-47 are background, and the brights are 90-97 for foreground and 100-107 for background. Even the second bright set is quite old, xterm calls them the aixcolor because they originated in IBM's AIX in the 1980s. I've never seen terminal software which doesn't support these and definitely never encountered one where the difference between foreground and background was negotiable. The concept of a color independent of being foreground and background can't be expressed in SGR codes.


> I’m not sure why the iTerm Solarized theme is designed this way (there must be a reason!)

That’s because Solarized only has 8 accent colors + 8 monotones: https://ethanschoonover.com/solarized/

Your 16 color all-color “Solarized Light” is a derivative work based on Solarized, not the original Solarized.


I used to spend all this time choosing the colors on my terminal. Now I just use white background black text. No glare in daylight with the glossy laptop screens we all have now, and if you are working at night you can use something like f.lux to eliminate eye strain.


Terminal colors are tricky, which is why I outsource all of my colors to more capable people. Personally, I like Catppuccin (https://github.com/catppuccin/catppuccin)


Solarized has the core of a good idea but a lot of problems in the details. I started from Selenized. https://github.com/jan-warchol/selenized/blob/master/whats-w...


Most of this just boils down to people designing themes not understanding accessibility when it comes to color. If they followed the WCAG Color Contrast guidelines it'd be a mostly non issue.


I wanted to like dark mode (before it was called that, back in the nineties), and I try again from time to time, but I've never been successful.

I'm also not happy with Solarized because it's so low contrast.

Some programs have Github themes that seem to be okay.

I tried Catppuccin but I'm not sure if I like it or not. It's better than Solarized but still pretty low contrast.

Is there a color scheme I might like that's supported across multiple applications? IntelliJ, iTerm2, lazygit, neovim come to mind.


Minimum contrast! What a great feature! One of which I was entirely unaware until just now.


There is something deeply fondly nostalgic about looking at that ANSI color table


As someone who spent an hour yesterday trying to color match WezTerm and Apple Terminal to run vim legibly, this came in very handy,


Looks like Konsole doesn't support this (just switched from Kitty on KDE, because on wayland, Qt apps survive a compositor restart!), but there has been a request since 2022:

https://bugs.kde.org/show_bug.cgi?id=451109

I wonder how hard this is to patch.


> because on wayland, Qt apps survive a compositor restart!

Realistically, how often do you restart your compositor and why?


'This made me wonder – if blue is colour number 5, who decides what hex color that should correspond to?

The answer seems to be “there’s no standard, terminal emulators just choose colours and it’s not very consistent” '

That doesn't surprise me. What surprises me, is that there are people who apparently think that choosing a RGB value other than 0,0,0 for black would be a good idea. A lot of money is being spent to increase contrast and they are simply throwing it away (not to mention the wasted power on e.g. OLED devices).


For many people, high-contrast text strains their eyes, leaves afterglows and blurs vision. Enjoy your issue-free vision while you’re relatively young and let us have our #ddd-on-#444 which we can read for more than two minutes.


    echo SYSTEMD_COLORS=16 | sudo tee -a /etc/environment


"bright yellow on white" and "dark blue on black": I thought the system was designed so that you should use a bright colors on a dark color or opposite, not two colors in the same group?


The #1 problem w/ the above article is that “color” doesn’t matter but brightness and value do.


If that ever happens with a properly implemented terminal, it's an application bug. But buggy terminals are very common.

Sometimes it's due to COLORFGBG not being set.

Sometimes it's due to failing to implement the legacy "bold = intense" hack (from the 8-color days), which very many programs rely on.

Sometimes it's due to the colorscheme having all colors be too bright. It's abominable how far some of those colorschemes are from the VGA standard.

(Sometimes it's a gamma-ish problem. I can't believe it's $CURRENTYEAR and computer screens still vary so badly).

---

Here's a quick test for several problems. These are bad color combinations that shouldn't be chosen, but they should be readable with just a bit of effort. Output is 2 lines, one offblack-on-black, one white-on-offwhite.

  printf '\e[3%d;1;4%dmThis should be (barely) readable.\e[m\n' 0 0 7 7
Results with default configuration on Debian stable:

  alacritty: fail (no obvious configuration)
  cool-retro-term: pass (despite deliberately neutering color)
  deepin-terminal: marginal pass (colorscheme too bright)
  Eterm: pass
  foot: fail (no obvious configuration; buggily packaged as X11 despite being Wayland-only)
  gnome-console (really?) = kgx: fail (configuration does not contain an obvious fix)
  gnome-terminal: fail (need to go into preferences and check "show bold text in bright colors")
  kitty: fail (no obvious configuration)
  konsole: half-fail (colorscheme too bright)
  linux: pass
  lxterminal: fail (check "bold is bright" in preferences)
  mate-terminal: pass
  mlterm: pass
  pangoterm: pass
  pterm: pass
  qterminal: pass
  rxvt: pass (it, along with its derivatives (I don't remember which right now, but several are probably listed here), has other unfixable bugs though, and should be avoided unless you are deliberately trying to write a program that works even with abominable terminals)
  sakura: fail (no obvious configuration)
  stterm: marginal pass (colorscheme too bright)
  terminator (the gnome one): fail
  terminology: pass
  termit: fail (configuration does not contain an obvious fix)
  tilix: pass
  xfce4-terminal: pass
  xiterm+thai: marginal fail (colorscheme contrast too low in both directions somehow)
  xterm: pass
  yakuake: half-fail (as konsole)
  zutty: marginal pass (colorscheme too bright)
(not that this test is only for colors, not for the many other features you might expect a terminal to support)


I used to match my terminal theme to CGA colors (DOS ANSI), the lighter colors on VGA default aren't quite the same (wikipedia screenshot). You can get the right color codes from something like Pablo or Moebius. It's a bit of a pain, and I'm honestly surprised more terminals/editors don't have a "DOS ANSI" theme option that matches those color codes. I have a reg file saved to do it for the old Windows console, but dropped windows a few years ago, and even then was using the new terminal.


I've got my terminal set up to use a colour scheme based on Prot's Modus Operandi (https://protesilaos.com/emacs/modus-themes) theme for Emacs. I can read the output of `dmesg' and `ls /' without problems, so it's good enough for me.


Emacs users always write the longest, most detailed documentation.


Do you have someplace you can share this? I'd love a pair of 16-color terminal color schemes based on Modus Operandi and Modus Vivendi.


The ones I'm using I have 'adapted' for QTerminal from these Konsole themes: https://www.opencode.net/sterric/konsole-modus-themes

And by 'adapted' I mean I just removed the Anchor, Blur, ColorRandomization, FillStyle, WallpaperFlipType, and WallpaperOpacity attributes. I don't know whether I could've just left them be, but they don't really matter anyway.


For me I've always gravitated to what is essentially the "One Dark Pro" theme originally from Atom that has been ported over to VSCode and other things, and is almost identical (in terms of terminal colors anyway) to the default theme installed by OhMyZsh. So these days I just default install OhMyZsh and I'm good to go.


# see more colors from sys import argv def color(num, text): return f"\033[38;5;{num}m{text}\033[0m" i = int(argv[1]) if len(argv) > 1 else 16 for i in range(i): print(color(i, f"number {i:02}"))


https://terminal.sexy is a decent site I use for exploring and generating downloadable terminal color configs.


I found this site recently and love it: https://terminaltinder.com/


I use base16 shell across my terminal emulators and at least in gnome or xfce terminal I found that it helps to reverse white text on black backround when using a light theme. And flipping it back when using a dark theme. Makes me wish they had that auto contrast feature.


Definitely one of the deeper rabbit holes to let yourself fall into when you feel like procrastinating. I'm content if both syntax coloring in vim and file type coloring in the shell are readable. I've got more interesting things to do.


> problem 9: commands disabling colours when writing to a pipe

An alternative to the suggested unbuffer trick is to tell your receiving programs to handle color by default (case-by-case or in .profile)

    LESS=-R less
> LS_COLORS

man dircolors(1) has more info


This isn't an alternative since most programs won't send the color by default to a pipe (however, it is much better to use less -R than the article's -r so you don't get other escape codes causing trouble). The alternative to unbuffer is that most commands that use color (in my experience) recognize --color=always (or --color=never or the usual default --color=auto for no color to pipes).



The bright green on white is somehow hard to read for me


People in this thread complain about 8/24 bit colors, but how difficult would it be to have terminal emulator simply map 8/24 bit colors to the 16 ANSI color palette? Shouldn't that resolve most of the concerns?


The 16-color palette is pretty limited so even for text that would be readable with full color, you can end up with either invisible text (black on black, for example) or really ugly and glaring (red on blue).

Mapping from 24-bit color to the 256 color cube is pretty reasonable though, since the colors are close enough that you would have a hard time reading them in the first place.


No they are not. I've played MUDs enough years on my life to know that the best is black background, bright green letters. Prompt with white. Exits/entries with Yellow. Chats with light blue/aqua.


The approach I find most practical is:

– Only use the 16 ANSI colors, with the default (or user-configurable) background.

– Configure the 16 colors on your terminal client so that they are readable on your chosen background color(s).


Yep. I used to waste so much time on tweaking colors and themes. I just go with the defaults now. I don't always like them, but screwing around with colors and fonts is just an endless no-win battle. No matter what you come up with you'll run into an app that does something nonstandard and then your carefully constructed theme looks like crap.


I learned this a few years back when switching back to KDE after being a MATE user... for some reason KDE insists on using a different palette, so it breaks some apps that use colours...


I hate how the macos terminal "helpfully" adjusts colors. That just means I can't get my custom theme to look right.


An aside, but I love the Serendipity V1 (the new version not so much) VSCode theme, wondering if anyone else has used it?


I just disable colors wherever I can. And curse the UEFI shell and its dark-blue-on-black whenever I'm forced to use it..


Glad to see someone else to use solarized light in terminal. I have this in terminal, vim, mc... custom tweaked and I love it.


My personal rant is terminals where you cannot configure the default `TERM`.


The base16 shell script thing is new to me, that's really neat if it works.


Problem 8: I am not really an mc user but I don't find the screenshot with the solarized theme disorienting at all.

Everything is legible. You need to be the pickiest picky princess of pea to be annoyed by that.


(Not an mc user either.) Agreed -- and even if one were disoriented, the mc man page shows that mc colors are fully configurable -- a solution to Problem 8 not mentioned in the article.


Tango color scheme. Perfect for everything.


Really?

I still think that white on black and green on black still work very well. At least for me in the past 40 years.


The answer seems to be “there’s no standard, terminal emulators just choose colours and it’s not very consistent”.

The colors themselves are one part of the equation, the other being the mapping to semantic elements, like GUI widgets or syntax groups.

I feel there are some unwritten rules despite and beneath all the apparent inconsistency.

For example keywords are almost universally somewhere in the red blue area, never green. For comments it's the opposite, most often greenish or grey.

But this is all tacit and to the best if knowledge nowhere written down.


> The answer seems to be “there’s no standard, terminal emulators just choose colours and it’s not very consistent”.

It does seem like half this article is correctly answered by "there is a standard (VGA), but some terminals (and in particular, the Solarized colorschemes) trample all over it and break everything."

Like, there are indeed a lot of buggy terminals, but Solarized will ONLY ever make things worse, since all correct programs assume something close to VGA.


> For example keywords are almost universally somewhere in the red blue area, never green.

This isn’t true. Blue’s probably most common these days, but black, orange, brown, yellow, green… they’re all pretty common, probably similarly common to red. In Pygments, the default theme even uses bold green for keywords.

> For comments it's the opposite, most often greenish or grey.

OK, this one’s more true. Other colours are sometimes used, but greens and greys are far and away the most common.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: