main
  1{
  2  den.aspects.desktop.ime.fcitx5 = {
  3    persistHome = {config, ...}: {
  4      directories = [
  5        "${config.xdg.data.directory}/fcitx5/rime" # RIME data
  6      ];
  7    };
  8
  9    nixos = {
 10      pkgs,
 11      config,
 12      ...
 13    }: let
 14      rime-frost = pkgs.stdenvNoCC.mkDerivation (finalAttrs: {
 15        pname = "rime-ice";
 16        version = "0-unstable-2026-08-16";
 17
 18        src = pkgs.fetchFromGitHub {
 19          owner = "gaboolic";
 20          repo = "rime-frost";
 21          rev = "6b74e54da2737d9b9ba8c502ce697145f94504ba";
 22          hash = "sha256-NKqjw7izkbNll9dM9qhjgW0IXUFz4o3l9uVOckyLx+w=";
 23        };
 24
 25        installPhase = ''
 26          runHook preInstall
 27
 28          rm -rf others README.md .git*
 29
 30          mv default.yaml rime_frost_suggestion.yaml
 31
 32          mkdir -p $out/share
 33          cp -r . $out/share/rime-data
 34
 35          runHook postInstall
 36        '';
 37
 38        meta = {
 39          homepage = "https://github.com/gaboolic/rime-frost";
 40          changelog = "https://github.com/gaboolic/rime-frost/blob/main/others/CHANGELOG.md";
 41          license = pkgs.lib.licenses.gpl3Only;
 42        };
 43      });
 44    in {
 45      i18n.inputMethod = {
 46        enable = true;
 47        type = "fcitx5";
 48
 49        fcitx5 = {
 50          addons = with pkgs; [
 51            (fcitx5-rime.override {rimeDataPkgs = [rime-frost];})
 52            fcitx5-gtk # gtk im module
 53          ];
 54          waylandFrontend = !config.services.xserver.enable;
 55        };
 56      };
 57    };
 58
 59    provides.to-users = {
 60      hjem = {
 61        pkgs,
 62        lib,
 63        ...
 64      }: let
 65        iniFormat = pkgs.formats.ini {};
 66        iniGlobalFormat = pkgs.formats.iniWithGlobalSection {};
 67        yamlFormat = pkgs.formats.yaml {};
 68
 69        normalizeFcitx5Value = value:
 70          if lib.isAttrs value
 71          then lib.mapAttrs (_: normalizeFcitx5Value) value
 72          else if builtins.isList value
 73          then map normalizeFcitx5Value value
 74          else if builtins.isBool value
 75          then
 76            if value
 77            then "True"
 78            else "False"
 79          else value;
 80      in {
 81        xdg.config.files."fcitx5/profile" = {
 82          generator = value: iniFormat.generate "fcitx5-profile" (normalizeFcitx5Value value);
 83          value = {
 84            GroupOrder."0" = "Default";
 85            "Groups/0" = {
 86              Name = "Default";
 87              "Default Layout" = "us";
 88              DefaultIM = "rime";
 89            };
 90            "Groups/0/Items/0" = {
 91              Name = "keyboard-us";
 92              Layout = "us";
 93            };
 94            "Groups/0/Items/1" = {
 95              Name = "rime";
 96              Layout = "us";
 97            };
 98          };
 99        };
100        xdg.config.files."fcitx5/conf/rime.conf" = {
101          generator = value: iniGlobalFormat.generate "fcitx5-conf-rime.conf" (normalizeFcitx5Value value);
102          value = {
103            globalSection = {
104              PreeditMode = "Composing text";
105              InputState = "All";
106              PreeditCursorPositionAtBeginning = true;
107              SwitchInputMethodBehavior = "Commit commit preview";
108            };
109          };
110        };
111
112        xdg.data.files."fcitx5/rime/default.custom.yaml" = {
113          generator = yamlFormat.generate "fcitx5-rime-default.custom.conf";
114          value = {
115            patch.__include = "rime_frost_suggestion:/";
116          };
117        };
118      };
119    };
120  };
121
122  den.aspects.desktop.ime.fcitx5.themes = {
123    catppuccin = {
124      nixos = {pkgs, ...}: {
125        i18n.inputMethod.fcitx5.addons = [
126          (pkgs.catppuccin-fcitx5.override {withRoundedCorners = true;})
127        ];
128      };
129
130      hjem = {pkgs, ...}: {
131        xdg.config.files."fcitx5/conf/classicui.conf" = {
132          generator = (pkgs.formats.iniWithGlobalSection {}).generate "fcitx5-conf-classicui.conf";
133          value.globalSection.Theme = "catppuccin-mocha-mauve";
134        };
135      };
136    };
137  };
138}