1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 imcfg = config.i18n.inputMethod;
9 cfg = imcfg.fcitx5;
10 fcitx5Package =
11 if cfg.plasma6Support then
12 pkgs.qt6Packages.fcitx5-with-addons.override { inherit (cfg) addons; }
13 else
14 pkgs.libsForQt5.fcitx5-with-addons.override { inherit (cfg) addons; };
15 settingsFormat = pkgs.formats.ini { };
16in
17{
18 options = {
19 i18n.inputMethod.fcitx5 = {
20 addons = lib.mkOption {
21 type = with lib.types; listOf package;
22 default = [ ];
23 example = lib.literalExpression "with pkgs; [ fcitx5-rime ]";
24 description = ''
25 Enabled Fcitx5 addons.
26 '';
27 };
28 waylandFrontend = lib.mkOption {
29 type = lib.types.bool;
30 default = false;
31 description = ''
32 Use the Wayland input method frontend.
33 See [Using Fcitx 5 on Wayland](https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland).
34 '';
35 };
36 plasma6Support = lib.mkOption {
37 type = lib.types.bool;
38 default = config.services.desktopManager.plasma6.enable;
39 defaultText = lib.literalExpression "config.services.desktopManager.plasma6.enable";
40 description = ''
41 Use qt6 versions of fcitx5 packages.
42 Required for configuring fcitx5 in KDE System Settings.
43 '';
44 };
45 quickPhrase = lib.mkOption {
46 type = with lib.types; attrsOf str;
47 default = { };
48 example = lib.literalExpression ''
49 {
50 smile = "(・∀・)";
51 angry = "( ̄ー ̄)";
52 }
53 '';
54 description = "Quick phrases.";
55 };
56 quickPhraseFiles = lib.mkOption {
57 type = with lib.types; attrsOf path;
58 default = { };
59 example = lib.literalExpression ''
60 {
61 words = ./words.mb;
62 numbers = ./numbers.mb;
63 }
64 '';
65 description = "Quick phrase files.";
66 };
67 settings = {
68 globalOptions = lib.mkOption {
69 type = lib.types.submodule {
70 freeformType = settingsFormat.type;
71 };
72 default = { };
73 description = ''
74 The global options in `config` file in ini format.
75 '';
76 };
77 inputMethod = lib.mkOption {
78 type = lib.types.submodule {
79 freeformType = settingsFormat.type;
80 };
81 default = { };
82 description = ''
83 The input method configure in `profile` file in ini format.
84 '';
85 };
86 addons = lib.mkOption {
87 type = with lib.types; (attrsOf anything);
88 default = { };
89 description = ''
90 The addon configures in `conf` folder in ini format with global sections.
91 Each item is written to the corresponding file.
92 '';
93 example = lib.literalExpression "{ pinyin.globalSection.EmojiEnabled = \"True\"; }";
94 };
95 };
96 ignoreUserConfig = lib.mkOption {
97 type = lib.types.bool;
98 default = false;
99 description = ''
100 Ignore the user configures. **Warning**: When this is enabled, the
101 user config files are totally ignored and the user dict can't be saved
102 and loaded.
103 '';
104 };
105 };
106 };
107
108 imports = [
109 (lib.mkRemovedOptionModule [ "i18n" "inputMethod" "fcitx5" "enableRimeData" ] ''
110 RIME data is now included in `fcitx5-rime` by default, and can be customized using `fcitx5-rime.override { rimeDataPkgs = ...; }`
111 '')
112 ];
113
114 config = lib.mkIf (imcfg.enable && imcfg.type == "fcitx5") {
115 i18n.inputMethod.package = fcitx5Package;
116
117 i18n.inputMethod.fcitx5.addons =
118 lib.optionals (cfg.quickPhrase != { }) [
119 (pkgs.writeTextDir "share/fcitx5/data/QuickPhrase.mb" (
120 lib.concatStringsSep "\n" (
121 lib.mapAttrsToList (
122 name: value: "${name} ${builtins.replaceStrings [ "\\" "\n" ] [ "\\\\" "\\n" ] value}"
123 ) cfg.quickPhrase
124 )
125 ))
126 ]
127 ++ lib.optionals (cfg.quickPhraseFiles != { }) [
128 (pkgs.linkFarm "quickPhraseFiles" (
129 lib.mapAttrs' (
130 name: value: lib.nameValuePair ("share/fcitx5/data/quickphrase.d/${name}.mb") value
131 ) cfg.quickPhraseFiles
132 ))
133 ];
134 environment.etc =
135 let
136 optionalFile =
137 p: f: v:
138 lib.optionalAttrs (v != { }) {
139 "xdg/fcitx5/${p}".text = f v;
140 };
141 in
142 lib.attrsets.mergeAttrsList [
143 (optionalFile "config" (lib.generators.toINI { }) cfg.settings.globalOptions)
144 (optionalFile "profile" (lib.generators.toINI { }) cfg.settings.inputMethod)
145 (lib.concatMapAttrs (
146 name: value: optionalFile "conf/${name}.conf" (lib.generators.toINIWithGlobalSection { }) value
147 ) cfg.settings.addons)
148 ];
149
150 environment.variables =
151 {
152 XMODIFIERS = "@im=fcitx";
153 QT_PLUGIN_PATH = [ "${fcitx5Package}/${pkgs.qt6.qtbase.qtPluginPrefix}" ];
154 }
155 // lib.optionalAttrs (!cfg.waylandFrontend) {
156 GTK_IM_MODULE = "fcitx";
157 QT_IM_MODULE = "fcitx";
158 }
159 // lib.optionalAttrs cfg.ignoreUserConfig {
160 SKIP_FCITX_USER_PATH = "1";
161 };
162 };
163}