Compare commits

..

1 Commits

Author SHA1 Message Date
home-manager-ci[bot]
e15a7f0b2c maintainers: update all-maintainers.nix
Automated update of the master maintainers list combining:
- Home Manager specific maintainers from modules/lib/maintainers.nix
- Nixpkgs maintainers referenced in Home Manager modules

**Added:** 0 maintainers
**Removed:** 0 maintainers
**Total:** 282 → 282 maintainers

Generated by: lib/python/generate-all-maintainers.py
2025-12-22 09:20:36 +00:00
129 changed files with 1697 additions and 2576 deletions

View File

@@ -1097,6 +1097,19 @@
name = "Hoang Nguyen";
source = "home-manager";
};
foo-dogsquared = {
email = "foodogsquared@foodogsquared.one";
github = "foo-dogsquared";
githubId = 34962634;
keys = [
{
fingerprint = "DDD7 D0BD 602E 564B AA04 FC35 1431 0D91 4115 2B92";
}
];
matrix = "@foodogsquared:matrix.org";
name = "Gabriel Arazas";
source = "nixpkgs";
};
fpob = {
email = "fpob@proton.me";
github = "fpob";

View File

@@ -57,9 +57,3 @@ changes are only active if the `home.stateVersion` option is set to
now default to `true` which is consistent with the default values
for those options used by `i3` and `sway`.
- The [](#opt-programs.swaylock.enable) option now defaults to `false`
and must be explicitly enabled. Previously, it would be implicitly
enabled when `programs.swaylock.settings` was non-empty. Users with
`home.stateVersion` set to earlier versions will continue to get the
old implicit behavior.

View File

@@ -27,8 +27,4 @@ The state version in this release includes the changes below. These
changes are only active if the `home.stateVersion` option is set to
\"25.05\" or later.
- The [](#opt-programs.git.signing.format) option no longer defaults to
`"openpgp"`. Users who use Git signing with GPG should explicitly set
this option to `"openpgp"` to maintain the previous behavior. Users
with `home.stateVersion` set to earlier versions will continue to get
the `"openpgp"` default for backwards compatibility.
- No changes.

View File

@@ -80,10 +80,3 @@ changes are only active if the `home.stateVersion` option is set to
`{ PASSWORD_STORE_DIR = $XDG_DATA_HOME/password-store; }` anymore by its
default value. This will revert to the default behaviour of the program,
namely `$HOME/.password-store` to be used as the store path.
- On macOS, [](#opt-targets.darwin.copyApps.enable) is now enabled by
default instead of [](#opt-targets.darwin.linkApps.enable). This means
applications from `home.packages` will be copied to
`~/Applications/Home Manager Apps` rather than symlinked, making them
work properly with Spotlight. Users with `home.stateVersion` set to
earlier versions will continue to use `linkApps` by default.

View File

@@ -7,19 +7,11 @@ section is therefore not final.
This release has the following notable changes:
- The [](#opt-programs.anki.uiScale) option now expects a value in the
range 1.02.0, previously it erroneously expected values in the
range `0.01.0`.
## State Version Changes {#sec-release-26.05-state-version-changes}
The state version in this release includes the changes below. These
changes are only active if the `home.stateVersion` option is set to
\"26.05\" or later.
- The [](#opt-gtk.gtk4.theme) option does not mirror
[](#opt-gtk.theme) by default anymore.
- The [](#opt-programs.zsh.dotDir) option now defaults to the XDG
configuration directory (usually `~/.config/zsh`) when
[](#opt-xdg.enable) is true.
- The `gtk.gtk4.theme` option does not mirror `gtk.theme` by default
anymore.

6
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1767767207,
"narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=",
"lastModified": 1766070988,
"narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5912c1772a44e31bf1c63c0390b90501e5026886",
"rev": "c6245e83d836d0433170a16eb185cefe0572f8b8",
"type": "github"
},
"original": {

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Home Manager\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
"PO-Revision-Date: 2026-01-07 17:01+0000\n"
"PO-Revision-Date: 2025-11-30 14:00+0000\n"
"Last-Translator: Brian E <brianellingsgaard9@gmail.com>\n"
"Language-Team: Faroese <https://hosted.weblate.org/projects/home-manager/cli/"
"fo/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.15.1\n"
"X-Generator: Weblate 5.15-dev\n"
#. translators: For example: "home-manager: missing argument for --cores"
#: home-manager/home-manager:16
@@ -41,12 +41,10 @@ msgid ""
"Keeping your Home Manager %s in %s is deprecated,\n"
"please move it to %s"
msgstr ""
"At hava Heimvørðurin %s í %s er fyrnast,\n"
"vinarliga flyt hann til %s"
#: home-manager/home-manager:99
msgid "No configuration file found. Please create one at %s"
msgstr "Eingin samansetingsfíla funni. Vinarliga stovna ein hjá %s"
msgstr ""
#: home-manager/home-manager:114
msgid "Home Manager not found at %s."

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Home Manager\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
"PO-Revision-Date: 2025-12-04 09:16+0000\n"
"PO-Revision-Date: 2025-12-04 04:17+0000\n"
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
"projects/home-manager/cli/zh_Hant/>\n"
@@ -215,7 +215,7 @@ msgstr "沒有即將過期的世代"
#: home-manager/home-manager:877
msgid "No home-manager packages seem to be installed."
msgstr "似乎沒有安裝 home-manager 套件。"
msgstr "似乎沒有安裝 home-manager 軟體包。"
#: home-manager/home-manager:962
msgid "Unknown argument %s"
@@ -223,11 +223,11 @@ msgstr "未知引數 %s"
#: home-manager/home-manager:987
msgid "This will remove Home Manager from your system."
msgstr "這將會從您的系統中移除 Home Manager。"
msgstr "這將會從系統中移除 Home Manager。"
#: home-manager/home-manager:990
msgid "This is a dry run, nothing will actually be uninstalled."
msgstr "這是模擬執行,實際上並不會解除安裝任何內容。"
msgstr "這是試執行結果,沒有實際解除安裝任何軟體包。"
#: home-manager/home-manager:994
msgid "Really uninstall Home Manager?"
@@ -235,27 +235,27 @@ msgstr "確定要解除安裝 Home Manager 嗎?"
#: home-manager/home-manager:1000
msgid "Switching to empty Home Manager configuration..."
msgstr "正在切換至空的 Home Manager 設定..."
msgstr "正在切換至空的 Home Manager 配置 ..."
#: home-manager/home-manager:1015
msgid "Yay!"
msgstr "太好了"
msgstr "好耶"
#: home-manager/home-manager:1020
msgid "Home Manager is uninstalled but your home.nix is left untouched."
msgstr "Home Manager 已解除安裝,但您的 home.nix 保持不變。"
msgstr "Home Manager 已解除安裝,但未改動您的 home.nix 配置檔案。"
#: home-manager/home-manager:1285
msgid "expire-generations expects one argument, got %d."
msgstr "expire-generations 預期一個引數,但到了 %d 個。"
msgstr "expire-generations 須要一個引數,但獲取到了 %d 個。"
#: home-manager/home-manager:1310
msgid "Unknown command: %s"
msgstr "未知令:%s"
msgstr "未知令:%s"
#: home-manager/install.nix:21
msgid "This derivation is not buildable, please run it using nix-shell."
msgstr "此 derivation 無法建置,請使用 nix-shell 執行。"
msgstr "此配置檔案/變體不可構建,請在 nix-shell 執行。"
#, sh-format
#~ msgid "Please set the $EDITOR environment variable"

View File

@@ -270,7 +270,9 @@ in
setupLaunchAgents
# Restore errexit
set -e
if [[ -o errexit ]]; then
set -e
fi
'';
})
];

View File

@@ -21,7 +21,6 @@
isList
mapAttrsToList
replicate
attrNames
;
initialIndent = concatStrings (replicate indentLevel " ");
@@ -29,36 +28,31 @@
toHyprconf' =
indent: attrs:
let
isImportantField =
n: _: foldl (acc: prev: if hasPrefix prev n then true else acc) false importantPrefixes;
importantFields = filterAttrs isImportantField attrs;
withoutImportantFields = fields: removeAttrs fields (attrNames importantFields);
allSections = filterAttrs (n: v: isAttrs v || isList v) attrs;
sections = withoutImportantFields allSections;
sections = filterAttrs (n: v: isAttrs v || (isList v && all isAttrs v)) attrs;
mkSection =
n: attrs:
if isList attrs then
let
separator = if all isAttrs attrs then "\n" else "";
in
(concatMapStringsSep separator (a: mkSection n a) attrs)
else if isAttrs attrs then
if lib.isList attrs then
(concatMapStringsSep "\n" (a: mkSection n a) attrs)
else
''
${indent}${n} {
${toHyprconf' " ${indent}" attrs}${indent}}
''
else
toHyprconf' indent { ${n} = attrs; };
'';
mkFields = generators.toKeyValue {
listsAsDuplicateKeys = true;
inherit indent;
};
allFields = filterAttrs (n: v: !(isAttrs v || isList v)) attrs;
fields = withoutImportantFields allFields;
allFields = filterAttrs (n: v: !(isAttrs v || (isList v && all isAttrs v))) attrs;
isImportantField =
n: _: foldl (acc: prev: if hasPrefix prev n then true else acc) false importantPrefixes;
importantFields = filterAttrs isImportantField allFields;
fields = builtins.removeAttrs allFields (mapAttrsToList (n: _: n) importantFields);
in
mkFields importantFields
+ concatStringsSep "\n" (mapAttrsToList mkSection sections)

View File

@@ -1,20 +0,0 @@
{ config, ... }:
{
time = "2025-12-27T19:00:00+00:00";
condition = config.programs.zsh.enable;
message = ''
The default value of `programs.zsh.dotDir` has changed.
When `home.stateVersion` is set to "26.05" or later, and `xdg.enable` is
`true` (the default), `programs.zsh.dotDir` now defaults to
`''${config.xdg.configHome}/zsh`. Previously, it defaulted to the home
directory.
This means your Zsh configuration files (`.zshrc`, `.zshenv`, etc.) will be
moved to `~/.config/zsh` (or your configured XDG config home).
If you prefer the old behavior, you can explicitly set:
`programs.zsh.dotDir = config.home.homeDirectory;`
'';
}

View File

@@ -1,10 +0,0 @@
{ config, ... }:
{
time = "2026-01-02T00:03:48+00:00";
condition = config.services.mpd.enable;
message = ''
`MPD_HOST` and `MPD_PORT` environment variables are now set automatically.
This can be disabled with `services.mpd.enableSessionVariables = false`.
'';
}

View File

@@ -136,7 +136,7 @@ in
xdg.stateHome = mkOptionDefault defaultStateHome;
home.sessionVariables = variables;
systemd.user.sessionVariables = variables;
systemd.user.sessionVariables = mkIf pkgs.stdenv.hostPlatform.isLinux variables;
}
)

View File

@@ -135,7 +135,7 @@ in
home.activation.xfconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] (
let
mkCommand = channel: property: value: ''
run ${pkgs.xfconf}/bin/xfconf-query \
run ${pkgs.xfce.xfconf}/bin/xfconf-query \
${lib.escapeShellArgs (
[
"-c"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Home Manager Modules\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
"PO-Revision-Date: 2026-01-07 17:01+0000\n"
"PO-Revision-Date: 2025-11-30 14:00+0000\n"
"Last-Translator: Brian E <brianellingsgaard9@gmail.com>\n"
"Language-Team: Faroese <https://hosted.weblate.org/projects/home-manager/"
"modules/fo/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.15.1\n"
"X-Generator: Weblate 5.15-dev\n"
#: modules/files.nix:206
msgid "Creating home file links in %s"
@@ -33,7 +33,7 @@ msgstr "Stovni nýggjan profil ættarlið"
#: modules/home-environment.nix:650
msgid "No change so reusing latest profile generation"
msgstr "Eingin broyting. Seinastið umhvarv ættarlið er enn í brúk"
msgstr ""
#: modules/home-environment.nix:699
msgid ""

View File

@@ -82,7 +82,7 @@ in
};
uiScale = lib.mkOption {
type = with lib.types; nullOr (numbers.between 1.0 2.0);
type = with lib.types; nullOr (numbers.between 0.0 1.0);
default = null;
example = 1.0;
description = "User interface scale.";

View File

@@ -112,7 +112,7 @@ let
answer_keys: tuple[tuple[int, str], ...] = (${
lib.strings.concatMapStringsSep ", " (val: "(${toString val.ease}, '${val.key}')") cfg.answerKeys
}${if cfg.answerKeys != [ ] then "," else ""})
})
for ease, key in answer_keys:
profile_manager.set_answer_key(ease, key)

View File

@@ -185,7 +185,7 @@ in
extraCss = mkOption {
type = nullOr lines;
default = null;
default = "";
description = ''
Extra CSS lines to add to {file}`~/.config/anyrun/style.css`.
'';

View File

@@ -11,6 +11,7 @@ let
tomlFormat = pkgs.formats.toml { };
inherit (lib) mkIf mkOption types;
inherit (pkgs.stdenv) isLinux isDarwin;
in
{
meta.maintainers = with lib.maintainers; [
@@ -220,82 +221,98 @@ in
};
}
(mkIf daemonCfg.enable {
assertions = [
(mkIf daemonCfg.enable (
lib.mkMerge [
{
assertion = lib.versionAtLeast cfg.package.version "18.2.0";
message = ''
The Atuin daemon requires at least version 18.2.0 or later.
'';
}
{
assertion = config.systemd.user.enable || config.launchd.enable;
message = "The Atuin daemon can only be configured on systems with systemd or launchd.";
}
];
programs.atuin.settings.daemon = {
enabled = true;
systemd_socket = config.systemd.user.enable;
socket_path = lib.mkIf (!config.systemd.user.enable) (
lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock"
);
};
systemd.user.services.atuin-daemon = {
Unit = {
Description = "Atuin daemon";
Requires = [ "atuin-daemon.socket" ];
};
Install = {
Also = [ "atuin-daemon.socket" ];
WantedBy = [ "default.target" ];
};
Service = {
ExecStart = "${lib.getExe cfg.package} daemon";
Environment = lib.optionals (daemonCfg.logLevel != null) [ "ATUIN_LOG=${daemonCfg.logLevel}" ];
Restart = "on-failure";
RestartSteps = 3;
RestartMaxDelaySec = 6;
};
};
systemd.user.sockets.atuin-daemon =
let
socket_dir = if lib.versionAtLeast cfg.package.version "18.4.0" then "%t" else "%D/atuin";
in
{
Unit = {
Description = "Atuin daemon socket";
};
Install = {
WantedBy = [ "sockets.target" ];
};
Socket = {
ListenStream = "${socket_dir}/atuin.sock";
SocketMode = "0600";
RemoveOnStop = true;
};
};
launchd.agents.atuin-daemon = {
enable = true;
config = {
ProgramArguments = [
"${lib.getExe cfg.package}"
"daemon"
assertions = [
{
assertion = lib.versionAtLeast cfg.package.version "18.2.0";
message = ''
The Atuin daemon requires at least version 18.2.0 or later.
'';
}
{
assertion = isLinux || isDarwin;
message = "The Atuin daemon can only be configured on either Linux or macOS.";
}
];
EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) {
ATUIN_LOG = daemonCfg.logLevel;
programs.atuin.settings = {
daemon = {
enabled = true;
};
};
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
}
(mkIf isLinux {
programs.atuin.settings = {
daemon = {
systemd_socket = true;
};
};
ProcessType = "Background";
};
};
})
systemd.user.services.atuin-daemon = {
Unit = {
Description = "Atuin daemon";
Requires = [ "atuin-daemon.socket" ];
};
Install = {
Also = [ "atuin-daemon.socket" ];
WantedBy = [ "default.target" ];
};
Service = {
ExecStart = "${lib.getExe cfg.package} daemon";
Environment = lib.optionals (daemonCfg.logLevel != null) [ "ATUIN_LOG=${daemonCfg.logLevel}" ];
Restart = "on-failure";
RestartSteps = 3;
RestartMaxDelaySec = 6;
};
};
systemd.user.sockets.atuin-daemon =
let
socket_dir = if lib.versionAtLeast cfg.package.version "18.4.0" then "%t" else "%D/atuin";
in
{
Unit = {
Description = "Atuin daemon socket";
};
Install = {
WantedBy = [ "sockets.target" ];
};
Socket = {
ListenStream = "${socket_dir}/atuin.sock";
SocketMode = "0600";
RemoveOnStop = true;
};
};
})
(mkIf isDarwin {
programs.atuin.settings = {
daemon = {
socket_path = lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock";
};
};
launchd.agents.atuin-daemon = {
enable = true;
config = {
ProgramArguments = [
"${lib.getExe cfg.package}"
"daemon"
];
EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) {
ATUIN_LOG = daemonCfg.logLevel;
};
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
};
};
})
]
))
]
);
}

View File

@@ -8,7 +8,7 @@ let
cfg = config.programs.bashmount;
in
{
meta.maintainers = [ ];
meta.maintainers = [ lib.maintainers.AndersonTorres ];
options.programs.bashmount = {
enable = lib.mkEnableOption "bashmount";

View File

@@ -75,7 +75,25 @@ in
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
enableFishIntegration =
lib.hm.shell.mkFishIntegrationOption {
inherit config;
extraDescription = ''
Note, enabling the direnv module will always activate its functionality
for Fish since the direnv package automatically gets loaded in Fish.
If this is not the case try adding
```nix
environment.pathsToLink = [ "/share/fish" ];
```
to the system configuration.
'';
}
// {
default = true;
readOnly = true;
};
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };

View File

@@ -224,24 +224,8 @@ in
message = "Ghostty systemd integration cannot be enabled for non-linux platforms";
}
];
xdg.configFile."systemd/user/app-com.mitchellh.ghostty.service".source =
"${cfg.package}/share/systemd/user/app-com.mitchellh.ghostty.service";
xdg.configFile."systemd/user/app-com.mitchellh.ghostty.service.d/overrides.conf".text = ''
[Unit]
X-SwitchMethod=keep-old
X-Reload-Triggers=${
let
storePathOf = name: config.xdg.configFile.${name}.source;
in
toString (
lib.optionals (cfg.settings != { }) [ (storePathOf "ghostty/config") ]
++ lib.mapAttrsToList (name: _: storePathOf "ghostty/themes/${name}") cfg.themes
)
}
'';
dbus.packages = [ cfg.package ];
})

View File

@@ -16,13 +16,18 @@ let
cfg = config.programs.gpg;
toKeyValue =
settings:
lib.generators.toKeyValue {
mkKeyValue =
key: value: if lib.isString value then "${key} ${value}" else lib.optionalString value key;
listsAsDuplicateKeys = true;
} settings;
mkKeyValue =
key: value: if lib.isString value then "${key} ${value}" else lib.optionalString value key;
cfgText = lib.generators.toKeyValue {
inherit mkKeyValue;
listsAsDuplicateKeys = true;
} cfg.settings;
scdaemonCfgText = lib.generators.toKeyValue {
inherit mkKeyValue;
listsAsDuplicateKeys = true;
} cfg.scdaemonSettings;
primitiveType = types.oneOf [
types.str
@@ -188,7 +193,6 @@ in
scdaemonSettings = mkOption {
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
default = { };
example = literalExpression ''
{
disable-ccid = true;
@@ -203,41 +207,6 @@ in
'';
};
dirmngrSettings = mkOption {
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
default = { };
example = literalExpression ''
{
allow-version-check = true;
keyserver = "ldaps://ldap.example.com";
}
'';
description = ''
Dirmngr configuration options. Available options are described
in
[
{manpage}`dirmngr(1)`
](https://www.gnupg.org/documentation/manuals/gnupg/Dirmngr-Options.html)
'';
};
gpgsmSettings = mkOption {
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
default = { };
example = literalExpression ''
{
with-key-data = true;
}
'';
description = ''
GPGSM configuration options. Available options are described
in
[
{manpage}`gpgsm(1)`
](https://www.gnupg.org/documentation/manuals/gnupg/GPGSM-Options.html)
'';
};
homedir = mkOption {
type = types.path;
example = literalExpression ''"''${config.xdg.dataHome}/gnupg"'';
@@ -298,7 +267,8 @@ in
cert-digest-algo = mkDefault "SHA512";
s2k-digest-algo = mkDefault "SHA512";
s2k-cipher-algo = mkDefault "AES256";
display-charset = mkDefault "utf-8";
charset = mkDefault "utf-8";
fixed-list-mode = mkDefault true;
no-comments = mkDefault true;
no-emit-version = mkDefault true;
keyid-format = mkDefault "0xlong";
@@ -307,6 +277,11 @@ in
with-fingerprint = mkDefault true;
require-cross-certification = mkDefault true;
no-symkey-cache = mkDefault true;
use-agent = mkDefault true;
};
programs.gpg.scdaemonSettings = {
# no defaults for scdaemon
};
home.packages = [ cfg.package ];
@@ -314,21 +289,9 @@ in
GNUPGHOME = cfg.homedir;
};
home.file."${cfg.homedir}/gpg.conf" = mkIf (cfg.settings != { }) {
text = toKeyValue cfg.settings;
};
home.file."${cfg.homedir}/gpg.conf".text = cfgText;
home.file."${cfg.homedir}/scdaemon.conf" = mkIf (cfg.scdaemonSettings != { }) {
text = toKeyValue cfg.scdaemonSettings;
};
home.file."${cfg.homedir}/dirmngr.conf" = mkIf (cfg.dirmngrSettings != { }) {
text = toKeyValue cfg.dirmngrSettings;
};
home.file."${cfg.homedir}/gpgsm.conf" = mkIf (cfg.gpgsmSettings != { }) {
text = toKeyValue cfg.gpgsmSettings;
};
home.file."${cfg.homedir}/scdaemon.conf".text = scdaemonCfgText;
# Link keyring if keys are not mutable
home.file."${cfg.homedir}/pubring.kbx" = mkIf (!cfg.mutableKeys && cfg.publicKeys != [ ]) {

View File

@@ -9,7 +9,7 @@ let
iniFormat = pkgs.formats.ini { };
in
{
meta.maintainers = with lib.maintainers; [ ];
meta.maintainers = with lib.maintainers; [ AndersonTorres ];
options.programs.havoc = {
enable = lib.mkEnableOption "Havoc terminal";

View File

@@ -62,15 +62,8 @@ in
Configuration written to
{file}`$XDG_CONFIG_HOME/keepassxc/keepassxc.ini`.
See <https://github.com/keepassxreboot/keepassxc/blob/develop/src/core/Config.cpp>
See <https://github.com/keepassxreboot/keepassxc/blob/647272e9c5542297d3fcf6502e6173c96f12a9a0/src/core/Config.cpp#L49-L223>
for the full list of options.
::: {.note}
When the settings are non-empty, the configuration file will be linked
into the Nix store and KeePassXC will report an access error for its
configuration file. This is expected and can not be fixed in a way that
aligns with Home Manager's principles. See [#8257](https://github.com/nix-community/home-manager/issues/8257) for more details.
:::
'';
};

View File

@@ -24,8 +24,7 @@ let
meliAccounts = (lib.attrsets.mapAttrs (name: value: (mkMeliAccounts name value)) enabledAccounts);
mkMeliAccounts = (
name: account:
{
name: account: {
root_mailbox = "${config.accounts.email.maildirBasePath}/${account.maildir.path}";
format = "Maildir";
identity = account.address;
@@ -34,14 +33,6 @@ let
send_mail = mkSmtp account;
mailboxes = account.meli.mailboxAliases;
}
// lib.optionalAttrs (account.flavor == "fastmail.com") {
server_username = account.userName;
server_password_command = lib.concatMapStringsSep " " lib.escapeShellArg account.passwordCommand;
format = "jmap";
server_url = "https://api.fastmail.com/jmap/session";
use_token = true;
}
// account.meli.settings
);
mkSmtp = account: {
@@ -162,14 +153,6 @@ in
};
description = "Folder display name";
};
settings = mkOption {
type = types.submodule {
freeformType = tomlFormat.type;
};
default = { };
description = "Account specific meli configuration";
};
};
}
)
@@ -177,15 +160,6 @@ in
};
};
config = mkIf config.programs.meli.enable {
assertions = [
{
assertion = cfg.settings ? accounts == false;
message = ''
programs.meli.settings.accounts override the accounts.email values.
Use per-email accounts.email.<ACCOUNT>.meli.settings instead'';
}
];
home.packages = [ config.programs.meli.package ];
# Generate meli configuration from email accounts

View File

@@ -213,17 +213,11 @@ in
extraLuaConfig = mkOption {
type = types.lines;
default = "";
example = lib.literalExpression ''
let
nvimEarlyInit = lib.mkOrder 500 "set rtp+=vim.opt.rtp:prepend('/home/user/myplugin')";
nvimLateInit = lib.mkAfter "vim.opt.signcolumn = 'auto:1-3'";
in
lib.mkMerge [ nvimEarlyInit nvimLateInit ];
example = ''
vim.opt.nobackup = true
'';
description = ''
Content to be added to {file}`init.lua`.
To specify the order, use `lib.mkOrder`, `lib.mkBefore`, `lib.mkAfter`.
Custom lua lines.
'';
};
@@ -432,10 +426,7 @@ in
(concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages)
];
wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package {
withNodeJs = cfg.withNodeJs || cfg.coc.enable;
plugins = map suppressNotVimlConfig pluginsNormalized;
neovimConfig = pkgs.neovimUtils.makeNeovimConfig {
inherit (cfg)
extraPython3Packages
withPython3
@@ -443,23 +434,38 @@ in
withPerl
viAlias
vimAlias
extraName
autowrapRuntimeDeps
waylandSupport
;
neovimRcContent = cfg.extraConfig;
wrapperArgs =
cfg.extraWrapperArgs ++ extraMakeWrapperArgs ++ extraMakeWrapperLuaCArgs ++ extraMakeWrapperLuaArgs;
wrapRc = false;
withNodeJs = cfg.withNodeJs || cfg.coc.enable;
plugins = map suppressNotVimlConfig pluginsNormalized;
customRC = cfg.extraConfig;
};
wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package (
neovimConfig
// {
inherit (cfg)
extraName
autowrapRuntimeDeps
waylandSupport
withNodeJs
;
wrapperArgs =
neovimConfig.wrapperArgs
++ cfg.extraWrapperArgs
++ extraMakeWrapperArgs
++ extraMakeWrapperLuaCArgs
++ extraMakeWrapperLuaArgs;
wrapRc = false;
}
);
in
{
programs.neovim = {
generatedConfigViml = cfg.extraConfig;
generatedConfigViml = neovimConfig.neovimRcContent;
generatedConfigs =
let
grouped = lib.groupBy (x: x.type) pluginsNormalized;
grouped = builtins.groupBy (x: x.type) pluginsNormalized;
configsOnly = lib.foldl (acc: p: if p.config != null then acc ++ [ p.config ] else acc) [ ];
in
lib.mapAttrs (_name: vals: lib.concatStringsSep "\n" (configsOnly vals)) grouped;
@@ -478,28 +484,29 @@ in
shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
};
programs.neovim.extraLuaConfig = lib.mkMerge [
(lib.mkIf (wrappedNeovim'.initRc != "") (
lib.mkBefore "vim.cmd [[source ${pkgs.writeText "nvim-init-home-manager.vim" wrappedNeovim'.initRc}]]"
))
(lib.mkIf (lib.hasAttr "lua" cfg.generatedConfigs) (lib.mkAfter cfg.generatedConfigs.lua))
];
xdg.configFile =
let
hasLuaConfig = lib.hasAttr "lua" config.programs.neovim.generatedConfigs;
luaRcContent =
lib.optionalString (
wrappedNeovim'.initRc != ""
) "vim.cmd [[source ${pkgs.writeText "nvim-init-home-manager.vim" wrappedNeovim'.initRc}]]\n"
+ config.programs.neovim.extraLuaConfig
+ lib.optionalString hasLuaConfig config.programs.neovim.generatedConfigs.lua;
in
lib.mkMerge (
# writes runtime
(map (x: x.runtime) pluginsNormalized)
++ [
{
"nvim/init.lua" = mkIf (luaRcContent != "") { text = luaRcContent; };
xdg.configFile = lib.mkMerge (
# writes runtime
(map (x: x.runtime) pluginsNormalized)
++ [
{
"nvim/init.lua" = mkIf (cfg.extraLuaConfig != "") {
text = cfg.extraLuaConfig;
};
"nvim/coc-settings.json" = mkIf cfg.coc.enable {
source = jsonFormat.generate "coc-settings.json" cfg.coc.settings;
};
}
]
);
"nvim/coc-settings.json" = mkIf cfg.coc.enable {
source = jsonFormat.generate "coc-settings.json" cfg.coc.settings;
};
}
]
);
}
);
}

