2477 Commits

Author SHA1 Message Date
Aly Raffauf
acd21c5a34 codex: add mutable settings option
Merge declared settings into writable TOML files with mkImpureConfigMerger. Preserve user settings and support transitions between mutable and immutable configurations.

Co-authored-by: Austin Horstman <khaneliman12@gmail.com>
2026-10-02 20:00:54 -05:00
Austin Horstman
47c54aec43 zed-editor: restore managed links when disabling mutable settings
Turning off mutableUserSettings, mutableUserKeymaps, mutableUserTasks,
or mutableUserDebug left the previously merged regular file in place.
When it matched the declared config it was never replaced by a link,
so it stayed writable and collided once the settings changed.

Run mkImpureConfigCleanup for each of the four files whose toggle is
off. The conditions that link those files now live in one binding that
both the file entries and the cleanup use, so they cannot drift apart.
The test checks zed's wiring: which files get a cleanup, where it runs,
and that a file disabled through home.file or xdg.configFile gets
none. The removal itself is covered by the helper's tests. Merging
behavior is unchanged.
2026-10-02 15:25:26 -05:00
Austin Horstman
dda5f1577f generators: add mkImpureConfigCleanup for immutable transitions
When a module turns a mutable config back into a managed link, the
regular file the merger left behind is accepted by checkLinkTargets if
it is byte-identical to the new source, but linkGeneration then skips
it. The file stays a writable copy and collides as soon as the declared
settings change.

Add a companion to mkImpureConfigMerger that removes such an unchanged
regular file between writeBoundary and linkGeneration so the link can
be created. It takes the effective file entry and compares the file on
disk with that entry's copy in the new generation, which is what
linkGeneration places, so sources given as absolute paths are compared
correctly. A disabled entry produces no cleanup, since it does not give
the module ownership of the path. Files that differ, even only in
formatting, and symlinks are left alone for the normal collision and
backup handling, and so is a file that is the declared source itself
or the generation's link to it, such as an out-of-store source reached
through a symlinked parent directory. Checking the declared source too
covers generations that copy it to adjust its executable bit.

This generalizes the cleanup programs.vscode already does for its user
settings. It is marked experimental because it relies on how collision
checking and link generation treat identical files.

The helper test runs collision checking, the cleanup, and link
generation for a real file entry, so consumers only need to test which
files they hand to it.
2026-10-02 15:25:26 -05:00
Austin Horstman
0560d64401 generators: replace mkImpureConfigMerger targets atomically
The merge overwrote the target in place with `cat "$tmp" > path`, so a
crash mid-write could leave a truncated file, and an application that
saved its config while activation ran had that change silently
overwritten.

Snapshot the existing file, write the merged result to a temporary
file next to the resolved target, copy the existing mode (or apply
`mode` or the umask for a new file), and rename it into place. The
snapshot keeps the configured file name inside a temporary directory,
so a reader that detects the format from the extension still
recognizes it, even through a symlink to a differently named file.
Symlinked targets are written through and stay symlinks; a dangling
symlink creates its target, as the hand-written mergers this helper
replaced did. Activation fails without writing if the content, the
mode, or the symlink target changed since the snapshot, and refuses
targets inside the Nix store. A target that cannot be renamed over,
such as a file bind-mounted by impermanence, is written in place
instead. Temporary files are cleaned up by a trap scoped to a
subshell, since activation owns the top-level EXIT trap; this also
keeps the merge's shell variables out of the activation script.

The change check is not a lock: a write between the final check and
the rename is still lost. The documentation says so, along with the
attributes a rename does not preserve.

This follows the approach programs.vscode uses for its mutable user
settings.
2026-10-02 10:30:05 -05:00
Austin Horstman
3378835aa9 generators: add mode input to mkImpureConfigMerger
Some applications store tokens in the files these merges manage, such
as gh's hosts.yml or Docker's config.json, so callers need a way to
create them as 600.

The new optional `mode` input applies only when the target does not
exist yet; existing files keep their mode. By default it is null and a
new file gets the permissions shell redirection would give it under the
activation's umask, as the hand-written mergers this helper replaces
did, instead of a fixed 644. A value that is not an octal string fails
evaluation, rather than the first activation on a machine where the
file does not exist yet.
2026-10-02 10:30:05 -05:00
Austin Horstman
199871bf7e generators: document TOML date limitation in mkImpureConfigMerger
jaq 3.1.1 reads TOML through toml-span, which does not deserialize
date or time values. An existing TOML file containing one makes the
merge refuse, so activation fails on every switch until the value is
removed. The file itself is left untouched.

