kitty: add autoThemeFiles option

Add support for kitty's automatic theme switching based on OS
color scheme. This creates the required auto theme config files:
- light-theme.auto.conf
- dark-theme.auto.conf
- no-preference-theme.auto.conf

Closes: nix-community/home-manager#6869
This commit is contained in:
Yus314 2026-01-30 13:06:47 +09:00 committed by Robert Helgesson
parent a6c93262f3
commit de4cfffc98
5 changed files with 121 additions and 6 deletions

View file

@ -168,10 +168,52 @@ in
in `kitty-themes`, without the `.conf` suffix. See
<https://github.com/kovidgoyal/kitty-themes/tree/master/themes> for a
list of themes.
Note that if any automatic themes are configured via
`programs.kitty.autoThemeFiles`, Kitty will prefer them based on the
OS color scheme and they will override other color and background image
settings.
'';
example = "SpaceGray_Eighties";
};
autoThemeFiles = mkOption {
type = types.nullOr (
types.submodule {
options = {
light = mkOption {
type = types.str;
description = "Theme name for light color scheme.";
};
dark = mkOption {
type = types.str;
description = "Theme name for dark color scheme.";
};
noPreference = mkOption {
type = types.str;
description = "Theme name for no-preference color scheme.";
};
};
}
);
default = null;
description = ''
Configure Kitty automatic color themes. This creates
{file}`$XDG_CONFIG_HOME/kitty/light-theme.auto.conf`,
{file}`$XDG_CONFIG_HOME/kitty/dark-theme.auto.conf`, and
{file}`$XDG_CONFIG_HOME/kitty/no-preference-theme.auto.conf`.
Kitty applies these based on the OS color scheme, and they override
other color and background image settings.
'';
example = literalExpression ''
{
light = "GitHub";
dark = "TokyoNight";
noPreference = "OneDark";
}
'';
};
font = mkOption {
type = types.nullOr lib.hm.types.fontType;
default = null;
@ -358,15 +400,35 @@ in
'';
};
home.activation.checkKittyTheme = mkIf (cfg.themeFile != null) (
xdg.configFile."kitty/light-theme.auto.conf" = mkIf (cfg.autoThemeFiles != null) {
text = "include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.autoThemeFiles.light}.conf\n";
};
xdg.configFile."kitty/dark-theme.auto.conf" = mkIf (cfg.autoThemeFiles != null) {
text = "include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.autoThemeFiles.dark}.conf\n";
};
xdg.configFile."kitty/no-preference-theme.auto.conf" = mkIf (cfg.autoThemeFiles != null) {
text = "include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.autoThemeFiles.noPreference}.conf\n";
};
home.activation.checkKittyTheme = mkIf (cfg.themeFile != null || cfg.autoThemeFiles != null) (
let
themePath = "${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.themeFile}.conf";
themePath = name: "${pkgs.kitty-themes}/share/kitty-themes/themes/${name}.conf";
checkThemeFile = name: ''
if [[ ! -f "${themePath name}" ]]; then
errorEcho "kitty-themes does not contain the theme file ${themePath name}!"
exit 1
fi
'';
in
lib.hm.dag.entryBefore [ "writeBoundary" ] ''
if [[ ! -f "${themePath}" ]]; then
errorEcho "kitty-themes does not contain the theme file ${themePath}!"
exit 1
fi
${lib.optionalString (cfg.themeFile != null) (checkThemeFile cfg.themeFile)}
${lib.optionalString (cfg.autoThemeFiles != null) ''
${checkThemeFile cfg.autoThemeFiles.light}
${checkThemeFile cfg.autoThemeFiles.dark}
${checkThemeFile cfg.autoThemeFiles.noPreference}
''}
''
);

View file

@ -0,0 +1,17 @@
{
home.username = "alice";
home.homeDirectory = "/home/alice";
home.stateVersion = "24.11";
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
programs.kitty = {
enable = true;
autoThemeFiles = {
light = "GitHub";
dark = "No Such Theme";
noPreference = "OneDark";
};
};
}

View file

@ -59,6 +59,14 @@
assert expected in actual, \
f"expected home-manager switch to contain {expected}, but got {actual}"
with subtest("Switch to Bad Kitty Auto Theme"):
succeed_as_alice("cp ${./kitty-auto-theme-bad-home.nix} /home/alice/.config/home-manager/home.nix")
actual = fail_as_alice("home-manager switch")
expected = "kitty-themes does not contain the theme file"
assert expected in actual, \
f"expected home-manager switch to contain {expected}, but got {actual}"
with subtest("Switch to Good Kitty"):
succeed_as_alice("cp ${./kitty-theme-good-home.nix} /home/alice/.config/home-manager/home.nix")

View file

@ -0,0 +1,27 @@
{ config, pkgs, ... }:
{
programs.kitty = {
enable = true;
autoThemeFiles = {
light = "GitHub";
dark = "TokyoNight";
noPreference = "OneDark";
};
};
test = {
assertFileExists = [
"home-files/.config/kitty/light-theme.auto.conf"
"home-files/.config/kitty/dark-theme.auto.conf"
"home-files/.config/kitty/no-preference-theme.auto.conf"
];
assertFileRegex = [
"home-files/.config/kitty/light-theme.auto.conf"
"^include .*themes/GitHub\\.conf$"
"home-files/.config/kitty/dark-theme.auto.conf"
"^include .*themes/TokyoNight\\.conf$"
"home-files/.config/kitty/no-preference-theme.auto.conf"
"^include .*themes/OneDark\\.conf$"
];
};
}

View file

@ -4,4 +4,5 @@
kitty-null-shellIntegration = ./null-shellIntegration.nix;
kitty-example-mkOrder = ./example-mkOrder.nix;
kitty-example-quickAccessTerminalConfig = ./example-quickAccessTerminalConfig.nix;
kitty-auto-theme-files = ./auto-theme-files.nix;
}