View File

@@ -100,7 +100,7 @@ in
lib.optional (cfg.clean.enable && config.nix.gc.automatic)
"programs.nh.clean.enable and nix.gc.automatic (Home-Manager) are both enabled. Please use one or the other to avoid conflict.";
assertions = [
assertions = lib.optionals pkgs.stdenv.isDarwin [
(lib.hm.darwin.assertInterval "programs.nh.clean.dates" cfg.clean.dates pkgs)
];
@@ -131,25 +131,30 @@ in
];
};
systemd.user = lib.mkIf cfg.clean.enable {
systemd.user = lib.mkIf (cfg.clean.enable && pkgs.stdenv.isLinux) {
services.nh-clean = {
Unit.Description = "Nh clean (user)";
Service = {
Type = "oneshot";
ExecStart = "${lib.getExe cfg.package} clean user ${cfg.clean.extraArgs}";
};
};
timers.nh-clean = {
Unit.Description = "Run nh clean";
Timer = {
OnCalendar = cfg.clean.dates;
Persistent = true;
};
Install.WantedBy = [ "timers.target" ];
};
};
launchd.agents.nh-clean = lib.mkIf cfg.clean.enable {
launchd.agents.nh-clean = lib.mkIf (cfg.clean.enable && pkgs.stdenv.isDarwin) {
enable = true;
config = {
ProgramArguments = [
@@ -158,7 +163,9 @@ in
"user"
]
++ lib.optional (cfg.clean.extraArgs != "") cfg.clean.extraArgs;
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.clean.dates;
};
};
};

View File

@@ -66,7 +66,10 @@ in
config = lib.mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "programs.niriswitcher" pkgs lib.platforms.linux)
{
assertion = pkgs.stdenv.hostPlatform.isLinux;
message = "niriswitcher is only available on Linux.";
}
];
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];

View File