Document the limitation and test that the refused merge leaves the
file byte-identical. If a later jaq parses these values, they would
pass through JSON as strings, so the test is expected to fail then and
prompt a review of the documented behavior.
2026-10-02 09:41:18 -05:00
Austin Horstman
22970e1ddb generators: write merged YAML in block style
`jaq --to yaml -c` writes the merged configuration in one-line flow
style, so a user's block-style YAML came back as `{a: {b: [x]}}`. Drop
the compact flag for every non-JSON format: YAML is now written in
block style, while TOML, CBOR, and XML output are byte-identical with
and without it.

Document that comments and formatting are not preserved. Test the
exact block-style output with nested mappings and a list, and that
merging the written file again leaves it unchanged.
2026-10-02 09:41:18 -05:00
Austin Horstman
894214fea9 generators: print mkImpureConfigMerger paths literally
The dry-run message interpolated the configured path into a
double-quoted string, and the parse error embedded an escaped path
inside one. A path containing a command substitution was therefore
executed while printing the message. Quote each complete message as a
single shell argument, as the verbose message already does, and test
both messages with such a path.
2026-10-02 09:36:50 -05:00
Austin Horstman
03cb70e331 generators: remove impure config merger input size limit
Pass JSON documents to jaq through process substitution instead of
--argjson. Linux limits a single argument to 128 KiB, so merging an
existing configuration file or Nix-declared settings above that size
failed activation with "Argument list too long".

Require exactly one JSON value in each input before merging, so
multi-value streams are still rejected as they were with --argjson.
Keep the merge operation on its own line inside that filter so a
trailing comment in it cannot comment out the closing parenthesis, and
name the config file when the merge fails.

Add regression coverage for large existing files, large Nix-declared
settings, an operation ending in a comment, and byte-preserving
rejection of multiple JSON values.
2026-10-02 09:36:50 -05:00
Austin Horstman
8ae0495502 home-cursor: quote sway cursor theme names
Sway treats a cursor theme with spaces as multiple arguments unless the
name is quoted. Escape quotes and backslashes inside the quoted name so
literal theme names survive parsing, and cover simple, spaced, and
escaped names.
2026-10-02 09:05:26 -05:00
Austin Horstman
14a1ad8d3e aerc: match notmuch config to package version
Aerc 0.22 discovers its notmuch database automatically and deprecates
path-bearing sources and maildir-store. Preserve those settings for
packages older than 0.22 while using the bare source for newer packages
or package = null. Keep maildir-account-path for both versions and cover
the legacy and null-package paths with golden tests.
2026-10-02 09:04:53 -05:00
Jairo Llopis
833540099e joplin-desktop: use mkImpureConfigMerger for settings
Replace the inline jq merge script with
`lib.hm.generators.mkImpureConfigMerger`. The merge still uses `+` to
match the previous shallow object merge.

Tighten the tests: the store regex stops at the first space so it no
longer captures trailing activation script text, and the basic
configuration test asserts the dry-run and verbose branches now emitted
by the shared helper.

Assisted-by: Goose + GLM 5.3 Flash
2026-10-02 03:07:18 -05:00
Jairo Llopis
190a8d40c7 zed-editor: use mkImpureConfigMerger for mutable settings
Replace the module-local `impureConfigMerger` with
`lib.hm.generators.mkImpureConfigMerger`, keeping the JSON5 reader for
settings that may contain comments.

Behavior is preserved but two rough edges are fixed along the way:

- A corrupted existing file now fails activation loudly instead of
  silently replacing the user's settings with the generated defaults.
- An existing file keeps its permissions and symlink target instead of
  being replaced with a fresh mode-644 file.

Add a test that runs the generated activation snippet with `$DRY_RUN` and
`$VERBOSE` set, covering a dry-run that leaves existing settings
untouched, a live merge on top of preexisting settings, verbose logging,
silent quiet mode, permission preservation, and loud failure on a
corrupted file.

