Compare commits

...

135 Commits

Author SHA1 Message Date
teto
9d32c214db neovim: let user insert snippets in init.lua
It is a common complaint for users that they can't insert their own code
where they want in the init.lua.
2025-12-29 01:51:32 +01:00
leiserfg
87785ddbc7 vicinae: Add tests for old vicinae version 2025-12-28 17:17:29 -06:00
leiserfg
113b155fe8 vicinae: Update to post 0.17 settings 2025-12-28 17:17:29 -06:00
teto
398bc87bc8 neovim: refactor to get rid of makeNeovimConfig 2025-12-28 20:13:09 +01:00
home-manager-ci[bot]
3613abcbd7 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/a6531044f6d0bef691ea18d4d4ce44d0daa6e816?narHash=sha256-3xY8CZ4rSnQ0NqGhMKAy5vgC%2B2IVK0NoVEzDoOh4DA4%3D' (2025-12-21)
  → 'github:NixOS/nixpkgs/3e2499d5539c16d0d173ba53552a4ff8547f4539?narHash=sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU%3D' (2025-12-25)
2025-12-28 10:30:53 -06:00
Austin Horstman
d7e794fe12 tests/anyrun: add empty css test
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-28 10:29:55 -06:00
Austin Horstman
8969535f1c anyrun: default extraCss to null
Prevent creating a file when not configured.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-28 10:29:55 -06:00
teto
80cca72314 meli: support account specific settings
also assert when overriding accounts. I had overriden settings when
testing this module, forgot about it and then wondered why my email
accounts were ignored.
2025-12-28 16:49:26 +01:00
Austin Horstman
d2e0458d65 zsh: don't suggest stateVersion update
Generally best to avoid telling normal users to adjust their
stateVersion to avoid other home-manager module logic changes based on
stateVersion.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-27 18:30:08 -06:00
Austin Horstman
b3ae822959 tests/zsh: add xdg dotDir tests
Verify we respect xdg.enable behavior when placing files.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-27 17:58:46 -06:00
Austin Horstman
d761c0ce89 news: add zsh dotDir default change
Default has changed to respect `xdg.enable`. Let user's know in case it
affects them surprisingly.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-27 17:58:46 -06:00
Austin Horstman
f84f474c1b zsh: respect xdg.enable for dotDir
Make sure we actually respect a user's `xdg.enable` preference.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-27 17:58:46 -06:00
Austin Horstman
ea6dfabe3c tests/zsh: add more test cases for dotdir
Adds tests for various dotDir configurations including trailing slashes
and spaces.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-27 17:58:46 -06:00
Austin Horstman
5432dc5bc4 zsh: fix dotDir path normalization and quoting
Fixes issue where dotDir with trailing slash caused failures.
Refactors lib.nix to use raw paths internally, fixing issues with spaces
in paths.
Updates history.path logic to correctly handle raw absolute paths.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-27 17:58:46 -06:00
Bruno BELANYI
bec08ef6e3 programs/ssh: DRY address/port options
The end goal is to hoist the forwarded path assertion directly into this
module rather than the top-level.
2025-12-27 15:12:05 -06:00
Sandro Marques
4067ca1ffb easyeffects: Fix race condition on Wayland session startup
Add systemd service ordering dependencies to prevent EasyEffects from
starting before the Wayland compositor is ready.

**Problem:** EasyEffects would crash during login with "Failed to create
wl_display (No such file or directory)" if started before the Wayland
display server was fully initialized.

**Solution:** Declaring the "After" property ensures EasyEffects waits
for the graphical session to be fully ready. The "PartOf" properly stops
EasyEffects when logging out. Got the tip from
https://github.com/wwmm/easyeffects/issues/1310.

Tested on NixOS 25.11 (Xantusia, 20251223.76701a1) and Home Manager 25.11
(0999ed8) with GNOME 49 on Wayland.
2025-12-27 12:56:02 -06:00
Oliver Geneser
2d36a6de2f ssh: add kexAlgorithms to matchBlocks
This commit adds the option to add kexAlgorithms as an matchBlock
option with updated test case.
2025-12-27 16:54:14 +01:00
Heitor Augusto
91cdb0e2d5 nixGL: patch systemd and d-bus services references 2025-12-25 11:16:13 -06:00
home-manager-ci[bot]
7eca7f7081 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/c6245e83d836d0433170a16eb185cefe0572f8b8?narHash=sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc%3D' (2025-12-18)
  → 'github:NixOS/nixpkgs/a6531044f6d0bef691ea18d4d4ce44d0daa6e816?narHash=sha256-3xY8CZ4rSnQ0NqGhMKAy5vgC%2B2IVK0NoVEzDoOh4DA4%3D' (2025-12-21)
2025-12-23 23:24:11 -06:00
Austin Horstman
20728df08f release/25.11: add darwin copy apps change
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-23 16:36:16 -06:00
Austin Horstman
af3c24de76 release/25.05: add git signing format change
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-23 16:36:16 -06:00
Austin Horstman
624c7e80fb release/23.05: add swaylock stateVersion change
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-23 16:36:16 -06:00
home-manager-ci[bot]
9c790e687e 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-23 13:45:25 -06:00
Austin Horstman
527ad07e66 tests/radicle: stub radicle-node
Failing build is blocking CI, test only verifies generated config.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-22 01:11:39 -06:00
home-manager-ci[bot]
57a02fd7d9 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/1306659b587dc277866c7b69eb97e5f07864d8c4?narHash=sha256-KJ2wa/BLSrTqDjbfyNx70ov/HdgNBCBBSQP3BIzKnv4%3D' (2025-12-15)
  → 'github:NixOS/nixpkgs/c6245e83d836d0433170a16eb185cefe0572f8b8?narHash=sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc%3D' (2025-12-18)
2025-12-22 01:11:39 -06:00
aleksana
3fe66908e0 television: fix keybindings 2025-12-21 23:41:33 -06:00
Austin Horstman
61fcc9de76 tests/neovim: add test to catch config eval
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 19:55:46 -06:00
Austin Horstman
7b73a6e98f neovim: fix eval
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 19:51:30 -06:00
Austin Horstman
4dc3c91c50 neovim: remove deprecated type coercion for extraXPackages
3 years old, no need to keep around.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:31 -06:00
Austin Horstman
a7d6bba358 neovim: remove old removal options
3-4 years old, no need to keep around.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:31 -06:00
Austin Horstman
bdb807dc28 neovim: modernize
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:31 -06:00
Austin Horstman
0a583021ea tests/neovim: add wrapper args test
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:31 -06:00
Austin Horstman
ab01ea24b2 neovim: add missing wrapper args
Add support for extraName, autowrapRuntimeDeps, waylandSupport, and
withPerl options in the neovim module. These options are passed to the
neovim wrapper to allow for more granular configuration.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:31 -06:00
Austin Horstman
c764a377a0 gemini-cli: fix settings example
Supposed to represent the settigns to pass in, not the generated json.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:06 -06:00
Austin Horstman
28b3622b80 tests/gemini-cli: verify defaultModel behavior
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:06 -06:00
Austin Horstman
c848303f1e gemini-cli: don't force GEMINI_MODEL
Default to null so user's can opt in to using this variable that will
override configurations.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-20 17:11:06 -06:00
Austin Horstman
bb35f07cc9 tests/claude-code: add rules tests
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-19 13:19:35 -06:00
Austin Horstman
9bf54edf10 claude-code: add rules support
Support the `rules` directory for modular memory files.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-19 13:19:35 -06:00
Benedikt Rips
89c9508bbe ssh-agent: set $SSH_AUTH_SOCK in non-interactive shells
Since PR #8099, the module sets `$SSH_AUTH_SOCK` through shells' options
for interactive shell initialization instead of
`home.sessionVariablesExtra`. The replacement was not faithful, however,
since `home.sessionVariablesExtra` is sourced also in non-interactive
shells. With this commit, the shells' profile options (where
`home.sessionVariablesExtra` is sourced) are used to set
`$SSH_AUTH_SOCK`.

Fixes #8129.
2025-12-17 08:15:55 -06:00
home-manager-ci[bot]
22202ff0d8 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/2fbfb1d73d239d2402a8fe03963e37aab15abe8b?narHash=sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0%3D' (2025-12-11)
  → 'github:NixOS/nixpkgs/1306659b587dc277866c7b69eb97e5f07864d8c4?narHash=sha256-KJ2wa/BLSrTqDjbfyNx70ov/HdgNBCBBSQP3BIzKnv4%3D' (2025-12-15)
