diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3250c615..b487576f 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,6 +4,9 @@
/modules/home-environment.nix @rycee
+/modules/i18n/input-method @Kranzes
+/tests/modules/i18n/input-method @Kranzes
+
/modules/misc/dconf.nix @gnidorah @rycee
/modules/misc/fontconfig.nix @rycee
diff --git a/modules/i18n/input-method/default.nix b/modules/i18n/input-method/default.nix
new file mode 100644
index 00000000..0abfec17
--- /dev/null
+++ b/modules/i18n/input-method/default.nix
@@ -0,0 +1,102 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+let
+
+ cfg = config.i18n.inputMethod;
+
+ gtk2Cache = pkgs.runCommandLocal "gtk2-immodule.cache" {
+ buildInputs = [ pkgs.gtk2 cfg.package ];
+ } ''
+ mkdir -p $out/etc/gtk-2.0/
+ GTK_PATH=${cfg.package}/lib/gtk-2.0/ \
+ gtk-query-immodules-2.0 > $out/etc/gtk-2.0/immodules.cache
+ '';
+
+ gtk3Cache = pkgs.runCommandLocal "gtk3-immodule.cache" {
+ buildInputs = [ pkgs.gtk3 cfg.package ];
+ } ''
+ mkdir -p $out/etc/gtk-3.0/
+ GTK_PATH=${cfg.package}/lib/gtk-3.0/ \
+ gtk-query-immodules-3.0 > $out/etc/gtk-3.0/immodules.cache
+ '';
+
+in {
+ imports =
+ [ ./fcitx.nix ./fcitx5.nix ./hime.nix ./kime.nix ./nabi.nix ./uim.nix ];
+
+ options.i18n = {
+ inputMethod = {
+ enabled = mkOption {
+ type = types.nullOr
+ (types.enum [ "fcitx" "fcitx5" "nabi" "uim" "hime" "kime" ]);
+ default = null;
+ example = "fcitx";
+ description = ''
+ Select the enabled input method. Input methods is a software to input
+ symbols that are not available on standard input devices.
+
+ Input methods are specially used to input Chinese, Japanese and Korean
+ characters.
+
+ Currently the following input methods are available in Home Manager:
+
+
+
+ fcitx
+
+ A customizable lightweight input method
+ extra input engines can be added using
+ i18n.inputMethod.fcitx.engines.
+
+
+
+ fcitx5
+
+ The next generation of fcitx,
+ addons (including engines, dictionaries, skins) can be added using
+ i18n.inputMethod.fcitx5.addons.
+
+
+
+ nabi
+
+ A Korean input method based on XIM. Nabi doesn't support Qt 5.
+
+
+
+ uim
+
+ The universal input method, is a library with a XIM bridge.
+ uim mainly support Chinese, Japanese and Korean.
+
+
+
+ hime
+ An extremely easy-to-use input method framework.
+
+
+ kime
+ A Korean IME.
+
+
+ '';
+ };
+
+ package = mkOption {
+ internal = true;
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ The input method method package.
+ '';
+ };
+ };
+ };
+
+ config = mkIf (cfg.enabled != null) {
+ home.packages = [ cfg.package gtk2Cache gtk3Cache ];
+ };
+
+ meta.maintainers = with lib; [ hm.maintainers.kranzes ];
+}
diff --git a/modules/i18n/input-method/fcitx.nix b/modules/i18n/input-method/fcitx.nix
new file mode 100644
index 00000000..b04382a7
--- /dev/null
+++ b/modules/i18n/input-method/fcitx.nix
@@ -0,0 +1,50 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.i18n.inputMethod.fcitx;
+ fcitxPackage = pkgs.fcitx.override { plugins = cfg.engines; };
+ fcitxEngine = types.package // {
+ name = "fcitx-engine";
+ check = x:
+ types.package.check x && attrByPath [ "meta" "isFcitxEngine" ] false x;
+ };
+in {
+ options = {
+
+ i18n.inputMethod.fcitx = {
+ engines = mkOption {
+ type = with types; listOf fcitxEngine;
+ default = [ ];
+ example = literalExample "with pkgs.fcitx-engines; [ mozc hangul ]";
+ description = let
+ enginesDrv = filterAttrs (const isDerivation) pkgs.fcitx-engines;
+ engines = concatStringsSep ", "
+ (map (name: "${name}") (attrNames enginesDrv));
+ in "Enabled Fcitx engines. Available engines are: ${engines}.";
+ };
+ };
+
+ };
+
+ config = mkIf (config.i18n.inputMethod.enabled == "fcitx") {
+ i18n.inputMethod.package = fcitxPackage;
+
+ home.sessionVariables = {
+ GTK_IM_MODULE = "fcitx";
+ QT_IM_MODULE = "fcitx";
+ XMODIFIERS = "@im=fcitx";
+ };
+
+ systemd.user.services.fcitx-daemon = {
+ Unit = {
+ Description = "Fcitx input method editor";
+ PartOf = [ "graphical-session.desktop" ];
+ };
+ Service.ExecStart = "${fcitxPackage}/bin/fcitx";
+ Install.WantedBy = [ "graphical-session.target" ];
+ };
+ };
+
+}
diff --git a/modules/i18n/input-method/fcitx5.nix b/modules/i18n/input-method/fcitx5.nix
new file mode 100644
index 00000000..29b0ed55
--- /dev/null
+++ b/modules/i18n/input-method/fcitx5.nix
@@ -0,0 +1,42 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ im = config.i18n.inputMethod;
+ cfg = im.fcitx5;
+ fcitx5Package = pkgs.fcitx5-with-addons.override { inherit (cfg) addons; };
+in {
+ options = {
+ i18n.inputMethod.fcitx5 = {
+ addons = mkOption {
+ type = with types; listOf package;
+ default = [ ];
+ example = literalExample "with pkgs; [ fcitx5-rime ]";
+ description = ''
+ Enabled Fcitx5 addons.
+ '';
+ };
+ };
+ };
+
+ config = mkIf (im.enabled == "fcitx5") {
+ i18n.inputMethod.package = fcitx5Package;
+
+ home.sessionVariables = {
+ GTK_IM_MODULE = "fcitx";
+ QT_IM_MODULE = "fcitx";
+ XMODIFIERS = "@im=fcitx";
+ };
+
+ systemd.user.services.fcitx5-daemon = {
+ Unit = {
+ Description = "Fcitx5 input method editor";
+ PartOf = [ "graphical-session.target" ];
+ };
+ Service.ExecStart = "${fcitx5Package}/bin/fcitx5";
+ Install.WantedBy = [ "graphical-session.target" ];
+ };
+ };
+
+}
diff --git a/modules/i18n/input-method/hime.nix b/modules/i18n/input-method/hime.nix
new file mode 100644
index 00000000..7b5700a9
--- /dev/null
+++ b/modules/i18n/input-method/hime.nix
@@ -0,0 +1,23 @@
+{ config, pkgs, lib, ... }:
+
+with lib; {
+ config = mkIf (config.i18n.inputMethod.enabled == "hime") {
+ i18n.inputMethod.package = pkgs.hime;
+
+ home.sessionVariables = {
+ GTK_IM_MODULE = "hime";
+ QT_IM_MODULE = "hime";
+ XMODIFIERS = "@im=hime";
+ };
+
+ systemd.user.services.hime-daemon = {
+ Unit = {
+ Description = "Hime input method editor";
+ PartOf = [ "graphical-session.desktop" ];
+ };
+ Service.ExecStart = "${pkgs.hime}/bin/hime";
+ Install.WantedBy = [ "graphical-session.target" ];
+ };
+ };
+
+}
diff --git a/modules/i18n/input-method/kime.nix b/modules/i18n/input-method/kime.nix
new file mode 100644
index 00000000..b948a99d
--- /dev/null
+++ b/modules/i18n/input-method/kime.nix
@@ -0,0 +1,58 @@
+{ config, pkgs, lib, generators, ... }:
+with lib;
+let
+ cfg = config.i18n.inputMethod.kime;
+ yamlFormat = pkgs.formats.yaml { };
+in {
+ options = {
+ i18n.inputMethod.kime = {
+ config = mkOption {
+ type = yamlFormat.type;
+ default = { };
+ example = literalExample ''
+ {
+ daemon = {
+ modules = ["Xim" "Indicator"];
+ };
+
+ indicator = {
+ icon_color = "White";
+ };
+
+ engine = {
+ hangul = {
+ layout = "dubeolsik";
+ };
+ };
+ }
+ '';
+ description = ''
+ kime configuration. Refer to
+
+ for details on supported values.
+ '';
+ };
+ };
+ };
+
+ config = mkIf (config.i18n.inputMethod.enabled == "kime") {
+ i18n.inputMethod.package = pkgs.kime;
+
+ home.sessionVariables = {
+ GTK_IM_MODULE = "kime";
+ QT_IM_MODULE = "kime";
+ XMODIFIERS = "@im=kime";
+ };
+
+ xdg.configFile."kime/config.yaml".text =
+ replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.config);
+
+ systemd.user.services.kime-daemon = {
+ Unit = { Description = "Kime input method editor"; };
+ PartOf = [ "graphical-session.target" ];
+ Service.ExecStart = "${pkgs.kime}/bin/kime";
+ Install.WantedBy = [ "graphical-session.target" ];
+ };
+ };
+
+}
diff --git a/modules/i18n/input-method/nabi.nix b/modules/i18n/input-method/nabi.nix
new file mode 100644
index 00000000..01f9f791
--- /dev/null
+++ b/modules/i18n/input-method/nabi.nix
@@ -0,0 +1,23 @@
+{ config, pkgs, lib, ... }:
+
+with lib; {
+ config = mkIf (config.i18n.inputMethod.enabled == "nabi") {
+ i18n.inputMethod.package = pkgs.nabi;
+
+ home.sessionVariables = {
+ GTK_IM_MODULE = "nabi";
+ QT_IM_MODULE = "nabi";
+ XMODIFIERS = "@im=nabi";
+ };
+
+ systemd.user.services.nabi-daemon = {
+ Unit = {
+ Description = "Nabi input method editor";
+ PartOf = [ "graphical-session.desktop" ];
+ };
+ Service.ExecStart = "${pkgs.nabi}/bin/nabi";
+ Install.WantedBy = [ "graphical-session.target" ];
+ };
+ };
+
+}
diff --git a/modules/i18n/input-method/uim.nix b/modules/i18n/input-method/uim.nix
new file mode 100644
index 00000000..e7890352
--- /dev/null
+++ b/modules/i18n/input-method/uim.nix
@@ -0,0 +1,45 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let cfg = config.i18n.inputMethod.uim;
+in {
+ options = {
+
+ i18n.inputMethod.uim = {
+ toolbar = mkOption {
+ type = types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt4" ];
+ default = "gtk";
+ example = "gtk-systray";
+ description = ''
+ Selected UIM toolbar.
+ '';
+ };
+ };
+
+ };
+
+ config = mkIf (config.i18n.inputMethod.enabled == "uim") {
+ i18n.inputMethod.package = pkgs.uim;
+
+ home.sessionVariables = {
+ GTK_IM_MODULE = "uim";
+ QT_IM_MODULE = "uim";
+ XMODIFIERS = "@im=uim";
+ };
+
+ systemd.user.services.uim-daemon = {
+ Unit = {
+ Description = "Uim input method editor";
+ PartOf = [ "graphical-session.desktop" ];
+ };
+ Service.ExecStart = toString
+ (pkgs.writeShellScript "start-uim-xim-and-uim-toolbar" ''
+ ${pkgs.uim}/bin/uim-xim &
+ ${pkgs.uim}/bin/uim-toolbar-${cfg.toolbar}
+ '');
+ Install.WantedBy = [ "graphical-session.target" ];
+ };
+ };
+
+}
diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix
index 8a06ea11..d091b28a 100644
--- a/modules/lib/maintainers.nix
+++ b/modules/lib/maintainers.nix
@@ -109,4 +109,10 @@
githubId = 34393802;
name = "Malte Voos";
};
+ kranzes = {
+ email = "personal@ilanjoselevich.com";
+ github = "Kranzes";
+ githubId = 56614642;
+ name = "Ilan Joselevich";
+ };
}
diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index a1fe0ab1..0446bd4b 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -2104,6 +2104,13 @@ in
'';
}
+ {
+ time = "2021-06-24T22:36:11+00:00";
+ condition = hostPlatform.isLinux;
+ message = ''
+ A new module is available: 'i18n.inputMethod'.
+ '';
+ }
];
};
}
diff --git a/modules/modules.nix b/modules/modules.nix
index dc539184..99d5f549 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -25,6 +25,7 @@ let
(loadModule ./config/i18n.nix { condition = hostPlatform.isLinux; })
(loadModule ./files.nix { })
(loadModule ./home-environment.nix { })
+ (loadModule ./i18n/input-method/default.nix { condition = hostPlatform.isLinux; })
(loadModule ./manual.nix { })
(loadModule ./misc/dconf.nix { })
(loadModule ./misc/debug.nix { })
diff --git a/tests/default.nix b/tests/default.nix
index 391d7a20..bdf0771b 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -88,6 +88,7 @@ import nmt {
./modules/targets-darwin
] ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [
./modules/config/i18n
+ ./modules/i18n/input-method
./modules/misc/debug
./modules/misc/gtk
./modules/misc/numlock
diff --git a/tests/modules/i18n/input-method/default.nix b/tests/modules/i18n/input-method/default.nix
new file mode 100644
index 00000000..f214d851
--- /dev/null
+++ b/tests/modules/i18n/input-method/default.nix
@@ -0,0 +1 @@
+{ input-method-fcitx5-configuration = ./fcitx5-configuration.nix; }
diff --git a/tests/modules/i18n/input-method/fcitx5-configuration.nix b/tests/modules/i18n/input-method/fcitx5-configuration.nix
new file mode 100644
index 00000000..b29a94aa
--- /dev/null
+++ b/tests/modules/i18n/input-method/fcitx5-configuration.nix
@@ -0,0 +1,15 @@
+{ config, pkgs, ... }:
+
+{
+ config = {
+ nixpkgs.overlays = [ (import ./fcitx5-overlay.nix) ];
+ i18n.inputMethod = {
+ enabled = "fcitx5";
+ fcitx5.addons = with pkgs; [ fcitx5-chinese-addons ];
+ };
+
+ nmt.script = ''
+ assertFileExists home-files/.config/systemd/user/fcitx5-daemon.service
+ '';
+ };
+}
diff --git a/tests/modules/i18n/input-method/fcitx5-overlay.nix b/tests/modules/i18n/input-method/fcitx5-overlay.nix
new file mode 100644
index 00000000..4007552c
--- /dev/null
+++ b/tests/modules/i18n/input-method/fcitx5-overlay.nix
@@ -0,0 +1,22 @@
+final: prev:
+
+let
+
+ dummy = prev.runCommandLocal "dummy-package" { } "mkdir $out";
+
+in {
+ fcitx5 = prev.runCommandLocal "fcitx5" { version = "0"; } ''
+ mkdir -p $out/bin $out/share/applications $out/etc/xdg/autostart
+ touch $out/bin/fcitx5 \
+ $out/share/applications/org.fcitx.Fcitx5.desktop \
+ $out/etc/xdg/autostart/org.fcitx.Fcitx5.desktop
+ chmod +x $out/bin/fcitx5
+ '';
+ fcitx5-configtool = dummy;
+ fcitx5-lua = dummy;
+ fcitx5-qt = dummy;
+ fcitx5-gtk = dummy;
+ fcitx5-with-addons =
+ prev.fcitx5-with-addons.override { inherit (final) fcitx5-qt; };
+ fcitx5-chinese-addons = dummy;
+}