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
 68        normalizeFcitx5Value = value:
 69          if lib.isAttrs value
 70          then lib.mapAttrs (_: normalizeFcitx5Value) value
 71          else if builtins.isList value
 72          then map normalizeFcitx5Value value
 73          else if builtins.isBool value
 74          then
 75            if value
 76            then "True"
 77            else "False"
 78          else value;
 79      in {
 80        xdg.config.files."fcitx5/profile" = {
 81          generator = value: iniFormat.generate "fcitx5-profile" (normalizeFcitx5Value value);
 82          value = {
 83            GroupOrder."0" = "Default";
 84            "Groups/0" = {
 85              Name = "Default";
 86              "Default Layout" = "us";
 87              DefaultIM = "rime";
 88            };
 89            "Groups/0/Items/0" = {
 90              Name = "keyboard-us";
 91              Layout = "us";
 92            };
 93            "Groups/0/Items/1" = {
 94              Name = "rime";
 95              Layout = "us";
 96            };
 97          };
 98        };
 99        xdg.config.files."fcitx5/conf/rime.conf" = {
100          generator = value: iniGlobalFormat.generate "fcitx5-conf-rime.conf" (normalizeFcitx5Value value);
101          value = {
102            globalSection = {
103              PreeditMode = "Composing text";
104              InputState = "All";
105              PreeditCursorPositionAtBeginning = true;
106              SwitchInputMethodBehavior = "Commit commit preview";
107            };
108          };
109        };
110
111        xdg.data.files = builtins.listToAttrs (
112          map (name: {
113            name = "fcitx5/rime/${name}";
114            value = {
115              source = toString ./rime/${name};
116            };
117          }) (builtins.attrNames (builtins.readDir ./rime))
118        );
119      };
120    };
121  };
122
123  den.aspects.desktop.ime.fcitx5.themes = {
124    catppuccin = {
125      nixos = {pkgs, ...}: {
126        i18n.inputMethod.fcitx5.addons = [
127          (pkgs.catppuccin-fcitx5.override {withRoundedCorners = true;})
128        ];
129      };
130
131      hjem = {pkgs, ...}: {
132        xdg.config.files."fcitx5/conf/classicui.conf" = {
133          generator = (pkgs.formats.iniWithGlobalSection {}).generate "fcitx5-conf-classicui.conf";
134          value.globalSection.Theme = "catppuccin-mocha-mauve";
135        };
136      };
137    };
138  };
139}