{ config, lib, pkgs, ... }: with lib; let cfg = config.programs.kitty.extras; # Create a Kitty config string from a Nix set setToKittyConfig = with generators; toKeyValue { mkKeyValue = mkKeyValueDefault { } " "; }; # Write a Nix set representing a kitty config into the Nix store writeKittyConfig = fileName: config: pkgs.writeTextDir "${fileName}" (setToKittyConfig config); # Path in Nix store containing light and dark kitty color configs kitty-colors = pkgs.symlinkJoin { name = "kitty-colors"; paths = [ (writeKittyConfig "dark.conf" cfg.colors.dark) (writeKittyConfig "light.conf" cfg.colors.light) ]; }; # Shell scripts for changing Kitty colors term-background = pkgs.writeShellScriptBin "term-background" '' # Accepts arguments "light" or "dark". # If shell is running in a Kitty window set the colors. if [ -n "$KITTY_WINDOW_ID" ]; then kitty @ --to $KITTY_LISTEN_ON set-colors --all --configured \ ${kitty-colors}/"$1".conf & fi ''; term-light = pkgs.writeShellScriptBin "term-light" '' ${term-background}/bin/term-background light ''; term-dark = pkgs.writeShellScriptBin "term-dark" '' ${term-background}/bin/term-background dark ''; in { options.programs.kitty.extras = { colors = { enable = mkOption { type = types.bool; default = false; description = '' When enabled, commands term-dark and term-light will toggle between your dark and a light colors. term-background which accepts one argument (the value of which should be dark or light) is also available. (Note that the Kitty setting allow_remote_control = true is set to enable this functionality.) ''; }; dark = mkOption { type = with types; attrsOf str; description = '' Kitty color settings for dark background colorscheme. ''; }; light = mkOption { type = with types; attrsOf str; description = '' Kitty color settings for light background colorscheme. ''; }; }; useSymbolsFromNerdFont = mkOption { type = types.str; default = ""; example = "JetBrainsMono Nerd Font"; description = '' NerdFont patched fonts frequently suffer from rendering issues in terminals. To mitigate this, we can use a non-NerdFont with Kitty and use the symbol_map setting to tell Kitty to only use a NerdFont for NerdFont symbols. Set this option the name of an installed NerdFont (the same name you'd use in the font_family setting), to enable this feature. ''; }; fixIcon = { enable = mkOption { type = types.bool; default = false; description = '' When enabled, uses fileicon (should be installed via homebrew) to fixup the icon. ''; }; appPath = mkOption { type = types.str; default = null; description = ''Path to kitty.app''; }; iconPath = mkOption { type = types.str; default = null; description = ''Path to kitty icns''; }; }; }; config = mkIf config.programs.kitty.enable { home.packages = mkIf cfg.colors.enable [ term-light term-dark term-background ]; home.activation = let fileicon = "/opt/homebrew/bin/fileicon"; in mkIf (pkgs.stdenv.isDarwin && cfg.fixIcon.enable) { cleanupKittyIcon = lib.hm.dag.entryBetween [ "darwinApps" ] [ "writeBoundary" ] '' if ${fileicon} test ${cfg.fixIcon.appPath}; then $DRY_RUN_CMD sudo ${fileicon} rm ${cfg.fixIcon.appPath} fi ''; fixKittyIcon = lib.hm.dag.entryAfter [ "darwinApps" ] '' $DRY_RUN_CMD sudo ${fileicon} set ${cfg.fixIcon.appPath} ${cfg.fixIcon.iconPath} ''; }; programs.kitty.settings = optionalAttrs cfg.colors.enable { allow_remote_control = "yes"; listen_on = "unix:/tmp/mykitty"; } // optionalAttrs (cfg.useSymbolsFromNerdFont != "") { # https://github.com/ryanoasis/nerd-fonts/wiki/Glyph-Sets-and-Code-Points symbol_map = "U+E5FA-U+E62B,U+E700-U+E7C5,U+F000-U+F2E0,U+E200-U+E2A9,U+F500-U+FD46,U+E300-U+E3EB,U+F400-U+F4A8,U+2665,U+26a1,U+F27C,U+E0A3,U+E0B4-U+E0C8,U+E0CA,U+E0CC-U+E0D2,U+E0D4,U+23FB-U+23FE,U+2B58,U+F300-U+F313,U+E000-U+E00D ${cfg.useSymbolsFromNerdFont}"; }; xdg.configFile."kitty/macos-launch-services-cmdline" = mkIf (pkgs.stdenv.isDarwin && cfg.colors.enable) { text = "--listen-on unix:/tmp/mykitty"; }; }; }