Skip to main content
  1. πŸ“ Notes/

Automatically adapt Helix Theme to macOS System Appearance

The problem: you switch macOS system appearance to Light/Dark theme, but Helixβ€˜ appearance does not adjust.

Apparently, I’m not the only one who is bothering to switch Helix appearance at runtime. There are a couple of Github issues discussing the topic from different angles:

While there is no native solution (yet), I found a pretty reliable workaround that I can use until native support lands on main.

The solution is built around the fact, that helix config can be reloaded via

$ pkill -USR1 hx

So setting my beloved cattpuccin_frappe can be achieved in a one liner:

$ sed -i 's/theme .*/theme = "cattpuccin_frappe"/' ~/.config/helix/config.toml && \
  pkill -USR1 hx

To automate the switch on system appearance chance, we can use the same tool Neovim people use: dark-notify. It is a program watching for when macOS switches its appearance (dark/light mode). We can install it via brew:

$ brew install cormacrelf/tap/dark-notify

Now we slightly improve our interface to toggle helix theme via a short bash script:

#!/usr/bin/env bash

set -e -u -o pipefail

HELIX_CONFIG_PATH="${HOME}/.config/helix/config.toml"
HELIX_THEME_LIGHT="catppuccin_latte"
HELIX_THEME_DARK="catppuccin_frappe"

switch_helix_theme() {
  local theme=$1
  if [[ $theme == "light" ]]; then
    
    # Set the light theme
    sed -i '' -E "s/^theme .*/theme = \"$HELIX_THEME_LIGHT\"/" "$HELIX_CONFIG_PATH"
  elif [[ $theme == "dark" ]]; then
      
    # Set the dark theme
    sed -i '' -E "s/^theme .*/theme = \"$HELIX_THEME_DARK\"/" "$HELIX_CONFIG_PATH"
  else
    echo "Error: Invalid theme '$theme'. Expected 'light' or 'dark'." >&2
    exit 1
  fi

  pkill -USR1 hx || true
}

if [[ $# -eq 0 ]]; then
  echo "Error: Missing theme argument." >&2
  exit 1
fi

switch_helix_theme "$1"

Now we need to set a launchd configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>local.cvoigt.dark-notify</string>

    <key>ProgramArguments</key>
    <array>
      <string>/opt/homebrew/bin/dark-notify</string>
      <string>-c</string>
      <string>/Users/c.voigt/go/src/github.com/voigt/dotfiles/themes/toggle_system_appearance.sh</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>
 	</dict>
</plist>

Obviously you will have to adjust the path to your bash script. Please note, that the path has to be absolute; relative paths won’t work.

I stored the service in ~/Library/LaunchAgents as local.cvoigt.dark-notify.plist.

Note: the filename and the Label value need to match. So my file name is local.cvoigt.dark-notify.plist, which means the Label needs to be local.cvoigt.dark-notify

Finally, load the service and make sure it is listed among the running services.

$ launchctl load ~/Library/LaunchAgents/local.cvoigt.dark-notify.plist

$ launchctl list | grep dark-notify
61513   0       local.cvoigt.dark-notif

Done correctly, your Helix theme should now adapt within milliseconds to your systems appearance.



Christoph Voigt
Author
Christoph Voigt
A little bit about you