@@ -133,7 +133,7 @@ in
The attribute name becomes the command filename, and the value is either:
- Inline content as a string
- A path to a file containing the command content
Commands are stored in {file}`$XDG_CONFIG_HOME/opencode/command/` directory.
Commands are stored in {file}`$XDG_CONFIG_HOME/.config/opencode/command/` directory.
'';
example = lib.literalExpression ''
{
@@ -162,7 +162,7 @@ in
The attribute name becomes the agent filename, and the value is either:
- Inline content as a string
- A path to a file containing the agent content
Agents are stored in {file}`$XDG_CONFIG_HOME/opencode/agent/` directory.
Agents are stored in {file}`$XDG_CONFIG_HOME/.config/opencode/agent/` directory.
'';
example = lib.literalExpression ''
{
@@ -183,49 +183,6 @@ in
'';
};
skills = lib.mkOption {
type = lib.types.either (lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path)) lib.types.path;
default = { };
description = ''
Custom agent skills for opencode.
This option can either be:
- An attribute set defining skills
- A path to a directory containing multiple skill folders
If an attribute set is used, the attribute name becomes the skill directory name,
and the value is either:
- Inline content as a string (creates `opencode/skill/<name>/SKILL.md`)
- A path to a file (creates `opencode/skill/<name>/SKILL.md`)
- A path to a directory (creates `opencode/skill/<name>/` with all files)
If a path is used, it is expected to contain one folder per skill name, each
containing a {file}`SKILL.md`. The directory is symlinked to
{file}`$XDG_CONFIG_HOME/opencode/skill/`.
See <https://opencode.ai/docs/skills/> for the documentation.
'';
example = lib.literalExpression ''
{
git-release = '''
---
name: git-release
description: Create consistent releases and changelogs
---
## What I do
- Draft release notes from merged PRs
- Propose a version bump
- Provide a copy-pasteable `gh release create` command
''';
# A skill can also be a directory containing SKILL.md and other files.
data-analysis = ./skills/data-analysis;
}
'';
};
themes = mkOption {
type = lib.types.attrsOf (lib.types.either jsonFormat.type lib.types.path);
default = { };
@@ -242,13 +199,6 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion = !lib.isPath cfg.skills || lib.pathIsDirectory cfg.skills;
message = "`programs.opencode.skills` must be a directory when set to a path";
}
];
home.packages = mkIf (cfg.package != null) [ cfg.package ];
xdg.configFile = {
@@ -277,11 +227,6 @@ in
text = cfg.rules;
})
);
"opencode/skill" = mkIf (lib.isPath cfg.skills) {
source = cfg.skills;
recursive = true;
};
}
// lib.mapAttrs' (
name: content:
@@ -295,18 +240,6 @@ in
if lib.isPath content then { source = content; } else { text = content; }
)
) cfg.agents
// lib.mapAttrs' (
name: content:
if lib.isPath content && lib.pathIsDirectory content then
lib.nameValuePair "opencode/skill/${name}" {
source = content;
recursive = true;
}
else
lib.nameValuePair "opencode/skill/${name}/SKILL.md" (
if lib.isPath content then { source = content; } else { text = content; }
)
) (if builtins.isAttrs cfg.skills then cfg.skills else { })
// lib.mapAttrs' (
name: content:
lib.nameValuePair "opencode/themes/${name}.json" (

View File

@@ -30,42 +30,44 @@ let
mapAttrsToList (name: value: ''${name}="${lib.escape [ ''"'' "\\" ] (toString value)}"'') envStr
);
mkAddressPortModule =
{
actionType,
nullableAddress ? actionType == "forward",
}:
types.submodule {
options = {
bindOptions = {
address = mkOption {
type = types.str;
default = "localhost";
example = "example.org";
description = "The address where to bind the port.";
};
port = mkOption {
type = types.nullOr types.port;
default = null;
example = 8080;
description = "Specifies port number to bind on bind address.";
};
};
dynamicForwardModule = types.submodule { options = bindOptions; };
forwardModule = types.submodule {
options = {
bind = bindOptions;
host = {
address = mkOption {
type = if nullableAddress then types.nullOr types.str else types.str;
default = if nullableAddress then null else "localhost";
type = types.nullOr types.str;
default = null;
example = "example.org";
description = "The address to ${actionType} to.";
description = "The address where to forward the traffic to.";
};
port = mkOption {
type = types.nullOr types.port;
default = null;
example = 8080;
description = "Specifies port number to ${actionType} to.";
example = 80;
description = "Specifies port number to forward the traffic to.";
};
};
};
dynamicForwardModule = mkAddressPortModule { actionType = "bind"; };
forwardModule = types.submodule {
options = {
bind = mkOption {
type = mkAddressPortModule { actionType = "bind"; };
description = "Local port binding options";
};
host = mkOption {
type = mkAddressPortModule { actionType = "forward"; };
description = "Host port binding options";
};
};
};
matchBlockModule = types.submodule {
@@ -381,18 +383,6 @@ let
example = "10m";
description = "Whether control socket should remain open in the background.";
};
kexAlgorithms = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
example = [
"curve25519-sha256@libssh.org"
"diffie-hellman-group-exchange-sha256"
];
description = ''
Specifies the available KEX (Key Exchange) algorithms.
'';
};
};
# config.host = mkDefault dagName;
@@ -440,9 +430,6 @@ let
++ map (f: " LocalForward" + addressPort f.bind + addressPort f.host) cf.localForwards
++ map (f: " RemoteForward" + addressPort f.bind + addressPort f.host) cf.remoteForwards
++ map (f: " DynamicForward" + addressPort f) cf.dynamicForwards
++ optional (
cf.kexAlgorithms != null
) " KexAlgorithms ${builtins.concatStringsSep "," cf.kexAlgorithms}"
++ [
(lib.generators.toKeyValue {
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";

View File

@@ -12,7 +12,6 @@ let
packageVersion = if cfg.package != null then lib.getVersion cfg.package else null;
themeIsToml = lib.versionAtLeast packageVersion "0.15.0";
versionPost0_17 = lib.versionAtLeast packageVersion "0.17.0";
in
{
meta.maintainers = [ lib.maintainers.leiserfg ];
@@ -44,12 +43,7 @@ in
useLayerShell = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether vicinae should use the layer shell.
If you are using version 0.17 or newer, you should use
{option}.programs.vicinae.settings.launcher_window.layer_shell.enabled = false
instead.
'';
description = "If vicinae should use the layer shell";
};
extensions = lib.mkOption {
@@ -133,22 +127,27 @@ in
settings = lib.mkOption {
inherit (jsonFormat) type;
default = { };
description = "Settings written as JSON to `~/.config/vicinae/vicinae.json.";
example = lib.literalExpression ''
{
favicon_service = "twenty";
font.normal.size = 10;
pop_to_root_on_close=false;
search_files_in_root= false;
faviconService = "twenty";
font = {
size = 10;
};
popToRootOnClose = false;
rootSearch = {
searchFiles = false;
};
theme = {
dark.name = "vicinae-dark";
light.name = "vicinae-light";
name = "vicinae-dark";
};
window = {
csd = true;
opacity = 0.95;
rounding = 10;
};
}
'';
description = ''
Settings written as JSON to {file}`~/.config/vicinae/settings.json`.
See {command}`vicinae config default`.
'';
};
};
@@ -159,10 +158,6 @@ in
assertion = cfg.systemd.enable -> cfg.package != null;
message = "{option}programs.vicinae.systemd.enable requires non null {option}programs.vicinae.package";
}
{
assertion = !cfg.useLayerShell -> !versionPost0_17;
message = ''After version 0.17, if you want to explicitly disable the use of layer shell, you need to set {option}.programs.vicinae.settings.launcher_window.layer_shell.enabled = false.'';
}
];
lib.vicinae.mkExtension = (
{
@@ -228,11 +223,10 @@ in
source = themeFormat.generate "vicinae-${name}-theme" theme;
}
) cfg.themes;
settingsPath = if versionPost0_17 then "vicinae/settings.json" else "vicinae/vicinae.json";
in
{
configFile = {
"${settingsPath}" = lib.mkIf (cfg.settings != { }) {
"vicinae/vicinae.json" = lib.mkIf (cfg.settings != { }) {
source = jsonFormat.generate "vicinae-settings" cfg.settings;
};
}
@@ -256,16 +250,14 @@ in
PartOf = [ cfg.systemd.target ];
};
Service = {
EnvironmentFile = pkgs.writeText "vicinae-env" ''
USE_LAYER_SHELL=${if cfg.useLayerShell then builtins.toString 1 else builtins.toString 0}
'';
Type = "simple";
ExecStart = "${lib.getExe' cfg.package "vicinae"} server";
Restart = "always";
RestartSec = 5;
KillMode = "process";
EnvironmentFile = lib.mkIf (!versionPost0_17) (
pkgs.writeText "vicinae-env" ''
USE_LAYER_SHELL=${if cfg.useLayerShell then builtins.toString 1 else builtins.toString 0}
''
);
};
Install = lib.mkIf cfg.systemd.autoStart {
WantedBy = [ cfg.systemd.target ];

View File

@@ -9,27 +9,12 @@ let
cfg = config.programs.yt-dlp;
configAtom =
with types;
oneOf [
bool
int
str
];
renderSingleOption =
renderSettings = lib.mapAttrsToList (
name: value:
if lib.isBool value then
if value then "--${name}" else "--no-${name}"
else
"--${name} ${toString value}";
renderSettings = lib.mapAttrsToList (
name: value:
if lib.isList value then
lib.concatStringsSep "\n" (map (renderSingleOption name) value)
else
renderSingleOption name value
"--${name} ${toString value}"
);
in
@@ -42,7 +27,13 @@ in
package = lib.mkPackageOption pkgs "yt-dlp" { };
settings = mkOption {
type = with types; attrsOf (either configAtom (listOf configAtom));
type =
with types;
attrsOf (oneOf [
bool
int
str
]);
default = { };
example = lib.literalExpression ''
{
@@ -51,10 +42,6 @@ in
sub-langs = "all";
downloader = "aria2c";
downloader-args = "aria2c:'-c -x8 -s8 -k1M'";
color = [
"stdout:no_color"
"stderr:always"
];
}
'';
description = ''

View File

@@ -2,7 +2,6 @@
config,
lib,
pkgs,
options,
...
}:
let
@@ -101,18 +100,9 @@ in
};
dotDir = mkOption {
default =
if config.xdg.enable && lib.versionAtLeast config.home.stateVersion "26.05" then
"${config.xdg.configHome}/zsh"
else
homeDir;
defaultText = lib.literalExpression ''
if config.xdg.enable && lib.versionAtLeast config.home.stateVersion "26.05" then
"''${config.xdg.configHome}/zsh"
else
config.home.homeDirectory
'';
example = literalExpression ''"''${config.xdg.configHome}/zsh"'';
default = homeDir;
defaultText = "`config.home.homeDirectory`";
example = "`\${config.xdg.configHome}/zsh`";
description = ''
Directory where the zsh configuration and more should be located,
relative to the users home directory. The default is the home
@@ -401,24 +391,7 @@ in
- config.xdg.dataHome (XDG data directory)
- config.xdg.cacheHome (XDG cache directory)
''
]
++
lib.optionals
(
config.xdg.enable
&& !lib.versionAtLeast config.home.stateVersion "26.05"
&& options.programs.zsh.dotDir.highestPrio >= 1500
)
[
''
The default value of `programs.zsh.dotDir` will change in future versions.
You are currently using the legacy default (home directory) because `home.stateVersion` is less than "26.05".
To silence this warning and lock in the current behavior, set:
programs.zsh.dotDir = config.home.homeDirectory;
To adopt the new behavior (XDG config directory), set:
programs.zsh.dotDir = "''${config.xdg.configHome}/zsh";
''
];
];
}
(mkIf (cfg.envExtra != "") {
@@ -439,7 +412,7 @@ in
(mkIf (dotDirAbs != homeDir) {
home.file."${dotDirRel}/.zshenv".text = ''
${config.lib.zsh.export "ZDOTDIR" dotDirAbs}
export ZDOTDIR=${dotDirAbs}
'';
# When dotDir is set, only use ~/.zshenv to source ZDOTDIR/.zshenv,
@@ -447,7 +420,7 @@ in
# already set correctly (by e.g. spawning a zsh inside a zsh), all env
# vars still get exported
home.file.".zshenv".text = ''
source ${lib.escapeShellArg "${dotDirAbs}/.zshenv"}
source ${dotDirAbs}/.zshenv
'';
})

View File

@@ -1,12 +1,9 @@
{ config, lib, ... }:
let
cfg = config.programs.zsh;
stripSlash = lib.removeSuffix "/";
in
rec {
# Raw home directory, no trailing slash.
homeDir = stripSlash config.home.homeDirectory;
homeDir = config.home.homeDirectory;
/*
Escape a path string for shell usage and remove trailing slashes.
@@ -21,11 +18,10 @@ rec {
cleanPathStr "/path/to/dir/" => "'/path/to/dir'"
cleanPathStr "path with spaces" => "'path with spaces'"
*/
cleanPathStr = pathStr: lib.escapeShellArg (stripSlash pathStr);
cleanPathStr = pathStr: lib.escapeShellArg (lib.removeSuffix "/" pathStr);
/*
Convert an absolute path to a relative path by stripping the home directory prefix.
Returns the raw path (unescaped) for use in home.file keys.
This function converts absolute paths within the home directory to relative paths
by removing the home directory prefix. Paths already relative are returned as-is.
@@ -34,22 +30,19 @@ rec {
Type: String -> String
Example:
mkRelPathStr "/home/user/config" => "config"
mkRelPathStr "config" => "config"
mkRelPathStr "/home/user" => "."
mkRelPathStr "/home/user/config" => "'config'"
mkRelPathStr "config" => "'config'"
mkRelPathStr "/etc/config" => <error>
*/
mkRelPathStr =
pathStr:
let
normPath = stripSlash pathStr;
in
if (!lib.hasPrefix "/" normPath) then
normPath
else if normPath == homeDir then
"."
else if (lib.hasPrefix "${homeDir}/" normPath) then
lib.removePrefix "${homeDir}/" normPath
# is already a relative path
if (!lib.hasPrefix "/" pathStr) then
cleanPathStr pathStr
# is an absolute path within home dir
else if (lib.hasPrefix homeDir pathStr) then
cleanPathStr (lib.removePrefix "${homeDir}/" pathStr)
# is an absolute path not in home dir
else
throw ''
Attempted to convert an absolute path not within home directory to a
@@ -61,47 +54,47 @@ rec {
'';
/*
Convert a relative path to an absolute path.
Returns RAW path (unescaped).
Convert a relative path to an absolute path by prepending the home directory.
This function ensures paths are absolute by prepending the home directory
to relative paths. Already absolute paths are returned unchanged (after cleaning).
This function does NOT support shell variables.
Type: String -> String
Example:
mkAbsPathStr "config" => "/home/user/config"
mkAbsPathStr "/absolute/path" => "/absolute/path"
mkAbsPathStr "config" => "'/home/user/config'"
mkAbsPathStr "/absolute/path" => "'/absolute/path'"
*/
mkAbsPathStr =
pathStr:
let
normPath = stripSlash pathStr;
in
if lib.hasPrefix "/" normPath then normPath else "${homeDir}/${normPath}";
pathStr: cleanPathStr ((lib.optionalString (!lib.hasPrefix "/" pathStr) "${homeDir}/") + pathStr);
/*
Convert a path to absolute form while preserving shell variables.
Returns RAW path (unescaped) unless vars are present (then preserves vars).
Convert a path to absolute form while preserving shell variables for runtime expansion.
This function handles both literal paths and shell variable expressions.
Shell variables (containing '$') are preserved unescaped to allow runtime expansion.
Literal paths are made absolute.
Literal paths are made absolute and properly escaped for shell usage.
Type: String -> String
Example:
mkShellVarPathStr "config" => "/home/user/config"
mkShellVarPathStr "config" => "'/home/user/config'"
mkShellVarPathStr "$HOME/config" => "$HOME/config"
mkShellVarPathStr "\${XDG_CONFIG_HOME:-$HOME/.config}/app" => "\${XDG_CONFIG_HOME:-$HOME/.config}/app"
*/
mkShellVarPathStr =
pathStr:
let
normPath = stripSlash pathStr;
hasShellVars = lib.hasInfix "$" normPath;
cleanPath = lib.removeSuffix "/" pathStr;
hasShellVars = lib.hasInfix "$" cleanPath;
in
if hasShellVars then normPath else mkAbsPathStr normPath;
if hasShellVars then
# Does not escape shell variables, allowing them to be expanded at runtime
cleanPath
else
# For literal paths, make them absolute if needed and escape them
cleanPathStr ((lib.optionalString (!lib.hasPrefix "/" cleanPath) "${homeDir}/") + cleanPath);
dotDirAbs = mkAbsPathStr cfg.dotDir;
dotDirRel = mkRelPathStr cfg.dotDir;
@@ -114,5 +107,5 @@ rec {
Type: String
*/
pluginsDir = dotDirAbs + (lib.optionalString (mkRelPathStr cfg.dotDir == ".") "/.zsh") + "/plugins";
pluginsDir = dotDirAbs + (lib.optionalString (homeDir == dotDirAbs) "/.zsh") + "/plugins";
}

View File

@@ -136,7 +136,7 @@ let
);
in
{
meta.maintainers = [ ];
meta.maintainers = with lib.maintainers; [ foo-dogsquared ];
options.services.activitywatch = {
enable = lib.mkEnableOption "ActivityWatch, an automated time tracker";

View File

@@ -32,72 +32,78 @@ in
};
};
config = lib.mkIf serviceConfig.enable {
systemd.user = {
services.borgmatic = {
Unit = {
Description = "borgmatic backup";
# Prevent borgmatic from running unless the machine is
# plugged into power:
ConditionACPower = true;
config = lib.mkIf serviceConfig.enable (
lib.mkMerge [
(lib.mkIf pkgs.stdenv.isLinux {
systemd.user = {
services.borgmatic = {
Unit = {
Description = "borgmatic backup";
# Prevent borgmatic from running unless the machine is
# plugged into power:
ConditionACPower = true;
};
Service = {
Type = "oneshot";
# Lower CPU and I/O priority:
Nice = 19;
IOSchedulingClass = "best-effort";
IOSchedulingPriority = 7;
IOWeight = 100;
Restart = "no";
LogRateLimitIntervalSec = 0;
# Delay start to prevent backups running during boot:
ExecStartPre = "${pkgs.coreutils}/bin/sleep 3m";
ExecStart = ''
${pkgs.systemd}/bin/systemd-inhibit \
--who="borgmatic" \
--what="sleep:shutdown" \
--why="Prevent interrupting scheduled backup" \
${programConfig.package}/bin/borgmatic \
--stats \
--verbosity -1 \
--list \
--syslog-verbosity 1
'';
};
};
timers.borgmatic = {
Unit.Description = "Run borgmatic backup";
Timer = {
OnCalendar = serviceConfig.frequency;
Persistent = true;
RandomizedDelaySec = "10m";
};
Install.WantedBy = [ "timers.target" ];
};
};
Service = {
Type = "oneshot";
})
# Lower CPU and I/O priority:
Nice = 19;
IOSchedulingClass = "best-effort";
IOSchedulingPriority = 7;
IOWeight = 100;
Restart = "no";
LogRateLimitIntervalSec = 0;
# Delay start to prevent backups running during boot:
ExecStartPre = "${pkgs.coreutils}/bin/sleep 3m";
ExecStart = ''
${pkgs.systemd}/bin/systemd-inhibit \
--who="borgmatic" \
--what="sleep:shutdown" \
--why="Prevent interrupting scheduled backup" \
${programConfig.package}/bin/borgmatic \
--stats \
--verbosity -1 \
--list \
--syslog-verbosity 1
'';
};
};
timers.borgmatic = {
Unit.Description = "Run borgmatic backup";
Timer = {
OnCalendar = serviceConfig.frequency;
Persistent = true;
RandomizedDelaySec = "10m";
};
Install.WantedBy = [ "timers.target" ];
};
};
assertions = [
(lib.hm.darwin.assertInterval "services.borgmatic.frequency" serviceConfig.frequency pkgs)
];
launchd.agents.borgmatic = {
enable = true;
config = {
ProgramArguments = [
(lib.getExe programConfig.package)
"--stats"
"--list"
(lib.mkIf pkgs.stdenv.isDarwin {
assertions = [
(lib.hm.darwin.assertInterval "services.borgmatic.frequency" serviceConfig.frequency pkgs)
];
ProcessType = "Background";
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval serviceConfig.frequency;
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stdout.log";
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stderr.log";
};
};
};
launchd.agents.borgmatic = {
enable = true;
config = {
ProgramArguments = [
(lib.getExe programConfig.package)
"--stats"
"--list"
];
ProcessType = "Background";
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval serviceConfig.frequency;
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stdout.log";
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stderr.log";
};
};
})
]
);
}

View File

@@ -156,7 +156,7 @@ in
xdg.configFile."clipse/custom_theme.json".source = jsonFormat.generate "theme" cfg.theme;
systemd.user.services.clipse = lib.mkIf (cfg.package != null) {
systemd.user.services.clipse = lib.mkIf (pkgs.stdenv.isLinux && (cfg.package != null)) {
Unit = {
Description = "Clipse listener";
PartOf = [ "graphical-session.target" ];

View File

@@ -163,7 +163,7 @@ in
};
};
config = lib.mkIf cfg.enable {
config = lib.mkIf cfg.enable ({
assertions = [
{
assertion = (lib.count (p: p.isActive) (lib.attrValues cfg.profiles)) <= 1;
@@ -189,74 +189,78 @@ in
if activeProfile.name != "default" then "colima-${activeProfile.name}" else "colima"
);
launchd.agents = lib.mapAttrs' (
name: profile:
lib.nameValuePair "colima-${name}" {
enable = true;
config = {
ProgramArguments = [
"${lib.getExe cfg.package}"
"start"
name
"-f"
"--activate=${if profile.isActive then "true" else "false"}"
"--save-config=false"
];
KeepAlive = true;
RunAtLoad = true;
EnvironmentVariables.PATH = lib.makeBinPath [
cfg.package
cfg.perlPackage
cfg.dockerPackage
cfg.sshPackage
cfg.coreutilsPackage
cfg.curlPackage
cfg.bashPackage
pkgs.darwin.DarwinTools
];
StandardOutPath = profile.logFile;
StandardErrorPath = profile.logFile;
};
}
) (lib.filterAttrs (_: p: p.isService) cfg.profiles);
launchd.agents = lib.mkIf pkgs.stdenv.isDarwin (
lib.mapAttrs' (
name: profile:
lib.nameValuePair "colima-${name}" {
enable = true;
config = {
ProgramArguments = [
"${lib.getExe cfg.package}"
"start"
name
"-f"
"--activate=${if profile.isActive then "true" else "false"}"
"--save-config=false"
];
KeepAlive = true;
RunAtLoad = true;
EnvironmentVariables.PATH = lib.makeBinPath [
cfg.package
cfg.perlPackage
cfg.dockerPackage
cfg.sshPackage
cfg.coreutilsPackage
cfg.curlPackage
cfg.bashPackage
pkgs.darwin.DarwinTools
];
StandardOutPath = profile.logFile;
StandardErrorPath = profile.logFile;
};
}
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
);
systemd.user.services = lib.mapAttrs' (
name: profile:
lib.nameValuePair "colima-${name}" {
Unit = {
Description = "Colima container runtime (${name} profile)";
After = [ "network-online.target" ];
Wants = [ "network-online.target" ];
};
Service = {
ExecStart = ''
${lib.getExe cfg.package} start ${name} \
-f \
--activate=${if profile.isActive then "true" else "false"} \
--save-config=false
'';
Restart = "always";
RestartSec = 2;
Environment = [
"PATH=${
lib.makeBinPath [
cfg.package
cfg.perlPackage
cfg.dockerPackage
cfg.sshPackage
cfg.coreutilsPackage
cfg.curlPackage
cfg.bashPackage
]
}"
];
StandardOutput = "append:${profile.logFile}";
StandardError = "append:${profile.logFile}";
};
Install = {
WantedBy = [ "default.target" ];
};
}
) (lib.filterAttrs (_: p: p.isService) cfg.profiles);
};
systemd.user.services = lib.mkIf pkgs.stdenv.isLinux (
lib.mapAttrs' (
name: profile:
lib.nameValuePair "colima-${name}" {
Unit = {
Description = "Colima container runtime (${name} profile)";
After = [ "network-online.target" ];
Wants = [ "network-online.target" ];
};
Service = {
ExecStart = ''
${lib.getExe cfg.package} start ${name} \
-f \
--activate=${if profile.isActive then "true" else "false"} \
--save-config=false
'';
Restart = "always";
RestartSec = 2;
Environment = [
"PATH=${
lib.makeBinPath [
cfg.package
cfg.perlPackage
cfg.dockerPackage
cfg.sshPackage
cfg.coreutilsPackage
cfg.curlPackage
cfg.bashPackage
]
}"
];
StandardOutput = "append:${profile.logFile}";
StandardError = "append:${profile.logFile}";
};
Install = {
WantedBy = [ "default.target" ];
};
}
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
);
});
}

View File

@@ -117,8 +117,6 @@ in
systemd.user.services.easyeffects = {
Unit = {
Description = "Easyeffects daemon";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Install.WantedBy = [ "graphical-session.target" ];

View File

@@ -107,10 +107,10 @@ in
'';
};
defaultEditor = mkOption {
defaultEditor = mkOption rec {
type = types.bool;
default = false;
example = true;
example = !default;
description = ''
Whether to configure {command}`emacsclient` as the default
editor using the {env}`EDITOR` and {env}`VISUAL`
@@ -119,117 +119,127 @@ in
};
};
config = mkIf cfg.enable {
home.sessionVariables =
let
editorBin = lib.getBin (
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
);
in
mkIf cfg.defaultEditor {
EDITOR = editorBin;
VISUAL = editorBin;
};
home.packages = optional (cfg.client.enable && pkgs.stdenv.isLinux) (lib.hiPrio clientDesktopItem);
systemd.user.services.emacs = {
Unit = {
Description = "Emacs text editor";
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
After = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
PartOf = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
# Avoid killing the Emacs session, which may be full of
# unsaved buffers.
X-RestartIfChanged = false;
config = mkIf cfg.enable (
lib.mkMerge [
{
home.sessionVariables =
let
editorBin = lib.getBin (
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
);
in
mkIf cfg.defaultEditor {
EDITOR = editorBin;
VISUAL = editorBin;
};
}
// optionalAttrs needsSocketWorkaround {
# Emacs deletes its socket when shutting down, which systemd doesn't
# handle, resulting in a server without a socket.
# See https://github.com/nix-community/home-manager/issues/2018
RefuseManualStart = true;
};
Service = {
Type = "notify";
(mkIf pkgs.stdenv.isLinux {
systemd.user.services.emacs = {
Unit = {
Description = "Emacs text editor";
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
# We wrap ExecStart in a login shell so Emacs starts with the user's
# environment, most importantly $PATH and $NIX_PROFILES. It may be
# worth investigating a more targeted approach for user services to
# import the user environment.
ExecStart = ''${pkgs.runtimeShell} -l -c "${emacsBinPath}/emacs --fg-daemon${
# In case the user sets 'server-directory' or 'server-name' in
# their Emacs config, we want to specify the socket path explicitly
# so launching 'emacs.service' manually doesn't break emacsclient
# when using socket activation.
lib.optionalString cfg.socketActivation.enable "=${lib.escapeShellArg socketPath}"
} ${lib.escapeShellArgs cfg.extraOptions}"'';
After = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
PartOf = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
# Emacs will exit with status 15 after having received SIGTERM, which
# is the default "KillSignal" value systemd uses to stop services.
SuccessExitStatus = 15;
# Avoid killing the Emacs session, which may be full of
# unsaved buffers.
X-RestartIfChanged = false;
}
// optionalAttrs needsSocketWorkaround {
# Emacs deletes its socket when shutting down, which systemd doesn't
# handle, resulting in a server without a socket.
# See https://github.com/nix-community/home-manager/issues/2018
RefuseManualStart = true;
};
Restart = "on-failure";
}
// optionalAttrs needsSocketWorkaround {
# Use read-only directory permissions to prevent emacs from
# deleting systemd's socket file before exiting.
ExecStartPost = "${pkgs.coreutils}/bin/chmod --changes -w ${socketDir}";
ExecStopPost = "${pkgs.coreutils}/bin/chmod --changes +w ${socketDir}";
};
}
// optionalAttrs (cfg.startWithUserSession != false) {
Install = {
WantedBy = [
(if cfg.startWithUserSession == true then "default.target" else "graphical-session.target")
];
};
};
Service = {
Type = "notify";
systemd.user.sockets.emacs = mkIf cfg.socketActivation.enable {
Unit = {
Description = "Emacs text editor";
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
};
# We wrap ExecStart in a login shell so Emacs starts with the user's
# environment, most importantly $PATH and $NIX_PROFILES. It may be
# worth investigating a more targeted approach for user services to
# import the user environment.
ExecStart = ''${pkgs.runtimeShell} -l -c "${emacsBinPath}/emacs --fg-daemon${
# In case the user sets 'server-directory' or 'server-name' in
# their Emacs config, we want to specify the socket path explicitly
# so launching 'emacs.service' manually doesn't break emacsclient
# when using socket activation.
lib.optionalString cfg.socketActivation.enable "=${lib.escapeShellArg socketPath}"
} ${lib.escapeShellArgs cfg.extraOptions}"'';
Socket = {
ListenStream = socketPath;
FileDescriptorName = "server";
SocketMode = "0600";
DirectoryMode = "0700";
# This prevents the service from immediately starting again
# after being stopped, due to the function
# `server-force-stop' present in `kill-emacs-hook', which
# calls `server-running-p', which opens the socket file.
FlushPending = true;
};
# Emacs will exit with status 15 after having received SIGTERM, which
# is the default "KillSignal" value systemd uses to stop services.
SuccessExitStatus = 15;
Install = {
WantedBy = [ "sockets.target" ];
# Adding this Requires= dependency ensures that systemd
# manages the socket file, in the case where the service is
# started when the socket is stopped.
# The socket unit is implicitly ordered before the service.
RequiredBy = [ "emacs.service" ];
};
};
launchd.agents.emacs = {
enable = true;
config = {
ProgramArguments = [
"${cfg.package}/bin/emacs"
"--fg-daemon"
]
++ cfg.extraOptions;
RunAtLoad = true;
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
Restart = "on-failure";
}
// optionalAttrs needsSocketWorkaround {
# Use read-only directory permissions to prevent emacs from
# deleting systemd's socket file before exiting.
ExecStartPost = "${pkgs.coreutils}/bin/chmod --changes -w ${socketDir}";
ExecStopPost = "${pkgs.coreutils}/bin/chmod --changes +w ${socketDir}";
};
}
// optionalAttrs (cfg.startWithUserSession != false) {
Install = {
WantedBy = [
(if cfg.startWithUserSession == true then "default.target" else "graphical-session.target")
];
};
};
};
};
};
home.packages = optional cfg.client.enable (lib.hiPrio clientDesktopItem);
})
(mkIf (cfg.socketActivation.enable && pkgs.stdenv.isLinux) {
systemd.user.sockets.emacs = {
Unit = {
Description = "Emacs text editor";
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
};
Socket = {
ListenStream = socketPath;
FileDescriptorName = "server";
SocketMode = "0600";
DirectoryMode = "0700";
# This prevents the service from immediately starting again
# after being stopped, due to the function
# `server-force-stop' present in `kill-emacs-hook', which
# calls `server-running-p', which opens the socket file.
FlushPending = true;
};
Install = {
WantedBy = [ "sockets.target" ];
# Adding this Requires= dependency ensures that systemd
# manages the socket file, in the case where the service is
# started when the socket is stopped.
# The socket unit is implicitly ordered before the service.
RequiredBy = [ "emacs.service" ];
};
};
})
(mkIf pkgs.stdenv.isDarwin {
launchd.agents.emacs = {
enable = true;
config = {
ProgramArguments = [
"${cfg.package}/bin/emacs"
"--fg-daemon"
]
++ cfg.extraOptions;
RunAtLoad = true;
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
};
};
})
]
);
}

