Compare commits

..

16 Commits

Author SHA1 Message Date
Aguirre Matteo
2bd0a86493 rclone: change cache directory to $XDG_CACHE_HOME/rclone
(cherry picked from commit df7bac2b2b)
2025-12-04 23:33:48 +00:00
tsrk.
f63d0fe9d8 thunderbird: fix aliases SMTP configuration not being listed as usable
Signed-off-by: tsrk. <tsrk@tsrk.me>
(cherry picked from commit d441981b20)
2025-12-04 10:34:05 -06:00
Andrew Jeffery
e1680d594a 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.

(cherry picked from commit 43173abcb4)
2025-12-03 16:49:19 +01:00
home-manager-ci[bot]
3366918730 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/9561691c9f450fad7c3526916e1c4f44be0d1192?narHash=sha256-CYbMp8hwuOf4umokSNp%2Bt1s4Hjd4vxXq4S5CD%2BxvgNs%3D' (2025-11-29)
  → 'github:NixOS/nixpkgs/8bb5646e0bed5dbd3ab08c7a7cc15b75ab4e1d0f?narHash=sha256-SqUuBFjhl/kpDiVaKLQBoD8TLD%2B/cTUzzgVFoaHrkqY%3D' (2025-11-30)
2025-12-02 22:41:12 -06:00
Anton Mosich
7385f250cc 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.

