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; +}