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