(cherry picked from commit c3d1e5c65a)
2025-12-02 21:33:04 -06:00
Anton Mosich
9ea0c94e00 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
(cherry picked from commit bf003999ed)
2025-12-02 21:33:04 -06:00
dependabot[bot]
f3902b5d87 ci: bump DeterminateSystems/update-flake-lock from 27 to 28
Bumps [DeterminateSystems/update-flake-lock](https://github.com/determinatesystems/update-flake-lock) from 27 to 28.
- [Release notes](https://github.com/determinatesystems/update-flake-lock/releases)
- [Commits](https://github.com/determinatesystems/update-flake-lock/compare/v27...v28)

---
updated-dependencies:
- dependency-name: DeterminateSystems/update-flake-lock
  dependency-version: '28'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 12:22:16 -06:00
novenary
44a3b79aad 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)
(cherry picked from commit e4e25a8c31)
2025-12-01 12:21:54 -06:00
novenary
ffae9e1bca Revert "fish: avoid shadowing builtin completions"
This reverts commit 23f2ba7ae0.

(cherry picked from commit 13b089b586)
2025-12-01 12:21:54 -06:00
Jo²
acd2931703 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.

(cherry picked from commit b1bb534c17)
2025-12-01 12:21:32 -06:00
Matt Sturgeon
3fdd076e08 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.

(cherry picked from commit 23f2ba7ae0)
2025-11-30 15:00:51 -06:00
home-manager-ci[bot]
ba2259d7d5 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/2fecba9952096ba043c16b9ef40b92851ff3e5d9?narHash=sha256-JaNFPy3nywPNxSDpEgFFqvngQww5Igb6twG4NhMo8oc%3D' (2025-11-26)
  → 'github:NixOS/nixpkgs/9561691c9f450fad7c3526916e1c4f44be0d1192?narHash=sha256-CYbMp8hwuOf4umokSNp%2Bt1s4Hjd4vxXq4S5CD%2BxvgNs%3D' (2025-11-29)
2025-11-30 14:18:28 -06:00
Austin Horstman
d0c5fdc48d tests/flake: lock to stable
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-29 00:48:34 -06:00
home-manager-ci[bot]
7f7e33a679 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/a320ce8e6e2cc6b4397eef214d202a50a4583829?narHash=sha256-6zddwDs2n%2Bn01l%2B1TG6PlyokDdXzu/oBmEejcH5L5%2BA%3D' (2025-11-24)
  → 'github:NixOS/nixpkgs/2fecba9952096ba043c16b9ef40b92851ff3e5d9?narHash=sha256-JaNFPy3nywPNxSDpEgFFqvngQww5Igb6twG4NhMo8oc%3D' (2025-11-26)
2025-11-29 00:48:34 -06:00
Austin Horstman
2217780c39 flake.nix: lock to stable branch
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 11:18:11 -06:00
Austin Horstman
cbe30a7689 release: mark as release branch
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-11-26 10:44:25 -06:00
179 changed files with 726 additions and 3387 deletions

View File

@@ -7,9 +7,10 @@ updates:
interval: "weekly"
commit-message:
prefix: "ci:"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "release-25.11"
target-branch: "release-25.05"
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@v4
uses: korthout/backport-action@v3
with:
# See https://github.com/korthout/backport-action#inputs
github_token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}

View File

@@ -9,9 +9,8 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name != 'schedule' || github.repository_owner == 'nix-community'
strategy:
fail-fast: false
matrix:
branch: [master, release-25.11]
branch: [master, release-25.05]
steps:
- name: Create GitHub App token
uses: actions/create-github-app-token@v2

View File

@@ -121,22 +121,6 @@ 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)
@@ -166,37 +150,6 @@ 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,11 +361,6 @@
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";
};
@@ -634,13 +629,6 @@
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";
@@ -2078,7 +2066,7 @@
source = "nixpkgs";
};
shikanime = {
email = "william.phetsinorath@shikanime.studio";
email = "deva.shikanime@protonmail.com";
github = "shikanime";
githubId = 22115108;
name = "William Phetsinorath";
@@ -2316,13 +2304,6 @@
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": 1764081664,
"narHash": "sha256-sUoHmPr/EwXzRMpv1u/kH+dXuvJEyyF2Q7muE+t0EU4=",
"lastModified": 1743938762,
"narHash": "sha256-UgFYn8sGv9B8PoFpUfCa43CjMZBl1x/ShQhRDHBFQdI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dc205f7b4fdb04c8b7877b43edb7b73be7730081",
"rev": "74a40410369a1c35ee09b8a1abee6f4acbedc059",
"type": "github"
},
"original": {

View File

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

View File

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

@@ -1,17 +0,0 @@
# 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.

8
flake.lock generated
View File

@@ -2,16 +2,16 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1766070988,
"narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=",
"lastModified": 1764522689,
"narHash": "sha256-SqUuBFjhl/kpDiVaKLQBoD8TLD+/cTUzzgVFoaHrkqY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c6245e83d836d0433170a16eb185cefe0572f8b8",
"rev": "8bb5646e0bed5dbd3ab08c7a7cc15b75ab4e1d0f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}

View File

@@ -1,7 +1,7 @@
{
description = "Home Manager for Nix";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
outputs =
{

View File

@@ -1277,7 +1277,7 @@ while [[ $# -gt 0 ]]; do
export VERBOSE=1
;;
--version)
echo 26.05-pre
echo 25.11-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-11-30 14:00+0000\n"
"PO-Revision-Date: 2025-08-23 20:02+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.15-dev\n"
"X-Generator: Weblate 5.13\n"
#. translators: For example: "home-manager: missing argument for --cores"
#: home-manager/home-manager:16
msgid "%s: missing argument for %s"
msgstr "%s: manglar eitt ávirki fyri %s"
msgstr ""
#. 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 "Eingin samansetingsfíla funni hjá %s"
msgstr ""
#. 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-12-04 04:17+0000\n"
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
"PO-Revision-Date: 2025-03-07 18:58+0000\n"
"Last-Translator: 807 <s10855168@gmail.com>\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.15-dev\n"
"X-Generator: Weblate 5.10.3-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 "%s%s 只能在 %s 之後使用"
msgstr ""
#: 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` 參數來指定路徑:\n"
" 如果你想要直接引入Home Manager 請你使用 `path` 參數r\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 "找不到合適的設定檔目錄,已嘗試 %s 和 %s"
msgstr "找不到合適的 profile 目錄,已嘗試 %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 "設定中不包含特化設定 \"%s\""
msgstr ""
#: 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

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

View File

@@ -193,13 +193,6 @@ 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 ''
@@ -577,25 +570,14 @@ in
warnings =
let
hmRelease = config.home.version.release;
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}'';
nixpkgsRelease = lib.trivial.release;
releaseMismatch = config.home.enableNixpkgsReleaseCheck && hmRelease != nixpkgsRelease;
in
lib.optional (config.home.enableNixpkgsReleaseCheck && releaseMismatch) ''
lib.optional releaseMismatch ''
You are using
${lib.replaceString "\n" "\n " versionsSummary}
Home Manager version ${hmRelease} and
Nixpkgs version ${nixpkgsRelease}.
Using mismatched versions is likely to cause errors and unexpected
behavior. It is therefore highly recommended to use a release of Home
@@ -849,9 +831,6 @@ 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,17 +117,6 @@ 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,29 +17,15 @@ 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.
mkStateDconfKeys =
nameSuffix: settings:
pkgs.writeText "dconf-keys${nameSuffix}.json" (
builtins.toJSON (
lib.concatLists (
lib.mapAttrsToList (dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries) settings
)
stateDconfKeys = pkgs.writeText "dconf-keys.json" (
builtins.toJSON (
lib.concatLists (
lib.mapAttrsToList (
dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries
) cfg.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
{
@@ -95,87 +81,73 @@ 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 && databases != [ ]) {
config = lib.mkIf (cfg.enable && cfg.settings != { }) {
# Make sure the dconf directory exists.
xdg.configFile."dconf/.keep".source = builtins.toFile "keep" "";
home.extraBuilderCommands = ''
mkdir -p $out/state/
''
+ lib.concatMapStrings (db: ''
ln -s ${db.stateDconfKeys} $out/state/${db.stateDconfKeys.name}
'') databases;
ln -s ${stateDconfKeys} $out/state/${stateDconfKeys.name}
'';
home.activation.dconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] (
lib.concatMapStrings (
db:
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni db.settings);
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
statePath = "state/${db.stateDconfKeys.name}";
statePath = "state/${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
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}"
# Can't do cleanup if we don't know the old state.
if [[ ! -f $oldState ]]; then
exit 0
fi
if [[ -v oldGenPath ]]; then
${cleanup} \
"$oldGenPath/${statePath}" \
"$newGenPath/${statePath}"
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
run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
if [[ -v oldGenPath ]]; then
${cleanup} \
"$oldGenPath/${statePath}" \
"$newGenPath/${statePath}"
fi
unset DCONF_DBUS_RUN_SESSION
''
) databases
run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
unset DCONF_DBUS_RUN_SESSION
''
);
};
}

View File

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

View File

@@ -45,17 +45,9 @@ in
packageExample = "pkgs.gnome.gnome-themes-extra";
}
);
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/).
'';
default = cfg.theme;
defaultText = literalExpression "config.gtk.theme";
description = "Theme for GTK 4 applications.";
};
iconTheme = mkOption {

View File

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

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

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

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

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

View File

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

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

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

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

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

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

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

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

@@ -8,10 +8,6 @@
let
cfg = config.qt;
qtctFormat = pkgs.formats.ini {
listToValue = values: lib.concatStringsSep ", " values;
};
# Map platform names to their packages.
platformPackages = with pkgs; {
gnome = [
@@ -290,34 +286,7 @@ 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 =
@@ -428,18 +397,5 @@ 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,7 +26,6 @@ in
"24.11"
"25.05"
"25.11"
"26.05"
];
description = ''
It is occasionally necessary for Home Manager to change

View File

@@ -8,28 +8,26 @@ 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-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"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\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 "Stávni heimafílaleinkir innaní %s"
msgstr ""
#: modules/files.nix:219
msgid "Cleaning up orphan links from %s"
msgstr "Ruddi foreldraleys leinkir frá %s"
msgstr ""
#: modules/home-environment.nix:647
msgid "Creating new profile generation"
msgstr "Stovni nýggjan profil ættarlið"
msgstr ""
#: 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-12-04 04:17+0000\n"
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
"PO-Revision-Date: 2025-03-07 18:58+0000\n"
"Last-Translator: 807 <s10855168@gmail.com>\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.15-dev\n"
"X-Generator: Weblate 5.10.3-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 "%s未知選項 '%s'"
msgstr ""
#: 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 "找不到合適的設定檔目錄,已嘗試 %s 和 %s"
msgstr "找不到合適的 profile 目錄,已嘗試 %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,12 +10,6 @@ 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:
@@ -45,19 +39,6 @@ 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";
@@ -100,7 +81,24 @@ in
};
};
settings = mkOption {
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 {
inherit (tomlFormat) type;
default = { };
example = lib.literalExpression ''
@@ -117,27 +115,6 @@ 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 = ''
@@ -151,68 +128,32 @@ 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.${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
'';
};
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"
'';
};
launchd.agents.aerospace = {

View File

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

@@ -1,43 +0,0 @@
{
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.nullOr types.package;
type = types.package;
readOnly = true;
description = ''
Resulting customized ${name} package
@@ -220,22 +220,15 @@ let
};
in
lib.mkIf cfg.enable {
assertions = [
{
assertion = !(cfg.package == null && cfg.commandLineArgs != [ ]);
message = "Cannot set `commandLineArgs` when `package` is null for ${browser}.";
}
];
programs.${browser}.finalPackage =
programs.${browser}.finalPackage = lib.mkIf (cfg.package != null) (
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,47 +197,6 @@ 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;
@@ -366,10 +325,6 @@ 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`";
@@ -393,7 +348,7 @@ in
makeWrapperArgs = lib.flatten (
lib.filter (x: x != [ ]) [
(lib.optional (cfg.mcpServers != { }) [
"--append-flags"
"--add-flags"
"--mcp-config ${jsonFormat.generate "claude-code-mcp-config.json" { inherit (cfg) mcpServers; }}"
])
]
@@ -431,11 +386,6 @@ 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;
@@ -456,12 +406,6 @@ 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,15 +68,8 @@ in
in
lib.mkMerge [
(mkIf cfg.enable {
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.
'';
}
];
# 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);
warnings =
lib.optional
@@ -84,12 +77,9 @@ 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 && config.programs.git.package != null) {
(mkIf (cfg.enable && cfg.enableGitIntegration) {
programs.git = {
enable = lib.mkDefault true;
iniContent =

View File

@@ -21,19 +21,14 @@ in
settings = lib.mkOption {
inherit (jsonFormat) type;
default = { };
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";
};
example = lib.literalExpression ''
{
"theme": "Default",
"vimMode": true,
"preferredEditor": "nvim",
"autoAccept": true
}
'';
description = "JSON config for gemini-cli";
};
@@ -86,12 +81,12 @@ in
};
defaultModel = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
type = lib.types.str;
default = "gemini-2.5-pro";
example = "gemini-2.5-flash";
description = ''
The default model to use for the CLI.
Will be set as $GEMINI_MODEL when configured.
Will be set as $GEMINI_MODEL.
'';
};
@@ -143,9 +138,7 @@ in
file.".gemini/settings.json" = lib.mkIf (cfg.settings != { }) {
source = jsonFormat.generate "gemini-cli-settings.json" cfg.settings;
};
sessionVariables = lib.mkIf (cfg.defaultModel != null) {
GEMINI_MODEL = cfg.defaultModel;
};
sessionVariables.GEMINI_MODEL = cfg.defaultModel;
};
}
{

View File

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

View File

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

View File

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

View File

@@ -1,81 +0,0 @@
{
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,8 +705,7 @@ in
default = false;
description = ''
Whether to configure {command}`kak` as the default
editor using the {env}`EDITOR` and {env}`VISUAL`
environment variables.
editor using the {env}`EDITOR` environment variable.
'';
};
@@ -756,10 +755,7 @@ 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";
VISUAL = "kak";
};
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; };
xdg.configFile = lib.mkMerge [
{ "kak/kakrc".source = configFile; }
(mkIf (cfg.colorSchemePackage != null) {

View File

@@ -37,17 +37,13 @@ in
options = lib.mkOption {
type =
with lib.types;
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`.";
attrsOf (oneOf [
bool
int
str
]);
default = { };
description = "GNU-style options to be set via {env}`$LESS`.";
example = {
RAW-CONTROL-CHARS = true;
quiet = true;
@@ -62,10 +58,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.concatStringsSep " " cfg.options}
LESS = ${lib.cli.toGNUCommandLineShell { } cfg.options}
''
);
};

View File

@@ -7,46 +7,121 @@
let
inherit (lib)
concatMapStringsSep
literalExpression
mkEnableOption
mkIf
mkOption
mkPackageOption
optionals
mkRemovedOptionModule
types
;
cfg = config.programs.neovim;
inherit
(
(import ../lib/file-type.nix {
inherit (config.home) homeDirectory;
inherit lib pkgs;
})
)
fileType
;
fileType =
(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;
@@ -71,17 +146,6 @@ 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;
@@ -91,12 +155,11 @@ in
'';
};
withPerl = mkOption {
type = types.bool;
default = false;
withRuby = mkOption {
type = types.nullOr types.bool;
default = true;
description = ''
Enable perl provider. Set to `true` to
use Perl plugins.
Enable ruby provider.
'';
};
@@ -109,16 +172,21 @@ in
'';
};
withRuby = mkOption {
type = types.nullOr types.bool;
default = true;
description = ''
Enable ruby provider.
'';
};
extraPython3Packages = mkOption {
type = types.functionTo (types.listOf types.package);
# 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);
default = _: [ ];
defaultText = literalExpression "ps: [ ]";
example = literalExpression "pyPkgs: with pyPkgs; [ python-language-server ]";
@@ -130,8 +198,21 @@ 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 = types.functionTo (types.listOf types.package);
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);
default = _: [ ];
defaultText = literalExpression "ps: [ ]";
example = literalExpression "luaPkgs: with luaPkgs; [ luautf8 ]";
@@ -143,34 +224,8 @@ 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 = types.listOf types.str;
type = with types; listOf str;
default = [ ];
example = literalExpression ''
[
@@ -191,14 +246,53 @@ in
'';
};
extraPackages = mkOption {
type = types.listOf types.package;
default = [ ];
example = literalExpression "[ pkgs.shfmt ]";
description = "Extra packages available to nvim.";
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.
'';
};
# Configuration & Plugins
extraConfig = mkOption {
type = types.lines;
default = "";
@@ -221,78 +315,37 @@ in
'';
};
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;
};
extraPackages = mkOption {
type = with types; listOf package;
default = [ ];
example = literalExpression "[ pkgs.shfmt ]";
description = "Extra packages available to nvim.";
};
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";
};
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.
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`.
'';
};
This option is mutually exclusive with {var}`configure`.
'';
};
coc = {
enable = mkEnableOption "Coc";
package = mkPackageOption pkgs "coc-nvim" {
package = lib.mkPackageOption pkgs "coc-nvim" {
default = [
"vimPlugins"
"coc-nvim"
@@ -322,7 +375,7 @@ in
filetypes = [ "haskell" "lhaskell" ];
};
};
}
};
'';
description = ''
Extra configuration lines to add to
@@ -339,52 +392,11 @@ 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 = mkIf cfg.enable (
config =
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;
@@ -400,38 +412,11 @@ in
suppressNotVimlConfig = p: if p.type != "viml" then p // { config = null; } else p;
# 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)
];
neovimConfig = pkgs.neovimUtils.makeNeovimConfig {
inherit (cfg)
extraPython3Packages
withPython3
withRuby
withPerl
viAlias
vimAlias
;
@@ -443,63 +428,54 @@ in
wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package (
neovimConfig
// {
inherit (cfg)
extraName
autowrapRuntimeDeps
waylandSupport
withNodeJs
;
wrapperArgs =
neovimConfig.wrapperArgs
++ cfg.extraWrapperArgs
++ extraMakeWrapperArgs
++ extraMakeWrapperLuaCArgs
++ extraMakeWrapperLuaArgs;
(lib.escapeShellArgs (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs))
+ " "
+ extraMakeWrapperArgs
+ " "
+ extraMakeWrapperLuaCArgs
+ " "
+ extraMakeWrapperLuaArgs;
wrapRc = false;
}
);
in
{
programs.neovim = {
generatedConfigViml = neovimConfig.neovimRcContent;
mkIf cfg.enable {
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;
programs.neovim.generatedConfigViml = neovimConfig.neovimRcContent;
finalPackage = wrappedNeovim';
};
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.packages = [ cfg.finalPackage ];
sessionVariables = mkIf cfg.defaultEditor {
EDITOR = "nvim";
VISUAL = "nvim";
};
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "nvim"; };
shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
};
home.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
xdg.configFile =
let
hasLuaConfig = lib.hasAttr "lua" config.programs.neovim.generatedConfigs;
luaRcContent =
lib.optionalString (
wrappedNeovim'.initRc != ""
) "vim.cmd [[source ${pkgs.writeText "nvim-init-home-manager.vim" wrappedNeovim'.initRc}]]\n"
+ config.programs.neovim.extraLuaConfig
+ lib.optionalString hasLuaConfig config.programs.neovim.generatedConfigs.lua;
in
lib.mkMerge (
# writes runtime
(map (x: x.runtime) pluginsNormalized)
++ [
{
"nvim/init.lua" = mkIf (luaRcContent != "") { text = luaRcContent; };
"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;
@@ -507,6 +483,7 @@ in
}
]
);
}
);
programs.neovim.finalPackage = wrappedNeovim';
};
}

View File

@@ -1,74 +0,0 @@
# 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

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

@@ -1,55 +0,0 @@
{
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.initContent = mkIf cfg.enableZshIntegration ''
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(sheldon source)"
'';

View File

@@ -151,7 +151,14 @@ let
identityFile = mkOption {
type = with types; either (listOf str) (nullOr str);
default = [ ];
apply = p: if p == null then [ ] else lib.toList p;
apply =
p:
if p == null then
[ ]
else if lib.isString p then
[ p ]
else
p;
description = ''
Specifies files from which the user identity is read.
Identities will be tried in the given order.
@@ -161,7 +168,14 @@ let
identityAgent = mkOption {
type = with types; either (listOf str) (nullOr str);
default = [ ];
apply = p: if p == null then [ ] else lib.toList p;
apply =
p:
if p == null then
[ ]
else if lib.isString p then
[ p ]
else
p;
description = ''
Specifies the location of the ssh identity agent.
'';
@@ -251,7 +265,14 @@ let
certificateFile = mkOption {
type = with types; either (listOf str) (nullOr str);
default = [ ];
apply = p: if p == null then [ ] else lib.toList p;
apply =
p:
if p == null then
[ ]
else if lib.isString p then
[ p ]
else
p;
description = ''
Specifies files from which the user certificate is read.
'';
@@ -430,13 +451,7 @@ 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
++ [
(lib.generators.toKeyValue {
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";
listsAsDuplicateKeys = true;
indent = " ";
} cf.extraOptions)
]
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
);
in

View File

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

View File

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

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

View File

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

View File

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

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

View File

@@ -1,86 +0,0 @@
{
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,17 +49,9 @@ in
default = {
manifest.url = "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml";
roots = [ ];
backup.path = "${config.xdg.stateHome}/backups/ludusavi";
restore.path = "${config.xdg.stateHome}/backups/ludusavi";
backup.path = "$XDG_STATE_HOME/backups/ludusavi";
restore.path = "$XDG_STATE_HOME/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";
@@ -102,24 +94,6 @@ 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,7 +43,6 @@ 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/${serviceName}" ];
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C" ];
ExecStart =
lib.optional doBackup backupCmd
@@ -591,7 +591,7 @@ in
lib.concatLines
]}
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
RESTIC_CACHE_DIR=$HOME/.cache/${serviceName}
PATH=${
lib.pipe environment [

View File

@@ -67,8 +67,6 @@ 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,7 +7,6 @@
let
cfg = config.services.snixembed;
waybarCfg = config.programs.waybar;
in
{
meta.maintainers = [ lib.maintainers.DamienCassou ];
@@ -33,10 +32,6 @@ 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,11 +84,13 @@ in
'';
in
{
# $SSH_AUTH_SOCK has to be set early since other tools rely on it
bash.profileExtra = lib.mkIf cfg.enableBashIntegration (lib.mkOrder 900 bashIntegration);
fish.shellInit = lib.mkIf cfg.enableFishIntegration (lib.mkOrder 900 fishIntegration);
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration (lib.mkOrder 900 nushellIntegration);
zsh.envExtra = lib.mkIf cfg.enableZshIntegration (lib.mkOrder 900 bashIntegration);
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;
};
}

View File

@@ -42,30 +42,21 @@ in
};
};
eventsModule = {
eventModule = {
options = {
before-sleep = mkOption {
type = types.nullOr types.str;
default = null;
description = "Command to run before suspending.";
event = mkOption {
type = types.enum [
"before-sleep"
"after-resume"
"lock"
"unlock"
];
description = "Event name.";
};
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.";
command = mkOption {
type = types.str;
description = "Command to run when event occurs.";
};
};
};
@@ -89,31 +80,13 @@ in
};
events = mkOption {
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 = { };
type = with types; listOf (submodule eventModule);
default = [ ];
example = literalExpression ''
{
"before-sleep" = "''${pkgs.swaylock}/bin/swaylock -fF";
"lock" = "lock";
}
[
{ event = "before-sleep"; command = "''${pkgs.swaylock}/bin/swaylock -fF"; }
{ event = "lock"; command = "lock"; }
]
'';
description = "Run command on occurrence of a event.";
};
@@ -171,17 +144,13 @@ in
t.resumeCommand
];
mkEvent = event: command: [
event
command
mkEvent = e: [
e.event
e.command
];
nonemptyEvents = lib.filterAttrs (event: command: command != null) cfg.events;
args =
cfg.extraArgs
++ (lib.concatMap mkTimeout cfg.timeouts)
++ (lib.flatten (lib.mapAttrsToList mkEvent nonemptyEvents));
cfg.extraArgs ++ (lib.concatMap mkTimeout cfg.timeouts) ++ (lib.concatMap mkEvent cfg.events);
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.PerchunPak ];
meta.maintainers = [ lib.maintainers.perchun ];
options.services.tldr-update = {
enable = lib.mkEnableOption ''

View File

@@ -119,24 +119,6 @@ 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 {
@@ -149,13 +131,11 @@ in
xsession.windowManager.command = "${cfg.package}/bin/herbstluftwm --locked";
xdg.configFile."herbstluftwm/autostart".source = pkgs.writeShellScript "herbstluftwm-autostart" ''
${lib.optionalString cfg.enableAlias ''
shopt -s expand_aliases
shopt -s expand_aliases
# shellcheck disable=SC2142
alias herbstclient='set -- "$@" ";"'
set --
''}
# shellcheck disable=SC2142
alias herbstclient='set -- "$@" ";"'
set --
herbstclient emit_hook reload
@@ -189,9 +169,7 @@ in
herbstclient unlock
${lib.optionalString cfg.enableAlias ''
${cfg.package}/bin/herbstclient chain ";" "$@"
''}
${cfg.package}/bin/herbstclient chain ";" "$@"
'';
};
}

View File

@@ -81,7 +81,7 @@
drivers = mkOption {
type = types.package;
internal = true;
readOnly = true;
description = "Resulting drivers package.";
};
};
@@ -104,9 +104,14 @@
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 = cfg.drivers;
nonNixosGpuEnv = drivers;
};
in
lib.mkIf cfg.enable {
@@ -143,7 +148,7 @@
in
lib.hm.dag.entryAnywhere ''
existing=$(readlink /run/opengl-driver || true)
new=${cfg.drivers}
new=${drivers}
verboseEcho Existing drivers: ''${existing}
verboseEcho New drivers: ''${new}
if [[ -z "''${existing}" ]] ; then
@@ -157,13 +162,7 @@
'';
targets.genericLinux.gpu = {
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
};
inherit setupPackage drivers;
};
};

View File

@@ -6,7 +6,6 @@
intel-media-driver,
nvidia-vaapi-driver,
linuxPackages,
system,
nvidia_x11 ? linuxPackages.nvidia_x11,
addNvidia ? false,
}:
@@ -16,8 +15,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

@@ -2,6 +2,7 @@
# For OS-specific configuration, please edit nixos/default.nix or nix-darwin/default.nix instead.
{
options,
config,
lib,
pkgs,
@@ -35,7 +36,7 @@ let
modules = [
(
{ name, options, ... }:
{ name, ... }:
{
imports =
import ../modules/modules.nix {
@@ -47,31 +48,22 @@ let
++ cfg.sharedModules;
config = {
submoduleSupport = {
enable = true;
externalPackageInstall = cfg.useUserPackages;
};
submoduleSupport.enable = true;
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
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;
};
home.username = config.users.users.${name}.name;
home.homeDirectory = config.users.users.${name}.home;
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;
# 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;
# 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;
};
# 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;
};
}
)
@@ -93,7 +85,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.
@@ -168,28 +160,30 @@ 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": "26.05",
"isReleaseBranch": false
"release": "25.11",
"isReleaseBranch": true
}

View File

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

View File

@@ -15,7 +15,7 @@
{
description = "Tests of Home Manager for Nix";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
outputs =
{ nixpkgs, ... }:

View File

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

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

@@ -1,77 +0,0 @@
{ 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"date --set='{time}'")
machine.succeed(f"timedatectl set-time '{time}'")
systemctl_succeed_as_alice("start restic-backups-prune-me.service")
snapshot_count += 1
actual = \

View File

@@ -2,7 +2,4 @@
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

@@ -1,39 +0,0 @@
{ 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;
};
}
);
})
];
}

View File

@@ -1,7 +0,0 @@
{
# home.uid defaults to null, so checkUid should not be called in the activation script
nmt.script = ''
assertFileNotRegex activate "checkUid [0-9]+"
'';
}

View File

@@ -1,7 +0,0 @@
{
home.uid = 1000;
nmt.script = ''
assertFileContains activate "checkUid 1000"
'';
}

View File

@@ -17,5 +17,4 @@
gtk4-basic-settings = ./gtk4/gtk4-basic-settings.nix;
gtk4-theme-css-injection = ./gtk4/gtk4-theme-css-injection.nix;
gtk4-no-theme-css-injection = ./gtk4/gtk4-no-theme-css-injection.nix;
gtk4-stateversion-no-theme-inheritance = ./gtk4/gtk4-stateversion-no-theme-inheritance.nix;
}

View File

@@ -0,0 +1,5 @@
/**
* GTK 4 reads the theme configured by gtk-theme-name, but ignores it.
* It does however respect user CSS, so import the theme from here.
**/
@import url("file://@gnome-themes-extra@/share/themes/Adwaita-dark/gtk-4.0/gtk.css");

View File

@@ -5,3 +5,4 @@ gtk-cursor-theme-size=24
gtk-font-name=Ubuntu 12
gtk-icon-theme-name=Adwaita
gtk-interface-color-scheme=2
gtk-theme-name=Adwaita-dark

View File

@@ -1,7 +1,5 @@
{ pkgs, ... }:
{
home.stateVersion = "26.05";
gtk = {
enable = true;
font = {
@@ -39,5 +37,9 @@
assertFileExists home-files/.config/gtk-4.0/settings.ini
assertFileContent home-files/.config/gtk-4.0/settings.ini \
${./gtk-global-inheritance-gtk4-expected.ini}
# Check GTK4 CSS with theme import
assertFileExists home-files/.config/gtk-4.0/gtk.css
assertFileContent home-files/.config/gtk-4.0/gtk.css ${./gtk-global-inheritance-gtk4-css-expected.css}
'';
}

View File

@@ -3,3 +3,4 @@ gtk-cursor-theme-name=Global-Cursor
gtk-font-name=GTK4-Font 11
gtk-icon-theme-name=Global-Icons
gtk-recent-files-limit=20
gtk-theme-name=Global-Theme

View File

@@ -1,6 +1,4 @@
{
home.stateVersion = "26.05";
gtk = {
enable = true;
# Global defaults
@@ -48,7 +46,7 @@
assertFileContent home-files/.config/gtk-3.0/gtk.css \
${./gtk-per-version-override-gtk3-css-expected.css}
# GTK4 should use overridden font, global icons/cursor
# GTK4 should use overridden font, global theme/icons/cursor
assertFileExists home-files/.config/gtk-4.0/settings.ini
assertFileContent home-files/.config/gtk-4.0/settings.ini \
${./gtk-per-version-override-gtk4-expected.ini}

View File

@@ -2,11 +2,11 @@
{
gtk = {
enable = true;
theme = {
name = "catppuccin-macchiato-blue-standard";
package = pkgs.catppuccin-gtk;
};
gtk4 = {
theme = {
name = "catppuccin-macchiato-blue-standard";
package = pkgs.catppuccin-gtk;
};
extraConfig = {
gtk-cursor-blink = false;
gtk-recent-files-limit = 20;

View File

@@ -1,2 +0,0 @@
[Settings]
gtk-icon-theme-name=Adwaita

View File

@@ -1,28 +0,0 @@
{ pkgs, ... }:
{
# Test that GTK4 theme does NOT inherit from global theme with stateVersion 26.05
# This shows the new default behavior where gtk4.theme defaults to null
home.stateVersion = "26.05";
gtk = {
enable = true;
theme = {
name = "Adwaita-dark";
package = pkgs.gnome-themes-extra;
};
iconTheme = {
name = "Adwaita";
package = pkgs.adwaita-icon-theme;
};
};
nmt.script = ''
# GTK4 settings should exist but WITHOUT theme (icon theme still inherits)
assertFileExists home-files/.config/gtk-4.0/settings.ini
assertFileContent home-files/.config/gtk-4.0/settings.ini \
${./gtk4-stateversion-no-theme-inheritance-expected.ini}
# GTK4 CSS should NOT exist since no theme is configured
assertPathNotExists home-files/.config/gtk-4.0/gtk.css
'';
}

View File

@@ -4,7 +4,4 @@
qt-platform-theme-gtk3 = ./qt-platform-theme-gtk3.nix;
qt-platform-theme-gnome = ./qt-platform-theme-gnome.nix;
qt-platform-theme-kde6-migration = ./qt-platform-theme-kde6-migration.nix;
qt-qt5ct-settings = ./qt-qt5ct-settings.nix;
qt-qt6ct-settings = ./qt-qt6ct-settings.nix;
qt-qtct-settings = ./qt-qtct-settings.nix;
}

View File

@@ -1,13 +0,0 @@
{
qt = {
enable = true;
qt5ctSettings = {
test_section.test_option = "test";
};
};
nmt.script = ''
assertFileExists "home-files/.config/qt5ct/qt5ct.conf"
assertPathNotExists "home-files/.config/qt6ct/qt6ct.conf"
'';
}

View File

@@ -1,13 +0,0 @@
{
qt = {
enable = true;
qt6ctSettings = {
test_section.test_option = "test";
};
};
nmt.script = ''
assertFileExists "home-files/.config/qt6ct/qt6ct.conf"
assertPathNotExists "home-files/.config/qt5ct/qt5ct.conf"
'';
}

View File

@@ -1,16 +0,0 @@
{
qt = {
enable = true;
qt5ctSettings = {
test_section.test_option = "test";
};
qt6ctSettings = {
test_section.test_option = "test";
};
};
nmt.script = ''
assertFileExists "home-files/.config/qt5ct/qt5ct.conf"
assertFileExists "home-files/.config/qt6ct/qt6ct.conf"
'';
}

View File

@@ -0,0 +1,41 @@
{ config, pkgs, ... }:
let
hmPkgs = pkgs.extend (
self: super: {
aerospace = config.lib.test.mkStubPackage {
name = "aerospace";
buildScript = ''
mkdir -p $out/bin
touch $out/bin/aerospace
chmod 755 $out/bin/aerospace
'';
};
}
);
in
{
programs.aerospace = {
enable = true;
package = hmPkgs.aerospace;
userSettings = {
gaps = {
outer.left = 8;
outer.bottom = 8;
outer.top = 8;
outer.right = 8;
};
mode.main.binding = {
alt-h = "focus left";
alt-j = "focus down";
alt-k = "focus up";
alt-l = "focus right";
};
key-mapping.preset = "colemak";
};
};
nmt.script = ''
assertFileContent home-files/.config/aerospace/aerospace.toml ${./colemak-settings-expected.toml}
'';
}

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