Handle doom emacs theme

This commit is contained in:
Alexander
2026-07-03 17:43:39 +02:00
parent 27409eb5fa
commit 6f2598ef52
2 changed files with 56 additions and 2 deletions
+29 -1
View File
@@ -30,15 +30,21 @@ let
availableVariants = concatStringsSep " " (attrNames themeVariants);
# variant:doomtheme pairs consumed by the theme-switch script's
# best-effort Doom Emacs hook (see ./theme-switch.sh).
doomThemeMap = concatStringsSep " "
(mapAttrsToList (variant: theme: "${variant}:${theme}") cfg.doomThemes);
# Userspace theme switcher: activates a pre-built Home Manager
# specialisation generation. No sudo, no OS rebuild — just runs the
# specialisation's activation script in the base HM generation.
#
# The script logic lives in ./theme-switch.sh (plain shell, no Nix
# escaping); we only inject the two config-derived values it needs.
# escaping); we only inject the config-derived values it needs.
theme-switch = pkgs.writeShellScriptBin "theme-switch" ''
baseVariant="${baseVariant}"
availableVariants="${availableVariants}"
doomThemes="${doomThemeMap}"
${builtins.readFile ./theme-switch.sh}
'';
@@ -67,6 +73,28 @@ in {
default = builtinThemes;
description = "Available themes with dark and light variants";
};
doomThemes = mkOption {
type = types.attrsOf types.str;
default = {
gruvbox-dark = "doom-gruvbox";
gruvbox-light = "doom-one-light";
catppuccin-dark = "doom-one";
catppuccin-light = "doom-one-light";
};
description = ''
Mapping from theme variant name (e.g. "gruvbox-dark") to the Doom
Emacs theme symbol (e.g. "doom-gruvbox") that theme-switch will
live-load via emacsclient when switching to that variant. Variants
absent from this map are left unchanged in Emacs.
Only themes actually installed in Doom will load; the defaults use
themes bundled with doom-themes (so they work out of the box, though
catppuccin variants fall back to generic dark/light). For accurate
catppuccin colours, install the `catppuccin-theme` Emacs package and
map the variants to `catppuccin-mocha` / `catppuccin-latte`.
'';
};
};
config = mkIf cfg.enable (
+27 -1
View File
@@ -1,18 +1,22 @@
# shellcheck shell=bash
# theme-switch — activate a pre-built Home Manager specialisation.
#
# Expects two variables to be injected by the Nix wrapper:
# Expects these variables to be injected by the Nix wrapper:
# baseVariant the variant that is the generation itself (not a
# specialisation), activated via `$gen/activate`.
# availableVariants space-separated list of all variant names (help text).
# doomThemes optional space-separated `variant:doomtheme` pairs for
# the best-effort Doom Emacs live-switch (may be empty).
#
# Standalone usage for testing:
# baseVariant=gruvbox-dark \
# availableVariants="gruvbox-dark gruvbox-light catppuccin-dark catppuccin-light" \
# doomThemes="gruvbox-dark:doom-gruvbox" \
# bash theme-switch.sh <variant>
: "${baseVariant:?theme-switch: baseVariant not set}"
: "${availableVariants:?theme-switch: availableVariants not set}"
: "${doomThemes:=}"
set -euo pipefail
variant="${1:-}"
@@ -74,4 +78,26 @@ if [ ! -x "$activate" ]; then
fi
echo "Switching theme to $variant..."
# Best-effort: live-switch the running Doom Emacs daemon too. No config
# files are touched; if the daemon isn't running or emacsclient isn't
# installed (e.g. on a server), this is silently skipped. A theme symbol
# that isn't installed in Doom makes emacsclient return non-zero, which we
# also treat as skip.
doom_theme=""
if [ -n "$doomThemes" ]; then
for pair in $doomThemes; do
case "$pair" in
"${variant}":*) doom_theme="${pair#*:}"; break ;;
esac
done
fi
if [ -n "$doom_theme" ] && command -v emacsclient >/dev/null 2>&1; then
if emacsclient --eval "(progn (mapc (function disable-theme) custom-enabled-themes) (load-theme (quote ${doom_theme}) t))" >/dev/null 2>&1; then
echo "Doom: ${doom_theme}"
else
echo "note: Doom theme switch skipped (daemon not running or '${doom_theme}' not installed)" >&2
fi
fi
exec "$activate"