Switch Effortlessly Between Light and Dark Colors, in your Shell and in your IDE
These days, every editor and every terminal provide a way to configure its colors of its UI. The set of colors is commonly known as the color scheme (or colorscheme). There are hundreds of color schemes out there for you to pick. These include “Gruvbox”, “Nord”, “Monokai”, “OneDark”. Some of them mix together a large range of the color palette, while others lean on variations of a single color, like green or blue etc…
For the purpose of this post, I will simply classify them in 2 broad categories:
- The light color schemes,
- the dark color schemes.


For most devs, picking their color scheme comes down to personal preference. This preference might evolve over a period of time, maybe a few weeks or months. Hence, for them there is no need to tinker with the color scheme configuration that often.
However, for the experienced outdoor roboticist, the choice of color scheme is more practical. Suppose you are the field on a sunny day, and you are monitoring and debugging your mobile robot through an ssh connection with your laptop. Working with a dark color scheme in those conditions is next to impossible as you cannot see anything on the screen. Conversely, in a shadowy area a light color scheme might be too contrasted. Then, you might want to switch back to your favorite setting in normal (office) conditions.
Switching back and forth the colors manually in all our terminals1 and all our IDEs can be tedious. Additionally, we might not want to quit our opened terminals because we want to analyze realtime logs.
Thankfully, in Linux, we can easily craft some solutions to adapt the colors quickly and efficiently.
In this post, I detail how I switch between light and dark in a few keystrokes,
both in an IDE (neovim
) and in the terminal (alacritty
) 2.
Switch colors in alacritty
terminal
The alacritty
configuration is saved into the
$XDG_CONFIG_HOME/alacritty/alacritty.yml
file. With no surprise, the colors
field is what we are looking for.
My configuration is as follows:
# my dark colors
gruvboxDark: &gruvboxDark
primary:
background: "#282828"
foreground: "#ebdbb2"
normal:
black: "#282828"
red: "#cc241d"
green: "#98971a"
yellow: "#d79921"
blue: "#458588"
magenta: "#b16286"
cyan: "#689d6a"
white: "#a89984"
bright:
black: "#928374"
red: "#fb4934"
green: "#b8bb26"
yellow: "#fabd2f"
blue: "#83a598"
magenta: "#d3869b"
cyan: "#8ec07c"
white: "#ebdbb2"
# my light colors
gruvboxLight: &gruvboxLight
primary:
background: "#ffffff"
foreground: "#1a1b17"
normal:
black: "#fbf1c7"
red: "#cc241d"
green: "#5F5F10"
yellow: "#d79921"
blue: "#458588"
magenta: "#b16286"
cyan: "#689d6a"
white: "#7c6f64"
bright:
black: "#928374"
red: "#9d0006"
green: "#79740e"
yellow: "#b57614"
blue: "#076678"
magenta: "#8f3f71"
cyan: "#427b58"
white: "#3c3836"
# the loaded colors
colors: *gruvboxDark #Light
The fields gruvboxLight
and gruvboxDark
are custom entries that contain the
color values in hex
format. By themselves they have no effect on the drawn
colors, unless they are selected by the colors
field through this pointer
inspired syntax. In this instance, the dark colors are pointed to.
To switch to light colors, I can edit the last line to:
colors: *gruvboxLight #Dark
It is a nice perk of alacritty
that live terminal sessions are reactive to
change in the config file.
Of course, we don’t want to manually edit that. In fact, I use a sed
command
to switch this line for me.
You might notice that I’ve left out a trailing comment #Light
/#Dark
in the
line of interest. This is because I want my sed
program to capture the current
color (resp. Light or Dark) and the commented color (resp. Dark or Light), and
then switch places.
This is achieved by using “captured group” in the regular expression:
sed 's/colors: \*gruvbox\(.*\) #\(.*\)/colors: \*gruvbox\2 #\1/' \
$XDG_CONFIG_HOME/alacritty/alacritty.yml \
-i --follow-symlinks
Inside the sed
“find” regular expression, the current color gets saved into
the first capture \1
, and the commented color gets saved into the second
capture group \2
. The “replace” regular expression simply flip the positions
of both captured items.
The sed
flags:
-i
edit the file in-place,--follow-symlinks
edits the file anyway if$XDG_CONFIG_HOME/alacritty/alacritty.yml
is in fact a symlink. As implied, this flag is not necessary unless, your config files (dotfiles) are located in an out-of-tree repository that distributes soft symbolic links in your$XDG
paths.
This command can then be easily called in the shell since it is now in your
$PATH
. You can even bind a shortcut to it in your desktop manager.
Adapting this approach to some other color scheme than gruvbox
is
straightforward. We could even be agnostic to the color scheme name by simply
using mycolorsDark
instead of gruvboxDark
and defer the interpretation of
mycolors
to another variable in the config.
We now turn our attention to switching the colors in our editor (or IDE).
Switch colors in neovim
Switching dark and light colors, with a shortcut, is a smoother process. In
neovim
(and vim
for that matter), we can get or set the current color via
the option background
(use :set background
in ex mode).
Trivially, I map the shortcut <space>y
(‘space’ then ‘y’) to make the switch
in my init.lua
config:
vim.keymap.set("nv","<space>y",function()
if vim.o.background=="light" then
vim.o.background="dark"
else
vim.o.background="light"
end
end,{noremap=true,silent=true})
Here, I have used the vim.keymap.set
API to add this shortcut in normal and
visual mode (the "nv"
part). If the current background
option is set to
light (resp. dark), it becomes dark (resp. light).
Alternatively, you could also change the function content, where instead of
changing the background
option, you would load another color scheme via
vim.cmd("colorscheme myFavoriteColorschemeForLightMode")
.
Footnotes
-
In a ROS framework, the number of monitoring terminals (e.g.
rostopic echo /cmd_vel
) is at least linear in the number of nodes of interest in the system. Even if you group them with a tool liketmux
, as I will recommend in an upcoming post, you might still open several instances to view them simultaneously. ↩ -
As is often the case in this blog, what’s important is not so much the specific terminal/IDE software used, but the approach proposed and its philosophy, which in my experience can be easily transfered on other free & open source software. ↩