Assisted-by: Goose + GLM 5.3 Flash
2026-10-02 03:07:18 -05:00
Jairo Llopis
3c8cde701a generators: add mkImpureConfigMerger for runtime config merging
Add a reusable `lib.hm.generators.mkImpureConfigMerger` that generates a
bash snippet merging a Nix-generated config file into an existing user
config at activation time. It preserves interactive changes the user has
made while applying the Nix-declared settings on top.

The merge uses `jaq`, which handles JSON, YAML, TOML, and CBOR natively
through its `--from`/`--to` flags. An optional `reader` parameter allows
custom preprocessing, for example JSON5 files with comments.

The snippet follows the existing activation contract:

- `$DRY_RUN` prints what would be done and skips the merge entirely.
- `$VERBOSE` logs a merge message, customizable through `verboseMsg`.
- A missing or zero-byte file is treated as the `empty` value, kept in
  memory so the target is only created once the merge is serialized.
- An existing file that fails to parse aborts activation with an error
  instead of silently overwriting the user's settings with the generated
  defaults. The reader's exit status is checked because it can emit valid
  JSON before failing, as when jaq prints the first object of a truncated
  stream.
- The result is written to a temporary file and moved into place only
  after the merge succeeds. An existing file is overwritten in place to
  keep its permissions and symlink target; a new file is created with
  mode 644.

The helper is marked experimental: the activation contract edge cases are
still being discovered, so external flakes should pin this input.

Add a lib-level regression test covering the truncated-stream refusal
with byte preservation, first activation on missing JSON and TOML
targets, user-key preservation, and zero-byte files treated as empty.

Assisted-by: Goose + GLM 5.3 Flash
2026-10-02 03:07:18 -05:00
PierreBorine
d85475546a hyprscratch: add module 2026-10-01 14:30:51 -05:00
Dom Rodriguez
c8ecc29e51 tests: cover home.backup{FileExtension,Command,Overwrite} options 2026-09-30 20:54:52 -05:00
PierreBorine
6f6cf27e57 anyrun: update configuration for current upstream 2026-09-30 16:13:23 -05:00
PierreBorine
a518a57cea anyrun: add configurable navigation keybinds 2026-09-30 16:13:23 -05:00
PierreBorine
6c345ffde0 anyrun: add extra configuration lines 2026-09-30 16:13:23 -05:00
hectorgray
cb2f28657d positron: add module 2026-09-30 15:26:17 -05:00
sensura-san
36d5f7e937 hyfetch: add platform-dependent path support
Now supports the correct filepath for macOS systems, which hyfetch on macOS reads from by default.
Hyfetch test cases are updated to cover this.
2026-09-30 15:00:11 -05:00
Yethal
7db6547815 devenv: add settings 2026-09-30 14:53:09 -05:00
Matthieu Coudron
40dbd9ebc8 noctalia: enable calendar support 2026-09-30 14:28:31 -05:00
無名氏
fab715cc65 pi-coding-agent: add appendSystem option
Allow configuring APPEND_SYSTEM.md with inline instructions or a file path, following the context option and respecting configDir.
2026-09-30 13:16:34 -05:00
Zexin Yuan
603fbca129 worktrunk: fix skills path after installAgentSkills migration
nixpkgs#558216 switched the worktrunk package to the installAgentSkills
hook, moving the bundled skills from $out/skills/ to
$out/share/skills/worktrunk/.

Assisted-by: Claude-Code:GLM-5.3
Co-authored-by: Austin Horstman <khaneliman12@gmail.com>
2026-09-30 13:15:22 -05:00
Clément DOUIN
7c0c726efe himalaya: bring v2 support 2026-09-30 13:08:34 -05:00
o-az
b75a0703c9 fnox: add module 2026-09-30 16:47:55 +02:00
Austin Horstman
bf3f7a120d astroid: migrate to native JSON settings
Add programs.astroid.settings for native JSON configuration and
generate the configuration file from it.

The extraConfig and externalEditor options become deprecated aliases
into settings. Home Manager no longer writes its bundled template;
Astroid's built-in defaults match it except editor.markdown_processor.
Astroid accounts still supply account settings, the notmuch path, and
the GPG path as per-key defaults. Empty settings write no file.

externalEditor now merges at ordinary priority instead of replacing
the editor keys, and priorities on extraConfig sections apply to the
section as a unit. The release notes describe both changes.
2026-09-30 08:40:10 -05:00
Austin Horstman
d4941d9c8d notmuch: migrate to native INI settings
Add programs.notmuch.settings for native INI configuration with list
values, and generate the configuration file from it.

