Now that Gnome has a feature to toggle between dark and light color schemes on the fly, it would be nice to make vim take that into account and switch it's theme accordingly. I'm using tmux for my multiplexer, which makes it easier to achieve this. In short, the steps are:
I'm using Lucius theme for vim. The trick boils down to doing a system call to gsettings get org.gnome.desktop.interface color-scheme
and seeing if it's set to default or prefer-light. Anything else (usually prefer-dark) means dark mode. Add the following to your .vimrc:
function! ChangeBackground()
let $gnome_color_scheme = system('gsettings get org.gnome.desktop.interface color-scheme
\ | tr -d "''"
\ | tr -d \\n')
if $gnome_color_scheme == "default" || "prefer-light"
LuciusWhiteHighContrast
else
LuciusBlackHighContrast
endif
endfunction
call ChangeBackground()
The whole thing is wrapped into a function, so the toggling can be done in ex mode by calling it. This will become important later on.
gsettings
returns it's output surrounded by single quites and adds a newline, so we have to use tr
to remove all that junk. Vimscript has to escape single quote by putting another single quote in front of it, that's why tr -d "''"
is the way it is. Same with backslash in front of \n
.
I'm also using lightline status line. Lightline's solarized, PaperColor, and one colorschemes automatically adjust based on background color (light or dark) when vim is opened, although the plugin doesn't do this when vim is already opened. To get lightline to work we have to do the following:
set laststatus=2
set noshowmode
let g:lightline = { 'colorscheme': 'one', }
autocmd OptionSet background
\ execute 'source' globpath(&rtp, 'autoload/lightline/colorscheme/one.vim')
\ | call lightline#init()
\ | call lightline#colorscheme()
\ | call lightline#update()
The one downside to all this is that if you already have vim open you have to do :so ~/.vimrc
or :call ChangeBackground()
in ex mode to toggle the color scheme. To get around this you can set up a bash script that swaps between light and dark Gnome themes, then bind it to a key combo. The method I use is described in my other post. To make that script work with vim you'll need to make a small addition that iterates through all tmux panes, checks if vim is running in them and if so, runs the ChangeBackround() function in vim which will adapt to the current Gnome color schme. So, the script would look like this:
#!/usr/bin/env bash
class=org.gnome.desktop.interface
name=color-scheme
status=$(gsettings get "$class" "$name" | tr -d "'")
if [[ $status = "default" || $status = "prefer-light" ]]; then
new_status="prefer-dark"
else
new_status="default"
fi
gsettings set "$class" "$name" "$new_status"
for session in $(tmux list-sessions -F '#{session_name}'); do
for window in $(tmux list-windows -t $session -F "$session:#{window_index}"); do
for pane in $(tmux list-panes -t $window -F "$window.#{pane_index}"); do
pane_content=$(ps -o state= -o comm= -t $(tmux display -t $pane -p '#{pane_tty}'))
if [[ $(echo $pane_content | grep -i 'vim') ]]
then
tmux if-shell -t "$pane" "" "send-keys -t $pane escape ENTER"
tmux if-shell -t "$pane" "" "send-keys -t $pane ':call ChangeBackground()' ENTER"
fi
done
done
done
Now whenever you press the key combo you defined for this script (Super + D
in my case), Gnome will toggle it's color scheme and so will vim if it is open in any of your tmux panes.
You can view my full vimrc here.