晴れときどき崩壊ブログ

home-managerの設定をある程度Nixと分離しておきたい

home-managerで多くのオレオレ環境の設定を残しているため、https://home-manager-options.extranix.com/?query=anyrun&release=masterなどで検索しながら設定するのですが、 Nixのみで設定を書くことが想定されているパッケージが多々あります。

Nix だけで書くということのデメリット

たとえば、swaynotificationcenter の設定は本来、~/.config/swaync/config.json に書かれることになっていますが、home-managerで提供されているオプションに従うと、以下のようにNixでJSONもどきを書かなくてはなりません。

services.swaync.settings = {
positionX = "right";
positionY = "top";
layer = "overlay";
control-center-layer = "top";
layer-shell = true;
cssPriority = "application";
control-center-margin-top = 0;
control-center-margin-bottom = 0;
control-center-margin-right = 0;
control-center-margin-left = 0;
notification-2fa-action = true;
notification-inline-replies = false;
notification-icon-size = 64;
notification-body-image-height = 100;
notification-body-image-width = 200;
};

もちろん、Nixで全て書くことのメリットもありますが、以下のようなデメリットがあります。

いいかんじにJSONファイルに分離する

こうして書かれたNixは、builtins.toJSON などの組込み関数でJSONに変換されてます。一方builtins.fromJSONなどの組み込み関数もあり、今回はこの関数を使うことで実現できます。

{
services.swaync = {
enable = true;
settings = builtins.fromJSON ''${builtins.readFile ./config.json}'';
style = builtins.readFile ./style.css;
};
}

同じ階層にJSONファイルで設定を書きます。

{
"$schema": "https://raw.githubusercontent.com/ErikReider/SwayNotificationCenter/refs/heads/main/src/configSchema.json",
"positionY": "top",
"layer": "overlay",
"control-center-layer": "top",
"layer-shell": true,\
...
}

JSON → Nix → JSON と若干まどろっこしいですが、公式どおりの設定ファイルの形式を維持することができるようになりました。

シンプルにいかないパターン

anyrun は組み込み関数でイッパツで変換、といったことを内部でしておらず、複雑めな処理が走っています。

こういったときは、anyrunhome-managerの定義を見て参考にしながら、抜け道を探します。以下抜粋。

xdg.configFile = mkMerge [
(mapAttrs' (name: value: nameValuePair ("anyrun/" + name) value) cfg.extraConfigFiles)
{
"anyrun/config.ron".text = ''
Config(
x: ${stringifyNumeric cfg.config.x},
y: ${stringifyNumeric cfg.config.y},
...
max_entries: ${
if cfg.config.maxEntries == null then "None" else "Some(${toString cfg.config.maxEntries})"
},
plugins: ${toJSON parsedPlugins},
)
'';
}
{
"anyrun/style.css" = mkIf (cfg.extraCss != null) {
text = cfg.extraCss;
};
}
];

どうやらこの部分で ~/.config/anyrun/config.ronに設定ファイルを配置しているようです。ではこれを lib.mkForce で上書きしてしまえばよさそうです。

{ lib, ... }: {
programs.anyrun = {
enable = true;
extraCss = builtins.readFile ./style.css;
config.plugins = [ ];
extraConfigFiles = {
"randr.ron".text = builtins.readFile ./randr.ron;
"websearch.ron".text = builtins.readFile ./websearch.ron;
};
};
xdg.configFile = lib.mkMerge [
{
"anyrun/config.ron".text = lib.mkForce (builtins.readFile ./config.ron);
}
];
}

こんな感じですね。

まとめ

我は天才かもしれないぞよ!


Previous Post
ブログが崩壊したので作りなおした
Next Post
Aerospace with Home Manager