The new.ignore, new.tags, maildir.synchronizeFlags, search.excludeTags,
and extraConfig options become deprecated aliases into settings.
Settings carry no static defaults: new.tags, new.ignore, and
maildir.synchronize_flags fall back to notmuch's identical defaults.
State versions before 26.11 keep search.exclude_tags = deleted;spam and
write database.path even without email accounts. Enabled email
accounts supply database.path, and notmuch-enabled accounts the user
identity. Null values and empty sections are omitted so a derived
value can be removed.

extraConfig no longer overwrites modeled values unconditionally: forced
definitions win and ordinary collisions fail. The release notes
describe the migration.

Mbsync, lieer, and mujmap now write settings.new.ignore directly, so
they do not trigger deprecation warnings.
2026-09-30 08:23:14 -05:00
Austin Horstman
7d46509d83 borgmatic: migrate backups to native settings
Add programs.borgmatic.backups.<name>.settings for native borgmatic
YAML and generate each backup file from it.

The location, storage, retention, and consistency options and the
section extraConfig options become deprecated aliases into settings.
Warnings name the affected backup. Legacy configurations without
overlapping keys produce the same YAML, and Home Manager symlink
exclusions still append to exclude_from.

Drop the assertions that rejected backups setting both or neither of
sourceDirectories and patterns, so native source patterns and
database-only backups work.
2026-09-30 07:59:27 -05:00
Austin Horstman
31830be4fc borgmatic: omit unspecified check frequency
Consistency checks without a frequency were written as
`frequency: null`, which borgmatic rejects during configuration
validation. Omit null check fields so borgmatic applies its own
default.
2026-09-30 07:59:27 -05:00
Austin Horstman
c421f4751f nixos: pass driver version to user service
The user-service drop-in invoked activate without a driver version, so
the script defaulted to driver 0 and always managed the per-user
home-manager profile, ignoring enableLegacyProfileManagement. Use the
same version as the system service and assert both generated
user-service commands.
2026-09-29 22:51:37 -05:00
Austin Horstman
5023607510 mpd-mpris: accept strings and paths for pwd-file
pwd-file was typed as a path, but ExecStart renders settings through
lib.cli.toCommandLine, whose default value formatter has no case for
paths, so a path literal such as ./mpd-password aborted evaluation with
"generators.mkValueStringDefault: this value is not supported".

Accept a string or a path, and render path-like values with toString,
which gives a path literal's location without copying the file into the
Nix store. Strings and derivations render as before. Add a test for a
path literal.
2026-09-25 13:01:17 -05:00
Austin Horstman
c5a75f0f75 mpd-mpris: use the settings rename helper
The network, host, and port migrations from services.mpd-mpris.mpd to
services.mpd-mpris.settings share the same prefixes and option names,
so lib.hm.deprecations.mkSettingsRenamedOptionModules expresses them
without repeating each option path. It expands to the same
mkRenamedOptionModule calls.

Add a test that sets the old options and checks the rename warnings and
the generated unit, which no existing test covered.
2026-09-25 13:01:17 -05:00
hectorgray
4b9add8645 xdg-mime-apps: add glob support 2026-09-24 18:24:37 -05:00
Olmo Kramer
f298114886 mpd-mpris: Make settings less confusing
Fixes #8000

The `mpd-mpris` module used different names for the options than
`mpd-mpris` itself, causing some confusion.

Additionally, this makes some more improvements in the module, largely
based on the upstream module [^1], which includes:

- Removing the `services.mpd-mpris.mpd` namespace, it did not serve any
  purpose. This also got rid of the `services.mpd-mpris.mpd.useLocal`
  option, just don't configure `host` to connect to the local instance.

- Removing the `password` option, it should have never gotten into this
  module because it will write the password to the world readable nix
  store. A new `password-file` option was added to replace it.

- Moving the settings to a new freeform submodule under the key
  `services.mpd-mpris.settings`.

- Replacing the `renderCmd` function with a use of `lib.cli.toCommandLine`.

While I diverged quite a bit from the upstream module, much credit for
these changes goes to @natsukagami!