View File

@@ -15,12 +15,49 @@ let
cfg = config.services.git-sync;
services =
mkService:
lib.mapAttrs' (name: repo: {
name = "git-sync-${name}";
value = mkService name repo;
}) cfg.repositories;
mkUnit = name: repo: {
Unit.Description = "Git Sync ${name}";
Install.WantedBy = [ "default.target" ];
Service = {
Environment = [
"PATH=${
lib.makeBinPath (
with pkgs;
[
openssh
git
]
++ repo.extraPackages
)
}"
"GIT_SYNC_DIRECTORY=${lib.strings.escapeShellArg repo.path}"
"GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync"
"GIT_SYNC_REPOSITORY=${lib.strings.escapeShellArg repo.uri}"
"GIT_SYNC_INTERVAL=${toString repo.interval}"
];
ExecStart = "${cfg.package}/bin/git-sync-on-inotify";
Restart = "on-abort";
};
};
mkAgent = name: repo: {
enable = true;
config = {
StartInterval = repo.interval;
ProcessType = "Background";
WorkingDirectory = "${repo.path}";
WatchPaths = [ "${repo.path}" ];
ProgramArguments = [ "${cfg.package}/bin/git-sync" ];
};
};
mkService = if pkgs.stdenv.isLinux then mkUnit else mkAgent;
services = lib.mapAttrs' (name: repo: {
name = "git-sync-${name}";
value = mkService name repo;
}) cfg.repositories;
repositoryType = types.submodule (
{ name, ... }:
@@ -104,48 +141,11 @@ in
};
};
config = mkIf cfg.enable {
launchd.agents = services (
name: repo: {
enable = true;
config = {
StartInterval = repo.interval;
ProcessType = "Background";
WorkingDirectory = "${repo.path}";
WatchPaths = [ "${repo.path}" ];
ProgramArguments = [ "${cfg.package}/bin/git-sync" ];
};
}
);
systemd.user.services = services (
name: repo: {
Unit.Description = "Git Sync ${name}";
Install.WantedBy = [ "default.target" ];
Service = {
Environment = [
"PATH=${
lib.makeBinPath (
with pkgs;
[
openssh
git
]
++ repo.extraPackages
)
}"
"GIT_SYNC_DIRECTORY=${lib.strings.escapeShellArg repo.path}"
"GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync"
"GIT_SYNC_REPOSITORY=${lib.strings.escapeShellArg repo.uri}"
"GIT_SYNC_INTERVAL=${toString repo.interval}"
];
ExecStart = "${cfg.package}/bin/git-sync-on-inotify";
Restart = "on-abort";
};
}
);
};
config = mkIf cfg.enable (
lib.mkMerge [
(mkIf pkgs.stdenv.isLinux { systemd.user.services = services; })
(mkIf pkgs.stdenv.isDarwin { launchd.agents = services; })
]
);
}

