mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
269 lines
8.2 KiB
Nix
269 lines
8.2 KiB
Nix
{
|
||
config,
|
||
pkgs,
|
||
lib,
|
||
...
|
||
}:
|
||
let
|
||
im = config.i18n.inputMethod;
|
||
cfg = im.fcitx5;
|
||
fcitx5Package = cfg.fcitx5-with-addons.override { inherit (cfg) addons; };
|
||
iniFormat = pkgs.formats.ini { };
|
||
iniGlobalFormat = pkgs.formats.iniWithGlobalSection { };
|
||
in
|
||
{
|
||
options = {
|
||
i18n.inputMethod.fcitx5 = {
|
||
fcitx5-with-addons = lib.mkOption {
|
||
type = lib.types.package;
|
||
default = pkgs.qt6Packages.fcitx5-with-addons;
|
||
example = lib.literalExpression "pkgs.kdePackages.fcitx5-with-addons";
|
||
description = ''
|
||
The fcitx5 package to use.
|
||
'';
|
||
};
|
||
addons = lib.mkOption {
|
||
type = with lib.types; listOf package;
|
||
default = [ ];
|
||
example = lib.literalExpression "with pkgs; [ fcitx5-rime ]";
|
||
description = ''
|
||
Enabled Fcitx5 addons.
|
||
'';
|
||
};
|
||
|
||
waylandFrontend = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Use the Wayland input method frontend.
|
||
See [Using Fcitx 5 on Wayland](https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland).
|
||
'';
|
||
};
|
||
|
||
quickPhrase = lib.mkOption {
|
||
type = with lib.types; attrsOf str;
|
||
default = { };
|
||
example = lib.literalExpression ''
|
||
{
|
||
smile = "(・∀・)";
|
||
angry = "( ̄ー ̄)";
|
||
}
|
||
'';
|
||
description = "Quick phrases.";
|
||
};
|
||
|
||
quickPhraseFiles = lib.mkOption {
|
||
type = with lib.types; attrsOf path;
|
||
default = { };
|
||
example = lib.literalExpression ''
|
||
{
|
||
words = ./words.mb;
|
||
numbers = ./numbers.mb;
|
||
}
|
||
'';
|
||
description = "Quick phrase files.";
|
||
};
|
||
|
||
settings = {
|
||
globalOptions = lib.mkOption {
|
||
type = lib.types.submodule {
|
||
freeformType = iniFormat.type;
|
||
};
|
||
default = { };
|
||
description = ''
|
||
The global options in `config` file in ini format.
|
||
'';
|
||
example = lib.literalExpression ''
|
||
{
|
||
Behavior = {
|
||
ActiveByDefault = false;
|
||
};
|
||
Hotkey = {
|
||
EnumerateWithTriggerKeys = true;
|
||
EnumerateSkipFirst = false;
|
||
ModifierOnlyKeyTimeout = 250;
|
||
};
|
||
}
|
||
'';
|
||
};
|
||
inputMethod = lib.mkOption {
|
||
type = lib.types.submodule {
|
||
freeformType = iniFormat.type;
|
||
};
|
||
default = { };
|
||
description = ''
|
||
The input method configure in `profile` file in ini format.
|
||
'';
|
||
example = lib.literalExpression ''
|
||
{
|
||
GroupOrder."0" = "Default";
|
||
"Groups/0" = {
|
||
Name = "Default";
|
||
"Default Layout" = "us";
|
||
DefaultIM = "pinyin";
|
||
};
|
||
"Groups/0/Items/0".Name = "keyboard-us";
|
||
"Groups/0/Items/1".Name = "pinyin";
|
||
}
|
||
'';
|
||
};
|
||
addons = lib.mkOption {
|
||
type = with lib.types; (attrsOf iniGlobalFormat.type);
|
||
default = { };
|
||
description = ''
|
||
The addon configures in `conf` folder in ini format with global sections.
|
||
Each item is written to the corresponding file.
|
||
'';
|
||
example = lib.literalExpression ''
|
||
{
|
||
classicui.globalSection.Theme = "example";
|
||
pinyin.globalSection.EmojiEnabled = "True";
|
||
}
|
||
'';
|
||
};
|
||
};
|
||
|
||
ignoreUserConfig = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Ignore the user configures. **Warning**: When this is enabled, the
|
||
user config files are totally ignored and the user dict can't be saved
|
||
and loaded.
|
||
'';
|
||
};
|
||
|
||
themes = lib.mkOption {
|
||
type =
|
||
with lib.types;
|
||
lazyAttrsOf (submodule {
|
||
options = {
|
||
theme = lib.mkOption {
|
||
type =
|
||
with lib.types;
|
||
nullOr (oneOf [
|
||
iniFormat.type
|
||
lines
|
||
path
|
||
]);
|
||
default = null;
|
||
description = ''
|
||
The `theme.conf` file of the theme.
|
||
|
||
See https://fcitx-im.org/wiki/Fcitx_5_Theme#Background_images
|
||
for more information.
|
||
'';
|
||
};
|
||
highlightImage = lib.mkOption {
|
||
type = with lib.types; nullOr path;
|
||
default = null;
|
||
description = "Path to the SVG of the highlight.";
|
||
};
|
||
panelImage = lib.mkOption {
|
||
type = with lib.types; nullOr path;
|
||
default = null;
|
||
description = "Path to the SVG of the panel.";
|
||
};
|
||
};
|
||
});
|
||
example = "";
|
||
description = ''
|
||
Themes to be written to {file}`$XDG_DATA_HOME/fcitx5/themes/''${name}`
|
||
'';
|
||
default = { };
|
||
};
|
||
};
|
||
};
|
||
|
||
config = lib.mkIf (im.enable && im.type == "fcitx5") {
|
||
i18n.inputMethod = {
|
||
package = fcitx5Package;
|
||
|
||
fcitx5.addons =
|
||
lib.optionals (cfg.quickPhrase != { }) [
|
||
(pkgs.writeTextDir "share/fcitx5/data/QuickPhrase.mb" (
|
||
lib.concatStringsSep "\n" (
|
||
lib.mapAttrsToList (
|
||
name: value: "${name} ${builtins.replaceStrings [ "\\" "\n" ] [ "\\\\" "\\n" ] value}"
|
||
) cfg.quickPhrase
|
||
)
|
||
))
|
||
]
|
||
++ lib.optionals (cfg.quickPhraseFiles != { }) [
|
||
(pkgs.linkFarm "quickPhraseFiles" (
|
||
lib.mapAttrs' (
|
||
name: value: lib.nameValuePair ("share/fcitx5/data/quickphrase.d/${name}.mb") value
|
||
) cfg.quickPhraseFiles
|
||
))
|
||
];
|
||
};
|
||
|
||
home = {
|
||
sessionVariables = {
|
||
GLFW_IM_MODULE = "ibus"; # IME support in kitty
|
||
SDL_IM_MODULE = "fcitx";
|
||
XMODIFIERS = "@im=fcitx";
|
||
}
|
||
// lib.optionalAttrs (!cfg.waylandFrontend) {
|
||
GTK_IM_MODULE = "fcitx";
|
||
QT_IM_MODULE = "fcitx";
|
||
}
|
||
// lib.optionalAttrs cfg.ignoreUserConfig {
|
||
SKIP_FCITX_USER_PATH = "1";
|
||
};
|
||
|
||
sessionSearchVariables.QT_PLUGIN_PATH = [ "${fcitx5Package}/${pkgs.qt6.qtbase.qtPluginPrefix}" ];
|
||
};
|
||
|
||
xdg = {
|
||
configFile.fcitx5 =
|
||
let
|
||
optionalFile =
|
||
p: f: v:
|
||
lib.optionalAttrs (v != { }) {
|
||
${p} = f "fcitx5-${builtins.replaceStrings [ "/" ] [ "-" ] p}" v;
|
||
};
|
||
entries = lib.attrsets.mergeAttrsList [
|
||
(optionalFile "config" iniFormat.generate cfg.settings.globalOptions)
|
||
(optionalFile "profile" iniFormat.generate cfg.settings.inputMethod)
|
||
(lib.concatMapAttrs (
|
||
name: value: optionalFile "conf/${name}.conf" iniGlobalFormat.generate value
|
||
) cfg.settings.addons)
|
||
];
|
||
in
|
||
lib.mkIf (entries != { }) { source = pkgs.linkFarm "fcitx-config" entries; };
|
||
|
||
dataFile = lib.concatMapAttrs (
|
||
name: attrs:
|
||
let
|
||
nullableFile =
|
||
n: maybeNull: source:
|
||
lib.nameValuePair "fcitx5/themes/${name}/${n}" (lib.mkIf (maybeNull != null) { inherit source; });
|
||
simpleFile = n: v: nullableFile n v v;
|
||
in
|
||
builtins.listToAttrs [
|
||
(simpleFile "highlight.svg" attrs.highlightImage)
|
||
(simpleFile "panel.svg" attrs.panelImage)
|
||
(nullableFile "theme.conf" attrs.theme (
|
||
if builtins.isPath attrs.theme || lib.isStorePath attrs.theme then
|
||
attrs.theme
|
||
else if builtins.isString attrs.theme then
|
||
pkgs.writeText "fcitx5-theme.conf" attrs.theme
|
||
else
|
||
iniFormat.generate "fcitx5-${name}-theme" attrs.theme
|
||
))
|
||
]
|
||
) cfg.themes;
|
||
};
|
||
|
||
systemd.user.services.fcitx5-daemon = {
|
||
Unit = {
|
||
Description = "Fcitx5 input method editor";
|
||
PartOf = [ "graphical-session.target" ];
|
||
After = [ "graphical-session.target" ];
|
||
};
|
||
Service.ExecStart = "${fcitx5Package}/bin/fcitx5";
|
||
Install.WantedBy = [ "graphical-session.target" ];
|
||
};
|
||
};
|
||
}
|