[^1] 90c4264e58/nix/module.nix
2026-09-24 13:43:54 -05:00
mikaeladev
4900baf1e2 openlinkhub: add module 2026-09-23 23:50:10 -05:00
Austin Horstman
e9796a288e lib/deprecations: name exact settings destinations
Forward converted values to the complete settings path so the standard
changed-option warning identifies the destination key. Preserve legacy
reads, priorities, defaults, and shadowed conversions.

Point mpdris2 at Library.music_dir directly and cover nested paths,
literal dotted keys, and the affected callers in warning tests. The
contributor guidelines now describe `to` as the settings path that
contains `key` instead of the settings root.
2026-09-23 22:37:57 -05:00
MithicSpirit
0b2f112917 gtk: fix gtk-interface-color-scheme
Fixes an issue introduced in [1] where gtk4 apps would print the
following warning:

> Error setting gtk-interface-color-scheme in
> /home/mithic/.config/gtk-4.0/settings.ini: Key file contains key
> “gtk-interface-color-scheme” which has a value that cannot be
> interpreted.

The value should be set to the nickname ("light" or "dark" in this
case), rather than the actual numerical value of the enum.  This lookup
happens at [2].

These nicknames appear to be undocumented and automatically generated at
compile time, but in general they appear to follow the pattern where an
enum value FOO_BAR_BAZ_QUUX of the enum FOO_BAR has nickname "baz-quux".
Regardless, they can be looked up in the generated file
gtktypebuiltins.c (it unfortunately appears that nix only keeps
gtktypebuiltins.h, which does not contain the nicknames).

[1] https://github.com/nix-community/home-manager/pull/7763
[2] https://gitlab.gnome.org/GNOME/gtk/-/blob/4.22.4/gtk/gtksettings.c#L1863
2026-09-22 21:00:14 -05:00
Austin Horstman
a5768f1a46 jjui: test configuration discovery and directory overrides
Cover session-variable omission for automatic paths and preservation for
custom paths and Darwin Lua-only configurations.
2026-09-22 16:00:21 -05:00
Austin Horstman
5e7de37a69 tests: stub jjui on Darwin
Avoid pulling the real jjui package into Darwin module tests.
2026-09-22 16:00:21 -05:00
nyxar77
a3dfb887d4 ninjabrain-bot: init module
adds programs.ninjabrain-bot, this module writes ninjabrainbot '’s Java preferences file from typed nix options
2026-09-21 15:16:33 -05:00
Austin Horstman
a6c231d51f getmail: omit unspecified mailbox settings
Allow native POP3 retrievers without an IMAP mailbox list. Preserve
explicit mailbox defaults and cover the omitted setting in the account
configuration test.
2026-09-21 12:08:57 -05:00
Austin Horstman
0a2d091b2c getmail: add per-account INI settings
Expose native filter, retriever, and destination configuration while
retaining account defaults and legacy boolean aliases. Preserve tuple
rendering and allow complete native retriever configuration without an
IMAP account block.
2026-09-21 12:08:57 -05:00
Austin Horstman
fae3c75896 joplin-desktop: skip empty configuration writes
Leave application-owned settings untouched when no effective settings
are configured. Keep activation merging for canonical and legacy values.
2026-09-21 09:53:13 -05:00
Austin Horstman
a3a247c583 joplin-desktop: use freeform JSON settings
Generate managed JSON from canonical settings while preserving legacy editor and sync conversions. Use the shared overlay helper for extraConfig priorities and effective-key detection.

Keep activation-time merging into the writable application file, including unmanaged settings and historical null and empty-string filtering.
2026-09-21 09:53:13 -05:00
Santhosh Raju
a26f7158fb yopass: add module
Adds programs.yopass for managing the yopass CLI configuration file
(~/.config/yopass/defaults.yml), with an NMT test verifying the
generated settings.

Assisted-by: Claude Fable 5
2026-09-21 10:07:57 +02:00
glmlm
5fa28c5bf4 wayland.windowManager.niri: remove extraConfigEarly and support mkOrder for extraConfig 2026-09-18 16:04:19 -05:00
Rachit Kumar Verma
4ac5a2ae90 module/impala: TUI for managing wifi on Linux
impala v0.9.0 introduces a configuration file to configure impala.
2026-09-17 20:31:15 -05:00
y3
067bb9844c wbg: add module 2026-09-17 20:28:42 -05:00