View File

@@ -344,115 +344,125 @@ in
};
};
config = mkIf cfg.enable {
# Grab the default binary name and fallback to expected value if `meta.mainProgram` not set
services.gpg-agent.pinentry.program = lib.mkOptionDefault (
cfg.pinentry.package.meta.mainProgram or "pinentry"
);
config = mkIf cfg.enable (
lib.mkMerge [
{
# Grab the default binary name and fallback to expected value if `meta.mainProgram` not set
services.gpg-agent.pinentry.program = lib.mkOptionDefault (
cfg.pinentry.package.meta.mainProgram or "pinentry"
);
home.file."${homedir}/gpg-agent.conf".text = lib.concatStringsSep "\n" (
optional cfg.enableSshSupport "enable-ssh-support"
++ optional cfg.grabKeyboardAndMouse "grab"
++ optional (!cfg.enableScDaemon) "disable-scdaemon"
++ optional cfg.noAllowExternalCache "no-allow-external-cache"
++ optional (cfg.defaultCacheTtl != null) "default-cache-ttl ${toString cfg.defaultCacheTtl}"
++ optional (
cfg.defaultCacheTtlSsh != null
) "default-cache-ttl-ssh ${toString cfg.defaultCacheTtlSsh}"
++ optional (cfg.maxCacheTtl != null) "max-cache-ttl ${toString cfg.maxCacheTtl}"
++ optional (cfg.maxCacheTtlSsh != null) "max-cache-ttl-ssh ${toString cfg.maxCacheTtlSsh}"
++ optional (
cfg.pinentry.package != null
) "pinentry-program ${lib.getExe' cfg.pinentry.package cfg.pinentry.program}"
++ [ cfg.extraConfig ]
);
home.file."${homedir}/gpg-agent.conf".text = lib.concatStringsSep "\n" (
optional cfg.enableSshSupport "enable-ssh-support"
++ optional cfg.grabKeyboardAndMouse "grab"
++ optional (!cfg.enableScDaemon) "disable-scdaemon"
++ optional cfg.noAllowExternalCache "no-allow-external-cache"
++ optional (cfg.defaultCacheTtl != null) "default-cache-ttl ${toString cfg.defaultCacheTtl}"
++ optional (
cfg.defaultCacheTtlSsh != null
) "default-cache-ttl-ssh ${toString cfg.defaultCacheTtlSsh}"
++ optional (cfg.maxCacheTtl != null) "max-cache-ttl ${toString cfg.maxCacheTtl}"
++ optional (cfg.maxCacheTtlSsh != null) "max-cache-ttl-ssh ${toString cfg.maxCacheTtlSsh}"
++ optional (
cfg.pinentry.package != null
) "pinentry-program ${lib.getExe' cfg.pinentry.package cfg.pinentry.program}"
++ [ cfg.extraConfig ]
);
home.sessionVariablesExtra = optionalString cfg.enableSshSupport ''
unset SSH_AGENT_PID
if [ -z "$SSH_CONNECTION" -o -z "$SSH_AUTH_SOCK" ] && [ "''${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(${gpgPkg}/bin/gpgconf --list-dirs agent-ssh-socket)"
fi
'';
home.sessionVariablesExtra = optionalString cfg.enableSshSupport ''
unset SSH_AGENT_PID
if [ -z "$SSH_CONNECTION" -o -z "$SSH_AUTH_SOCK" ] && [ "''${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(${gpgPkg}/bin/gpgconf --list-dirs agent-ssh-socket)"
fi
'';
programs = {
bash.initExtra = mkIf cfg.enableBashIntegration gpgBashInitStr;
zsh.initContent = mkIf cfg.enableZshIntegration gpgZshInitStr;
fish.interactiveShellInit = mkIf cfg.enableFishIntegration gpgFishInitStr;
nushell.extraConfig = mkIf cfg.enableNushellIntegration gpgNushellInitStr;
};
# Trailing newlines are important
home.file."${homedir}/sshcontrol" = mkIf (cfg.sshKeys != null) {
text = lib.concatMapStrings (s: ''
${s}
'') cfg.sshKeys;
};
systemd.user = {
services.gpg-agent = {
Unit = {
Description = "GnuPG cryptographic agent and passphrase cache";
Documentation = "man:gpg-agent(1)";
Requires = "gpg-agent.socket";
After = "gpg-agent.socket";
# This is a socket-activated service:
RefuseManualStart = true;
programs = {
bash.initExtra = mkIf cfg.enableBashIntegration gpgBashInitStr;
zsh.initContent = mkIf cfg.enableZshIntegration gpgZshInitStr;
fish.interactiveShellInit = mkIf cfg.enableFishIntegration gpgFishInitStr;
nushell.extraConfig = mkIf cfg.enableNushellIntegration gpgNushellInitStr;
};
}
Service = {
ExecStart = "${gpgPkg}/bin/gpg-agent --supervised" + optionalString cfg.verbose " --verbose";
ExecReload = "${gpgPkg}/bin/gpgconf --reload gpg-agent";
Environment = [ "GNUPGHOME=${homedir}" ];
};
};
(mkIf (cfg.sshKeys != null) {
# Trailing newlines are important
home.file."${homedir}/sshcontrol".text = lib.concatMapStrings (s: ''
${s}
'') cfg.sshKeys;
})
sockets = {
gpg-agent = mkSocket {
desc = "GnuPG cryptographic agent and passphrase cache";
docs = "man:gpg-agent(1)";
stream = "S.gpg-agent";
fdName = "std";
};
(lib.mkMerge [
(mkIf pkgs.stdenv.isLinux {
systemd.user = {
services.gpg-agent = {
Unit = {
Description = "GnuPG cryptographic agent and passphrase cache";
Documentation = "man:gpg-agent(1)";
Requires = "gpg-agent.socket";
After = "gpg-agent.socket";
# This is a socket-activated service:
RefuseManualStart = true;
};
gpg-agent-ssh = mkIf cfg.enableSshSupport (mkSocket {
desc = "GnuPG cryptographic agent (ssh-agent emulation)";
docs = "man:gpg-agent(1) man:ssh-add(1) man:ssh-agent(1) man:ssh(1)";
stream = "S.gpg-agent.ssh";
fdName = "ssh";
});
Service = {
ExecStart = "${gpgPkg}/bin/gpg-agent --supervised" + optionalString cfg.verbose " --verbose";
ExecReload = "${gpgPkg}/bin/gpgconf --reload gpg-agent";
Environment = [ "GNUPGHOME=${homedir}" ];
};
};
gpg-agent-extra = mkIf cfg.enableExtraSocket (mkSocket {
desc = "GnuPG cryptographic agent and passphrase cache (restricted)";
docs = "man:gpg-agent(1) man:ssh(1)";
stream = "S.gpg-agent.extra";
fdName = "extra";
});
};
};
sockets = {
gpg-agent = mkSocket {
desc = "GnuPG cryptographic agent and passphrase cache";
docs = "man:gpg-agent(1)";
stream = "S.gpg-agent";
fdName = "std";
};
launchd.agents.gpg-agent = {
enable = true;
config = {
ProgramArguments = [
"${gpgPkg}/bin/gpg-agent"
"--supervised"
]
++ optional cfg.verbose "--verbose";
EnvironmentVariables = {
GNUPGHOME = homedir;
};
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
RunAtLoad = cfg.enableSshSupport;
Sockets = {
Agent = mkAgentSock "S.gpg-agent";
Ssh = mkIf cfg.enableSshSupport (mkAgentSock "S.gpg-agent.ssh");
Extra = mkIf cfg.enableExtraSocket (mkAgentSock "S.gpg-agent.extra");
};
};
};
};
gpg-agent-ssh = mkIf cfg.enableSshSupport (mkSocket {
desc = "GnuPG cryptographic agent (ssh-agent emulation)";
docs = "man:gpg-agent(1) man:ssh-add(1) man:ssh-agent(1) man:ssh(1)";
stream = "S.gpg-agent.ssh";
fdName = "ssh";
});
gpg-agent-extra = mkIf cfg.enableExtraSocket (mkSocket {
desc = "GnuPG cryptographic agent and passphrase cache (restricted)";
docs = "man:gpg-agent(1) man:ssh(1)";
stream = "S.gpg-agent.extra";
fdName = "extra";
});
};
};
})
(mkIf pkgs.stdenv.isDarwin {
launchd.agents.gpg-agent = {
enable = true;
config = {
ProgramArguments = [
"${gpgPkg}/bin/gpg-agent"
"--supervised"
]
++ optional cfg.verbose "--verbose";
EnvironmentVariables = {
GNUPGHOME = homedir;
};
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
RunAtLoad = cfg.enableSshSupport;
Sockets = {
Agent = mkAgentSock "S.gpg-agent";
Ssh = mkIf cfg.enableSshSupport (mkAgentSock "S.gpg-agent.ssh");
Extra = mkIf cfg.enableExtraSocket (mkAgentSock "S.gpg-agent.extra");
};
};
};
})
])
]
);
}

View File

@@ -81,38 +81,46 @@ in
};
};
config = lib.mkIf cfg.enable {
config = lib.mkIf cfg.enable (
lib.mkMerge [
(lib.mkIf pkgs.stdenv.isLinux {
systemd.user = {
timers.home-manager-auto-expire = {
Unit.Description = "Home Manager expire generations timer";
systemd.user = {
timers.home-manager-auto-expire = {
Unit.Description = "Home Manager expire generations timer";
Install.WantedBy = [ "timers.target" ];
Timer = {
OnCalendar = cfg.frequency;
Unit = "home-manager-auto-expire.service";
Persistent = true;
Install.WantedBy = [ "timers.target" ];
Timer = {
OnCalendar = cfg.frequency;
Unit = "home-manager-auto-expire.service";
Persistent = true;
};
};
services.home-manager-auto-expire = {
Unit.Description = "Home Manager expire generations";
Service.ExecStart = toString script;
};
};
};
services.home-manager-auto-expire = {
Unit.Description = "Home Manager expire generations";
Service.ExecStart = toString script;
};
};
})
assertions = [
(lib.hm.darwin.assertInterval "services.home-manager.autoExpire.frequency" cfg.frequency pkgs)
];
(lib.mkIf pkgs.stdenv.isDarwin {
assertions = [
(lib.hm.darwin.assertInterval "services.home-manager.autoExpire.frequency" cfg.frequency pkgs)
];
launchd.agents.home-manager-auto-expire = {
enable = true;
config = {
ProgramArguments = [ (toString script) ];
ProcessType = "Background";
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.frequency;
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stdout.log";
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stderr.log";
};
};
};
launchd.agents.home-manager-auto-expire = {
enable = true;
config = {
ProgramArguments = [ (toString script) ];
ProcessType = "Background";
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.frequency;
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stdout.log";
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stderr.log";
};
};
})
]
);
}

View File

@@ -45,18 +45,16 @@ in
'';
example = lib.literalExpression ''
{
ipc = "on";
splash = false;
splash_offset = 2.0;
preload =
[ "/share/wallpapers/buttons.png" "/share/wallpapers/cat_pacman.png" ];
wallpaper = [
{
monitor = "DP-3";
path = "/share/wallpapers/buttons.png";
fit_mode = "tile";
}
{
monitor = "DP-1";
path = "/share/wallpapers/cat_pacman.png";
}
"DP-3,/share/wallpapers/buttons.png"
"DP-1,/share/wallpapers/cat_pacman.png"
];
}
'';
@@ -64,10 +62,7 @@ in
importantPrefixes = lib.mkOption {
type = with lib.types; listOf str;
default = [
"$"
"monitor"
];
default = [ "$" ];
example = [ "$" ];
description = ''
List of prefix of attributes to source at the top of the config.

View File

@@ -29,7 +29,7 @@ in
default = { };
description = ''
Configuration settings for hyprshell. All the avaiblable
options can be found here: <https://github.com/H3rmt/hyprshell/blob/hyprshell-release/docs/CONFIGURE.md#config-options>
options can be found here: <https://github.com/H3rmt/hyprshell/blob/hyprshell-release/CONFIGURE.md#config-options>
'';
};
@@ -38,7 +38,7 @@ in
default = "";
description = ''
CSS file for customizing hyprshell. All the available
options can be found here: <https://github.com/H3rmt/hyprshell/blob/hyprshell-release/docs/CONFIGURE.md#css>
options can be found here: <https://github.com/H3rmt/hyprshell/blob/hyprshell-release/CONFIGURE.md#css>
'';
};

View File