2025-12-17 07:57:35 -06:00
Anton Mosich
09de9577d4 pimsync: add Install.WantedBy for default.target (#8344) 2025-12-15 22:40:45 -06:00
dependabot[bot]
f575cb24f6 ci: bump korthout/backport-action from 3 to 4
Bumps [korthout/backport-action](https://github.com/korthout/backport-action) from 3 to 4.
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](https://github.com/korthout/backport-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 22:38:37 -06:00
DaRacci
3a92ffa192 home-manager: expose all attributes returned by evalModules
This change brings the homeConfigurations output inline with how the
nixosConfiguration output presents its attributes.

The primary purpose is for exposing the graph attribute however there is
no downside to exposing the rest along with it to prevent needing to add
each desired attribute individually in the future if more are added.
2025-12-15 22:36:33 -06:00
home-manager-ci[bot]
6cdf765eed flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/addf7cf5f383a3101ecfba091b98d0a1263dc9b8?narHash=sha256-hM20uyap1a0M9d344I692r%2Bik4gTMyj60cQWO%2BhAYP8%3D' (2025-12-08)
  → 'github:NixOS/nixpkgs/2fbfb1d73d239d2402a8fe03963e37aab15abe8b?narHash=sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0%3D' (2025-12-11)
2025-12-15 22:13:51 -06:00
home-manager-ci[bot]
8315c1544f 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-15 19:32:11 +01:00
will
58bf3ecb2d modules/services/colima: init 2025-12-13 21:17:23 -06:00
Benedikt Rips
d787ec69c3 less: list options in correct order 2025-12-13 00:08:50 -06:00
Benedikt Rips
07d79726f1 less: enable options to be specified multiple times 2025-12-13 00:08:50 -06:00
Olmo Kramer
4767a9c719 herbstluftwm: Make herbstclient alias optional
The `herbstclient` alias in the generated `autostart` made it impossible
to use bash functions.

This makes the `herbstclient` alias optional by adding an extra
`herbstclientAlias` option on the herbstluftwm configuration. The new
option defaults to `false` as to not confuse newcomers to the
herbstluftwm module, which is not a breaking change because it was only
an optimization.
2025-12-12 23:53:36 -06:00
Austin Horstman
39cb677ed9 news: add defaultEditor entry
Let users know about new variable being set.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-11 13:12:54 -06:00
Jacob Abel
0cf525a5be option defaultEditor: Set {env}VISUAL on true (#8322)
The defaultEditor option sets {env}`EDITOR` however strictly speaking
{env}`EDITOR` is intended for editors that are fully compatible with
teletype terminals (ex: `ed` or `vi`'s `ex` mode).

The {env}`VISUAL variable is intended for modern "visual mode"
terminal editors (ex: `vi` or `emacs`).

Technically speaking editors that are assigned to {env}`EDITOR` should
be configured to operate in teletype compatible mode (see `vi -e` and
`vim -e`).

We don't do this currently because for most users this would be
unintuitive behavior when a script or program mistakenly checks
{env}`EDITOR` instead of first checking {env}`VISUAL`.

In the future it may be worthwhile to introduce an additional option to
these modules to configure {env}`EDITOR` in a strictly conforming manner
(i.e. using the teletype/`ex` mode flags or unsetting {env}`EDITOR`
entirely).

Related Issue: #8314

Signed-off-by: Jacob Abel <jacobabel@nullpo.dev>
2025-12-11 13:04:13 -06:00
Mirko Lenz
9b5ac85d79 npm: add module 2025-12-11 12:58:36 -06:00
Austin Horstman
574f6d3526 hyprpanel: perchun -> PerchunPak
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-11 12:51:49 -06:00
Austin Horstman
e52be4fb78 tldr-update: perchun -> PerchunPak
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-11 12:51:49 -06:00
home-manager-ci[bot]
dd18018d06 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/f61125a668a320878494449750330ca58b78c557?narHash=sha256-BmPWzogsG2GsXZtlT%2BMTcAWeDK5hkbGRZTeZNW42fwA%3D' (2025-12-05)
  → 'github:NixOS/nixpkgs/addf7cf5f383a3101ecfba091b98d0a1263dc9b8?narHash=sha256-hM20uyap1a0M9d344I692r%2Bik4gTMyj60cQWO%2BhAYP8%3D' (2025-12-08)
2025-12-11 12:51:49 -06:00
Nick DeGroot
7b34e428f3 chromium: fix null package 2025-12-11 14:56:50 +01:00
Kyure_A
af7c726e8b sheldon: replace initExtra with initContent 2025-12-11 14:55:22 +01:00
fidgetingbits
13cc1efd78 snixembed: add waybar incompatbility warning
If snixembed is enabled and you try to use the waybar tray the two tools
conflict with eachother and often waybar's tray will not show any icons.
This adds a warning about it, as the problem can be difficult to
diagnose.
2025-12-09 21:27:32 -06:00
June Stepp
e5b1f87841 anki: enable tests on Darwin
Anki is no longer marked as broken in nixpkgs.
2025-12-08 12:16:00 -06:00
home-manager-ci[bot]
caa47b637d 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:** 1 maintainers
**Removed:** 0 maintainers
**Total:** 281 → 282 maintainers

** Added:** xavwe

Generated by: lib/python/generate-all-maintainers.py
2025-12-08 08:04:06 -06:00
Austin Horstman
a788734077 swayidle: fix events default
Changed from list to attrset, but default never updated.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-07 23:45:14 -06:00
Mirko Lenz
6bdf2a68e1 ty: add module 2025-12-07 23:30:36 -06:00
Viktor Titov
f9d45d664e qt: added qt{5,6}ctSettings options (#8271)
Added qtctSettings option to qt module to make it possible to configure qt(5/6)ct declaratively.
2025-12-07 23:17:30 -06:00
home-manager-ci[bot]
082822b8a6 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/2d293cbfa5a793b4c50d17c05ef9e385b90edf6c?narHash=sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4%3D' (2025-11-30)
  → 'github:NixOS/nixpkgs/f61125a668a320878494449750330ca58b78c557?narHash=sha256-BmPWzogsG2GsXZtlT%2BMTcAWeDK5hkbGRZTeZNW42fwA%3D' (2025-12-05)
2025-12-07 23:14:56 -06:00
Austin Horstman
27a6182347 tests/diff-highlight: add null assertion test
Verify eval when setting git package to null.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-05 23:18:20 -06:00
Austin Horstman
012cfcc44a diff-highlight: add git package assertion
Git package can be made nullable now, but module is written with
expectation of its availability.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-05 23:18:20 -06:00
Hanwen Guo
36817384a6 programs/git: package nullable
Some platforms (e.g. macOS) provide their customized version of git with
exclusive features, and user might want to use that instead.
2025-12-05 23:03:42 -06:00
Aguirre Matteo
571c5eed1d news: add hyprlauncher entry 2025-12-05 22:35:12 -06:00
Aguirre Matteo
2e02e22e28 hyprlauncher: add module 2025-12-05 22:35:12 -06:00
Aguirre Matteo
ccd22c13b2 restic: change cache directory to $XDG_CACHE_HOME/restic 2025-12-05 20:04:55 -06:00
Austin Horstman
519828bf1c claude-code: refactor wrapper to use append-flags
Alternative approach suggested in
https://github.com/nix-community/home-manager/pull/8290#discussion_r2593114782

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-05 10:42:15 -06:00
David
1a99a515a1 nixos/common: guard nix.package access when nix.enable is false
When nix-darwin has `nix.enable = false` (e.g., for Determinate Nix
users), accessing `config.nix.package` throws an error:

    error: nix.package: accessed when `nix.enable` is off

This regression was introduced in commit a521eab when adding the
`home.uid` option. The code restructuring changed `inherit (config.nix)
package` to be evaluated unconditionally, whereas PR #6383 had
previously ensured this worked correctly.

The fix wraps the package assignment in `mkIf config.nix.enable` to
only access `config.nix.package` when nix management is enabled in the
host OS configuration.

Fixes: #8303
2025-12-05 10:37:47 -06:00
Austin Horstman
6bcb2395ab home-environment: style cleanup
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-04 23:34:56 -06:00
Austin Horstman
f16bfa59e3 home-environment: fix undefined access eval
`uid` isn't guaranteed to be defined, have fallback logic in place to
account for that. Even if we require it eventually, we can't show a
proper assertion/warning without being able to eval.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-04 23:34:56 -06:00
Aguirre Matteo
35545f71dd news: add screen entry 2025-12-04 22:41:15 -06:00
Aguirre Matteo
6bbc48804b screen: add module 2025-12-04 22:41:15 -06:00
Jess
a8b6296a1e tests/restic: fix timedatectl failure
Systemd
[added a check](6a12c90ca3)
which broke this test. So use `date` instead of `timedatectl`.
2025-12-04 22:39:18 -06:00
Aguirre Matteo
68f7b34179 news: add calibre entry 2025-12-04 22:38:55 -06:00
Aguirre Matteo
24cc5c080c calibre: add module 2025-12-04 22:38:55 -06:00
Aguirre Matteo
df7bac2b2b rclone: change cache directory to $XDG_CACHE_HOME/rclone 2025-12-05 00:33:32 +01:00
Austin Horstman
05a56dbf24 claude-code: fix wrapper to inject --mcp-config after subcommands
Manually wrap program to maintain options called from cli.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-04 12:19:32 -06:00
Urocissa Caerulea.Tw
9379fbf4f5 Translate using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (39 of 39 strings)

Translate using Weblate (Chinese (Traditional Han script))

Currently translated at 100.0% (17 of 17 strings)

Co-authored-by: Urocissa Caerulea.Tw <urocissa.tw@proton.me>
Translate-URL: https://hosted.weblate.org/projects/home-manager/cli/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/home-manager/modules/zh_Hant/
Translation: Home Manager/Home Manager CLI
Translation: Home Manager/Home Manager Modules
2025-12-04 10:33:19 -06:00
Bernardo Meurer
a521eab881 home-environment: add home.uid option
Add a home.uid option similar to home.username. When set, the
activation script verifies the current UID matches the expected
value using the new checkUid function.

When using the NixOS or nix-darwin modules, home.uid is
auto-discovered from users.users.<name>.uid when that value
is set.

This is useful for constructing paths that depend on the user's
UID, such as /run/user/<uid> paths for gpg-agent sockets or
other user-specific runtime directories.
2025-12-04 17:22:25 +01:00
tsrk.
d441981b20 thunderbird: fix aliases SMTP configuration not being listed as usable
Signed-off-by: tsrk. <tsrk@tsrk.me>
2025-12-04 10:16:29 +01:00
Xaver Wenhart
fca4cba863 parallel: package nullable 2025-12-03 12:58:50 -06:00
trash-panda-v91-beta
af324afa72 cargo: fix typo in tests
testing docker-cli instead of cargo in empty-config.nix
2025-12-03 10:43:50 -06:00
Bruno BELANYI
12e7786854 programs/ssh: use 'toList' 2025-12-03 09:48:51 -06:00
Bruno BELANYI
28741978a3 programs/ssh: use 'toKeyValue' for 'extraOptions'
A first step towards refactoring the module.

Unfortunately the config is not consistent in using comma-separated
values or repeated keys for lists, since the user can always add commas
by themselves, we should default to repeated keys in the generator.
2025-12-03 09:44:29 -06:00
Andrew Jeffery
43173abcb4 pimsync: Make storage names unique
This includes the calendar/contacts prefix in the storage name as well
as the pair name to ensure that if the same name is used for contacts
and calendar then it is correctly referenced.
2025-12-03 13:46:21 +01:00
home-manager-ci[bot]
bcc7afa1d8 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/2fad6eac6077f03fe109c4d4eb171cf96791faa4?narHash=sha256-sKoIWfnijJ0%2B9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI%3D' (2025-11-27)
  → 'github:NixOS/nixpkgs/2d293cbfa5a793b4c50d17c05ef9e385b90edf6c?narHash=sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4%3D' (2025-11-30)
2025-12-02 22:41:07 -06:00
Patrick Steinhardt
281e9398cc swayidle: improve confusing "events" configuration
With swayidle one can configure two different kinds of hooks:

  - Idle timeouts are executed after the session has been idle for a
    specific amount of time.

  - Events are executed when systemd notifies us that for example the
    user session is locked or that the device is about to suspend.

While not obvious, there is a significant difference between how these
two kinds are configured: there can be several timeouts with separate
commands to be executed, but each event can only be specified once. If
an event is specified multiple times, then the last command wins.

This can be very easy to miss in swayidle's documentation. Furthermore,
because the config is a list of `{ event = "..."; command = "..."; }`
attrset, we double down on this confusion and make it seem like having
multiple handlers for an event was actually supported.

Fix this by converting from a list of "event" submodules to an attrset
where the key is the event name and the value is the command to be
executed. This makes it impossible to specify multiple commands for a
single event by accident.

If a user _does_ want to have multiple commands executed on any event
they can for example use `pkgs.writeShellScript` and manually chain the
commands in that script.
2025-12-02 22:24:56 -06:00
Aguirre Matteo
93d907a205 news: ludusavi's default backup path changed entry 2025-12-02 21:57:23 -06:00
Aguirre Matteo
eca5f967cd ludusavi: use config.xdg.stateHome instead of $XDG_STATE_HOME 2025-12-02 21:57:23 -06:00
Aguirre Matteo
db44f38047 ludusavi: add test 2025-12-02 21:57:23 -06:00
Mirko Lenz
06f81463bb infat: add module 2025-12-02 21:39:05 -06:00
Matt Sturgeon
ab8e4b2b5a home-environment: extend release check to include pkgs
`lib` comes from the Nixpkgs used to instantiate Home Manager itself and
cannot change within the module fixpoint. However, `pkgs` is configurable
(via `nixpkgs.*` or `_module.args`) and may come from a different Nixpkgs
instance from the one providing `lib`.

Mismatches between Home Manager's release and the release of the `pkgs`
instance are more common and also more likely to cause subtle issues.

This change extends the release check to include `pkgs.lib.trivial.release`
so that such mismatches can be detected and reported.
2025-12-02 21:35:34 -06:00
Anton Mosich
c3d1e5c65a pimsync: extend test to contacts
If I had added such a test right away, I would have encountered #8258
myself. I mistakenly believed the contact and calendar modules to be the
same.
2025-12-03 04:10:48 +01:00
Anton Mosich
bf003999ed accounts.contacts: fix eval error
You would encounter an eval error when a module (such as pimsync) would
try to access an attribute of `accounts.contacts.<name>.local`, since it
would default to `null`. The same problem was encountered in the
`accounts.calendar` module, and fixed in
2c157e22dc which has the same solution.

Closes #8258

Reported-by: redbeardymcgee
2025-12-03 04:10:48 +01:00
Xaver Wenhart
ff067cfc61 parallel: init module (#8240) 2025-12-02 01:44:57 +01:00
Austin Horstman
effe4c007d ci: remove unused dependabot ignore
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-12-01 09:37:35 -06:00
home-manager-ci[bot]
6cedf24ada 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:** 1 maintainers
**Removed:** 0 maintainers
**Total:** 280 → 281 maintainers

** Added:** arunoruto

Generated by: lib/python/generate-all-maintainers.py
2025-12-01 09:34:48 -06:00
novenary
e4e25a8c31 fish: ensure generated completions considered last
home-manager's generated completions shadow built-in completion scripts.
fish actually has logic to deal with this when the path ends with
/generated_completions, so let's take advantage of it.

Link: 47c773300a/src/autoload.rs (L421-L424)
2025-11-30 17:12:04 -06:00
novenary
13b089b586 Revert "fish: avoid shadowing builtin completions"
This reverts commit 23f2ba7ae0.
2025-11-30 17:12:04 -06:00
Victor Engmark
784a83782c nixos: Don't "[a]ttempt to evaluate package pkgs.trash-cli"
Closes #8161.
2025-11-30 14:28:55 -06:00
Brian E
704b6ffa8a Translate using Weblate (Faroese)
Currently translated at 7.6% (3 of 39 strings)

Translate using Weblate (Faroese)

Currently translated at 17.6% (3 of 17 strings)

Co-authored-by: Brian E <brianellingsgaard9@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/home-manager/cli/fo/
Translate-URL: https://hosted.weblate.org/projects/home-manager/modules/fo/
Translation: Home Manager/Home Manager CLI
Translation: Home Manager/Home Manager Modules
2025-11-30 14:18:18 -06:00
Carl
83053e1d33 GPU freedom (#8239)
* gpu: only add intel driver for x86_64-linux

* gpu: allow configuring drivers option

Allow overriding the drivers option if you're an advanced user
2025-11-30 14:48:38 +01:00
Aguirre Matteo
ae400a1dcc shikane: add package to PATH (#8233) 2025-11-30 14:48:16 +01:00
DDoSolitary
edbb012a21 dconf: support configuring specific user databases (#6301)
By default, dconf uses $XDG_CONFIG_HOME/dconf/user as the user database, but this can be changed by specifying user-db:<name> in a profile file and setting the DCONF_PROFILE environment variable to that profile. One may want to use different user databases for different DE/WMs to avoid collision.

Currently the module invokes dconf without touching DCONF_PROFILE, which means that 1) it is unable to configure multiple different user databases, and 2) the behavior of activation script will be affected by the DCONF_PROFILE environment variable when it is invoked, possibly leading to undesired results.

This PR adds a dconf.databases option, so that settings under dconf.databases.<name> will be written to $XDG_CONFIG_HOME/dconf/<name>. The old dconf.settings option is left as-is to avoid breaking compatibility.
2025-11-30 14:37:17 +01:00
Jo²
b1bb534c17 xsession: only require xdg autostart target if explicitely enabled (#8237)
This is a fix for PR #7108 that forcibly enables xdg-desktop-autostart
units, whether or not `config.xdg.autostart` is enabled.
Partially fixes #7708, there is still a risk for conflict if
`xdg.autostart` and `services.picom` are enabled.
2025-11-30 14:35:54 +01:00
Austin Horstman
780be8ef50 tests: disable release check bypass
nixos-unstable bumped

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-28 14:27:50 -06:00
home-manager-ci[bot]
40c18076d8 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/5ae3b07d8d6527c42f17c876e404993199144b6a?narHash=sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0%3D' (2025-11-24)
  → 'github:NixOS/nixpkgs/2fad6eac6077f03fe109c4d4eb171cf96791faa4?narHash=sha256-sKoIWfnijJ0%2B9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI%3D' (2025-11-27)
2025-11-28 14:27:50 -06:00
Austin Horstman
d13041d6f0 tests/gtk4: add test for stateversion change
Ensure default behavior with new state version works properly.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-28 14:14:32 -06:00
Fugi
ae9f38e889 gtk4: don't enable theme by default
This is not officially supported and causes issues in some cases.
Also adds a warning to the option.
2025-11-28 14:14:32 -06:00
Friedrich Altheide
86ff0ef506 cargo: add module 2025-11-27 22:29:55 -06:00
damidoug
c220f242cd aerospace: add more tests and fix expected values 2025-11-27 22:27:29 -06:00
damidoug
1ed596c638 aerospace: remove extraConfig, use settings instead 2025-11-27 22:27:29 -06:00
damidoug
9f31ea236b aerospace: add more settings examples 2025-11-27 22:27:29 -06:00
damidoug
b414c94d4e aerospace: fallback default settings 2025-11-27 22:27:29 -06:00
damidoug
5b8d259ee6 aerospace: auto-reload config on file changes; 2025-11-27 22:27:29 -06:00
damidoug
29b672194d aerospace: add assertion to ensure launchd.enable and after-startup-command are used instead of start-at-login and after-login-command 2025-11-27 22:27:29 -06:00
damidoug
f302550865 aerospace: rename userSettings → settings 2025-11-27 22:27:29 -06:00
Matt Sturgeon
23f2ba7ae0 fish: avoid shadowing builtin completions
The fish shell comes with builtin completions. For example, git
completion supports context-aware completion of things like commit
hashes, branch names, sub-commands, etc.

Until fish 4.2, builtin completions were explicitly loaded from
`share/fish/completions`, however that is now deprecated and disabled.
In effect, this means generating manpage-based completion will shadow
and disable builtin completion.

Avoid that, by only generating completion when fish does not have
builtin support for the command.
2025-11-27 22:17:20 -06:00
Mirza Arnaut
470d24d809 vivid: change colorMode type to enum 2025-11-27 22:07:41 -06:00
Mirza Arnaut
740134d4af vivid: replace theme content from yaml with json
This should fix missinterpretation of hex colors (which should be a
string) as numbers in scientific notation. For example: 1e2030.
2025-11-27 22:07:41 -06:00
Mirza Arnaut
c23379a330 vivid: add arunoruto to maintainers list 2025-11-27 22:07:41 -06:00
Austin Horstman
9651819d75 ci: update checkout and update-flake-lock
https://github.com/DeterminateSystems/update-flake-lock/releases/tag/v28
updated with checkout v6 support.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 16:02:49 -06:00
Austin Horstman
8220473f95 ci: revert actions/checkout to v5 due to update-flake-lock incompatibility
Root cause: DeterminateSystems/update-flake-lock@v27 uses
peter-evans/create-pull-request@v6.0.5 internally, which is incompatible
with actions/checkout@v6's new credential storage mechanism.

The Problem Chain:
- actions/checkout@v6 moved credentials from .git/config to $RUNNER_TEMP
  (security improvement)
- peter-evans/create-pull-request@v6.0.5 cannot access credentials from
  the new $RUNNER_TEMP location
- This causes exit code 128 when update-flake-lock tries to create PRs

The Fix:
- create-pull-request@v7.0.9 fixed v6 compatibility
- However, update-flake-lock@v27 (released July 2025) hasn't upgraded yet
- Reverting to v5 restores working credential access

Next Steps:
- Can upgrade to v6 once update-flake-lock uses create-pull-request@v7.0.9+
  - https://github.com/DeterminateSystems/update-flake-lock/pull/224
- Dependabot configured to ignore v6 upgrades until compatibility is fixed

Fixes: https://github.com/nix-community/home-manager/actions/runs/19712979574
See: https://github.com/peter-evans/create-pull-request/issues/690

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 12:47:12 -06:00
Austin Horstman
946907fa6a maintaining.md: add note about dependabot release branch update
When creating a new release branch, dependabot.yml needs to be updated
to include the new branch for automated dependency updates.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 12:38:45 -06:00
Austin Horstman
201c883d0d ci: dependabot update release branch
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 12:38:45 -06:00
Austin Horstman
cc0425becf ci: disable fail fast on flake update
We don't need to block a channels flake update because of a bug in
another.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:59:27 -06:00
Austin Horstman
ee7f4646da maintaining.md: add note about flake.nix / lock update
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:20:41 -06:00
Austin Horstman
ad0b497533 tests: disable release check temporarily
Remove after nixos-unstable bumped

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:16:38 -06:00
Austin Horstman
089d5bf615 ci: update release in matrix
New stable branch

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:16:38 -06:00
Austin Horstman
4d5fbb182e flake.lock: update
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:16:38 -06:00
Austin Horstman
8433591183 home-manager: prepare 26.05
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:16:38 -06:00
232 changed files with 3973 additions and 930 deletions

View File

@@ -7,10 +7,9 @@ updates:
interval: "weekly"
commit-message:
prefix: "ci:"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "release-25.05"
target-branch: "release-25.11"
schedule:
interval: "weekly"
commit-message:

View File

@@ -37,7 +37,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
id: backport
uses: korthout/backport-action@v3
uses: korthout/backport-action@v4
with:
# See https://github.com/korthout/backport-action#inputs
github_token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}

View File

@@ -9,8 +9,9 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name != 'schedule' || github.repository_owner == 'nix-community'
strategy:
fail-fast: false
matrix:
branch: [master, release-25.05]
branch: [master, release-25.11]
steps:
- name: Create GitHub App token
uses: actions/create-github-app-token@v2
@@ -41,7 +42,7 @@ jobs:
- name: Install Nix
uses: cachix/install-nix-action@v31
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@v27
uses: DeterminateSystems/update-flake-lock@v28
with:
token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
git-committer-name: ${{ steps.user-info.outputs.name || 'github-actions[bot]' }}

View File

@@ -121,6 +121,22 @@ Reference commits:
- Change `isReleaseBranch` from `false` to `true`
- Do NOT change the `release` field (it's already correct from Step 1)
2. **flake.nix**
- Update the nixpkgs input to track the corresponding stable branch
- Example: For `release-25.11`, change from:
```nix
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
```
to:
```nix
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
```
- Run `nix flake update` to update flake.lock to the stable branch
- Commit the flake.nix and flake.lock changes
**Note**: The release branch should track the stable NixOS release channel
(e.g., `nixos-25.11`), while master continues to track `nixos-unstable`.
#### Step 3.5: On master - Update CI for the New Release Branch
**When**: After marking the release branch as a release branch (Step 3)
@@ -150,6 +166,37 @@ Reference commits:
- This ensures automated flake.lock updates run on the current stable branch
- Note: We only maintain CI for the latest stable release, not older releases
2. **.github/dependabot.yml** (on master)
- Replace the old stable branch with the new release branch
- Example: When creating `release-25.11`, update the target-branch from:
```yaml
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "release-25.05"
schedule:
interval: "weekly"
commit-message:
prefix: "ci:"
```
to:
```yaml
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "release-25.11"
schedule:
interval: "weekly"
commit-message:
prefix: "ci:"
```
- This ensures automated dependency updates for GitHub Actions on the current
stable branch
- Note: We only maintain dependabot for the latest stable release, not older
releases
**Important**: CI workflows are executed from master, so this change must be
committed to the master branch.

View File

@@ -361,6 +361,11 @@
email = "nixpkgs@perchun.it";
github = "PerchunPak";
githubId = 68118654;
keys = [
{
fingerprint = "BBB5 1142 959D 8549 A3D2 F6C5 313F 67D1 EAB7 70F9";
}
];
name = "Perchun Pak";
source = "nixpkgs";
};
@@ -629,6 +634,13 @@
name = "Arjan Schrijver";
source = "nixpkgs";
};
arunoruto = {
email = "mirza.arnaut45@gmail.com";
github = "arunoruto";
githubId = 21687187;
name = "Mirza Arnaut";
source = "nixpkgs";
};
asymmetric = {
email = "lorenzo@mailbox.org";
github = "asymmetric";
@@ -2066,7 +2078,7 @@
source = "nixpkgs";
};
shikanime = {
email = "deva.shikanime@protonmail.com";
email = "william.phetsinorath@shikanime.studio";
github = "shikanime";
githubId = 22115108;
name = "William Phetsinorath";
@@ -2304,6 +2316,13 @@
name = "Florian Peter";
source = "nixpkgs";
};
xavwe = {
email = "git@xavwe.dev";
github = "xavwe";
githubId = 125409009;
name = "Xaver Wenhart";
source = "nixpkgs";
};
xlambein = {
email = "xlambein@gmail.com";
github = "xlambein";

6
docs/flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1743938762,
"narHash": "sha256-UgFYn8sGv9B8PoFpUfCa43CjMZBl1x/ShQhRDHBFQdI=",
"lastModified": 1764081664,
"narHash": "sha256-sUoHmPr/EwXzRMpv1u/kH+dXuvJEyyF2Q7muE+t0EU4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "74a40410369a1c35ee09b8a1abee6f4acbedc059",
"rev": "dc205f7b4fdb04c8b7877b43edb7b73be7730081",
"type": "github"
},
"original": {

View File

@@ -1,6 +1,6 @@
# Home Manager Manual {#home-manager-manual}
## Version 25.11
## Version 26.05 (unstable)
```{=include=} preface

View File

@@ -4,6 +4,7 @@ This section lists the release notes for stable versions of Home Manager
and the current unstable version.
```{=include=} chapters
rl-2605.md
rl-2511.md
rl-2505.md
rl-2411.md

View File

@@ -57,3 +57,9 @@ 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,4 +27,8 @@ 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.
- No changes.
- 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.

View File

@@ -80,3 +80,10 @@ 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

@@ -0,0 +1,21 @@
# Release 26.05 {#sec-release-26.05}
This is the current unstable branch and the information in this
section is therefore not final.
## Highlights {#sec-release-26.05-highlights}
This release has the following notable changes:
## 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 `gtk.gtk4.theme` option does not mirror `gtk.theme` by default
anymore.
- The `programs.zsh.dotDir` option now defaults to the XDG configuration
directory (usually `~/.config/zsh`) when `xdg.enable` is true.

6
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1763678758,
"narHash": "sha256-+hBiJ+kG5IoffUOdlANKFflTT5nO3FrrR2CA3178Y5s=",
"lastModified": 1766651565,
"narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "117cc7f94e8072499b0a7aa4c52084fa4e11cc9b",
"rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539",
"type": "github"
},
"original": {

View File

@@ -1277,7 +1277,7 @@ while [[ $# -gt 0 ]]; do
export VERBOSE=1
;;
--version)
echo 25.11-pre
echo 26.05-pre
exit 0
;;
*)

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-08-23 20:02+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,12 +17,12 @@ 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.13\n"
"X-Generator: Weblate 5.15-dev\n"
#. translators: For example: "home-manager: missing argument for --cores"
#: home-manager/home-manager:16
msgid "%s: missing argument for %s"
msgstr ""
msgstr "%s: manglar eitt ávirki fyri %s"
#. translators: For example: "home-manager: --rollback can only be used after switch"
#: home-manager/home-manager:22
@@ -31,7 +31,7 @@ msgstr "%s: %s kann bert brúkast aftaná %s"
#: home-manager/home-manager:71
msgid "No configuration file found at %s"
msgstr ""
msgstr "Eingin samansetingsfíla funni hjá %s"
#. translators: The first '%s' specifier will be replaced by either
#. 'home.nix' or 'flake.nix'.

View File

@@ -8,8 +8,8 @@ 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-03-07 18:58+0000\n"
"Last-Translator: 807 <s10855168@gmail.com>\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"
"Language: zh_Hant\n"
@@ -17,21 +17,21 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.3-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#. translators: For example: "home-manager: missing argument for --cores"
#: home-manager/home-manager:16
msgid "%s: missing argument for %s"
msgstr "%s: 缺少參數 %s"
msgstr "%s:缺少 %s 的引數"
#. translators: For example: "home-manager: --rollback can only be used after switch"
#: home-manager/home-manager:22
msgid "%s: %s can only be used after %s"
msgstr ""
msgstr "%s%s 只能在 %s 之後使用"
#: home-manager/home-manager:71
msgid "No configuration file found at %s"
msgstr "在 %s 處找到配置檔案"
msgstr "在 %s 找不到設定檔"
#. translators: The first '%s' specifier will be replaced by either
#. 'home.nix' or 'flake.nix'.
@@ -41,12 +41,12 @@ msgid ""
"Keeping your Home Manager %s in %s is deprecated,\n"
"please move it to %s"
msgstr ""
"保持你的 Home Manager 在 %s 中,%s 已被拋棄\n"
"請將它移動到 %s"
" Home Manager 的 %s 放在 %s 中, 已經被棄用\n"
"請改放到 %s"
#: home-manager/home-manager:99
msgid "No configuration file found. Please create one at %s"
msgstr "未找到配置檔案。請在 %s 建立一份"
msgstr "找不到設定檔。請在 %s 建立新的設定檔"
#: home-manager/home-manager:114
msgid "Home Manager not found at %s."
@@ -57,7 +57,7 @@ msgstr "在 %s 中找不到 Home Manager。"
msgid ""
"The fallback Home Manager path %s has been deprecated and a file/directory "
"was found there."
msgstr "備用的 Home Manager 路徑 %s 已被拋棄,但一個檔案/資料夾在這被找到。"
msgstr "備用的 Home Manager 路徑 %s 已被棄用,且在該處找到了檔案/目錄。"
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
#: home-manager/home-manager:125
@@ -80,21 +80,21 @@ msgid ""
"\n"
" $ rm -r \"%s\""
msgstr ""
"要消除這個警告,請做以下其中一。\n"
"若要移除此警告,請執行下列其中一。\n"
"\n"
"1. 告訴Home Manager使用路徑,例如加入\n"
"1. 明確告知 Home Manager 使用路徑,例如\n"
"\n"
" { programs.home-manager.path = \"%s\"; }\n"
"\n"
" 到你的配置中。\n"
" 中,加入您的設定。\n"
"\n"
" 如果你想要直接引入Home Manager 請你使用 `path` 參數r\n"
" 如果想直接匯入 Home Manager可以在呼叫時使用 `path` 參數來指定路徑:\n"
"\n"
" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n"
"\n"
" 當呼叫 Home Manager 模組。\n"
" 這樣就能正確傳遞 Home Manager 的路徑。\n"
"\n"
"2. 刪除無效的路徑\n"
"2. 移除已棄用的路徑\n"
"\n"
" $ rm -r \"%s\""
@@ -104,33 +104,33 @@ msgstr "正在進行 Nix 完整性檢查"
#: home-manager/home-manager:173
msgid "Could not find suitable profile directory, tried %s and %s"
msgstr "找不到合適的 profile 目錄,已嘗試 %s 和 %s"
msgstr "找不到合適的設定檔目錄,已嘗試 %s 和 %s"
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
#: home-manager/home-manager:230
msgid "Can't inspect options of a flake configuration"
msgstr "無法檢查 flake 配置中的選項"
msgstr "無法檢查 flake 設定的選項"
#: home-manager/home-manager:305 home-manager/home-manager:328
#: home-manager/home-manager:734 home-manager/home-manager:1237
msgid "%s: unknown option '%s'"
msgstr "%s未知選項 %s"
msgstr "%s未知選項 '%s'"
#: home-manager/home-manager:310 home-manager/home-manager:1238
msgid "Run '%s --help' for usage help"
msgstr "執行 %s --help 獲取用法幫助"
msgstr "執行 '%s --help' 以取得使用說明"
#: home-manager/home-manager:336 home-manager/home-manager:441
msgid "The file %s already exists, leaving it unchanged..."
msgstr "檔案 %s 已存在,不更改它..."
msgstr "檔案 %s 已存在,保持不變..."
#: home-manager/home-manager:338 home-manager/home-manager:443
msgid "Creating %s..."
msgstr "創建 %s..."
msgstr "正在建立 %s..."
#: home-manager/home-manager:487
msgid "Creating initial Home Manager generation..."
msgstr "正在建立初始 Home Manager 世代 ..."
msgstr "正在建立初始 Home Manager 世代..."
#. translators: The "%s" specifier will be replaced by a file path.
#: home-manager/home-manager:492
@@ -142,12 +142,12 @@ msgid ""
"to configure Home Manager. Run 'man home-configuration.nix' to\n"
"see all available options."
msgstr ""
"全部工作完成home-manager 工具現應已安裝,您可以編輯\n"
"全部完成home-manager 工具現在應該已被安裝,您可以編輯\n"
"\n"
" %s\n"
"\n"
"來配置 Home Manager。執行 man home-configuration.nix\n"
"來檢視所有可用選項。"
"來設定 Home Manager。執行 'man home-configuration.nix' 時\n"
"可查看所有可用選項。"
#. translators: The "%s" specifier will be replaced by a URL.
#: home-manager/home-manager:497
@@ -158,16 +158,16 @@ msgid ""
"\n"
"if the error seems to be the fault of Home Manager."
msgstr ""
"啊哦,安裝失敗了!如果感覺是 Home Manager 造成的錯誤,請在下方\n"
"糟糕,安裝失敗了!如果感覺是 Home Manager 造成的錯誤,請在此連結\n"
"\n"
" %s\n"
"\n"
"建立 Issue 告知我們。"
"中,建立 Issue 告知我們。"
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
#: home-manager/home-manager:508
msgid "Can't instantiate a flake configuration"
msgstr "無法建立 flake 配置例項"
msgstr "無法實例化 flake 設定"
#: home-manager/home-manager:584
msgid ""
@@ -177,12 +177,12 @@ msgid_plural ""
"There are %d unread and relevant news items.\n"
"Read them by running the command \"%s news\"."
msgstr[0] ""
"有 %d 未讀相關新聞或訊息。\n"
"執行%s news” 命令進行閱讀。"
"有 %d 未讀相關的消息項目。\n"
"執行指令 \"%s news\" 來進行確認。"
#: home-manager/home-manager:598
msgid "Unknown \"news.display\" setting \"%s\"."
msgstr "未知的 news.display 設定項 “%s”。"
msgstr "未知的 \"news.display\" 設定值 \"%s\"。"
#: home-manager/home-manager:606
#, sh-format
@@ -191,11 +191,11 @@ msgstr "請設定 $EDITOR 或 $VISUAL 環境變數"
#: home-manager/home-manager:624
msgid "Cannot run build in read-only directory"
msgstr "無法在唯讀目錄中執行建"
msgstr "無法在唯讀目錄中執行建"
#: home-manager/home-manager:787
msgid "The configuration did not contain the specialisation \"%s\""
msgstr ""
msgstr "設定中不包含特化設定 \"%s\""
#: home-manager/home-manager:841
msgid "No generation with ID %s"
@@ -203,7 +203,7 @@ msgstr "沒有 ID 為 %s 的世代"
#: home-manager/home-manager:843
msgid "Cannot remove the current generation %s"
msgstr "無法移除當前世代 %s"
msgstr "無法移除目前的世代 %s"
#: home-manager/home-manager:845
msgid "Removing generation %s"

View File

@@ -102,8 +102,8 @@ let
};
local = mkOption {
type = types.nullOr (localModule name);
default = null;
type = localModule name;
default = { };
description = ''
Local configuration for the contacts.
'';

View File

@@ -57,9 +57,8 @@ let
let
module = moduleChecks rawModule;
in
{
inherit (module) options config;
module
// {
activationPackage = module.config.home.activationPackage;
# For backwards compatibility. Please use activationPackage instead.

View File

@@ -193,6 +193,13 @@ in
description = "The user's username.";
};
home.uid = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
example = 1000;
description = "The user's uid.";
};
home.homeDirectory = mkOption {
type = types.path;
defaultText = literalExpression ''
@@ -570,14 +577,25 @@ in
warnings =
let
hmRelease = config.home.version.release;
nixpkgsRelease = lib.trivial.release;
releaseMismatch = config.home.enableNixpkgsReleaseCheck && hmRelease != nixpkgsRelease;
libRelease = lib.trivial.release;
pkgsRelease = pkgs.lib.trivial.release;
releaseMismatch = hmRelease != libRelease || hmRelease != pkgsRelease;
versionsSummary =
if libRelease == pkgsRelease then
''
Home Manager version ${hmRelease} and
Nixpkgs version ${libRelease}.''
else
''
Home Manager version: ${hmRelease}
Nixpkgs version used to evaluate Home Manager: ${libRelease}
Nixpkgs version used for packages (`pkgs`): ${pkgsRelease}'';
in
lib.optional releaseMismatch ''
lib.optional (config.home.enableNixpkgsReleaseCheck && releaseMismatch) ''
You are using
Home Manager version ${hmRelease} and
Nixpkgs version ${nixpkgsRelease}.
${lib.replaceString "\n" "\n " versionsSummary}
Using mismatched versions is likely to cause errors and unexpected
behavior. It is therefore highly recommended to use a release of Home
@@ -831,6 +849,9 @@ in
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
checkUsername ${lib.escapeShellArg config.home.username}
checkHomeDirectory ${lib.escapeShellArg config.home.homeDirectory}
${lib.optionalString (config.home.uid != null) ''
checkUid ${toString config.home.uid}
''}
fi
${lib.optionalString config.home.activationGenerateGcRoot ''

View File

@@ -117,6 +117,17 @@ function checkHomeDirectory() {
fi
}
function checkUid() {
local expectedUid="$1"
local actualUid
actualUid="$(id -u)"
if [[ "$actualUid" != "$expectedUid" ]]; then
_iError 'Error: UID is "%s" but we expect "%s"' "$actualUid" "$expectedUid"
exit 1
fi
}
# Note, the VERBOSE_ECHO variable is deprecated and should not be used inside
# the Home Manager project. It is provided here for backwards compatibility.
if [[ -v VERBOSE ]]; then

View File

@@ -17,15 +17,29 @@ let
# The dconf keys managed by this configuration. We store this as part of the
# generation state to be able to reset keys that become unmanaged during
# switch.
stateDconfKeys = pkgs.writeText "dconf-keys.json" (
builtins.toJSON (
lib.concatLists (
lib.mapAttrsToList (
dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries
) cfg.settings
mkStateDconfKeys =
nameSuffix: settings:
pkgs.writeText "dconf-keys${nameSuffix}.json" (
builtins.toJSON (
lib.concatLists (
lib.mapAttrsToList (dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries) settings
)
)
)
);
);
databases =
lib.optional (cfg.settings != { }) {
dconfProfile = null;
stateDconfKeys = mkStateDconfKeys "" cfg.settings;
inherit (cfg) settings;
}
++ lib.mapAttrsToList (name: value: {
dconfProfile = pkgs.writeText "dconf-profile-${name}" ''
user-db:${name}
'';
stateDconfKeys = mkStateDconfKeys "-${name}" value;
settings = value;
}) cfg.databases;
in
{
@@ -81,73 +95,87 @@ in
to convert dconf database dumps into compatible Nix expression.
'';
};
databases = lib.mkOption {
type = with types; attrsOf (attrsOf (attrsOf lib.hm.types.gvariant));
default = { };
description = ''
Settings to write to specific dconf user databases.
See [](#opt-dconf.settings) for details.
'';
};
};
};
config = lib.mkIf (cfg.enable && cfg.settings != { }) {
config = lib.mkIf (cfg.enable && databases != [ ]) {
# Make sure the dconf directory exists.
xdg.configFile."dconf/.keep".source = builtins.toFile "keep" "";
home.extraBuilderCommands = ''
mkdir -p $out/state/
ln -s ${stateDconfKeys} $out/state/${stateDconfKeys.name}
'';
''
+ lib.concatMapStrings (db: ''
ln -s ${db.stateDconfKeys} $out/state/${db.stateDconfKeys.name}
'') databases;
home.activation.dconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] (
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
lib.concatMapStrings (
db:
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni db.settings);
statePath = "state/${stateDconfKeys.name}";
statePath = "state/${db.stateDconfKeys.name}";
cleanup = pkgs.writeShellScript "dconf-cleanup" ''
set -euo pipefail
cleanup = pkgs.writeShellScript "dconf-cleanup" ''
set -euo pipefail
${config.lib.bash.initHomeManagerLib}
${config.lib.bash.initHomeManagerLib}
PATH=${
lib.makeBinPath [
pkgs.dconf
pkgs.jq
]
}''${PATH:+:}$PATH
PATH=${
lib.makeBinPath [
pkgs.dconf
pkgs.jq
]
}''${PATH:+:}$PATH
oldState="$1"
newState="$2"
oldState="$1"
newState="$2"
# Can't do cleanup if we don't know the old state.
if [[ ! -f $oldState ]]; then
exit 0
# Can't do cleanup if we don't know the old state.
if [[ ! -f $oldState ]]; then
exit 0
fi
# Reset all keys that are present in the old generation but not the new
# one.
jq -r -n \
--slurpfile old "$oldState" \
--slurpfile new "$newState" \
'($old[] - $new[])[]' \
| while read -r key; do
verboseEcho "Resetting dconf key \"$key\""
run $DCONF_DBUS_RUN_SESSION dconf reset "$key"
done
'';
envCommand = lib.optionalString (db.dconfProfile != null) "env DCONF_PROFILE=${db.dconfProfile}";
in
''
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
export DCONF_DBUS_RUN_SESSION="${envCommand}"
else
export DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session --dbus-daemon=${pkgs.dbus}/bin/dbus-daemon ${envCommand}"
fi
# Reset all keys that are present in the old generation but not the new
# one.
jq -r -n \
--slurpfile old "$oldState" \
--slurpfile new "$newState" \
'($old[] - $new[])[]' \
| while read -r key; do
verboseEcho "Resetting dconf key \"$key\""
run $DCONF_DBUS_RUN_SESSION dconf reset "$key"
done
'';
in
''
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
export DCONF_DBUS_RUN_SESSION=""
else
export DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session --dbus-daemon=${pkgs.dbus}/bin/dbus-daemon"
fi
if [[ -v oldGenPath ]]; then
${cleanup} \
"$oldGenPath/${statePath}" \
"$newGenPath/${statePath}"
fi
if [[ -v oldGenPath ]]; then
${cleanup} \
"$oldGenPath/${statePath}" \
"$newGenPath/${statePath}"
fi
run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
unset DCONF_DBUS_RUN_SESSION
''
unset DCONF_DBUS_RUN_SESSION
''
) databases
);
};
}

View File

@@ -59,7 +59,7 @@ in
theme = mkOption {
type = types.nullOr themeType;
default = null;
description = "Default theme for all GTK versions.";
description = "Default theme for GTK 2/3.";
};
iconTheme = mkOption {

View File

@@ -45,9 +45,17 @@ in
packageExample = "pkgs.gnome.gnome-themes-extra";
}
);
default = cfg.theme;
defaultText = literalExpression "config.gtk.theme";
description = "Theme for GTK 4 applications.";
default = if lib.versionOlder config.home.stateVersion "26.05" then cfg.theme else null;
defaultText = literalExpression ''if lib.versionOlder config.home.stateVersion "26.05" then cfg.theme else null'';
description = ''
Theme for GTK 4 applications.
Warning: This is not officially supported and applied using a workaround.
It may cause issues with some apps.
For context, see [Please dont theme our apps](https://stopthemingmy.app/)
and [Restyling apps at scale](https://blogs.gnome.org/tbernard/2018/10/15/restyling-apps-at-scale/).
'';
};
iconTheme = mkOption {

View File

@@ -0,0 +1,9 @@
{
time = "2025-10-14T23:44:58+00:00";
condition = true;
message = ''
A new module is available: `services.colima`
Colima is a tool for orchestrating container runtimes under a linux VM.
'';
}

View File

@@ -0,0 +1,9 @@
{
time = "2025-11-26T05:33:49+00:00";
condition = true;
message = ''
A new module is available: 'programs.cargo'.
cargo is the build system and package manager of Rust.
'';
}

View File

@@ -0,0 +1,11 @@
{
time = "2025-11-26T10:55:28+00:00";
condition = true;
message = ''
The option 'gtk.theme' does not apply to GTK 4 automatically anymore for new
installations (with `home.stateVersion` >= "26.05"). Using a custom theme is
not officially supported by GTK 4, and implemented by home-manager using a
workaround that may cause issues in some cases. If you still want to use a GTK
4 theme, you need to explicitly set 'gtk.gtk4.theme'.
'';
}

View File

@@ -0,0 +1,10 @@
{ pkgs, ... }:
{
time = "2025-11-27T07:22:14+00:00";
condition = pkgs.stdenv.hostPlatform.isDarwin;
message = ''
A new module is available: 'programs.infat'.
Infat is a command line tool to set default openers
for file formats and url schemes on macOS.
'';
}

View File

@@ -0,0 +1,7 @@
{
time = "2025-11-29T23:04:38+00:00";
condition = true;
message = ''
A new module is available: 'programs.parallel'.
'';
}

View File

@@ -0,0 +1,16 @@
{ config, ... }:
{
time = "2025-12-01T12:35:38+00:00";
condition = config.services.ludusavi.enable;
message = ''
BREAKING CHANGE:
The `ludusavi` module has changed its default backup and restore path.
The new module implements a mechanism to automatically migrate the backups
to the new path, but if it doesn't work and you can't find your backups in
`ludusavi`, they should be in the old path: ~/\$XDG_STATE_HOME/backups/ludusavi/
(that means a directory literally called $XDG_STATE_HOME in your home, rather than
the env var expanded). For more info, see pull #8234.
'';
}

View File

@@ -0,0 +1,12 @@
{
time = "2025-12-03T13:14:53+00:00";
condition = true;
message = ''
A new module is available: `programs.calibre`
Calibre is a powerful and easy to use e-book manager. Users say its outstanding
and a must-have. Itll allow you to do nearly everything and it takes things a
step beyond normal e-book software. Its also completely free and open source
and great for both casual users and computer experts.
'';
}

View File

@@ -0,0 +1,12 @@
{
time = "2025-12-04T19:34:38+00:00";
condition = true;
message = ''
A new module is available: `programs.screen`
GNU Screen is a terminal multiplexer, a software application that can
be used to multiplex several virtual consoles, allowing a user to access
multiple separate login sessions inside a single terminal window, or detach
and reattach sessions from a terminal.
'';
}

View File

@@ -0,0 +1,12 @@
{ pkgs, ... }:
{
time = "2025-12-05T01:50:03+00:00";
condition = pkgs.stdenv.hostPlatform.isLinux;
message = ''
A new module is available: `programs.hyprlauncher`
Hyprlauncher is a multipurpose and versatile launcher/picker
for hyprland. Its fast, simple, and provides various modules.
'';
}

View File

@@ -0,0 +1,10 @@
{
time = "2025-12-06T10:03:01+00:00";
condition = true;
message = ''
A new module is available: `programs.npm`
It allows you manage your npm user configuration (`.npmrc`)
and install a specific version of the package.
'';
}

View File

@@ -0,0 +1,10 @@
{
time = "2025-12-06T10:05:43+00:00";
condition = true;
message = ''
A new module is available: `programs.ty`
It allows to manage the configuration and package
of the Python language server `ty` by Astral.
'';
}

View File

@@ -0,0 +1,32 @@
{ config, ... }:
{
time = "2025-12-11T19:04:30+00:00";
condition =
let
helixEnabled = config.programs.helix.enable && config.programs.helix.defaultEditor;
kakouneEnabled = config.programs.kakoune.enable && config.programs.kakoune.defaultEditor;
neovimEnabled = config.programs.neovim.enable && config.programs.neovim.defaultEditor;
vimEnabled = config.programs.vim.enable && config.programs.vim.defaultEditor;
emacsEnabled = config.services.emacs.enable && config.services.emacs.defaultEditor;
in
helixEnabled || kakouneEnabled || neovimEnabled || vimEnabled || emacsEnabled;
message = ''
The 'defaultEditor' option now sets both {env}`EDITOR` and {env}`VISUAL`
environment variables.
Previously, only {env}`EDITOR` was set. The {env}`VISUAL` variable is now
also configured to point to the same editor, which is the expected behavior
for modern terminal editors.
This change affects the following modules:
- programs.helix
- programs.kakoune
- programs.neovim
- programs.vim
- services.emacs
No action is required. This change should improve compatibility with tools
that check {env}`VISUAL` before {env}`EDITOR`.
'';
}

View File

@@ -0,0 +1,12 @@
{ config, ... }:
{
time = "2025-12-12T19:20:28+00:00";
condition = config.xsession.windowManager.herbstluftwm.enable;
message = ''
It is now possible to disable the `herbstclient` alias in the autostart
script by setting `xsession.windowManagers.herbsluftwm.enableAlias = false`.
This makes it possible to use the `herbstclient` command in bash functions,
though may cause flickering while the autostart script runs.
'';
}

View File

@@ -0,0 +1,20 @@
{ 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

@@ -8,6 +8,10 @@
let
cfg = config.qt;
qtctFormat = pkgs.formats.ini {
listToValue = values: lib.concatStringsSep ", " values;
};
# Map platform names to their packages.
platformPackages = with pkgs; {
gnome = [
@@ -286,7 +290,34 @@ in
'';
};
};
};
}
// (lib.genAttrs' [ "qt5ct" "qt6ct" ] (
name:
lib.nameValuePair "${name}Settings" (
lib.mkOption {
type = lib.types.nullOr qtctFormat.type;
default = null;
example = lib.literalExpression ''
{
Appearance = {
style = "kvantum";
icon_theme = "Papirus-Dark";
standar_dialogs = "xdgdesktopportal";
};
Fonts = {
fixed = "\"DejaVuSansM Nerd Font Mono,12\"";
general = "\"DejaVu Sans,12\"";
};
}
'';
description = ''
Qtct configuration. Writes settings to `${name}/${name}.conf`
file. Lists will be translated to comma-separated strings.
Fonts must be quoted (see example).
'';
}
)
));
};
config =
@@ -397,5 +428,18 @@ in
]
++ lib.optionals (platformTheme.name != null) [ "QT_QPA_PLATFORMTHEME" ]
++ lib.optionals (cfg.style.name != null) [ "QT_STYLE_OVERRIDE" ];
xdg.configFile =
lib.pipe
[ "qt5ct" "qt6ct" ]
[
(lib.filter (qtct: cfg."${qtct}Settings" != null))
(lib.flip lib.genAttrs' (
qtct:
lib.nameValuePair "${qtct}/${qtct}.conf" {
source = qtctFormat.generate "${qtct}-config" cfg."${qtct}Settings";
}
))
];
};
}

View File

@@ -26,6 +26,7 @@ in
"24.11"
"25.05"
"25.11"
"26.05"
];
description = ''
It is occasionally necessary for Home Manager to change

View File

@@ -8,26 +8,28 @@ 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: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\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"
"Language: fo\n"
"MIME-Version: 1.0\n"
"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-dev\n"
#: modules/files.nix:206
msgid "Creating home file links in %s"
msgstr ""
msgstr "Stávni heimafílaleinkir innaní %s"
#: modules/files.nix:219
msgid "Cleaning up orphan links from %s"
msgstr ""
msgstr "Ruddi foreldraleys leinkir frá %s"
#: modules/home-environment.nix:647
msgid "Creating new profile generation"
msgstr ""
msgstr "Stovni nýggjan profil ættarlið"
#: modules/home-environment.nix:650
msgid "No change so reusing latest profile generation"

View File

@@ -8,8 +8,8 @@ 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: 2025-03-07 18:58+0000\n"
"Last-Translator: 807 <s10855168@gmail.com>\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/modules/zh_Hant/>\n"
"Language: zh_Hant\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.3-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: modules/files.nix:206
msgid "Creating home file links in %s"
@@ -25,15 +25,15 @@ msgstr "正在 %s 中建立家目錄檔案連結"
#: modules/files.nix:219
msgid "Cleaning up orphan links from %s"
msgstr "正在 %s 清理孤立連結"
msgstr "正在清理 %s 中的孤立連結"
#: modules/home-environment.nix:647
msgid "Creating new profile generation"
msgstr "正在建立新一代的配置文件中"
msgstr "正在建立新的世代設定檔"
#: modules/home-environment.nix:650
msgid "No change so reusing latest profile generation"
msgstr "為發生改變,請重新使用新一代的配置文件"
msgstr "沒有變更,將重複使用最新的設定檔世代"
#: modules/home-environment.nix:699
msgid ""
@@ -50,18 +50,18 @@ msgid ""
"\n"
"Then try activating your Home Manager configuration again."
msgstr ""
"糟糕Nix 未能安裝您的新 Home Manager 配置文件\n"
"糟糕Nix 無法安裝您的新 Home Manager 設定檔\n"
"\n"
"也許這裏和使用 \"%s\" 安裝的包有衝突?\n"
"嘗試行\n"
"可能與使用 \"%s\" 安裝的套件衝突?\n"
"嘗試行\n"
"\n"
" %s\n"
"\n"
"如果有衝突的包,你可以用\n"
"如果有衝突的套件,您可以使用以下指令移除\n"
"\n"
" %s\n"
"\n"
"來移除。然後嘗試再次啟用您的 Home Manager 配置。"
"然後再次嘗試啟用您的 Home Manager 設定。"
#: modules/home-environment.nix:735
msgid "Activating %s"
@@ -69,27 +69,27 @@ msgstr "正在啟用 %s"
#: modules/home-environment.nix:807
msgid "%s: unknown option '%s'"
msgstr ""
msgstr "%s未知選項 '%s'"
#: modules/lib-bash/activation-init.sh:22
msgid "Migrating profile from %s to %s"
msgstr "正在從 %S 配置文件轉移到 %s"
msgstr "正在將設定檔從 %s 遷移至 %s"
#: modules/lib-bash/activation-init.sh:54
msgid "Could not find suitable profile directory, tried %s and %s"
msgstr "找不到合適的 profile 目錄,已嘗試 %s 和 %s"
msgstr "找不到合適的設定檔目錄,已嘗試 %s 和 %s"
#: modules/lib-bash/activation-init.sh:106
msgid "Error: USER is set to \"%s\" but we expect \"%s\""
msgstr "錯誤USER 被設定為 「%s」但我們希望是 「%s」"
msgstr "錯誤USER 被設定為「%s」但我們的預期為「%s」"
#: modules/lib-bash/activation-init.sh:115
msgid "Error: HOME is set to \"%s\" but we expect \"%s\""
msgstr "錯誤HOME 被設定為 「%s」但我們預期得到 「%s」"
msgstr "錯誤HOME 被設定為「%s」但我們預期「%s」"
#: modules/lib-bash/activation-init.sh:132
msgid "Starting Home Manager activation"
msgstr "正在啟動 Home Manager 初始化程式"
msgstr "正在進行 Home Manager 啟用程序"
#: modules/lib-bash/activation-init.sh:136
msgid "Sanity checking Nix"
@@ -97,19 +97,19 @@ msgstr "正在進行 Nix 完整性檢查"
#: modules/lib-bash/activation-init.sh:149
msgid "This is a dry run"
msgstr "這是試運行"
msgstr "這是模擬執行"
#: modules/lib-bash/activation-init.sh:153
msgid "This is a live run"
msgstr "這是實際行"
msgstr "這是實際行"
#: modules/lib-bash/activation-init.sh:159
msgid "Using Nix version: %s"
msgstr "正在使用的 Nix 版本: %s"
msgstr "使用的 Nix 版本%s"
#: modules/lib-bash/activation-init.sh:162
msgid "Activation variables:"
msgstr "啟用變數:"
msgstr "啟用變數"
#~ msgid "Creating profile generation %s"
#~ msgstr "正在建立配置檔案世代 %s"

View File

@@ -10,6 +10,12 @@ let
tomlFormat = pkgs.formats.toml { };
configPath =
if config.xdg.enable then
"${lib.removePrefix config.home.homeDirectory config.xdg.configHome}/aerospace/aerospace.toml"
else
".aerospace.toml";
# filterAttrsRecursive supporting lists, as well.
filterListAndAttrsRecursive =
pred: set:
@@ -39,6 +45,19 @@ in
{
meta.maintainers = with lib.maintainers; [ damidoug ];
imports = [
(lib.mkRenamedOptionModule
[ "programs" "aerospace" "userSettings" ]
[ "programs" "aerospace" "settings" ]
)
(lib.mkRemovedOptionModule [
"programs"
"aerospace"
"extraConfig"
] "This option has been removed. Please use 'programs.aerospace.settings' instead.")
];
options.programs.aerospace = {
enable = lib.mkEnableOption "AeroSpace window manager";
@@ -81,24 +100,7 @@ in
};
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration to append to the aerospace.toml file.
This allows you to add raw TOML content, including multiline strings.
'';
example = lib.literalExpression ''
alt-enter = ''''exec-and-forget osascript -e '
tell application "Terminal"
do script
activate
end tell'
''''
'';
};
userSettings = mkOption {
settings = mkOption {
inherit (tomlFormat) type;
default = { };
example = lib.literalExpression ''
@@ -115,6 +117,27 @@ in
alt-k = "focus up";
alt-l = "focus right";
};
on-window-detected = [
{
"if".app-id = "com.apple.finder";
run = "move-node-to-workspace 9";
}
{
"if" = {
app-id = "com.apple.systempreferences";
app-name-regex-substring = "settings";
window-title-regex-substring = "substring";
workspace = "workspace-name";
during-aerospace-startup = true;
};
check-further-callbacks = true;
run = [
"layout floating"
"move-node-to-workspace S"
];
}
];
}
'';
description = ''
@@ -128,32 +151,68 @@ in
config = lib.mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "programs.aerospace" pkgs lib.platforms.darwin)
# 1. Fail if user sets start-at-login = true BUT launchd is disabled.
{
assertion =
!((lib.hasAttr "start-at-login" cfg.settings) && (cfg.settings."start-at-login" == true))
|| (cfg.launchd.enable == true);
message = ''
You have set `programs.aerospace.settings."start-at-login" = true;`
but `programs.aerospace.launchd.enable` is false.
This tells AeroSpace to manage its own startup, which can conflict
with Home Manager.
To manage startup with Home Manager, please set
`programs.aerospace.launchd.enable = true;`
(You can leave `start-at-login = true` in your settings, it will be
correctly overridden).
'';
}
# 2. Fail if user sets after-login-command (in any case).
{
assertion =
!(
(lib.hasAttr "after-login-command" cfg.settings)
&& (lib.isList cfg.settings."after-login-command")
&& (cfg.settings."after-login-command" != [ ])
);
message = ''
You have set `programs.aerospace.settings."after-login-command"`.
This setting is not supported when using this Home Manager module,
as it either conflicts with the launchd service (if enabled)
or bypasses it (if disabled).
The correct way to run commands after AeroSpace starts is to use:
1. `programs.aerospace.launchd.enable = true;`
2. `programs.aerospace.settings."after-startup-command" = [ ... ];`
'';
}
];
home = {
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
file.".config/aerospace/aerospace.toml".source =
let
generatedConfig = tomlFormat.generate "aerospace" (
filterNulls (
cfg.userSettings
// lib.optionalAttrs cfg.launchd.enable {
# Override these to avoid launchd conflicts
start-at-login = false;
after-login-command = [ ];
}
)
);
extraConfig = pkgs.writeText "aerospace-extra-config" cfg.extraConfig;
in
pkgs.runCommandLocal "aerospace.toml"
{
inherit generatedConfig extraConfig;
}
''
cat "$generatedConfig" "$extraConfig" > "$out"
'';
file.${configPath} = lib.mkIf (cfg.settings != { }) {
source = tomlFormat.generate "aerospace" (
filterNulls (
cfg.settings
// {
# Override these to avoid launchd conflicts
start-at-login = false;
after-login-command = [ ];
}
)
);
onChange = lib.mkIf cfg.launchd.enable ''
echo "AeroSpace config changed, reloading..."
${lib.getExe cfg.package} reload-config
'';
};
};
launchd.agents.aerospace = {

View File

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

View File

@@ -0,0 +1,44 @@
{
lib,
pkgs,
config,
...
}:
let
inherit (lib)
types
mkIf
mkEnableOption
mkPackageOption
mkOption
;
cfg = config.programs.calibre;
in
{
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
options.programs.calibre = {
enable = mkEnableOption "calibre";
package = mkPackageOption pkgs "calibre" { nullable = true; };
plugins = mkOption {
type = with types; listOf path;
default = [ ];
description = "List of plugins to install for calibre";
};
};
config = mkIf cfg.enable {
home.packages = mkIf (cfg.package != null) [ cfg.package ];
xdg.configFile = mkIf (cfg.plugins != [ ]) (
let
symlinkedPlugins = pkgs.symlinkJoin {
name = "calibre-plugins";
paths = cfg.plugins;
};
in
lib.mapAttrs' (
k: _: lib.nameValuePair "calibre/plugins/${k}" { source = (symlinkedPlugins + "/${k}"); }
) (builtins.readDir symlinkedPlugins)
);
};
}

View File

@@ -0,0 +1,43 @@
{
lib,
config,
pkgs,
...
}:
let
inherit (lib) mkEnableOption;
tomlFormat = pkgs.formats.toml { };
cfg = config.programs.cargo;
in
{
meta.maintainers = [ lib.maintainers.friedrichaltheide ];
options = {
programs = {
cargo = {
enable = mkEnableOption "management of cargo config";
settings = lib.mkOption {
inherit (tomlFormat) type;
default = { };
description = ''
Available configuration options for the .cargo/config see:
https://doc.rust-lang.org/cargo/reference/config.html
'';
};
};
};
};
config = lib.mkIf cfg.enable {
home = {
file = {
".cargo/config.toml" = {
source = tomlFormat.generate "config.toml" cfg.settings;
};
};
};
};
}

View File

@@ -40,7 +40,7 @@ let
finalPackage = mkOption {
inherit visible;
type = types.package;
type = types.nullOr types.package;
readOnly = true;
description = ''
Resulting customized ${name} package
@@ -220,15 +220,22 @@ let
};
in
lib.mkIf cfg.enable {
programs.${browser}.finalPackage = lib.mkIf (cfg.package != null) (
assertions = [
{
assertion = !(cfg.package == null && cfg.commandLineArgs != [ ]);
message = "Cannot set `commandLineArgs` when `package` is null for ${browser}.";
}
];
programs.${browser}.finalPackage =
if cfg.commandLineArgs != [ ] then
cfg.package.override {
commandLineArgs = lib.concatStringsSep " " cfg.commandLineArgs;
}
else
cfg.package
);
cfg.package;
home.packages = lib.mkIf (cfg.finalPackage != null) [
cfg.finalPackage

View File

@@ -197,6 +197,47 @@ in
};
};
rules = lib.mkOption {
type = lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path);
default = { };
description = ''
Modular rule files for Claude Code.
The attribute name becomes the rule filename, and the value is either:
- Inline content as a string
- A path to a file containing the rule content
Rules are stored in .claude/rules/ directory.
All markdown files in .claude/rules/ are automatically loaded as project memory.
'';
example = lib.literalExpression ''
{
code-style = '''
# Code Style Guidelines
- Use consistent formatting
- Follow language conventions
''';
testing = '''
# Testing Conventions
- Write tests for all new features
- Maintain test coverage above 80%
''';
security = ./rules/security.md;
}
'';
};
rulesDir = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Path to a directory containing rule files for Claude Code.
Rule files from this directory will be symlinked to .claude/rules/.
All markdown files in this directory are automatically loaded as project memory.
'';
example = lib.literalExpression "./rules";
};
agentsDir = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
@@ -325,6 +366,10 @@ in
assertion = !(cfg.memory.text != null && cfg.memory.source != null);
message = "Cannot specify both `programs.claude-code.memory.text` and `programs.claude-code.memory.source`";
}
{
assertion = !(cfg.rules != { } && cfg.rulesDir != null);
message = "Cannot specify both `programs.claude-code.rules` and `programs.claude-code.rulesDir`";
}
{
assertion = !(cfg.agents != { } && cfg.agentsDir != null);
message = "Cannot specify both `programs.claude-code.agents` and `programs.claude-code.agentsDir`";
@@ -348,7 +393,7 @@ in
makeWrapperArgs = lib.flatten (
lib.filter (x: x != [ ]) [
(lib.optional (cfg.mcpServers != { }) [
"--add-flags"
"--append-flags"
"--mcp-config ${jsonFormat.generate "claude-code-mcp-config.json" { inherit (cfg) mcpServers; }}"
])
]
@@ -386,6 +431,11 @@ in
if cfg.memory.text != null then { text = cfg.memory.text; } else { source = cfg.memory.source; }
);
".claude/rules" = lib.mkIf (cfg.rulesDir != null) {
source = cfg.rulesDir;
recursive = true;
};
".claude/agents" = lib.mkIf (cfg.agentsDir != null) {
source = cfg.agentsDir;
recursive = true;
@@ -406,6 +456,12 @@ in
recursive = true;
};
}
// lib.mapAttrs' (
name: content:
lib.nameValuePair ".claude/rules/${name}.md" (
if lib.isPath content then { source = content; } else { text = content; }
)
) cfg.rules
// lib.mapAttrs' (
name: content:
lib.nameValuePair ".claude/agents/${name}.md" (

View File

@@ -68,8 +68,15 @@ in
in
lib.mkMerge [
(mkIf cfg.enable {
# Auto-enable git integration if programs.git.diff-highlight.enable was set to true
programs.diff-highlight.enableGitIntegration = lib.mkIf oldOptionEnabled (lib.mkOverride 1490 true);
assertions = [
{
assertion = !cfg.enableGitIntegration || config.programs.git.package != null;
message = ''
programs.diff-highlight.enableGitIntegration requires programs.git.package to be set.
Please set programs.git.package to a valid git package.
'';
}
];
warnings =
lib.optional
@@ -77,9 +84,12 @@ in
cfg.enableGitIntegration && options.programs.diff-highlight.enableGitIntegration.highestPrio == 1490
)
"`programs.diff-highlight.enableGitIntegration` automatic enablement is deprecated. Please explicitly set `programs.diff-highlight.enableGitIntegration = true`.";
# Auto-enable git integration if programs.git.diff-highlight.enable was set to true
programs.diff-highlight.enableGitIntegration = lib.mkIf oldOptionEnabled (lib.mkOverride 1490 true);
})
(mkIf (cfg.enable && cfg.enableGitIntegration) {
(mkIf (cfg.enable && cfg.enableGitIntegration && config.programs.git.package != null) {
programs.git = {
enable = lib.mkDefault true;
iniContent =

View File

@@ -645,7 +645,7 @@ in
# Support completion for `man` by building a cache for `apropos`.
programs.man.generateCaches = lib.mkDefault true;
xdg.dataFile."fish/home-manager_generated_completions".source =
xdg.dataFile."fish/home-manager/generated_completions".source =
let
# Paths later in the list will overwrite those already linked
destructiveSymlinkJoin =
@@ -696,7 +696,7 @@ in
set -l post_joined (string replace $prev_joined "" $joined)
set -l prev (string split " " (string trim $prev_joined))
set -l post (string split " " (string trim $post_joined))
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager/generated_completions" $post
end
'';
}

View File

@@ -21,14 +21,19 @@ in
settings = lib.mkOption {
inherit (jsonFormat) type;
default = { };
example = lib.literalExpression ''
{
"theme": "Default",
"vimMode": true,
"preferredEditor": "nvim",
"autoAccept": true
}
'';
example = {
ui.theme = "Default";
general = {
vimMode = true;
preferredEditor = "nvim";
previewFeatures = true;
};
ide.enabled = true;
privacy.usageStatisticsEnabled = false;
tools.autoAccept = false;
context.loadMemoryFromIncludeDirectories = true;
security.auth.selectedType = "oauth-personal";
};
description = "JSON config for gemini-cli";
};
@@ -81,12 +86,12 @@ in
};
defaultModel = lib.mkOption {
type = lib.types.str;
default = "gemini-2.5-pro";
type = lib.types.nullOr lib.types.str;
default = null;
example = "gemini-2.5-flash";
description = ''
The default model to use for the CLI.
Will be set as $GEMINI_MODEL.
Will be set as $GEMINI_MODEL when configured.
'';
};
@@ -138,7 +143,9 @@ in
file.".gemini/settings.json" = lib.mkIf (cfg.settings != { }) {
source = jsonFormat.generate "gemini-cli-settings.json" cfg.settings;
};
sessionVariables.GEMINI_MODEL = cfg.defaultModel;
sessionVariables = lib.mkIf (cfg.defaultModel != null) {
GEMINI_MODEL = cfg.defaultModel;
};
};
}
{

View File

@@ -41,6 +41,7 @@ in
enable = mkEnableOption "Git";
package = lib.mkPackageOption pkgs "git" {
nullable = true;
example = "pkgs.gitFull";
extraDescription = ''
Use {var}`pkgs.gitFull`
@@ -328,7 +329,7 @@ in
config = mkIf cfg.enable (
lib.mkMerge [
{
home.packages = [ cfg.package ];
home.packages = lib.optionals (cfg.package != null) [ cfg.package ];
assertions = [
{
@@ -516,7 +517,7 @@ in
Type = "oneshot";
ExecStart =
let
exe = lib.getExe cfg.package;
exe = if cfg.package != null then lib.getExe cfg.package else "git";
in
''
"${exe}" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i
@@ -553,7 +554,7 @@ in
launchd.agents =
let
baseArguments = [
"${lib.getExe cfg.package}"
"${if cfg.package != null then lib.getExe cfg.package else "git"}"
"for-each-repo"
"--keep-going"
"--config=maintenance.repo"

View File

@@ -49,7 +49,8 @@ in
default = false;
description = ''
Whether to configure {command}`hx` as the default
editor using the {env}`EDITOR` environment variable.
editor using the {env}`EDITOR` and {env}`VISUAL`
environment variables.
'';
};
@@ -225,7 +226,10 @@ in
else
[ cfg.package ];
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "hx"; };
home.sessionVariables = mkIf cfg.defaultEditor {
EDITOR = "hx";
VISUAL = "hx";
};
xdg.configFile =
let

View File

@@ -9,7 +9,7 @@ let
jsonFormat = pkgs.formats.json { };
in
{
meta.maintainers = [ lib.maintainers.perchun ];
meta.maintainers = [ lib.maintainers.PerchunPak ];
imports = [
(lib.mkRemovedOptionModule [ "programs" "hyprpanel" "dontAssertNotificationDaemons " ] ''

View File

@@ -0,0 +1,81 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.programs.infat;
tomlFormat = pkgs.formats.toml { };
configDir =
if config.xdg.enable then
config.xdg.configHome
else
"${config.home.homeDirectory}/Library/Application Support";
configFile = "${configDir}/infat/config.toml";
in
{
meta.maintainers = with lib.maintainers; [
mirkolenz
];
options = {
programs.infat = {
enable = lib.mkEnableOption "infat";
package = lib.mkPackageOption pkgs "infat" { nullable = true; };
settings = lib.mkOption {
type = tomlFormat.type;
default = { };
example = lib.literalExpression ''
{
extensions = {
md = "TextEdit";
html = "Safari";
pdf = "Preview";
};
schemes = {
mailto = "Mail";
web = "Safari";
};
types = {
plain-text = "VSCode";
};
}
'';
description = ''
Configuration written to
{file}`$XDG_CONFIG_HOME/infat/config.toml`.
'';
};
autoActivate = lib.mkEnableOption "auto-activate infat" // {
default = true;
example = false;
description = ''
Automatically activate infat on startup.
This is useful if you want to use infat as a
default application handler for certain file types.
If you don't want this, set this to false.
This option is only effective if `settings` is set.
'';
};
};
};
config = lib.mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "programs.infat" pkgs lib.platforms.darwin)
];
home = {
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
file.${configFile} = lib.mkIf (cfg.settings != { }) {
source = tomlFormat.generate "infat-settings.toml" cfg.settings;
};
activation = lib.mkIf (cfg.settings != { } && cfg.package != null && cfg.autoActivate) {
infat = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
run ${lib.getExe cfg.package} --config "${configFile}" $VERBOSE_ARG
'';
};
};
};
}

View File

@@ -705,7 +705,8 @@ in
default = false;
description = ''
Whether to configure {command}`kak` as the default
editor using the {env}`EDITOR` environment variable.
editor using the {env}`EDITOR` and {env}`VISUAL`
environment variables.
'';
};
@@ -755,7 +756,10 @@ in
programs.kakoune.finalPackage = lib.mkIf (cfg.package != null) kakouneWithPlugins;
home.packages = lib.mkIf (cfg.finalPackage != null) [ cfg.finalPackage ];
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; };
home.sessionVariables = mkIf cfg.defaultEditor {
EDITOR = "kak";
VISUAL = "kak";
};
xdg.configFile = lib.mkMerge [
{ "kak/kakrc".source = configFile; }
(mkIf (cfg.colorSchemePackage != null) {

View File

@@ -37,13 +37,17 @@ in
options = lib.mkOption {
type =
with lib.types;
attrsOf (oneOf [
bool
int
str
]);
default = { };
description = "GNU-style options to be set via {env}`$LESS`.";
let
scalar = oneOf [
bool
int
str
];
attrs = attrsOf (either scalar (listOf scalar));
in
coercedTo attrs (lib.cli.toGNUCommandLine { }) (listOf str);
default = [ ];
description = "Options to be set via {env}`$LESS`.";
example = {
RAW-CONTROL-CHARS = true;
quiet = true;
@@ -58,10 +62,10 @@ in
xdg.configFile."lesskey" = lib.mkIf (cfg.config != "") { text = cfg.config; };
programs.less.config = lib.mkIf (cfg.options != { }) (
programs.less.config = lib.mkIf (cfg.options != [ ]) (
lib.mkBefore ''
#env
LESS = ${lib.cli.toGNUCommandLineShell { } cfg.options}
LESS = ${lib.concatStringsSep " " cfg.options}
''
);
};

View File

@@ -24,7 +24,8 @@ 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;
@@ -33,6 +34,7 @@ let
send_mail = mkSmtp account;
mailboxes = account.meli.mailboxAliases;
}
// account.meli.settings
);
mkSmtp = account: {
@@ -153,6 +155,14 @@ in
};
description = "Folder display name";
};
settings = mkOption {
type = types.submodule {
freeformType = tomlFormat.type;
};
default = { };
description = "Account specific meli configuration";
};
};
}
)
@@ -160,6 +170,15 @@ 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

@@ -7,121 +7,46 @@
let
inherit (lib)
concatMapStringsSep
literalExpression
mkEnableOption
mkIf
mkOption
mkRemovedOptionModule
mkPackageOption
optionals
types
;
cfg = config.programs.neovim;
fileType =
(import ../lib/file-type.nix {
inherit (config.home) homeDirectory;
inherit lib pkgs;
}).fileType;
inherit
(
(import ../lib/file-type.nix {
inherit (config.home) homeDirectory;
inherit lib pkgs;
})
)
fileType
;
jsonFormat = pkgs.formats.json { };
pluginWithConfigType = types.submodule {
options = {
config = mkOption {
type = types.nullOr types.lines;
description = "Script to configure this plugin. The scripting language should match type.";
default = null;
};
type = mkOption {
type = types.either (types.enum [
"lua"
"viml"
"teal"
"fennel"
]) types.str;
description = "Language used in config. Configurations are aggregated per-language.";
default = "viml";
};
optional = mkEnableOption "optional" // {
description = "Don't load by default (load with :packadd)";
};
plugin = lib.mkPackageOption pkgs.vimPlugins "plugin" {
default = null;
example = "pkgs.vimPlugins.nvim-treesitter";
pkgsText = "pkgs.vimPlugins";
};
runtime = mkOption {
default = { };
# passing actual "${xdg.configHome}/nvim" as basePath was a bit tricky
# due to how fileType.target is implemented
type = fileType "programs.neovim.plugins._.runtime" "{var}`xdg.configHome/nvim`" "nvim";
example = literalExpression ''
{ "ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; }
'';
description = ''
Set of files that have to be linked in nvim config folder.
'';
};
};
};
allPlugins =
cfg.plugins
++ lib.optional cfg.coc.enable {
type = "viml";
plugin = cfg.coc.package;
config = cfg.coc.pluginConfig;
optional = false;
};
luaPackages = cfg.finalPackage.unwrapped.lua.pkgs;
resolvedExtraLuaPackages = cfg.extraLuaPackages luaPackages;
extraMakeWrapperArgs = lib.optionalString (
cfg.extraPackages != [ ]
) ''--suffix PATH : "${lib.makeBinPath cfg.extraPackages}"'';
extraMakeWrapperLuaCArgs =
lib.optionalString (resolvedExtraLuaPackages != [ ])
''--suffix LUA_CPATH ";" "${
lib.concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages
}"'';
extraMakeWrapperLuaArgs =
lib.optionalString (resolvedExtraLuaPackages != [ ])
''--suffix LUA_PATH ";" "${
lib.concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages
}"'';
in
{
meta.maintainers = with lib.maintainers; [ khaneliman ];
imports = [
(mkRemovedOptionModule [
"programs"
"neovim"
"withPython"
] "Python2 support has been removed from neovim.")
(mkRemovedOptionModule [
"programs"
"neovim"
"extraPythonPackages"
] "Python2 support has been removed from neovim.")
(mkRemovedOptionModule [ "programs" "neovim" "configure" ] ''
programs.neovim.configure is deprecated.
Other programs.neovim options can override its settings or ignore them.
Please use the other options at your disposal:
configure.packages.*.opt -> programs.neovim.plugins = [ { plugin = ...; optional = true; }]
configure.packages.*.start -> programs.neovim.plugins = [ { plugin = ...; }]
configure.customRC -> programs.neovim.extraConfig
'')
];
options = {
programs.neovim = {
enable = mkEnableOption "Neovim";
package = mkPackageOption pkgs "neovim" { default = "neovim-unwrapped"; };
finalPackage = mkOption {
type = types.package;
readOnly = true;
description = "Resulting customized neovim package.";
};
# Aliases
viAlias = mkOption {
type = types.bool;
default = false;
@@ -146,6 +71,17 @@ in
'';
};
defaultEditor = mkOption {
type = types.bool;
default = false;
description = ''
Whether to configure {command}`nvim` as the default
editor using the {env}`EDITOR` and {env}`VISUAL`
environment variables.
'';
};
# Providers & Runtimes
withNodeJs = mkOption {
type = types.bool;
default = false;
@@ -155,11 +91,12 @@ in
'';
};
withRuby = mkOption {
type = types.nullOr types.bool;
default = true;
withPerl = mkOption {
type = types.bool;
default = false;
description = ''
Enable ruby provider.
Enable perl provider. Set to `true` to
use Perl plugins.
'';
};
@@ -172,21 +109,16 @@ in
'';
};
withRuby = mkOption {
type = types.nullOr types.bool;
default = true;
description = ''
Enable ruby provider.
'';
};
extraPython3Packages = mkOption {
# In case we get a plain list, we need to turn it into a function,
# as expected by the function in nixpkgs.
# The only way to do so is to call `const`, which will ignore its input.
type =
let
fromType = types.listOf types.package;
in
types.coercedTo fromType (lib.flip lib.warn lib.const ''
Assigning a plain list to extraPython3Packages is deprecated.
Please assign a function taking a package set as argument, so
extraPython3Packages = [ pkgs.python3Packages.xxx ];
should become
extraPython3Packages = ps: [ ps.xxx ];
'') (types.functionTo fromType);
type = types.functionTo (types.listOf types.package);
default = _: [ ];
defaultText = literalExpression "ps: [ ]";
example = literalExpression "pyPkgs: with pyPkgs; [ python-language-server ]";
@@ -198,21 +130,8 @@ in
'';
};
# We get the Lua package from the final package and use its
# Lua packageset to evaluate the function that this option was set to.
# This ensures that we always use the same Lua version as the Neovim package.
extraLuaPackages = mkOption {
type =
let
fromType = types.listOf types.package;
in
types.coercedTo fromType (lib.flip lib.warn lib.const ''
Assigning a plain list to extraLuaPackages is deprecated.
Please assign a function taking a package set as argument, so
extraLuaPackages = [ pkgs.lua51Packages.xxx ];
should become
extraLuaPackages = ps: [ ps.xxx ];
'') (types.functionTo fromType);
type = types.functionTo (types.listOf types.package);
default = _: [ ];
defaultText = literalExpression "ps: [ ]";
example = literalExpression "luaPkgs: with luaPkgs; [ luautf8 ]";
@@ -224,8 +143,34 @@ in
'';
};
# Wrapper Configuration
extraName = mkOption {
type = types.str;
default = "";
description = ''
Extra name appended to the wrapper package name.
'';
};
autowrapRuntimeDeps = mkOption {
type = types.bool;
default = true;
description = ''
Whether to automatically wrap the binary with the runtime dependencies of the plugins.
'';
};
waylandSupport = mkOption {
type = types.bool;
default = pkgs.stdenv.isLinux;
defaultText = literalExpression "pkgs.stdenv.isLinux";
description = ''
Whether to enable Wayland clipboard support.
'';
};
extraWrapperArgs = mkOption {
type = with types; listOf str;
type = types.listOf types.str;
default = [ ];
example = literalExpression ''
[
@@ -246,53 +191,14 @@ in
'';
};
generatedConfigViml = mkOption {
type = types.lines;
visible = true;
readOnly = true;
description = ''
Generated vimscript config.
'';
};
generatedConfigs = mkOption {
type = types.attrsOf types.lines;
visible = true;
readOnly = true;
example = literalExpression ''
{
viml = '''
" Generated by home-manager
map <leader> ,
''';
lua = '''
-- Generated by home-manager
vim.opt.background = "dark"
''';
}'';
description = ''
Generated configurations with as key their language (set via type).
'';
};
package = lib.mkPackageOption pkgs "neovim" { default = "neovim-unwrapped"; };
finalPackage = mkOption {
type = types.package;
readOnly = true;
description = "Resulting customized neovim package.";
};
defaultEditor = mkOption {
type = types.bool;
default = false;
description = ''
Whether to configure {command}`nvim` as the default
editor using the {env}`EDITOR` environment variable.
'';
extraPackages = mkOption {
type = types.listOf types.package;
default = [ ];
example = literalExpression "[ pkgs.shfmt ]";
description = "Extra packages available to nvim.";
};
# Configuration & Plugins
extraConfig = mkOption {
type = types.lines;
default = "";
@@ -307,45 +213,92 @@ in
extraLuaConfig = mkOption {
type = types.lines;
default = "";
example = ''
vim.opt.nobackup = true
example = lib.literalExpression ''
let
nvimEarlyInit = lib.mkOrder 500 "set rtp+=vim.opt.rtp:prepend('/home/user/myplugin')";
nvimLateInit = lib.mkAfter 1000 "vim.opt.signcolumn = 'auto:1-3'";
in
lib.mkMerge [ nvimEarlyInit nvimLateInit ];
'';
description = ''
Custom lua lines.
Content to be added to {file}`init.lua`.
To specify the order, use `lib.mkOrder`, `lib.mkBefore`, `lib.mkAfter`.
'';
};
extraPackages = mkOption {
type = with types; listOf package;
default = [ ];
example = literalExpression "[ pkgs.shfmt ]";
description = "Extra packages available to nvim.";
};
plugins =
let
pluginWithConfigType = types.submodule {
options = {
config = mkOption {
type = types.nullOr types.lines;
description = "Script to configure this plugin. The scripting language should match type.";
default = null;
};
plugins = mkOption {
type = with types; listOf (either package pluginWithConfigType);
default = [ ];
example = literalExpression ''
with pkgs.vimPlugins; [
yankring
vim-nix
{ plugin = vim-startify;
config = "let g:startify_change_to_vcs_root = 0";
}
]
'';
description = ''
List of vim plugins to install optionally associated with
configuration to be placed in init.vim.
type = mkOption {
type = types.either (types.enum [
"lua"
"viml"
"teal"
"fennel"
]) types.str;
description = "Language used in config. Configurations are aggregated per-language.";
default = "viml";
};
This option is mutually exclusive with {var}`configure`.
'';
};
optional = mkEnableOption "optional" // {
description = "Don't load by default (load with :packadd)";
};
plugin = mkPackageOption pkgs.vimPlugins "plugin" {
default = null;
example = "pkgs.vimPlugins.nvim-treesitter";
pkgsText = "pkgs.vimPlugins";
};
runtime = mkOption {
default = { };
# passing actual "${xdg.configHome}/nvim" as basePath was a bit tricky
# due to how fileType.target is implemented
type = fileType "programs.neovim.plugins._.runtime" "{var}`xdg.configHome/nvim`" "nvim";
example = literalExpression ''
{ "ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; }
'';
description = ''
Set of files that have to be linked in nvim config folder.
'';
};
};
};
in
mkOption {
type = types.listOf (types.either types.package pluginWithConfigType);
default = [ ];
example = literalExpression ''
with pkgs.vimPlugins;
[
yankring
vim-nix
{ plugin = vim-startify;
config = "let g:startify_change_to_vcs_root = 0";
}
]
'';
description = ''
List of vim plugins to install optionally associated with
configuration to be placed in init.vim.
This option is mutually exclusive with {var}`configure`.
'';
};
coc = {
enable = mkEnableOption "Coc";
package = lib.mkPackageOption pkgs "coc-nvim" {
package = mkPackageOption pkgs "coc-nvim" {
default = [
"vimPlugins"
"coc-nvim"
@@ -375,7 +328,7 @@ in
filetypes = [ "haskell" "lhaskell" ];
};
};
};
}
'';
description = ''
Extra configuration lines to add to
@@ -392,11 +345,52 @@ in
description = "Script to configure CoC. Must be viml.";
};
};
# Generated / Read-Only
generatedConfigViml = mkOption {
type = types.lines;
visible = true;
readOnly = true;
description = ''
Generated vimscript config.
'';
};
generatedConfigs = mkOption {
type = types.attrsOf types.lines;
visible = true;
readOnly = true;
example = literalExpression ''
{
viml = '''
" Generated by home-manager
map <leader> ,
''';
lua = '''
-- Generated by home-manager
vim.opt.background = "dark"
''';
}
'';
description = ''
Generated configurations with as key their language (set via type).
'';
};
};
};
config =
config = mkIf cfg.enable (
let
allPlugins =
cfg.plugins
++ lib.optional cfg.coc.enable {
type = "viml";
plugin = cfg.coc.package;
config = cfg.coc.pluginConfig;
optional = false;
};
defaultPlugin = {
type = "viml";
plugin = null;
@@ -412,78 +406,100 @@ in
suppressNotVimlConfig = p: if p.type != "viml" then p // { config = null; } else p;
neovimConfig = pkgs.neovimUtils.makeNeovimConfig {
# Lua & Python Package Resolution
luaPackages = cfg.finalPackage.unwrapped.lua.pkgs;
resolvedExtraLuaPackages = cfg.extraLuaPackages luaPackages;
# Wrapper Arguments Construction
extraMakeWrapperArgs = optionals (cfg.extraPackages != [ ]) [
"--suffix"
"PATH"
":"
(lib.makeBinPath cfg.extraPackages)
];
extraMakeWrapperLuaCArgs = optionals (resolvedExtraLuaPackages != [ ]) [
"--suffix"
"LUA_CPATH"
";"
(concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages)
];
extraMakeWrapperLuaArgs = optionals (resolvedExtraLuaPackages != [ ]) [
"--suffix"
"LUA_PATH"
";"
(concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages)
];
wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package {
withNodeJs = cfg.withNodeJs || cfg.coc.enable;
plugins = map suppressNotVimlConfig pluginsNormalized;
inherit (cfg)
extraPython3Packages
withPython3
withRuby
withPerl
viAlias
vimAlias
extraName
autowrapRuntimeDeps
waylandSupport
;
withNodeJs = cfg.withNodeJs || cfg.coc.enable;
plugins = map suppressNotVimlConfig pluginsNormalized;
customRC = cfg.extraConfig;
neovimRcContent = cfg.extraConfig;
wrapperArgs =
cfg.extraWrapperArgs ++ extraMakeWrapperArgs ++ extraMakeWrapperLuaCArgs ++ extraMakeWrapperLuaArgs;
wrapRc = false;
};
in
{
programs.neovim = {
generatedConfigViml = cfg.extraConfig;
generatedConfigs =
let
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;
finalPackage = wrappedNeovim';
};
wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package (
neovimConfig
// {
wrapperArgs =
(lib.escapeShellArgs (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs))
+ " "
+ extraMakeWrapperArgs
+ " "
+ extraMakeWrapperLuaCArgs
+ " "
+ extraMakeWrapperLuaArgs;
wrapRc = false;
}
home = {
packages = [ cfg.finalPackage ];
sessionVariables = mkIf cfg.defaultEditor {
EDITOR = "nvim";
VISUAL = "nvim";
};
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 = 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;
};
}
]
);
in
mkIf cfg.enable {
programs.neovim.generatedConfigViml = neovimConfig.neovimRcContent;
programs.neovim.generatedConfigs =
let
grouped = lib.lists.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;
home.packages = [ cfg.finalPackage ];
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "nvim"; };
home.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
xdg.configFile =
let
hasLuaConfig = lib.hasAttr "lua" config.programs.neovim.generatedConfigs;
in
lib.mkMerge (
# writes runtime
(map (x: x.runtime) pluginsNormalized)
++ [
{
"nvim/init.lua" =
let
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
mkIf (luaRcContent != "") { text = luaRcContent; };
"nvim/coc-settings.json" = mkIf cfg.coc.enable {
source = jsonFormat.generate "coc-settings.json" cfg.coc.settings;
};
}
]
);
programs.neovim.finalPackage = wrappedNeovim';
};
}
);
}

74
modules/programs/npm.nix Normal file
View File

@@ -0,0 +1,74 @@
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/programs/npm.nix
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.npm;
xdgConfigHome = lib.removePrefix config.home.homeDirectory config.xdg.configHome;
configFile = if config.home.preferXdgDirectories then "${xdgConfigHome}/npm/npmrc" else ".npmrc";
iniFormat = pkgs.formats.ini {
listsAsDuplicateKeys = true;
};
toNpmrc =
let
mkLine = lib.generators.mkKeyValueDefault { } "=";
mkLines = k: v: if lib.isList v then map (x: mkLine "${k}[]" x) v else [ (mkLine k v) ];
in
attrs: lib.concatLines (lib.concatLists (lib.mapAttrsToList mkLines attrs));
in
{
meta.maintainers = with lib.maintainers; [ mirkolenz ];
options = {
programs.npm = {
enable = lib.mkEnableOption "{command}`npm` user config";
package = lib.mkPackageOption pkgs [ "nodejs" ] {
example = "nodejs_24";
nullable = true;
};
settings = lib.mkOption {
type = lib.types.attrsOf iniFormat.lib.types.atom;
description = ''
The user-specific npm configuration.
See <https://docs.npmjs.com/cli/using-npm/config> and
<https://docs.npmjs.com/cli/configuring-npm/npmrc>
for more information.
'';
default = {
prefix = "\${HOME}/.npm";
};
example = lib.literalExpression ''
{
color = true;
include = [
"dev"
"prod"
];
init-license = "MIT";
prefix = "''${HOME}/.npm";
}
'';
};
};
};
config = lib.mkIf cfg.enable {
home = {
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
file.${configFile} = lib.mkIf (cfg.settings != { }) {
text = toNpmrc cfg.settings;
};
sessionVariables = lib.mkIf (cfg.settings != { }) {
NPM_CONFIG_USERCONFIG = "${config.home.homeDirectory}/${configFile}";
};
};
};
}

View File

@@ -0,0 +1,42 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkIf
mkEnableOption
mkOption
types
;
cfg = config.programs.parallel;
in
{
meta.maintainers = [ lib.maintainers.xavwe ];
options.programs.parallel = {
enable = mkEnableOption "GNU Parallel";
package = lib.mkPackageOption pkgs "parallel-full" { nullable = true; };
will-cite = mkOption {
type = types.bool;
default = false;
description = ''
Accept GNU Parallels citation policy: <https://www.gnu.org/software/parallel/parallel_design.html#citation-notice>
'';
};
};
config = mkIf cfg.enable {
home = {
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
file.".parallel/will-cite" = mkIf cfg.will-cite {
text = "generated by home manager (programs.parallel.will-cite)";
};
};
};
}

View File

@@ -51,7 +51,7 @@
localStorage = calendar: name: acc: {
name = "storage";
params = [ "${name}-local" ];
params = [ "${if calendar then "calendar" else "contacts"}-${name}-local" ];
children =
(attrsToDirectives {
inherit (acc.local) path;
@@ -63,7 +63,7 @@
remoteStorage = calendar: name: acc: {
name = "storage";
params = [ "${name}-remote" ];
params = [ "${if calendar then "calendar" else "contacts"}-${name}-remote" ];
children =
(attrsToDirectives {
inherit (acc.remote) url;
@@ -91,8 +91,8 @@
params = lib.singleton "${if calendar then "calendar" else "contacts"}-${name}";
children =
(attrsToDirectives {
storage_a = "${name}-local";
storage_b = "${name}-remote";
storage_a = "${if calendar then "calendar" else "contacts"}-${name}-local";
storage_b = "${if calendar then "calendar" else "contacts"}-${name}-remote";
})
++ acc.pimsync.extraPairDirectives;
};

View File

@@ -153,7 +153,7 @@ in
default = { };
apply = lib.mergeAttrs {
vfs-cache-mode = "full";
cache-dir = "%C";
cache-dir = "%C/rclone";
};
description = ''
An attribute set of option values passed to `rclone mount`. To set

View File

@@ -0,0 +1,55 @@
{
lib,
pkgs,
config,
...
}:
let
inherit (lib)
types
mkIf
mkEnableOption
mkPackageOption
mkOption
;
cfg = config.programs.screen;
in
{
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
options.programs.screen = {
enable = mkEnableOption "screen";
package = mkPackageOption pkgs "screen" { nullable = true; };
screenrc = mkOption {
type = with types; nullOr (either path lines);
default = null;
example = ''
screen -t rtorrent rtorrent
screen -t irssi irssi
screen -t centerim centerim
screen -t ncmpc ncmpc -c
screen -t bash4
screen -t bash5
screen -t bash6
screen -t bash7
screen -t bash8
screen -t bash9
altscreen on
term screen-256color
bind ',' prev
bind '.' next
'';
description = ''
Config file for GNU Screen. All the details can be found here:
<https://www.gnu.org/software/screen/manual/screen.html>.
'';
};
};
config = mkIf cfg.enable {
home.packages = mkIf (cfg.package != null) [ cfg.package ];
home.file.".screenrc" = mkIf (cfg.screenrc != null) {
source = if lib.isPath cfg.screenrc then cfg.screenrc else pkgs.writeText "screenrc" cfg.screenrc;
};
};
}

View File

@@ -52,7 +52,7 @@ in
eval "$(sheldon source)"
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
eval "$(sheldon source)"
'';

View File

@@ -30,44 +30,42 @@ let
mapAttrsToList (name: value: ''${name}="${lib.escape [ ''"'' "\\" ] (toString value)}"'') envStr
);
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 = {
mkAddressPortModule =
{
actionType,
nullableAddress ? actionType == "forward",
}:
types.submodule {
options = {
address = mkOption {
type = types.nullOr types.str;
default = null;
type = if nullableAddress then types.nullOr types.str else types.str;
default = if nullableAddress then null else "localhost";
example = "example.org";
description = "The address where to forward the traffic to.";
description = "The address to ${actionType} to.";
};
port = mkOption {
type = types.nullOr types.port;
default = null;
example = 80;
description = "Specifies port number to forward the traffic to.";
example = 8080;
description = "Specifies port number to ${actionType} 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 {
@@ -151,14 +149,7 @@ let
identityFile = mkOption {
type = with types; either (listOf str) (nullOr str);
default = [ ];
apply =
p:
if p == null then
[ ]
else if lib.isString p then
[ p ]
else
p;
apply = p: if p == null then [ ] else lib.toList p;
description = ''
Specifies files from which the user identity is read.
Identities will be tried in the given order.
@@ -168,14 +159,7 @@ let
identityAgent = mkOption {
type = with types; either (listOf str) (nullOr str);
default = [ ];
apply =
p:
if p == null then
[ ]
else if lib.isString p then
[ p ]
else
p;
apply = p: if p == null then [ ] else lib.toList p;
description = ''
Specifies the location of the ssh identity agent.
'';
@@ -265,14 +249,7 @@ let
certificateFile = mkOption {
type = with types; either (listOf str) (nullOr str);
default = [ ];
apply =
p:
if p == null then
[ ]
else if lib.isString p then
[ p ]
else
p;
apply = p: if p == null then [ ] else lib.toList p;
description = ''
Specifies files from which the user certificate is read.
'';
@@ -404,6 +381,18 @@ 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;
@@ -451,7 +440,16 @@ 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
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
++ optional (
cf.kexAlgorithms != null
) " KexAlgorithms ${builtins.concatStringsSep "," cf.kexAlgorithms}"
++ [
(lib.generators.toKeyValue {
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";
listsAsDuplicateKeys = true;
indent = " ";
} cf.extraOptions)
]
);
in

View File

@@ -106,13 +106,13 @@ in
];
programs.bash.initExtra = lib.mkIf cfg.enableBashIntegration ''
eval "$(${lib.getExe cfg.package} init bash)"
source ${cfg.package}/share/television/completion.bash
'';
programs.zsh.initContent = lib.mkIf cfg.enableZshIntegration ''
eval "$(${lib.getExe cfg.package} init zsh)"
source ${cfg.package}/share/television/completion.zsh
'';
programs.fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
${lib.getExe cfg.package} init fish | source
source ${cfg.package}/share/television/completion.fish
'';
};
}

View File

@@ -9,6 +9,7 @@ let
attrValues
concatStringsSep
filter
flatten
length
literalExpression
mapAttrsToList
@@ -918,7 +919,14 @@ in
calendarAccounts = getAccountsForProfile name enabledCalendarAccountsWithId;
contactAccounts = getAccountsForProfile name enabledContactAccountsWithId;
smtp = filter (a: a.smtp != null) emailAccounts;
accountsSmtp = filter (a: a.smtp != null) emailAccounts;
aliasesSmtp =
let
getAliasesWithSmtp = a: filter (al: builtins.isAttrs al && al.smtp != null) a.aliases;
getAliasesWithId = a: map (al: al // { id = getId a al; }) (getAliasesWithSmtp a);
in
flatten (map getAliasesWithId emailAccounts);
smtp = accountsSmtp ++ aliasesSmtp;
feedAccounts = addId (attrValues profile.feedAccounts);

51
modules/programs/ty.nix Normal file
View File

@@ -0,0 +1,51 @@
{
pkgs,
config,
lib,
...
}:
let
inherit (lib)
mkEnableOption
mkPackageOption
mkOption
literalExpression
;
tomlFormat = pkgs.formats.toml { };
cfg = config.programs.ty;
in
{
meta.maintainers = with lib.maintainers; [ mirkolenz ];
options.programs.ty = {
enable = mkEnableOption "ty";
package = mkPackageOption pkgs "ty" { nullable = true; };
settings = mkOption {
type = tomlFormat.type;
default = { };
example = literalExpression ''
{
rules.index-out-of-bounds = "ignore";
}
'';
description = ''
Configuration written to
{file}`$XDG_CONFIG_HOME/ty/ty.toml`.
See <https://docs.astral.sh/ty/configuration/>
and <https://docs.astral.sh/ty/reference/configuration/>
for more information.
'';
};
};
config = lib.mkIf cfg.enable {
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
xdg.configFile."ty/ty.toml" = lib.mkIf (cfg.settings != { }) {
source = tomlFormat.generate "ty-config.toml" cfg.settings;
};
};
}

View File

@@ -12,6 +12,7 @@ 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 ];
@@ -43,7 +44,12 @@ in
useLayerShell = lib.mkOption {
type = lib.types.bool;
default = true;
description = "If vicinae should use the layer shell";
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.
'';
};
extensions = lib.mkOption {
@@ -127,7 +133,7 @@ in
settings = lib.mkOption {
inherit (jsonFormat) type;
default = { };
description = "Settings written as JSON to `~/.config/vicinae/vicinae.json.";
description = "Settings written as JSON to `~/.config/vicinae/settings.json.";
example = lib.literalExpression ''
{
faviconService = "twenty";
@@ -158,6 +164,10 @@ 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 = (
{
@@ -223,10 +233,11 @@ in
source = themeFormat.generate "vicinae-${name}-theme" theme;
}
) cfg.themes;
settingsPath = if versionPost0_17 then "vicinae/settings.json" else "vicinae/vicinae.json";
in
{
configFile = {
"vicinae/vicinae.json" = lib.mkIf (cfg.settings != { }) {
"${settingsPath}" = lib.mkIf (cfg.settings != { }) {
source = jsonFormat.generate "vicinae-settings" cfg.settings;
};
}
@@ -250,14 +261,16 @@ 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

@@ -162,7 +162,8 @@ in
default = false;
description = ''
Whether to configure {command}`vim` as the default
editor using the {env}`EDITOR` environment variable.
editor using the {env}`EDITOR` and {env}`VISUAL`
environment variables.
'';
};
};
@@ -213,7 +214,10 @@ in
home.packages = [ cfg.package ];
home.sessionVariables = lib.mkIf cfg.defaultEditor { EDITOR = "vim"; };
home.sessionVariables = lib.mkIf cfg.defaultEditor {
EDITOR = "vim";
VISUAL = "vim";
};
programs.vim = {
package = vim;

View File

@@ -23,7 +23,10 @@ let
yamlFormat = pkgs.formats.yaml { };
in
{
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
meta.maintainers = [
lib.hm.maintainers.aguirre-matteo
lib.maintainers.arunoruto
];
options.programs.vivid = {
enable = mkEnableOption "vivid";
@@ -34,7 +37,14 @@ in
enableFishIntegration = mkFishIntegrationOption { inherit config; };
colorMode = mkOption {
type = with types; nullOr str;
type =
with types;
nullOr (
either str (enum [
"8-bit"
"24-bit"
])
);
default = null;
example = "8-bit";
description = ''
@@ -135,7 +145,7 @@ in
// (lib.mapAttrs' (
name: value:
lib.nameValuePair "vivid/themes/${name}.yml" {
source = if lib.isAttrs value then yamlFormat.generate "${name}.yml" value else value;
source = if lib.isAttrs value then pkgs.writeText "${name}.json" (builtins.toJSON value) else value;
}
) cfg.themes);

View File

@@ -2,6 +2,7 @@
config,
lib,
pkgs,
options,
...
}:
let
@@ -100,8 +101,17 @@ in
};
dotDir = mkOption {
default = homeDir;
defaultText = "`config.home.homeDirectory`";
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 = "`\${config.xdg.configHome}/zsh`";
description = ''
Directory where the zsh configuration and more should be located,
@@ -391,7 +401,24 @@ 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 != "") {
@@ -412,7 +439,7 @@ in
(mkIf (dotDirAbs != homeDir) {
home.file."${dotDirRel}/.zshenv".text = ''
export ZDOTDIR=${dotDirAbs}
${config.lib.zsh.export "ZDOTDIR" dotDirAbs}
'';
# When dotDir is set, only use ~/.zshenv to source ZDOTDIR/.zshenv,
@@ -420,7 +447,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 ${dotDirAbs}/.zshenv
source ${lib.escapeShellArg "${dotDirAbs}/.zshenv"}
'';
})

View File

@@ -1,9 +1,12 @@
{ config, lib, ... }:
let
cfg = config.programs.zsh;
stripSlash = lib.removeSuffix "/";
in
rec {
homeDir = config.home.homeDirectory;
# Raw home directory, no trailing slash.
homeDir = stripSlash config.home.homeDirectory;
/*
Escape a path string for shell usage and remove trailing slashes.
@@ -18,10 +21,11 @@ rec {
cleanPathStr "/path/to/dir/" => "'/path/to/dir'"
cleanPathStr "path with spaces" => "'path with spaces'"
*/
cleanPathStr = pathStr: lib.escapeShellArg (lib.removeSuffix "/" pathStr);
cleanPathStr = pathStr: lib.escapeShellArg (stripSlash 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.
@@ -30,19 +34,22 @@ rec {
Type: String -> String
Example:
mkRelPathStr "/home/user/config" => "'config'"
mkRelPathStr "config" => "'config'"
mkRelPathStr "/home/user/config" => "config"
mkRelPathStr "config" => "config"
mkRelPathStr "/home/user" => "."
mkRelPathStr "/etc/config" => <error>
*/
mkRelPathStr =
pathStr:
# 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
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
else
throw ''
Attempted to convert an absolute path not within home directory to a
@@ -54,47 +61,47 @@ rec {
'';
/*
Convert a relative path to an absolute path by prepending the home directory.
Convert a relative path to an absolute path.
Returns RAW path (unescaped).
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: cleanPathStr ((lib.optionalString (!lib.hasPrefix "/" pathStr) "${homeDir}/") + pathStr);
pathStr:
let
normPath = stripSlash pathStr;
in
if lib.hasPrefix "/" normPath then normPath else "${homeDir}/${normPath}";
/*
Convert a path to absolute form while preserving shell variables for runtime expansion.
Convert a path to absolute form while preserving shell variables.
Returns RAW path (unescaped) unless vars are present (then preserves vars).
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 and properly escaped for shell usage.
Literal paths are made absolute.
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
cleanPath = lib.removeSuffix "/" pathStr;
hasShellVars = lib.hasInfix "$" cleanPath;
normPath = stripSlash pathStr;
hasShellVars = lib.hasInfix "$" normPath;
in
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);
if hasShellVars then normPath else mkAbsPathStr normPath;
dotDirAbs = mkAbsPathStr cfg.dotDir;
dotDirRel = mkRelPathStr cfg.dotDir;
@@ -107,5 +114,5 @@ rec {
Type: String
*/
pluginsDir = dotDirAbs + (lib.optionalString (homeDir == dotDirAbs) "/.zsh") + "/plugins";
pluginsDir = dotDirAbs + (lib.optionalString (mkRelPathStr cfg.dotDir == ".") "/.zsh") + "/plugins";
}

266
modules/services/colima.nix Normal file
View File

@@ -0,0 +1,266 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.colima;
yamlFormat = pkgs.formats.yaml { };
in
{
meta.maintainers = [
lib.hm.maintainers.will-lol
];
options.services.colima = {
enable = lib.mkEnableOption "Colima, a container runtime";
package = lib.mkPackageOption pkgs "colima" { };
dockerPackage = lib.mkPackageOption pkgs "docker" {
extraDescription = "Used by colima to activate profiles. Not needed if no profile is set to isActive.";
};
perlPackage = lib.mkPackageOption pkgs "perl" {
extraDescription = "Used by colima during image download for the shasum command.";
};
sshPackage = lib.mkPackageOption pkgs "openssh" {
extraDescription = "Used by colima to manage the vm.";
};
coreutilsPackage = lib.mkPackageOption pkgs "coreutils" {
extraDescription = "Used in various ways by colima.";
};
curlPackage = lib.mkPackageOption pkgs "curl" {
extraDescription = "Used by colima to donwload images.";
};
bashPackage = lib.mkPackageOption pkgs "bashNonInteractive" {
extraDescription = "Used by colima's internal scripts.";
};
profiles = lib.mkOption {
default = {
default = {
isActive = true;
isService = true;
};
};
description = ''
Profiles allow multiple colima configurations. The default profile is active by default.
If you have used colima before, you may need to delete existing configuration using `colima delete` or use a different profile.
Note that removing a configured profile will not delete the corresponding Colima instance.
You will need to manually run `colima delete <profile-name>` to remove the instance and release resources.
'';
example = ''
{
default = {
isActive = true;
isService = true;
};
rosetta = {
isService = true;
settings.rosetta = true;
};
powerful = {
settings.cpu = 8;
};
};
'';
type = lib.types.attrsOf (
lib.types.submodule (
{ name, ... }:
{
options = {
name = lib.mkOption {
type = lib.types.str;
default = name;
readOnly = true;
description = "The profile's name.";
};
isService = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
Whether this profile will run as a service.
'';
};
isActive = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
Whether to set this profile as:
- active docker context
- active kubernetes context
- active incus remote
Exactly one or zero profiles should have this option set.
'';
};
logFile = lib.mkOption {
type = lib.types.path;
default = "${config.home.homeDirectory}/.local/state/colima-${name}.log";
defaultText = lib.literalExpression "\${config.home.homeDirectory}/.local/state/colima-\${name}.log";
description = "Combined stdout and stderr log file for the Colima service.";
};
settings = lib.mkOption {
inherit (yamlFormat) type;
default = { };
description = "Colima configuration settings, see <https://github.com/abiosoft/colima/blob/main/embedded/defaults/colima.yaml> or run `colima template`.";
example = ''
{
cpu = 2;
disk = 100;
memory = 2;
arch = "host";
runtime = "docker";
hostname = null;
kubernetes = {
enabled = false;
version = "v1.33.3+k3s1";
k3sArgs = [ "--disable=traefik" ];
port = 0;
};
autoActivate = true;
network = {
address = false;
mode = "shared";
interface = "en0";
preferredRoute = false;
dns = [ ];
dnsHosts = {
"host.docker.internal" = "host.lima.internal";
};
hostAddresses = false;
};
forwardAgent = false;
docker = { };
vmType = "qemu";
portForwarder = "ssh";
rosetta = false;
binfmt = true;
nestedVirtualization = false;
mountType = "sshfs";
mountInotify = false;
cpuType = "host";
provision = [ ];
sshConfig = true;
sshPort = 0;
mounts = [ ];
diskImage = "";
rootDisk = 20;
env = { };
}
'';
};
};
}
)
);
};
};
config = lib.mkIf cfg.enable ({
assertions = [
{
assertion = (lib.count (p: p.isActive) (lib.attrValues cfg.profiles)) <= 1;
message = "Only one Colima profile can be active at a time.";
}
];
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
home.file = lib.mkMerge (
lib.mapAttrsToList (profileName: profile: {
".colima/${profileName}/colima.yaml" = {
source = yamlFormat.generate "colima.yaml" profile.settings;
};
}) (lib.filterAttrs (name: profile: profile.settings != { }) cfg.profiles)
);
programs.docker-cli.settings.currentContext =
let
activeProfile = lib.findFirst (p: p.isActive) null (lib.attrValues cfg.profiles);
in
lib.mkIf (activeProfile != null) (
if activeProfile.name != "default" then "colima-${activeProfile.name}" else "colima"
);
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.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,6 +117,8 @@ in
systemd.user.services.easyeffects = {
Unit = {
Description = "Easyeffects daemon";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Install.WantedBy = [ "graphical-session.target" ];

View File

@@ -113,7 +113,8 @@ in
example = !default;
description = ''
Whether to configure {command}`emacsclient` as the default
editor using the {env}`EDITOR` environment variable.
editor using the {env}`EDITOR` and {env}`VISUAL`
environment variables.
'';
};
};
@@ -121,11 +122,16 @@ in
config = mkIf cfg.enable (
lib.mkMerge [
{
home.sessionVariables = mkIf cfg.defaultEditor {
EDITOR = lib.getBin (
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
);
};
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;
};
}
(mkIf pkgs.stdenv.isLinux {

View File

@@ -0,0 +1,86 @@
{
lib,
pkgs,
config,
...
}:
let
inherit (lib)
mkIf
mkEnableOption
mkPackageOption
mkOption
;
cfg = config.services.hyprlauncher;
in
{
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
options.services.hyprlauncher = {
enable = mkEnableOption "hyprlauncher";
package = mkPackageOption pkgs "hyprlauncher" { nullable = true; };
settings = mkOption {
type =
with lib.types;
let
valueType =
nullOr (oneOf [
bool
int
float
str
path
(attrsOf valueType)
(listOf valueType)
])
// {
description = "Hyprland configuration value";
};
in
valueType;
default = { };
example = {
general.grab_focus = true;
cache.enabled = true;
ui.window_size = "400 260";
finders = {
math_prefix = "=";
desktop_icons = true;
};
};
description = ''
Configuration settings for hyprlauncher. All the available options can be found here:
<https://wiki.hypr.land/Hypr-Ecosystem/hyprlauncher/#config>
'';
};
};
config = mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.hyprlauncher" pkgs lib.platforms.linux)
];
home.packages = mkIf (cfg.package != null) [ cfg.package ];
xdg.configFile."hypr/hyprlauncher.conf" = mkIf (cfg.settings != { }) {
text = lib.hm.generators.toHyprconf { attrs = cfg.settings; };
};
systemd.user.services.hyprlauncher = mkIf (cfg.package != null) {
Install.WantedBy = [ config.wayland.systemd.target ];
Unit = {
Description = "hyprlauncher";
After = [ config.wayland.systemd.target ];
PartOf = [ config.wayland.systemd.target ];
X-Restart-Triggers = lib.mkIf (cfg.settings != { }) [
"${config.xdg.configFile."hypr/hyprlauncher.conf".source}"
];
};
Service = {
ExecStart = "${lib.getExe cfg.package} -d";
Restart = "always";
RestartSec = "10";
};
};
};
}

View File

@@ -49,9 +49,17 @@ in
default = {
manifest.url = "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml";
roots = [ ];
backup.path = "$XDG_STATE_HOME/backups/ludusavi";
restore.path = "$XDG_STATE_HOME/backups/ludusavi";
backup.path = "${config.xdg.stateHome}/backups/ludusavi";
restore.path = "${config.xdg.stateHome}/backups/ludusavi";
};
defaultText = ''
{
manifest.url = "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml";
roots = [ ];
backup.path = "$XDG_STATE_HOME/backups/ludusavi";
restore.path = "$XDG_STATE_HOME/backups/ludusavi";
}
'';
example = {
language = "en-US";
theme = "light";
@@ -94,6 +102,24 @@ in
Service = {
Type = "oneshot";
ExecStart = "${lib.getExe cfg.package} backup --force";
ExecStartPre = "${pkgs.writeShellScript "ludusavi-migrate-backup" ''
old_base_dir="${config.home.homeDirectory}/\$XDG_STATE_HOME"
old_dir="$old_base_dir/backups/ludusavi"
new_base_dir="${config.xdg.stateHome}/backups"
new_dir="$new_base_dir/ludusavi"
if [[ -d "$old_base_dir" ]]; then
echo "Migrating old Ludusavi's backup... (See home-manager/#8234)"
if [[ ! -d "$new_base_dir" ]]; then
mkdir -p "$new_base_dir"
fi
mv "$old_dir" "$new_dir"
rmdir "$old_base_dir/backups"
rmdir "$old_base_dir"
echo "Migration completed successfully."
fi
''}";
}
// lib.optionalAttrs cfg.backupNotification {
ExecStartPost = "${lib.getExe pkgs.libnotify} 'Ludusavi' 'Backup completed' -i com.mtkennerly.ludusavi -a 'Ludusavi'";

View File

@@ -43,6 +43,7 @@ in
Description = "pimsync calendar and contacts synchronization";
PartOf = [ "network-online.target" ];
};
Install.WantedBy = [ "default.target" ];
Service = {
# TODO: make use of the readiness notification
Type = "simple";

View File

@@ -475,7 +475,7 @@ in
CacheDirectoryMode = "0700";
PrivateTmp = true;
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C" ];
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C/${serviceName}" ];
ExecStart =
lib.optional doBackup backupCmd
@@ -591,7 +591,7 @@ in
lib.concatLines
]}
RESTIC_CACHE_DIR=$HOME/.cache/${serviceName}
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
PATH=${
lib.pipe environment [

View File

@@ -67,6 +67,8 @@ in
(lib.hm.assertions.assertPlatform "services.shikane" pkgs lib.platforms.linux)
];
home.packages = [ cfg.package ];
xdg.configFile."shikane/config.toml" = lib.mkIf (cfg.settings != { }) {
source = tomlFormat.generate "shikane-config" cfg.settings;
};

View File

@@ -7,6 +7,7 @@
let
cfg = config.services.snixembed;
waybarCfg = config.programs.waybar;
in
{
meta.maintainers = [ lib.maintainers.DamienCassou ];
@@ -32,6 +33,10 @@ in
assertions = [
(lib.hm.assertions.assertPlatform "services.snixembed" pkgs lib.platforms.linux)
];
warnings = lib.optional waybarCfg.enable ''
snixembed and waybar should not be enabled at the same time.
You may experience inconsistent tray behavior as a result.
'';
systemd.user.services.snixembed = {
Install.WantedBy = [ "graphical-session.target" ];

View File

@@ -84,13 +84,11 @@ in
'';
in
{
bash.initExtra = lib.mkIf cfg.enableBashIntegration bashIntegration;
zsh.initContent = lib.mkIf cfg.enableZshIntegration bashIntegration;
fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration fishIntegration;
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration nushellIntegration;
# $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);
};
}

View File

@@ -42,21 +42,30 @@ in
};
};
eventModule = {
eventsModule = {
options = {
event = mkOption {
type = types.enum [
"before-sleep"
"after-resume"
"lock"
"unlock"
];
description = "Event name.";
before-sleep = mkOption {
type = types.nullOr types.str;
default = null;
description = "Command to run before suspending.";
};
command = mkOption {
type = types.str;
description = "Command to run when event occurs.";
after-resume = mkOption {
type = types.nullOr types.str;
default = null;
description = "Command to run after resuming.";
};
lock = mkOption {
type = types.nullOr types.str;
default = null;
description = "Command to run when the logind session is locked.";
};
unlock = mkOption {
type = types.nullOr types.str;
default = null;
description = "Command to run when the logind session is unlocked.";
};
};
};
@@ -80,13 +89,31 @@ in
};
events = mkOption {
type = with types; listOf (submodule eventModule);
default = [ ];
type =
with types;
(coercedTo (listOf attrs)) (
events:
lib.warn
''
The syntax of services.swayidle.events has changed. While it
previously accepted a list of events, it now accepts an attrset
keyed by the event name.
''
(
lib.listToAttrs (
map (e: {
name = e.event;
value = e.command;
}) events
)
)
) (submodule eventsModule);
default = { };
example = literalExpression ''
[
{ event = "before-sleep"; command = "''${pkgs.swaylock}/bin/swaylock -fF"; }
{ event = "lock"; command = "lock"; }
]
{
"before-sleep" = "''${pkgs.swaylock}/bin/swaylock -fF";
"lock" = "lock";
}
'';
description = "Run command on occurrence of a event.";
};
@@ -144,13 +171,17 @@ in
t.resumeCommand
];
mkEvent = e: [
e.event
e.command
mkEvent = event: command: [
event
command
];
nonemptyEvents = lib.filterAttrs (event: command: command != null) cfg.events;
args =
cfg.extraArgs ++ (lib.concatMap mkTimeout cfg.timeouts) ++ (lib.concatMap mkEvent cfg.events);
cfg.extraArgs
++ (lib.concatMap mkTimeout cfg.timeouts)
++ (lib.flatten (lib.mapAttrsToList mkEvent nonemptyEvents));
in
"${lib.getExe cfg.package} ${lib.escapeShellArgs args}";
};

View File

@@ -8,7 +8,7 @@ let
cfg = config.services.tldr-update;
in
{
meta.maintainers = [ lib.maintainers.perchun ];
meta.maintainers = [ lib.maintainers.PerchunPak ];
options.services.tldr-update = {
enable = lib.mkEnableOption ''

View File

@@ -119,6 +119,24 @@ in
{file}`$XDG_CONFIG_HOME/herbstluftwm/autostart`.
'';
};
enableAlias = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Set an alias for the {command}`herbstclient` command in the
{file}`autostart` script that only stores its arguments and executes
them all at once at the end of the {file}`autostart` script.
This reduces the amount of flickering you get while all options are
being applied and improves the performance.
On the other hand, this makes it more difficult to write bash functions
that call {command}`herbstclient`. You can work around this by calling
{command}`command herbstclient` in your functions to still get some of
the benefits of enabling this alias.
'';
};
};
config = lib.mkIf cfg.enable {
@@ -131,11 +149,13 @@ in
xsession.windowManager.command = "${cfg.package}/bin/herbstluftwm --locked";
xdg.configFile."herbstluftwm/autostart".source = pkgs.writeShellScript "herbstluftwm-autostart" ''
shopt -s expand_aliases
${lib.optionalString cfg.enableAlias ''
shopt -s expand_aliases
# shellcheck disable=SC2142
alias herbstclient='set -- "$@" ";"'
set --
# shellcheck disable=SC2142
alias herbstclient='set -- "$@" ";"'
set --
''}
herbstclient emit_hook reload
@@ -169,7 +189,9 @@ in
herbstclient unlock
${cfg.package}/bin/herbstclient chain ";" "$@"
${lib.optionalString cfg.enableAlias ''
${cfg.package}/bin/herbstclient chain ";" "$@"
''}
'';
};
}

View File

@@ -81,7 +81,7 @@
drivers = mkOption {
type = types.package;
readOnly = true;
internal = true;
description = "Resulting drivers package.";
};
};
@@ -104,14 +104,9 @@
kernel = null;
};
drivers = cfg.packages.callPackage ./gpu-libs-env.nix {
addNvidia = cfg.nvidia.enable;
nvidia_x11 = nvidia; # Only used if addNvidia is enabled
};
setupPackage = cfg.packages.callPackage ./setup {
inherit (cfg) nixStateDirectory;
nonNixosGpuEnv = drivers;
nonNixosGpuEnv = cfg.drivers;
};
in
lib.mkIf cfg.enable {
@@ -148,7 +143,7 @@
in
lib.hm.dag.entryAnywhere ''
existing=$(readlink /run/opengl-driver || true)
new=${drivers}
new=${cfg.drivers}
verboseEcho Existing drivers: ''${existing}
verboseEcho New drivers: ''${new}
if [[ -z "''${existing}" ]] ; then
@@ -162,7 +157,13 @@
'';
targets.genericLinux.gpu = {
inherit setupPackage drivers;
inherit setupPackage;
drivers = cfg.packages.callPackage ./gpu-libs-env.nix {
inherit (pkgs.stdenv.hostPlatform) system;
addNvidia = cfg.nvidia.enable;
nvidia_x11 = nvidia; # Only used if addNvidia is enabled
};
};
};

View File

@@ -6,6 +6,7 @@
intel-media-driver,
nvidia-vaapi-driver,
linuxPackages,
system,
nvidia_x11 ? linuxPackages.nvidia_x11,
addNvidia ? false,
}:
@@ -15,8 +16,8 @@ buildEnv {
paths = [
mesa
libvdpau-va-gl
intel-media-driver
]
++ lib.optional (system == "x86_64-linux") intel-media-driver
++ lib.optionals addNvidia [
nvidia_x11
nvidia-vaapi-driver

View File

@@ -274,6 +274,26 @@ 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

@@ -188,10 +188,13 @@ in
hm-graphical-session = {
Unit = {
Description = "Home Manager X session";
Requires = [
"graphical-session-pre.target"
"xdg-desktop-autostart.target"
];
Requires =
let
requires = lib.optional (config.xdg.autostart.enable) "xdg-desktop-autostart.target" ++ [
"graphical-session-pre.target"
];
in
requires;
BindsTo = [
"graphical-session.target"
"tray.target"

View File

@@ -2,7 +2,6 @@
# For OS-specific configuration, please edit nixos/default.nix or nix-darwin/default.nix instead.
{
options,
config,
lib,
pkgs,
@@ -36,7 +35,7 @@ let
modules = [
(
{ name, ... }:
{ name, options, ... }:
{
imports =
import ../modules/modules.nix {
@@ -48,22 +47,31 @@ let
++ cfg.sharedModules;
config = {
submoduleSupport.enable = true;
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
submoduleSupport = {
enable = true;
externalPackageInstall = cfg.useUserPackages;
};
home.username = config.users.users.${name}.name;
home.homeDirectory = config.users.users.${name}.home;
home = {
username = config.users.users.${name}.name;
homeDirectory = config.users.users.${name}.home;
uid = mkIf (options.users.users.${name}.uid.isDefined or false) config.users.users.${name}.uid;
};
# Forward `nix.enable` from the OS configuration. The
# conditional is to check whether nix-darwin is new enough
# to have the `nix.enable` option; it was previously a
# `mkRemovedOptionModule` error, which we can crudely detect
# by `visible` being set to `false`.
nix.enable = mkIf (options.nix.enable.visible or true) config.nix.enable;
nix = {
# Forward `nix.enable` from the OS configuration. The
# conditional is to check whether nix-darwin is new enough
# to have the `nix.enable` option; it was previously a
# `mkRemovedOptionModule` error, which we can crudely detect
# by `visible` being set to `false`.
enable = mkIf (options.nix.enable.visible or true) config.nix.enable;
# Make activation script use same version of Nix as system as a whole.
# This avoids problems with Nix not being in PATH.
nix.package = config.nix.package;
# Make activation script use same version of Nix as system as a whole.
# This avoids problems with Nix not being in PATH.
# Only set package when nix is enabled to avoid errors when
# nix-darwin has nix.enable = false (e.g., Determinate Nix users).
package = mkIf config.nix.enable config.nix.package;
};
};
}
)
@@ -85,7 +93,7 @@ in
backupCommand = mkOption {
type = types.nullOr (types.either types.str types.path);
default = null;
example = lib.literalExpression "''${pkgs.trash-cli}/bin/trash";
example = lib.literalExpression "\${pkgs.trash-cli}/bin/trash";
description = ''
On activation run this command on each existing file
rather than exiting with an error.
@@ -160,30 +168,28 @@ in
};
};
config = (
lib.mkMerge [
# Fix potential recursion when configuring home-manager users based on values in users.users #594
(mkIf (cfg.useUserPackages && cfg.users != { }) {
users.users = (lib.mapAttrs (_username: usercfg: { packages = [ usercfg.home.path ]; }) cfg.users);
environment.pathsToLink = [ "/etc/profile.d" ];
})
(mkIf (cfg.users != { }) {
warnings = lib.flatten (
flip lib.mapAttrsToList cfg.users (
user: config: flip map config.warnings (warning: "${user} profile: ${warning}")
)
);
config = lib.mkMerge [
# Fix potential recursion when configuring home-manager users based on values in users.users #594
(mkIf (cfg.useUserPackages && cfg.users != { }) {
users.users = lib.mapAttrs (_username: usercfg: { packages = [ usercfg.home.path ]; }) cfg.users;
environment.pathsToLink = [ "/etc/profile.d" ];
})
(mkIf (cfg.users != { }) {
warnings = lib.flatten (
flip lib.mapAttrsToList cfg.users (
user: config: flip map config.warnings (warning: "${user} profile: ${warning}")
)
);
assertions = lib.flatten (
flip lib.mapAttrsToList cfg.users (
user: config:
flip map config.assertions (assertion: {
inherit (assertion) assertion;
message = "${user} profile: ${assertion.message}";
})
)
);
})
]
);
assertions = lib.flatten (
flip lib.mapAttrsToList cfg.users (
user: config:
flip map config.assertions (assertion: {
inherit (assertion) assertion;
message = "${user} profile: ${assertion.message}";
})
)
);
})
];
}

View File

@@ -1,4 +1,4 @@
{
"release": "25.11",
"release": "26.05",
"isReleaseBranch": false
}

View File

@@ -27,6 +27,7 @@ let
"broot"
"browserpass"
"btop"
"calibre"
"carapace"
"cava"
"claude-code"
@@ -96,6 +97,7 @@ let
"lf"
"lieer"
"lsd"
"ludusavi"
"mbsync"
"meli"
"mergiraf"

View File

@@ -130,6 +130,13 @@ 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

@@ -27,6 +27,7 @@ let
standalone-flake-basics = runTest ./standalone/flake-basics.nix;
standalone-specialisation = runTest ./standalone/specialisation.nix;
standalone-standard-basics = runTest ./standalone/standard-basics.nix;
dconf = runTest ./standalone/dconf.nix;
};
in
tests

View File

@@ -0,0 +1,22 @@
{ pkgs, ... }:
{
home.username = "alice";
home.homeDirectory = "/home/alice";
home.stateVersion = "25.11"; # Please read the comment before changing.
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
dconf.settings = {
foo = {
bar = 42;
};
};
dconf.databases.custom = {
foo1 = {
bar1 = 42;
};
};
}

View File

@@ -0,0 +1,77 @@
{ pkgs, ... }:
{
name = "dconf";
meta.maintainers = [ pkgs.lib.maintainers.rycee ];
nodes.machine = {
imports = [ "${pkgs.path}/nixos/modules/installer/cd-dvd/channel.nix" ];
virtualisation.memorySize = 2048;
users.users.alice = {
isNormalUser = true;
description = "Alice Foobar";
password = "foobar";
uid = 1000;
};
programs.dconf = {
enable = true;
profiles.custom = pkgs.writeText "dconf-profile-custom" ''
user-db:custom
'';
};
};
testScript = ''
start_all()
machine.wait_for_unit("network.target")
machine.wait_for_unit("multi-user.target")
home_manager = "${../../..}"
def login_as_alice():
machine.wait_until_tty_matches("1", "login: ")
machine.send_chars("alice\n")
machine.wait_until_tty_matches("1", "Password: ")
machine.send_chars("foobar\n")
machine.wait_until_tty_matches("1", "alice\\@machine")
def logout_alice():
machine.send_chars("exit\n")
def alice_cmd(cmd):
return f"su -l alice --shell /bin/sh -c $'export XDG_RUNTIME_DIR=/run/user/$UID ; {cmd}'"
def succeed_as_alice(cmd):
return machine.succeed(alice_cmd(cmd))
def fail_as_alice(cmd):
return machine.fail(alice_cmd(cmd))
# Create a persistent login so that Alice has a systemd session.
login_as_alice()
# Set up a home-manager channel.
succeed_as_alice(" ; ".join([
"mkdir -p /home/alice/.nix-defexpr/channels",
f"ln -s {home_manager} /home/alice/.nix-defexpr/channels/home-manager"
]))
succeed_as_alice("nix-shell \"<home-manager>\" -A install")
succeed_as_alice("cp ${./dconf-home.nix} /home/alice/.config/home-manager/home.nix")
succeed_as_alice("home-manager switch")
succeed_as_alice("test -e /home/alice/.config/dconf/user")
actual = succeed_as_alice("dconf dump /")
expected = """[foo]
bar=42
"""
assert actual == expected, "invalid content in dconf database \"user\""
succeed_as_alice("test -e /home/alice/.config/dconf/custom")
actual = succeed_as_alice("DCONF_PROFILE=custom dconf dump /")
expected = """[foo1]
bar1=42
"""
assert actual == expected, "invalid content in dconf database \"custom\""
'';
}

View File

@@ -216,7 +216,7 @@ in
def make_backup(time):
global snapshot_count
machine.succeed(f"timedatectl set-time '{time}'")
machine.succeed(f"date --set='{time}'")
systemctl_succeed_as_alice("start restic-backups-prune-me.service")
snapshot_count += 1
actual = \

View File

@@ -2,4 +2,7 @@
home-session-path = ./session-path.nix;
home-session-search-variables = ./session-search-variables.nix;
home-session-variables = ./session-variables.nix;
home-nixpkgs-release-check-pkgs = ./nixpkgs-release-check-pkgs.nix;
home-uid = ./uid.nix;
home-uid-null = ./uid-null.nix;
}

View File

@@ -0,0 +1,39 @@
{ lib, ... }:
let
releaseInfo = lib.importJSON ../../../release.json;
hmRelease = releaseInfo.release;
pkgsRelease = "<invalid>";
in
{
test.asserts.warnings.expected = [
''
You are using
Home Manager version: ${hmRelease}
Nixpkgs version used to evaluate Home Manager: ${hmRelease}
Nixpkgs version used for packages (`pkgs`): ${pkgsRelease}
Using mismatched versions is likely to cause errors and unexpected
behavior. It is therefore highly recommended to use a release of Home
Manager that corresponds with your chosen release of Nixpkgs.
If you insist then you can disable this warning by adding
home.enableNixpkgsReleaseCheck = false;
to your configuration.
''
];
nixpkgs.overlays = [
(final: prev: {
lib = prev.lib.extend (
final: prev: {
trivial = prev.trivial // {
release = pkgsRelease;
};
}
);
})
];
}

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