@@ -8,6 +8,7 @@ let
inherit (lib) mkOption types;
cfg = config.services.linux-wallpaperengine;
in
{
meta.maintainers = [ lib.hm.maintainers.ckgxrg ];
@@ -104,10 +105,10 @@ in
config = lib.mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.linux-wallpaperengine" pkgs lib.platforms.linux)
{
({
assertion = cfg.wallpapers != null;
message = "linux-wallpaperengine: You must set at least one wallpaper";
}
})
];
home.packages = [ cfg.package ];
@@ -120,7 +121,7 @@ in
lib.cli.toGNUCommandLine { } {
screen-root = each.monitor;
inherit (each) scaling fps;
inherit (each.audio) silent;
silent = each.audio.silent;
noautomute = !each.audio.automute;
no-audio-processing = !each.audio.processing;
}
@@ -137,12 +138,11 @@ in
PartOf = [ "graphical-session.target" ];
};
Service = {
ExecStart = lib.concatStringsSep " " (
[ (lib.getExe cfg.package) ]
++ lib.optional (cfg.assetsPath != null) "--assets-dir ${cfg.assetsPath}"
++ lib.optional (cfg.clamping != null) "--clamping ${cfg.clamping}"
++ args
);
ExecStart =
lib.getExe cfg.package
+ (lib.optionalString (cfg.assetsPath != null) " --assets-dir ${cfg.assetsPath} ")
+ (lib.optionalString (cfg.clamping != null) "--clamping ${cfg.clamping} ")
+ (lib.strings.concatStringsSep " " args);
Restart = "on-failure";
};
Install = {

View File

@@ -75,7 +75,7 @@ let
in
{
meta.maintainers = [ ];
meta.maintainers = [ lib.maintainers.foo-dogsquared ];
options.services.mopidy = {
enable = lib.mkEnableOption "Mopidy music player daemon";

View File

@@ -22,15 +22,6 @@ in
package = lib.mkPackageOption pkgs "mpd" { };
enableSessionVariables = mkOption {
type = types.bool;
default = true;
description = ''
Whether to set {env}`MPD_HOST` {env}`MPD_PORT` environment variables
according to {option}`services.mpd.network`.
'';
};
musicDirectory = mkOption {
type = with types; either path str;
defaultText = lib.literalExpression ''
@@ -164,17 +155,7 @@ in
);
in
mkIf cfg.enable {
home = {
packages = [ cfg.package ];
sessionVariables = mkIf cfg.enableSessionVariables (
{
MPD_PORT = builtins.toString cfg.network.port;
}
// lib.optionalAttrs (cfg.network.listenAddress != "any") {
MPD_HOST = cfg.network.listenAddress;
}
);
};
home.packages = [ cfg.package ];
services.mpd = lib.mkMerge [
(mkIf (lib.versionAtLeast config.home.stateVersion "22.11" && config.xdg.userDirs.enable) {
@@ -186,7 +167,7 @@ in
})
];
systemd.user = {
systemd.user = lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
services.mpd = {
Unit = lib.mkMerge [
{
@@ -240,7 +221,7 @@ in
};
};
launchd.agents.mpd = {
launchd.agents.mpd = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
enable = true;
config = {
ProgramArguments = [

View File

@@ -83,51 +83,56 @@ in
};
};
config = lib.mkIf cfg.automatic {
systemd.user.services.nix-gc = {
Unit = {
Description = "Nix Garbage Collector";
};
Service = {
Type = "oneshot";
ExecStart = pkgs.writeShellScript "nix-gc" "exec ${nixPackage}/bin/nix-collect-garbage ${
lib.optionalString (cfg.options != null) cfg.options
}";
};
};
config = lib.mkIf cfg.automatic (
lib.mkMerge [
(lib.mkIf pkgs.stdenv.isLinux {
systemd.user.services.nix-gc = {
Unit = {
Description = "Nix Garbage Collector";
};
Service = {
Type = "oneshot";
ExecStart = pkgs.writeShellScript "nix-gc" "exec ${nixPackage}/bin/nix-collect-garbage ${
lib.optionalString (cfg.options != null) cfg.options
}";
};
};
systemd.user.timers.nix-gc = {
Unit = {
Description = "Nix Garbage Collector";
};
Timer = {
OnCalendar = cfg.dates;
RandomizedDelaySec = cfg.randomizedDelaySec;
Persistent = cfg.persistent;
Unit = "nix-gc.service";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
})
systemd.user.timers.nix-gc = {
Unit = {
Description = "Nix Garbage Collector";
};
Timer = {
OnCalendar = cfg.dates;
RandomizedDelaySec = cfg.randomizedDelaySec;
Persistent = cfg.persistent;
Unit = "nix-gc.service";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
(lib.mkIf pkgs.stdenv.isDarwin {
assertions = [
{
assertion = (lib.length cfg.dates) == 1;
message = "On Darwin, `nix.gc.dates` must contain a single element.";
}
(lib.hm.darwin.assertInterval "nix.gc.dates.*" (lib.elemAt cfg.dates 0) pkgs)
];
assertions = [
{
assertion = pkgs.stdenv.isDarwin -> (lib.length cfg.dates == 1);
message = "On Darwin, `nix.gc.dates` must contain a single element.";
}
(lib.hm.darwin.assertInterval "nix.gc.dates.*" (lib.elemAt cfg.dates 0) pkgs)
];
launchd.agents.nix-gc = {
enable = true;
config = {
ProgramArguments = [
"${nixPackage}/bin/nix-collect-garbage"
]
++ lib.optional (cfg.options != null) cfg.options;
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval (lib.elemAt cfg.dates 0);
};
};
};
launchd.agents.nix-gc = {
enable = true;
config = {
ProgramArguments = [
"${nixPackage}/bin/nix-collect-garbage"
]
++ lib.optional (cfg.options != null) cfg.options;
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval (lib.elemAt cfg.dates 0);
};
};
})
]
);
}

View File

@@ -87,7 +87,7 @@ in
};
config = mkIf cfg.enable {
systemd.user.services.ollama = {
systemd.user.services.ollama = mkIf pkgs.stdenv.isLinux {
Unit = {
Description = "Server for local large language models";
After = [ "network.target" ];
@@ -105,7 +105,7 @@ in
};
};
launchd.agents.ollama = {
launchd.agents.ollama = mkIf pkgs.stdenv.isDarwin {
enable = true;
config = {
ProgramArguments = [

View File

@@ -11,7 +11,7 @@ let
pueuedBin = "${cfg.package}/bin/pueued";
in
{
meta.maintainers = [ ];
meta.maintainers = [ lib.maintainers.AndersonTorres ];
options.services.pueue = {
enable = lib.mkEnableOption "Pueue, CLI process scheduler and manager";
@@ -35,49 +35,51 @@ in
};
};
config = lib.mkIf cfg.enable {
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
}
(lib.mkIf pkgs.stdenv.isLinux {
xdg.configFile."pueue/pueue.yml".source = configFile;
systemd.user = lib.mkIf (cfg.package != null) {
services.pueued = {
Unit = {
Description = "Pueue Daemon - CLI process scheduler and manager";
};
xdg.configFile."pueue/pueue.yml" = lib.mkIf pkgs.stdenv.isLinux { source = configFile; };
Service = {
Restart = "on-failure";
ExecStart = "${pueuedBin} -v -c ${configFile}";
};
systemd.user = lib.mkIf (cfg.package != null) {
services.pueued = {
Unit = {
Description = "Pueue Daemon - CLI process scheduler and manager";
Install.WantedBy = [ "default.target" ];
};
};
})
(lib.mkIf pkgs.stdenv.isDarwin {
# This is the default configuration file location for pueue on
# darwin (https://github.com/Nukesor/pueue/wiki/Configuration)
home.file."Library/Application Support/pueue/pueue.yml".source = configFile;
launchd.agents.pueued = lib.mkIf (cfg.package != null) {
enable = true;
Service = {
Restart = "on-failure";
ExecStart = "${pueuedBin} -v -c ${configFile}";
config = {
ProgramArguments = [
pueuedBin
"-v"
"-c"
"${configFile}"
];
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
RunAtLoad = true;
};
};
Install.WantedBy = [ "default.target" ];
};
};
# This is the default configuration file location for pueue on
# darwin (https://github.com/Nukesor/pueue/wiki/Configuration)
home.file."Library/Application Support/pueue/pueue.yml" = lib.mkIf pkgs.stdenv.isDarwin {
source = configFile;
};
launchd.agents.pueued = lib.mkIf (cfg.package != null) {
enable = true;
config = {
ProgramArguments = [
pueuedBin
"-v"
"-c"
"${configFile}"
];
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
RunAtLoad = true;
};
};
};
})
]
);
}

View File

@@ -103,7 +103,7 @@ let
settingsFormat = recollConfFormat { };
in
{
meta.maintainers = [ ];
meta.maintainers = [ lib.maintainers.foo-dogsquared ];
options.services.recoll = {
enable = lib.mkEnableOption "Recoll file index service";

View File

@@ -62,13 +62,15 @@ let
))
];
inherit (pkgs.stdenv.hostPlatform) isLinux;
# Until we have launchd support (#7924), mark the options
# not used in the helper script as "linux exclusive"
linuxExclusive =
option:
option
// {
readOnly = !pkgs.stdenv.hostPlatform.isLinux;
readOnly = pkgs.stdenv.hostPlatform.isDarwin;
description = option.description + ''
@@ -391,209 +393,219 @@ in
};
};
config = lib.mkIf cfg.enable {
assertions = lib.mapAttrsToList (n: v: {
assertion = lib.xor (v.repository == null) (v.repositoryFile == null);
message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set";
}) cfg.backups;
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
assertions = lib.mapAttrsToList (n: v: {
assertion = lib.xor (v.repository == null) (v.repositoryFile == null);
message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set";
}) cfg.backups;
}
systemd.user.services = lib.mapAttrs' (
name: backup:
let
doBackup = backup.dynamicFilesFrom != null || backup.paths != [ ];
doPrune = backup.pruneOpts != [ ];
doCheck = backup.runCheck;
serviceName = "restic-backups-${name}";
(lib.mkIf isLinux {
systemd.user.services = lib.mapAttrs' (
name: backup:
let
doBackup = backup.dynamicFilesFrom != null || backup.paths != [ ];
doPrune = backup.pruneOpts != [ ];
doCheck = backup.runCheck;
serviceName = "restic-backups-${name}";
extraOptions = lib.concatMap (arg: [
"-o"
arg
]) backup.extraOptions;
extraOptions = lib.concatMap (arg: [
"-o"
arg
]) backup.extraOptions;
excludeFile = pkgs.writeText "exclude-patterns" (lib.concatLines backup.exclude);
excludeFileFlag = "--exclude-file=${excludeFile}";
excludeFile = pkgs.writeText "exclude-patterns" (lib.concatLines backup.exclude);
excludeFileFlag = "--exclude-file=${excludeFile}";
filesFromTmpFile = "/run/user/$UID/${serviceName}/includes";
filesFromFlag = "--files-from=${filesFromTmpFile}";
filesFromTmpFile = "/run/user/$UID/${serviceName}/includes";
filesFromFlag = "--files-from=${filesFromTmpFile}";
inhibitCmd = lib.optionals backup.inhibitsSleep [
"${pkgs.systemd}/bin/systemd-inhibit"
"--mode='block'"
"--who='restic'"
"--what='idle'"
"--why=${lib.escapeShellArg "Scheduled backup ${name}"}"
];
inhibitCmd = lib.optionals backup.inhibitsSleep [
"${pkgs.systemd}/bin/systemd-inhibit"
"--mode='block'"
"--who='restic'"
"--what='idle'"
"--why=${lib.escapeShellArg "Scheduled backup ${name}"}"
];
mkResticCmd' =
pre: args:
lib.concatStringsSep " " (
pre ++ lib.singleton (lib.getExe backup.package) ++ extraOptions ++ lib.flatten args
);
mkResticCmd = mkResticCmd' [ ];
mkResticCmd' =
pre: args:
lib.concatStringsSep " " (
pre ++ lib.singleton (lib.getExe backup.package) ++ extraOptions ++ lib.flatten args
);
mkResticCmd = mkResticCmd' [ ];
backupCmd =
"${lib.getExe pkgs.bash} -c "
+ lib.escapeShellArg (
mkResticCmd' inhibitCmd [
"backup"
backup.extraBackupArgs
excludeFileFlag
filesFromFlag
]
);
backupCmd =
"${lib.getExe pkgs.bash} -c "
+ lib.escapeShellArg (
mkResticCmd' inhibitCmd [
"backup"
backup.extraBackupArgs
excludeFileFlag
filesFromFlag
]
);
forgetCmd = mkResticCmd [
"forget"
"--prune"
backup.pruneOpts
];
checkCmd = mkResticCmd [
"check"
backup.checkOpts
];
unlockCmd = mkResticCmd "unlock";
in
lib.nameValuePair serviceName {
Unit = {
Description = "Restic backup service";
Wants = [ "network-online.target" ];
After = [ "network-online.target" ];
};
forgetCmd = mkResticCmd [
"forget"
"--prune"
backup.pruneOpts
];
checkCmd = mkResticCmd [
"check"
backup.checkOpts
];
unlockCmd = mkResticCmd "unlock";
in
lib.nameValuePair serviceName {
Unit = {
Description = "Restic backup service";
Wants = [ "network-online.target" ];
After = [ "network-online.target" ];
};
Service = {
Type = "oneshot";
Service = {
Type = "oneshot";
X-RestartIfChanged = true;
RuntimeDirectory = serviceName;
CacheDirectory = serviceName;
CacheDirectoryMode = "0700";
PrivateTmp = true;
X-RestartIfChanged = true;
RuntimeDirectory = serviceName;
CacheDirectory = serviceName;
CacheDirectoryMode = "0700";
PrivateTmp = true;
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C/${serviceName}" ];
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C/${serviceName}" ];
ExecStart =
lib.optional doBackup backupCmd
++ lib.optionals doPrune [
unlockCmd
forgetCmd
]
++ lib.optional doCheck checkCmd;
ExecStart =
lib.optional doBackup backupCmd
++ lib.optionals doPrune [
unlockCmd
forgetCmd
]
++ lib.optional doCheck checkCmd;
ExecStartPre = lib.getExe (
pkgs.writeShellApplication {
name = "${serviceName}-exec-start-pre";
inherit runtimeInputs;
text = ''
set -x
ExecStartPre = lib.getExe (
pkgs.writeShellApplication {
name = "${serviceName}-exec-start-pre";
inherit runtimeInputs;
text = ''
set -x
${lib.optionalString (backup.backupPrepareCommand != null) ''
${pkgs.writeShellScript "backupPrepareCommand" backup.backupPrepareCommand}
''}
${lib.optionalString (backup.backupPrepareCommand != null) ''
${pkgs.writeShellScript "backupPrepareCommand" backup.backupPrepareCommand}
''}
${lib.optionalString (backup.initialize) ''
${
mkResticCmd [
"cat"
"config"
]
} 2>/dev/null || ${mkResticCmd "init"}
''}
${lib.optionalString (backup.initialize) ''
${
mkResticCmd [
"cat"
"config"
]
} 2>/dev/null || ${mkResticCmd "init"}
''}
${lib.optionalString (backup.paths != null && backup.paths != [ ]) ''
cat ${pkgs.writeText "staticPaths" (lib.concatLines backup.paths)} >> ${filesFromTmpFile}
''}
${lib.optionalString (backup.paths != null && backup.paths != [ ]) ''
cat ${pkgs.writeText "staticPaths" (lib.concatLines backup.paths)} >> ${filesFromTmpFile}
''}
${lib.optionalString (backup.dynamicFilesFrom != null) ''
${pkgs.writeShellScript "dynamicFilesFromScript" backup.dynamicFilesFrom} >> ${filesFromTmpFile}
''}
'';
${lib.optionalString (backup.dynamicFilesFrom != null) ''
${pkgs.writeShellScript "dynamicFilesFromScript" backup.dynamicFilesFrom} >> ${filesFromTmpFile}
''}
'';
}
);
ExecStopPost = lib.getExe (
pkgs.writeShellApplication {
name = "${serviceName}-exec-stop-post";
inherit runtimeInputs;
text = ''
set -x
${lib.optionalString (backup.backupCleanupCommand != null) ''
${pkgs.writeShellScript "backupCleanupCommand" backup.backupCleanupCommand}
''}
'';
}
);
}
);
// lib.optionalAttrs (backup.environmentFile != null) {
EnvironmentFile = backup.environmentFile;
};
}
) cfg.backups;
})
ExecStopPost = lib.getExe (
pkgs.writeShellApplication {
name = "${serviceName}-exec-stop-post";
inherit runtimeInputs;
text = ''
set -x
(lib.mkIf isLinux {
systemd.user.timers = lib.mapAttrs' (
name: backup:
lib.nameValuePair "restic-backups-${name}" {
Unit.Description = "Restic backup service";
Install.WantedBy = [ "timers.target" ];
${lib.optionalString (backup.backupCleanupCommand != null) ''
${pkgs.writeShellScript "backupCleanupCommand" backup.backupCleanupCommand}
''}
'';
}
);
}
// lib.optionalAttrs (backup.environmentFile != null) {
EnvironmentFile = backup.environmentFile;
};
Timer = backup.timerConfig;
}
) (lib.filterAttrs (_: v: v.timerConfig != null) cfg.backups);
})
{
home.packages = lib.mapAttrsToList (
name: backup:
let
serviceName = "restic-backups-${name}";
environment = mkEnvironment backup;
notPathVar = x: !(lib.hasPrefix "PATH" x);
extraOptions = lib.concatMap (arg: [
"-o"
arg
]) backup.extraOptions;
restic = lib.concatStringsSep " " (
lib.flatten [
(lib.getExe backup.package)
extraOptions
]
);
in
pkgs.writeShellApplication {
name = "restic-${name}";
excludeShellChecks = [
# https://github.com/koalaman/shellcheck/issues/1986
"SC2034"
# Allow sourcing environmentFile
"SC1091"
];
bashOptions = [
"errexit"
"nounset"
"allexport"
];
text = ''
${lib.optionalString (backup.environmentFile != null) ''
source ${backup.environmentFile}
''}
# Set same environment variables as the systemd service
${lib.pipe environment [
(lib.filter notPathVar)
lib.concatLines
]}
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
PATH=${
lib.pipe environment [
(lib.filter (lib.hasPrefix "PATH="))
lib.head
(lib.removePrefix "PATH=")
]
}:$PATH
exec ${restic} "$@"
'';
}
) (lib.filterAttrs (_: v: v.createWrapper) cfg.backups);
}
) cfg.backups;
systemd.user.timers = lib.mapAttrs' (
name: backup:
lib.nameValuePair "restic-backups-${name}" {
Unit.Description = "Restic backup service";
Install.WantedBy = [ "timers.target" ];
Timer = backup.timerConfig;
}
) (lib.filterAttrs (_: v: v.timerConfig != null) cfg.backups);
home.packages = lib.mapAttrsToList (
name: backup:
let
serviceName = "restic-backups-${name}";
environment = mkEnvironment backup;
notPathVar = x: !(lib.hasPrefix "PATH" x);
extraOptions = lib.concatMap (arg: [
"-o"
arg
]) backup.extraOptions;
restic = lib.concatStringsSep " " (
lib.flatten [
(lib.getExe backup.package)
extraOptions
]
);
in
pkgs.writeShellApplication {
name = "restic-${name}";
excludeShellChecks = [
# https://github.com/koalaman/shellcheck/issues/1986
"SC2034"
# Allow sourcing environmentFile
"SC1091"
];
bashOptions = [
"errexit"
"nounset"
"allexport"
];
text = ''
${lib.optionalString (backup.environmentFile != null) ''
source ${backup.environmentFile}
''}
# Set same environment variables as the systemd service
${lib.pipe environment [
(lib.filter notPathVar)
lib.concatLines
]}
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
PATH=${
lib.pipe environment [
(lib.filter (lib.hasPrefix "PATH="))
lib.head
(lib.removePrefix "PATH=")
]
}:$PATH
exec ${restic} "$@"
'';
}
) (lib.filterAttrs (_: v: v.createWrapper) cfg.backups);
};
]
);
}

View File

@@ -46,85 +46,89 @@ in
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
};
config = lib.mkIf cfg.enable {
programs =
let
socketPath =
if pkgs.stdenv.isDarwin then
"$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"
else
"$XDG_RUNTIME_DIR/${cfg.socket}";
# Preserve $SSH_AUTH_SOCK only if it stems from a forwarded agent which
# is the case if both $SSH_AUTH_SOCK and $SSH_CONNECTION are set.
bashIntegration = ''
if [ -z "$SSH_AUTH_SOCK" -o -z "$SSH_CONNECTION" ]; then
export SSH_AUTH_SOCK=${socketPath}
fi
'';
fishIntegration = ''
if test -z "$SSH_AUTH_SOCK"; or test -z "$SSH_CONNECTION"
set -x SSH_AUTH_SOCK ${socketPath}
end
'';
nushellIntegration =
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
programs =
let
unsetOrEmpty = var: ''("${var}" not-in $env) or ($env.${var} | is-empty)'';
socketPath =
if pkgs.stdenv.isDarwin then
''$"(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"''
"$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"
else
''$"($env.XDG_RUNTIME_DIR)/${cfg.socket}"'';
"$XDG_RUNTIME_DIR/${cfg.socket}";
bashIntegration = ''
if [ -z "$SSH_AUTH_SOCK" ]; then
export SSH_AUTH_SOCK=${socketPath}
fi
'';
fishIntegration = ''
if test -z "$SSH_AUTH_SOCK"
set -x SSH_AUTH_SOCK ${socketPath}
end
'';
nushellIntegration =
if pkgs.stdenv.isDarwin then
''
if "SSH_AUTH_SOCK" not-in $env {
$env.SSH_AUTH_SOCK = $"(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"
}
''
else
''
if "SSH_AUTH_SOCK" not-in $env {
$env.SSH_AUTH_SOCK = $"($env.XDG_RUNTIME_DIR)/${cfg.socket}"
}
'';
in
''
if ${unsetOrEmpty "SSH_AUTH_SOCK"} or ${unsetOrEmpty "SSH_CONNECTION"} {
$env.SSH_AUTH_SOCK = ${socketPath}
}
'';
in
{
# $SSH_AUTH_SOCK has to be set early since other tools rely on it
bash.profileExtra = lib.mkIf cfg.enableBashIntegration (lib.mkOrder 900 bashIntegration);
fish.shellInit = lib.mkIf cfg.enableFishIntegration (lib.mkOrder 900 fishIntegration);
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration (lib.mkOrder 900 nushellIntegration);
zsh.envExtra = lib.mkIf cfg.enableZshIntegration (lib.mkOrder 900 bashIntegration);
};
{
# $SSH_AUTH_SOCK has to be set early since other tools rely on it
bash.profileExtra = lib.mkIf cfg.enableBashIntegration (lib.mkOrder 900 bashIntegration);
fish.shellInit = lib.mkIf cfg.enableFishIntegration (lib.mkOrder 900 fishIntegration);
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration (lib.mkOrder 900 nushellIntegration);
zsh.envExtra = lib.mkIf cfg.enableZshIntegration (lib.mkOrder 900 bashIntegration);
};
}
systemd.user.services.ssh-agent = {
Install.WantedBy = [ "default.target" ];
Unit = {
Description = "SSH authentication agent";
Documentation = "man:ssh-agent(1)";
};
Service.ExecStart = "${lib.getExe' cfg.package "ssh-agent"} -D -a %t/${cfg.socket}${
lib.optionalString (
cfg.defaultMaximumIdentityLifetime != null
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
}";
};
launchd.agents.ssh-agent = {
enable = true;
config = {
ProgramArguments = [
(lib.getExe pkgs.bash)
"-c"
''${lib.getExe' cfg.package "ssh-agent"} -D -a "$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"${
(lib.mkIf pkgs.stdenv.isLinux {
systemd.user.services.ssh-agent = {
Install.WantedBy = [ "default.target" ];
Unit = {
Description = "SSH authentication agent";
Documentation = "man:ssh-agent(1)";
};
Service.ExecStart = "${lib.getExe' cfg.package "ssh-agent"} -D -a %t/${cfg.socket}${
lib.optionalString (
cfg.defaultMaximumIdentityLifetime != null
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
}''
];
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
}";
};
ProcessType = "Background";
RunAtLoad = true;
};
};
};
})
(lib.mkIf pkgs.stdenv.isDarwin {
launchd.agents.ssh-agent = {
enable = true;
config = {
ProgramArguments = [
(lib.getExe pkgs.bash)
"-c"
''${lib.getExe' cfg.package "ssh-agent"} -D -a "$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"${
lib.optionalString (
cfg.defaultMaximumIdentityLifetime != null
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
}''
];
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
RunAtLoad = true;
};
};
})
]
);
}

View File

@@ -11,7 +11,7 @@ let
in
{
meta.maintainers = [ ];
meta.maintainers = [ lib.maintainers.AndersonTorres ];
options = {
xsession.windowManager.fluxbox = {

View File

@@ -164,14 +164,6 @@ in
xwayland.enable = lib.mkEnableOption "XWayland" // {
default = true;
description = ''
Whether or not to enable XWayland.
Overrides the `enableXWayland` option of the Hyprland package.
In newer versions of Hyprland, you can use the {option}`wayland.windowManager.hyprland.settings.xwayland`
option to avoid recompiling Hyprland.
'';
};
settings = lib.mkOption {

View File

@@ -19,15 +19,6 @@ let
self.xmonad-extras
];
};
ghc-builder = cfg.haskellPackages.ghcWithPackages (
self:
[ self.xmonad ]
++ (cfg.extraPackages self)
++ lib.optionals cfg.enableContribAndExtras [
self.xmonad-contrib
self.xmonad-extras
]
);
in
{
@@ -113,21 +104,6 @@ in
contents of the files.
'';
};
buildScript = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Build script for your xmonad configuration.
'';
example = literalExpression ''
pkgs.writeText "build" '''
#!/bin/sh
# Enable -threaded
ghc --make xmonad.hs -threaded -i -ilib -fforce-recomp -main-is main -v0 -O2 -o "$1"
'''
'';
};
};
};
@@ -143,12 +119,7 @@ in
xmonadBin = "${
pkgs.runCommandLocal "xmonad-compile"
{
nativeBuildInputs = [
xmonad
]
++ lib.optional (cfg.buildScript != null) [
ghc-builder
];
nativeBuildInputs = [ xmonad ];
}
''
mkdir -p $out/bin
@@ -160,9 +131,7 @@ in
mkdir -p "$XMONAD_CONFIG_DIR/lib" "$XMONAD_CACHE_DIR" "$XMONAD_DATA_DIR"
cp ${cfg.config} xmonad-config/xmonad.hs
${lib.optionalString (cfg.buildScript != null) ''
install -m 555 ${cfg.buildScript} xmonad-config/build
''}
declare -A libFiles
libFiles=(${
lib.concatStringsSep " " (lib.mapAttrsToList (name: value: "['${name}']='${value}'") cfg.libFiles)

View File

@@ -19,71 +19,79 @@ in
package = lib.mkPackageOption pkgs "yubikey-agent" { };
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
config = mkIf cfg.enable (
lib.mkMerge [
{ home.packages = [ cfg.package ]; }
home.sessionVariables.SSH_AUTH_SOCK =
if pkgs.stdenv.isDarwin then
"/tmp/yubikey-agent.sock"
else
"\${XDG_RUNTIME_DIR:-/run/user/$UID}/yubikey-agent/yubikey-agent.sock";
(mkIf pkgs.stdenv.isLinux {
systemd.user.services.yubikey-agent = {
Unit = {
Description = "Seamless ssh-agent for YubiKeys";
Documentation = "https://github.com/FiloSottile/yubikey-agent";
Requires = "yubikey-agent.socket";
After = "yubikey-agent.socket";
RefuseManualStart = true;
};
systemd.user.services.yubikey-agent = {
Unit = {
Description = "Seamless ssh-agent for YubiKeys";
Documentation = "https://github.com/FiloSottile/yubikey-agent";
Requires = "yubikey-agent.socket";
After = "yubikey-agent.socket";
RefuseManualStart = true;
};
Service = {
ExecStart = "${cfg.package}/bin/yubikey-agent -l %t/yubikey-agent/yubikey-agent.sock";
Type = "simple";
# /run/user/$UID for the socket
ReadWritePaths = [ "%t" ];
};
};
systemd.user.sockets.yubikey-agent = {
Unit = {
Description = "Unix domain socket for Yubikey SSH agent";
Documentation = "https://github.com/FiloSottile/yubikey-agent";
};
Socket = {
ListenStream = "%t/yubikey-agent/yubikey-agent.sock";
RuntimeDirectory = "yubikey-agent";
SocketMode = "0600";
DirectoryMode = "0700";
};
Install = {
WantedBy = [ "sockets.target" ];
};
};
launchd.agents.yubikey-agent = {
enable = true;
config = {
ProgramArguments = [
"${cfg.package}/bin/yubikey-agent"
"-l"
"/tmp/yubikey-agent.sock"
];
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
Sockets = {
Listener = {
SockPathName = "/tmp/yubikey-agent.sock";
SockPathMode = 384; # 0600 in decimal
Service = {
ExecStart = "${cfg.package}/bin/yubikey-agent -l %t/yubikey-agent/yubikey-agent.sock";
Type = "simple";
# /run/user/$UID for the socket
ReadWritePaths = [ "%t" ];
};
};
};
};
};
systemd.user.sockets.yubikey-agent = {
Unit = {
Description = "Unix domain socket for Yubikey SSH agent";
Documentation = "https://github.com/FiloSottile/yubikey-agent";
};
Socket = {
ListenStream = "%t/yubikey-agent/yubikey-agent.sock";
RuntimeDirectory = "yubikey-agent";
SocketMode = "0600";
DirectoryMode = "0700";
};
Install = {
WantedBy = [ "sockets.target" ];
};
};
home.sessionVariables = {
SSH_AUTH_SOCK = "\${XDG_RUNTIME_DIR:-/run/user/$UID}/yubikey-agent/yubikey-agent.sock";
};
})
(mkIf pkgs.stdenv.isDarwin {
launchd.agents.yubikey-agent = {
enable = true;
config = {
ProgramArguments = [
"${cfg.package}/bin/yubikey-agent"
"-l"
"/tmp/yubikey-agent.sock"
];
KeepAlive = {
Crashed = true;
SuccessfulExit = false;
};
ProcessType = "Background";
Sockets = {
Listener = {
SockPathName = "/tmp/yubikey-agent.sock";
SockPathMode = 384; # 0600 in decimal
};
};
};
};
home.sessionVariables = {
SSH_AUTH_SOCK = "/tmp/yubikey-agent.sock";
};
})
]
);
}

View File

@@ -430,7 +430,10 @@ in
# Do not install any user services if username is root.
config = mkIf (cfg.enable && config.home.username != "root") {
assertions = [
(lib.hm.assertions.assertPlatform "systemd" pkgs lib.platforms.linux)
{
assertion = pkgs.stdenv.isLinux;
message = "This module is only available on Linux.";
}
];
xdg.configFile = mkMerge [

View File

@@ -274,26 +274,6 @@ in
sed "s|${pkg.out}|$out|g" "$src" > "$dsk"
done
# Patch systemd user services
for svc in "$out/share/systemd/user"/*.service ; do
if ! grep -q "${pkg.out}" "$svc"; then
continue
fi
src="$(readlink "$svc")"
rm "$svc"
sed "s|${pkg.out}|$out|g" "$src" > "$svc"
done
# Patch DBus services
for svc in "$out/share/dbus-1/services"/*.service ; do
if ! grep -q "${pkg.out}" "$svc"; then
continue
fi
src="$(readlink "$svc")"
rm "$svc"
sed "s|${pkg.out}|$out|g" "$src" > "$svc"
done
shopt -u nullglob # Revert nullglob back to its normal default state
'';
}))

View File

@@ -130,13 +130,6 @@ let
stateVersion = lib.mkDefault "18.09";
};
# NOTE: Added 2025-12-27
# Avoid option change deprecation warning
# Remove after deprecation period
programs.zsh.dotDir = lib.mkIf (config.home.stateVersion == "18.09") (
lib.mkDefault "/home/hm-user"
);
# Avoid including documentation since this will cause
# unnecessary rebuilds of the tests.
manual.manpages.enable = lib.mkDefault false;

View File

@@ -1,5 +1,4 @@
{
generators-hyprconf = ./tohyprconf.nix;
generators-tokdl = ./tokdl.nix;
generators-toscfg-empty = ./toscfg-empty.nix;
generators-toscfg-example = ./toscfg-example.nix;

View File

@@ -1,93 +0,0 @@
$important=123
attrs-section {
bool=true
float=0.800000
int=5
null=null
string=abc
}
combined-attrs-nested-section {
a {
a=123
}
a {
b=123
}
a {
c=123
}
b {
a=123
}
b {
b=123
}
b {
c=123
}
}
combined-list-nested-section {
b {
c {
abc=123
}
}
}
combined-list-nested-section {
bar {
baz {
aaa=111
}
}
}
list-section=foo
list-section=bar
list-section=baz
list-with-strings-and-attrs=abc
list-with-strings-and-attrs {
a=123
}
list-with-strings-and-attrs=foo
list-with-strings-and-attrs {
b=321
}
nested-attrs-section {
a {
b {
c {
abc=123
}
}
}
foo {
bar {
baz {
aaa=111
}
}
}
}
nested-list-section {
a=123
}
nested-list-section {
b=123
}
nested-list-section {
c=123
}

View File

@@ -1,70 +0,0 @@
{ lib, ... }:
{
home.file."tohyprconf-result.txt".text = lib.hm.generators.toHyprconf {
attrs = rec {
"$important" = 123;
list-section = [
"foo"
"bar"
"baz"
];
attrs-section = {
string = "abc";
int = 5;
float = 0.8;
bool = true;
null = null;
};
nested-attrs-section = {
a = {
b = {
c = {
abc = 123;
};
};
};
foo = {
bar = {
baz = {
aaa = 111;
};
};
};
};
nested-list-section = [
{ a = 123; }
{ b = 123; }
{ c = 123; }
];
combined-list-nested-section = [
nested-attrs-section.a
nested-attrs-section.foo
];
combined-attrs-nested-section = {
a = nested-list-section;
b = nested-list-section;
};
list-with-strings-and-attrs = [
"abc"
{ a = 123; }
"foo"
{ b = 321; }
];
};
};
nmt.script = ''
assertFileContent \
home-files/tohyprconf-result.txt \
${./tohyprconf-result.txt}
'';
}

View File

@@ -2,5 +2,4 @@
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
anyrun = ./basic-config.nix;
anyrun-empty-css = ./empty-css.nix;
}

View File

@@ -1,10 +0,0 @@
{
programs.anyrun = {
enable = true;
config.plugins = [ ];
};
nmt.script = ''
assertPathNotExists home-files/.config/anyrun/style.css
'';
}

View File

@@ -1,10 +1,5 @@
{ lib, pkgs, ... }:
{
ghostty-empty-settings = ./empty-settings.nix;
ghostty-example-settings = ./example-settings.nix;
ghostty-empty-settings = ./empty-settings.nix;
ghostty-example-theme = ./example-theme.nix;
}
// lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
ghostty-systemd-service = ./systemd-service.nix;
}

View File

@@ -11,9 +11,6 @@
};
nmt.script = ''
servicePath=home-files/.config/systemd/user/app-com.mitchellh.ghostty.service
assertPathNotExists $servicePath
assertFileContent \
home-files/.config/ghostty/config \
${./example-config-expected}

View File

@@ -1,56 +0,0 @@
{ config, ... }:
{
programs.ghostty = {
enable = true;
package = config.lib.test.mkStubPackage { outPath = null; };
systemd.enable = true;
settings = {
theme = "catppuccin-mocha";
font-size = 10;
};
themes = {
catppuccin-mocha = {
palette = [
"0=#45475a"
"1=#f38ba8"
"2=#a6e3a1"
"3=#f9e2af"
"4=#89b4fa"
"5=#f5c2e7"
"6=#94e2d5"
"7=#bac2de"
"8=#585b70"
"9=#f38ba8"
"10=#a6e3a1"
"11=#f9e2af"
"12=#89b4fa"
"13=#f5c2e7"
"14=#94e2d5"
"15=#a6adc8"
];
background = "1e1e2e";
foreground = "cdd6f4";
cursor-color = "f5e0dc";
selection-background = "353749";
selection-foreground = "cdd6f4";
};
};
};
nmt.script = ''
servicePath=home-files/.config/systemd/user/app-com.mitchellh.ghostty.service
serviceOverridesPath=$servicePath.d/overrides.conf
assertFileExists $serviceOverridesPath
assertFileContent $(normalizeStorePaths $serviceOverridesPath) \
${builtins.toFile "ghostty-service-overrides" ''
[Unit]
X-SwitchMethod=keep-old
X-Reload-Triggers=/nix/store/00000000000000000000000000000000-ghostty-config /nix/store/00000000000000000000000000000000-ghostty-catppuccin-mocha-theme
''}
assertFileContent \
home-files/.config/ghostty/config \
${./example-config-expected}
'';
}

View File

@@ -3,5 +3,4 @@
gpg-mutable-keyfiles = ./mutable-keyfiles.nix;
gpg-multiple-keys-trust = ./multiple-keys-trust.nix;
gpg-override-defaults = ./override-defaults.nix;
gpg-other-settings = ./other-settings.nix;
}

View File

@@ -12,7 +12,7 @@
{
source = realPkgs.fetchurl {
url = "https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x44CF42371ADF842E12F116EAA9D3F98FCCF5460B";
hash = "sha256-csrFDI6QSPfNN+adOPEAupAtspYNBCybFZExvVS+vRY=";
hash = "sha256-bSluCZh6ijwppigk8iF2BwWKZgq1WDbIjyYQRK772dM=";
};
trust = 1; # "unknown"
}

View File

@@ -1,2 +0,0 @@
keyserver ldaps://ldap.example.com
use-tor

View File

@@ -1,3 +0,0 @@
cipher-algo AES256
validation-model steed
with-md5-fingerprint

View File

@@ -1,3 +0,0 @@
application-priority openpgp p15 sc-hsm nks geldkarte dinsig
disable-ccid
reader-port 32769

View File

@@ -1,32 +0,0 @@
{
programs.gpg = {
enable = true;
scdaemonSettings = {
disable-ccid = true;
reader-port = "32769";
application-priority = "openpgp p15 sc-hsm nks geldkarte dinsig";
};
dirmngrSettings = {
use-tor = true;
keyserver = "ldaps://ldap.example.com";
};
gpgsmSettings = {
cipher-algo = "AES256";
with-md5-fingerprint = true;
validation-model = "steed";
};
};
nmt.script = ''
assertFileExists home-files/.gnupg/scdaemon.conf
assertFileExists home-files/.gnupg/dirmngr.conf
assertFileExists home-files/.gnupg/gpgsm.conf
assertFileContent home-files/.gnupg/scdaemon.conf ${./other-scdaemon.conf}
assertFileContent home-files/.gnupg/dirmngr.conf ${./other-dirmngr.conf}
assertFileContent home-files/.gnupg/gpgsm.conf ${./other-gpgsm.conf}
'';
}

View File

@@ -1,6 +1,7 @@
cert-digest-algo SHA512
charset utf-8
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
display-charset utf-8
fixed-list-mode
keyid-format 0xlong
list-options show-uid-validity
@@ -15,5 +16,6 @@ s2k-digest-algo SHA512
throw-keyids
trusted-key 0xXXXXXXXXXXXXX
trusted-key 0xYYYYYYYYYYYYY
use-agent
verify-options show-uid-validity
with-fingerprint

View File

@@ -5,9 +5,6 @@ identity = "hm@example.com"
root_mailbox = "/home/hm-user/Mail/hm@example.com"
subscribed_mailboxes = ["Inbox", "Sent", "Trash", "Drafts"]
[accounts."hm@example.com".listing]
index_style = "compact"
[accounts."hm@example.com".mailboxes]
[accounts."hm@example.com".send_mail]

View File

@@ -16,12 +16,7 @@
};
accounts.email.accounts = {
"hm@example.com" = {
meli = {
enable = true;
settings = {
listing.index_style = "compact";
};
};
meli.enable = true;
smtp.port = 1848;
};
};

View File

@@ -9,10 +9,6 @@
opencode-agents-path = ./agents-path.nix;
opencode-commands-path = ./commands-path.nix;
opencode-mixed-content = ./mixed-content.nix;
opencode-skills-inline = ./skills-inline.nix;
opencode-skills-path = ./skills-path.nix;
opencode-skills-directory = ./skills-directory.nix;
opencode-skills-bulk-directory = ./skills-bulk-directory.nix;
opencode-themes-inline = ./themes-inline.nix;
opencode-themes-path = ./themes-path.nix;
opencode-mcp-integration = ./mcp-integration.nix;

View File

@@ -1,10 +0,0 @@
---
name: git-release
description: Create consistent releases and changelogs
---
## What I do
- Draft release notes from merged PRs
- Propose a version bump
- Provide a copy-pasteable `gh release create` command

View File

@@ -1,9 +0,0 @@
---
name: pdf-processing
description: Extract text and tables from PDF files
---
## What I do
- Extract text from PDFs
- Identify tables and structured data

View File

@@ -1,9 +0,0 @@
---
name: data-analysis
description: Help analyze datasets and results
---
## What I do
- Summarize datasets
- Suggest charts and metrics

View File

@@ -1 +0,0 @@
extra fixture file

View File

@@ -1,15 +0,0 @@
{
programs.opencode = {
enable = true;
skills = ./skills-bulk;
};
nmt.script = ''
assertFileExists home-files/.config/opencode/skill/git-release/SKILL.md
assertFileExists home-files/.config/opencode/skill/pdf-processing/SKILL.md
assertFileContent home-files/.config/opencode/skill/git-release/SKILL.md \
${./skills-bulk/git-release/SKILL.md}
assertFileContent home-files/.config/opencode/skill/pdf-processing/SKILL.md \
${./skills-bulk/pdf-processing/SKILL.md}
'';
}

View File

@@ -1,6 +0,0 @@
---
name: git-release
description: Create consistent releases and changelogs
---
This is the bulk skillsDir fixture for git-release.

View File

@@ -1,6 +0,0 @@
---
name: pdf-processing
description: Extract text and tables from PDF files
---
This is the bulk skillsDir fixture for pdf-processing.

View File

@@ -1,15 +0,0 @@
{
programs.opencode = {
enable = true;
skills = {
data-analysis = ./skill-dir/data-analysis;
};
};
nmt.script = ''
assertFileExists home-files/.config/opencode/skill/data-analysis/SKILL.md
assertFileExists home-files/.config/opencode/skill/data-analysis/notes.txt
assertFileContent home-files/.config/opencode/skill/data-analysis/SKILL.md \
${./skill-dir/data-analysis/SKILL.md}
'';
}

View File

@@ -1,25 +0,0 @@
{
programs.opencode = {
enable = true;
skills = {
git-release = ''
---
name: git-release
description: Create consistent releases and changelogs
---
## What I do
- Draft release notes from merged PRs
- Propose a version bump
- Provide a copy-pasteable `gh release create` command
'';
};
};
nmt.script = ''
assertFileExists home-files/.config/opencode/skill/git-release/SKILL.md
assertFileContent home-files/.config/opencode/skill/git-release/SKILL.md \
${./git-release-SKILL.md}
'';
}

View File

@@ -1,14 +0,0 @@
{
programs.opencode = {
enable = true;
skills = {
pdf-processing = ./pdf-processing-SKILL.md;
};
};
nmt.script = ''
assertFileExists home-files/.config/opencode/skill/pdf-processing/SKILL.md
assertFileContent home-files/.config/opencode/skill/pdf-processing/SKILL.md \
${./pdf-processing-SKILL.md}
'';
}

View File

@@ -15,7 +15,6 @@ Host xyz
RemoteForward [localhost]:8081 [10.0.0.2]:80
RemoteForward /run/user/1000/gnupg/S.gpg-agent.extra /run/user/1000/gnupg/S.gpg-agent
DynamicForward [localhost]:2839
KexAlgorithms sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,mlkem768x25519-sha256
Host ordered
Port 1

View File

@@ -34,11 +34,6 @@
host.address = "/run/user/1000/gnupg/S.gpg-agent";
}
];
kexAlgorithms = [
"sntrup761x25519-sha512"
"sntrup761x25519-sha512@openssh.com"
"mlkem768x25519-sha256"
];
dynamicForwards = [ { port = 2839; } ];
setEnv = {
FOO = "foo12";

View File

@@ -1,5 +1,4 @@
{ lib, pkgs, ... }:
lib.optionalAttrs (pkgs.stdenv.hostPlatform.isLinux) {
vicinae-pre17-settings = ./pre17-settings.nix;
vicinae-example-settings = ./example-settings.nix;
}

View File

@@ -8,7 +8,7 @@
programs.vicinae = {
enable = true;
systemd.enable = true;
useLayerShell = false;
settings = {
faviconService = "twenty";
font = {
@@ -62,9 +62,9 @@
extensions = [
(config.lib.vicinae.mkRayCastExtension {
name = "cdnjs";
sha256 = "sha256-k3YfruMxSOMf8K65iTW84aZxiknADCcntJOAE89agYc=";
rev = "ac7c50844bf77d0cf51daa840e369d999f2add59";
name = "gif-search";
sha256 = "sha256-G7il8T1L+P/2mXWJsb68n4BCbVKcrrtK8GnBNxzt73Q=";
rev = "4d417c2dfd86a5b2bea202d4a7b48d8eb3dbaeb1";
})
(config.lib.vicinae.mkExtension {
name = "test-extension";
@@ -80,16 +80,11 @@
];
};
test.asserts.assertions.expected = [
''After version 0.17, if you want to explicitly disable the use of layer shell, you need to set {option}.programs.vicinae.settings.launcher_window.layer_shell.enabled = false.''
];
nmt.script = ''
assertFileExists "home-files/.config/vicinae/settings.json"
assertFileExists "home-files/.config/vicinae/vicinae.json"
assertFileExists "home-files/.config/systemd/user/vicinae.service"
assertFileExists "home-files/.local/share/vicinae/themes/catppuccin-mocha.toml"
assertFileExists "home-files/.local/share/vicinae/extensions/cdnjs/package.json"
assertFileExists "home-files/.local/share/vicinae/extensions/gif-search/package.json"
assertFileExists "home-files/.local/share/vicinae/extensions/test-extension/package.json"
assertFileContent "home-files/.config/systemd/user/vicinae.service" ${./service.service}
'';
}

View File

@@ -1,46 +0,0 @@
{
pkgs,
config,
...
}:
{
programs.vicinae = {
enable = true;
systemd.enable = true;
package = pkgs.stdenv.mkDerivation {
pname = "fake-vicinae";
version = "0.10.0";
src = pkgs.emptyFile;
buildCommand = "mkdir -p $out";
meta = {
mainProgram = "vicinae";
};
};
settings = {
faviconService = "twenty";
font = {
size = 10;
};
popToRootOnClose = false;
rootSearch = {
searchFiles = false;
};
theme = {
name = "vicinae-dark";
};
window = {
csd = true;
opacity = 0.95;
rounding = 10;
};
};
};
nmt.script = ''
assertFileExists "home-files/.config/vicinae/vicinae.json"
assertFileExists "home-files/.config/systemd/user/vicinae.service"
assertFileContains "home-files/.config/systemd/user/vicinae.service" "EnvironmentFile"
'';
}

View File

@@ -1,15 +0,0 @@
[Install]
WantedBy=graphical-session.target
[Service]
ExecStart=@vicinae@/bin/vicinae server
KillMode=process
Restart=always
RestartSec=5
Type=simple
[Unit]
After=graphical-session.target
Description=Vicinae server daemon
Documentation=https://docs.vicinae.com
PartOf=graphical-session.target

View File

@@ -1,4 +1,5 @@
{ lib, pkgs, ... }:
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
yt-dlp-config = ./yt-dlp-config.nix;
yt-dlp-simple-config = ./yt-dlp-simple-config.nix;
yt-dlp-extraConfig = ./yt-dlp-extraConfig.nix;
}

View File

@@ -0,0 +1,2 @@
--config-locations /home/user/.yt-dlp.conf

View File

@@ -0,0 +1,13 @@
{
programs.yt-dlp = {
enable = true;
extraConfig = ''
--config-locations /home/user/.yt-dlp.conf
'';
};
nmt.script = ''
assertFileExists home-files/.config/yt-dlp/config
assertFileContent home-files/.config/yt-dlp/config ${./yt-dlp-extraConfig-expected}
'';
}

View File

@@ -1,5 +1,3 @@
--color stdout:no_color
--color stderr:always
--downloader aria2c
--downloader-args aria2c:'-c -x8 -s8 -k1M'
--no-embed-subs

Some files were not shown because too many files have changed in this diff Show More