Compare commits
80 commits
ff067cfc61
...
7eca7f7081
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eca7f7081 | ||
|
|
20728df08f | ||
|
|
af3c24de76 | ||
|
|
624c7e80fb | ||
|
|
9c790e687e | ||
|
|
527ad07e66 | ||
|
|
57a02fd7d9 | ||
|
|
3fe66908e0 | ||
|
|
61fcc9de76 | ||
|
|
7b73a6e98f | ||
|
|
4dc3c91c50 | ||
|
|
a7d6bba358 | ||
|
|
bdb807dc28 | ||
|
|
0a583021ea | ||
|
|
ab01ea24b2 | ||
|
|
c764a377a0 | ||
|
|
28b3622b80 | ||
|
|
c848303f1e | ||
|
|
bb35f07cc9 | ||
|
|
9bf54edf10 | ||
|
|
89c9508bbe | ||
|
|
22202ff0d8 | ||
|
|
09de9577d4 | ||
|
|
f575cb24f6 | ||
|
|
3a92ffa192 | ||
|
|
6cdf765eed | ||
|
|
8315c1544f | ||
|
|
58bf3ecb2d | ||
|
|
d787ec69c3 | ||
|
|
07d79726f1 | ||
|
|
4767a9c719 | ||
|
|
39cb677ed9 | ||
|
|
0cf525a5be | ||
|
|
9b5ac85d79 | ||
|
|
574f6d3526 | ||
|
|
e52be4fb78 | ||
|
|
dd18018d06 | ||
|
|
7b34e428f3 | ||
|
|
af7c726e8b | ||
|
|
13cc1efd78 | ||
|
|
e5b1f87841 | ||
|
|
caa47b637d | ||
|
|
a788734077 | ||
|
|
6bdf2a68e1 | ||
|
|
f9d45d664e | ||
|
|
082822b8a6 | ||
|
|
27a6182347 | ||
|
|
012cfcc44a | ||
|
|
36817384a6 | ||
|
|
571c5eed1d | ||
|
|
2e02e22e28 | ||
|
|
ccd22c13b2 | ||
|
|
519828bf1c | ||
|
|
1a99a515a1 | ||
|
|
6bcb2395ab | ||
|
|
f16bfa59e3 | ||
|
|
35545f71dd | ||
|
|
6bbc48804b | ||
|
|
a8b6296a1e | ||
|
|
68f7b34179 | ||
|
|
24cc5c080c | ||
|
|
df7bac2b2b | ||
|
|
05a56dbf24 | ||
|
|
9379fbf4f5 | ||
|
|
a521eab881 | ||
|
|
d441981b20 | ||
|
|
fca4cba863 | ||
|
|
af324afa72 | ||
|
|
12e7786854 | ||
|
|
28741978a3 | ||
|
|
43173abcb4 | ||
|
|
bcc7afa1d8 | ||
|
|
281e9398cc | ||
|
|
93d907a205 | ||
|
|
eca5f967cd | ||
|
|
db44f38047 | ||
|
|
06f81463bb | ||
|
|
ab8e4b2b5a | ||
|
|
c3d1e5c65a | ||
|
|
bf003999ed |
138 changed files with 2643 additions and 520 deletions
2
.github/workflows/backport.yml
vendored
2
.github/workflows/backport.yml
vendored
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Create backport PRs
|
||||
id: backport
|
||||
uses: korthout/backport-action@v3
|
||||
uses: korthout/backport-action@v4
|
||||
with:
|
||||
# See https://github.com/korthout/backport-action#inputs
|
||||
github_token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -361,6 +361,11 @@
|
|||
email = "nixpkgs@perchun.it";
|
||||
github = "PerchunPak";
|
||||
githubId = 68118654;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "BBB5 1142 959D 8549 A3D2 F6C5 313F 67D1 EAB7 70F9";
|
||||
}
|
||||
];
|
||||
name = "Perchun Pak";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
|
|
@ -2073,7 +2078,7 @@
|
|||
source = "nixpkgs";
|
||||
};
|
||||
shikanime = {
|
||||
email = "deva.shikanime@protonmail.com";
|
||||
email = "william.phetsinorath@shikanime.studio";
|
||||
github = "shikanime";
|
||||
githubId = 22115108;
|
||||
name = "William Phetsinorath";
|
||||
|
|
@ -2311,6 +2316,13 @@
|
|||
name = "Florian Peter";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
xavwe = {
|
||||
email = "git@xavwe.dev";
|
||||
github = "xavwe";
|
||||
githubId = 125409009;
|
||||
name = "Xaver Wenhart";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
xlambein = {
|
||||
email = "xlambein@gmail.com";
|
||||
github = "xlambein";
|
||||
|
|
|
|||
|
|
@ -57,3 +57,9 @@ changes are only active if the `home.stateVersion` option is set to
|
|||
|
||||
now default to `true` which is consistent with the default values
|
||||
for those options used by `i3` and `sway`.
|
||||
|
||||
- The [](#opt-programs.swaylock.enable) option now defaults to `false`
|
||||
and must be explicitly enabled. Previously, it would be implicitly
|
||||
enabled when `programs.swaylock.settings` was non-empty. Users with
|
||||
`home.stateVersion` set to earlier versions will continue to get the
|
||||
old implicit behavior.
|
||||
|
|
|
|||
|
|
@ -27,4 +27,8 @@ The state version in this release includes the changes below. These
|
|||
changes are only active if the `home.stateVersion` option is set to
|
||||
\"25.05\" or later.
|
||||
|
||||
- No changes.
|
||||
- The [](#opt-programs.git.signing.format) option no longer defaults to
|
||||
`"openpgp"`. Users who use Git signing with GPG should explicitly set
|
||||
this option to `"openpgp"` to maintain the previous behavior. Users
|
||||
with `home.stateVersion` set to earlier versions will continue to get
|
||||
the `"openpgp"` default for backwards compatibility.
|
||||
|
|
|
|||
|
|
@ -80,3 +80,10 @@ changes are only active if the `home.stateVersion` option is set to
|
|||
`{ PASSWORD_STORE_DIR = $XDG_DATA_HOME/password-store; }` anymore by its
|
||||
default value. This will revert to the default behaviour of the program,
|
||||
namely `$HOME/.password-store` to be used as the store path.
|
||||
|
||||
- On macOS, [](#opt-targets.darwin.copyApps.enable) is now enabled by
|
||||
default instead of [](#opt-targets.darwin.linkApps.enable). This means
|
||||
applications from `home.packages` will be copied to
|
||||
`~/Applications/Home Manager Apps` rather than symlinked, making them
|
||||
work properly with Spotlight. Users with `home.stateVersion` set to
|
||||
earlier versions will continue to use `linkApps` by default.
|
||||
|
|
|
|||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1764242076,
|
||||
"narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=",
|
||||
"lastModified": 1766309749,
|
||||
"narHash": "sha256-3xY8CZ4rSnQ0NqGhMKAy5vgC+2IVK0NoVEzDoOh4DA4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4",
|
||||
"rev": "a6531044f6d0bef691ea18d4d4ce44d0daa6e816",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ msgstr ""
|
|||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
|
||||
"PO-Revision-Date: 2025-03-07 18:58+0000\n"
|
||||
"Last-Translator: 807 <s10855168@gmail.com>\n"
|
||||
"PO-Revision-Date: 2025-12-04 04:17+0000\n"
|
||||
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
|
||||
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
|
||||
"projects/home-manager/cli/zh_Hant/>\n"
|
||||
"Language: zh_Hant\n"
|
||||
|
|
@ -17,21 +17,21 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 5.10.3-dev\n"
|
||||
"X-Generator: Weblate 5.15-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr "%s: 缺少參數 %s"
|
||||
msgstr "%s:缺少 %s 的引數"
|
||||
|
||||
#. translators: For example: "home-manager: --rollback can only be used after switch"
|
||||
#: home-manager/home-manager:22
|
||||
msgid "%s: %s can only be used after %s"
|
||||
msgstr ""
|
||||
msgstr "%s:%s 只能在 %s 之後使用"
|
||||
|
||||
#: home-manager/home-manager:71
|
||||
msgid "No configuration file found at %s"
|
||||
msgstr "未在 %s 處找到配置檔案"
|
||||
msgstr "在 %s 找不到設定檔"
|
||||
|
||||
#. translators: The first '%s' specifier will be replaced by either
|
||||
#. 'home.nix' or 'flake.nix'.
|
||||
|
|
@ -41,12 +41,12 @@ msgid ""
|
|||
"Keeping your Home Manager %s in %s is deprecated,\n"
|
||||
"please move it to %s"
|
||||
msgstr ""
|
||||
"保持你的 Home Manager 在 %s 中,%s 已被拋棄,\n"
|
||||
"請將它移動到 %s"
|
||||
"將 Home Manager 的 %s 放在 %s 中, 已經被棄用,\n"
|
||||
"請改放到 %s"
|
||||
|
||||
#: home-manager/home-manager:99
|
||||
msgid "No configuration file found. Please create one at %s"
|
||||
msgstr "未找到配置檔案。請在 %s 處建立一份"
|
||||
msgstr "找不到設定檔。請在 %s 建立新的設定檔"
|
||||
|
||||
#: home-manager/home-manager:114
|
||||
msgid "Home Manager not found at %s."
|
||||
|
|
@ -57,7 +57,7 @@ msgstr "在 %s 中找不到 Home Manager。"
|
|||
msgid ""
|
||||
"The fallback Home Manager path %s has been deprecated and a file/directory "
|
||||
"was found there."
|
||||
msgstr "備用的 Home Manager 路徑 %s 已被拋棄,但一個檔案/資料夾在這被找到。"
|
||||
msgstr "備用的 Home Manager 路徑 %s 已被棄用,且在該處找到了檔案/目錄。"
|
||||
|
||||
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
|
||||
#: home-manager/home-manager:125
|
||||
|
|
@ -80,21 +80,21 @@ msgid ""
|
|||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
msgstr ""
|
||||
"要消除這個警告,請做以下其中一步。\n"
|
||||
"若要移除此警告,請執行下列其中一項。\n"
|
||||
"\n"
|
||||
"1. 告訴Home Manager去使用路徑,例如加入\n"
|
||||
"1. 明確告知 Home Manager 使用該路徑,例如在\n"
|
||||
"\n"
|
||||
" { programs.home-manager.path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" 到你的配置中。\n"
|
||||
" 中,加入您的設定。\n"
|
||||
"\n"
|
||||
" 如果你想要直接引入Home Manager, 請你使用 `path` 參數r\n"
|
||||
" 如果想直接匯入 Home Manager,可以在呼叫時使用 `path` 參數來指定路徑:\n"
|
||||
"\n"
|
||||
" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" 當呼叫 Home Manager 模組。\n"
|
||||
" 這樣就能正確傳遞 Home Manager 的路徑。\n"
|
||||
"\n"
|
||||
"2. 刪除無效的路徑\n"
|
||||
"2. 移除已棄用的路徑。\n"
|
||||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
|
||||
|
|
@ -104,33 +104,33 @@ msgstr "正在進行 Nix 完整性檢查"
|
|||
|
||||
#: home-manager/home-manager:173
|
||||
msgid "Could not find suitable profile directory, tried %s and %s"
|
||||
msgstr "找不到合適的 profile 目錄,已經嘗試 %s 和 %s"
|
||||
msgstr "找不到合適的設定檔目錄,已嘗試 %s 和 %s"
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:230
|
||||
msgid "Can't inspect options of a flake configuration"
|
||||
msgstr "無法檢查 flake 配置中的選項"
|
||||
msgstr "無法檢查 flake 設定的選項"
|
||||
|
||||
#: home-manager/home-manager:305 home-manager/home-manager:328
|
||||
#: home-manager/home-manager:734 home-manager/home-manager:1237
|
||||
msgid "%s: unknown option '%s'"
|
||||
msgstr "%s:未知選項 ‘%s’"
|
||||
msgstr "%s:未知選項 '%s'"
|
||||
|
||||
#: home-manager/home-manager:310 home-manager/home-manager:1238
|
||||
msgid "Run '%s --help' for usage help"
|
||||
msgstr "執行 ‘%s --help’ 獲取用法幫助"
|
||||
msgstr "執行 '%s --help' 以取得使用說明"
|
||||
|
||||
#: home-manager/home-manager:336 home-manager/home-manager:441
|
||||
msgid "The file %s already exists, leaving it unchanged..."
|
||||
msgstr "檔案 %s 已經存在,不更改它..."
|
||||
msgstr "檔案 %s 已存在,保持不變..."
|
||||
|
||||
#: home-manager/home-manager:338 home-manager/home-manager:443
|
||||
msgid "Creating %s..."
|
||||
msgstr "創建 %s 中..."
|
||||
msgstr "正在建立 %s..."
|
||||
|
||||
#: home-manager/home-manager:487
|
||||
msgid "Creating initial Home Manager generation..."
|
||||
msgstr "正在建立初始 Home Manager 世代 ..."
|
||||
msgstr "正在建立初始 Home Manager 世代..."
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a file path.
|
||||
#: home-manager/home-manager:492
|
||||
|
|
@ -142,12 +142,12 @@ msgid ""
|
|||
"to configure Home Manager. Run 'man home-configuration.nix' to\n"
|
||||
"see all available options."
|
||||
msgstr ""
|
||||
"全部工作完成了!home-manager 工具現應已安裝,您可以編輯\n"
|
||||
"全部完成!home-manager 工具現在應該已被安裝,您可以編輯\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"來配置 Home Manager。執行 ‘man home-configuration.nix’\n"
|
||||
"來檢視所有可用選項。"
|
||||
"來設定 Home Manager。執行 'man home-configuration.nix' 時\n"
|
||||
"可查看所有可用選項。"
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a URL.
|
||||
#: home-manager/home-manager:497
|
||||
|
|
@ -158,16 +158,16 @@ msgid ""
|
|||
"\n"
|
||||
"if the error seems to be the fault of Home Manager."
|
||||
msgstr ""
|
||||
"啊哦,安裝失敗了!如果感覺是 Home Manager 造成的錯誤,請在下方\n"
|
||||
"糟糕,安裝失敗了!如果感覺是 Home Manager 所造成的錯誤,請在此連結\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"處建立 Issue 告知我們。"
|
||||
"中,建立 Issue 告知我們。"
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:508
|
||||
msgid "Can't instantiate a flake configuration"
|
||||
msgstr "無法建立 flake 配置例項"
|
||||
msgstr "無法實例化 flake 設定"
|
||||
|
||||
#: home-manager/home-manager:584
|
||||
msgid ""
|
||||
|
|
@ -177,12 +177,12 @@ msgid_plural ""
|
|||
"There are %d unread and relevant news items.\n"
|
||||
"Read them by running the command \"%s news\"."
|
||||
msgstr[0] ""
|
||||
"有 %d 條未讀的相關新聞或訊息。\n"
|
||||
"可執行 “%s news” 命令進行閱讀。"
|
||||
"有 %d 則未讀且相關的消息項目。\n"
|
||||
"執行指令 \"%s news\" 來進行確認。"
|
||||
|
||||
#: home-manager/home-manager:598
|
||||
msgid "Unknown \"news.display\" setting \"%s\"."
|
||||
msgstr "未知的 “news.display” 設定項 “%s”。"
|
||||
msgstr "未知的 \"news.display\" 設定值 \"%s\"。"
|
||||
|
||||
#: home-manager/home-manager:606
|
||||
#, sh-format
|
||||
|
|
@ -191,11 +191,11 @@ msgstr "請設定 $EDITOR 或 $VISUAL 環境變數"
|
|||
|
||||
#: home-manager/home-manager:624
|
||||
msgid "Cannot run build in read-only directory"
|
||||
msgstr "無法在唯讀目錄中執行構建"
|
||||
msgstr "無法在唯讀目錄中執行建置"
|
||||
|
||||
#: home-manager/home-manager:787
|
||||
msgid "The configuration did not contain the specialisation \"%s\""
|
||||
msgstr ""
|
||||
msgstr "設定中不包含特化設定 \"%s\""
|
||||
|
||||
#: home-manager/home-manager:841
|
||||
msgid "No generation with ID %s"
|
||||
|
|
@ -203,7 +203,7 @@ msgstr "沒有 ID 為 %s 的世代"
|
|||
|
||||
#: home-manager/home-manager:843
|
||||
msgid "Cannot remove the current generation %s"
|
||||
msgstr "無法移除當前世代 %s"
|
||||
msgstr "無法移除目前的世代 %s"
|
||||
|
||||
#: home-manager/home-manager:845
|
||||
msgid "Removing generation %s"
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ let
|
|||
};
|
||||
|
||||
local = mkOption {
|
||||
type = types.nullOr (localModule name);
|
||||
default = null;
|
||||
type = localModule name;
|
||||
default = { };
|
||||
description = ''
|
||||
Local configuration for the contacts.
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -57,9 +57,8 @@ let
|
|||
let
|
||||
module = moduleChecks rawModule;
|
||||
in
|
||||
{
|
||||
inherit (module) options config;
|
||||
|
||||
module
|
||||
// {
|
||||
activationPackage = module.config.home.activationPackage;
|
||||
|
||||
# For backwards compatibility. Please use activationPackage instead.
|
||||
|
|
|
|||
|
|
@ -193,6 +193,13 @@ in
|
|||
description = "The user's username.";
|
||||
};
|
||||
|
||||
home.uid = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 1000;
|
||||
description = "The user's uid.";
|
||||
};
|
||||
|
||||
home.homeDirectory = mkOption {
|
||||
type = types.path;
|
||||
defaultText = literalExpression ''
|
||||
|
|
@ -570,14 +577,25 @@ in
|
|||
warnings =
|
||||
let
|
||||
hmRelease = config.home.version.release;
|
||||
nixpkgsRelease = lib.trivial.release;
|
||||
releaseMismatch = config.home.enableNixpkgsReleaseCheck && hmRelease != nixpkgsRelease;
|
||||
libRelease = lib.trivial.release;
|
||||
pkgsRelease = pkgs.lib.trivial.release;
|
||||
releaseMismatch = hmRelease != libRelease || hmRelease != pkgsRelease;
|
||||
|
||||
versionsSummary =
|
||||
if libRelease == pkgsRelease then
|
||||
''
|
||||
Home Manager version ${hmRelease} and
|
||||
Nixpkgs version ${libRelease}.''
|
||||
else
|
||||
''
|
||||
Home Manager version: ${hmRelease}
|
||||
Nixpkgs version used to evaluate Home Manager: ${libRelease}
|
||||
Nixpkgs version used for packages (`pkgs`): ${pkgsRelease}'';
|
||||
in
|
||||
lib.optional releaseMismatch ''
|
||||
lib.optional (config.home.enableNixpkgsReleaseCheck && releaseMismatch) ''
|
||||
You are using
|
||||
|
||||
Home Manager version ${hmRelease} and
|
||||
Nixpkgs version ${nixpkgsRelease}.
|
||||
${lib.replaceString "\n" "\n " versionsSummary}
|
||||
|
||||
Using mismatched versions is likely to cause errors and unexpected
|
||||
behavior. It is therefore highly recommended to use a release of Home
|
||||
|
|
@ -831,6 +849,9 @@ in
|
|||
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
|
||||
checkUsername ${lib.escapeShellArg config.home.username}
|
||||
checkHomeDirectory ${lib.escapeShellArg config.home.homeDirectory}
|
||||
${lib.optionalString (config.home.uid != null) ''
|
||||
checkUid ${toString config.home.uid}
|
||||
''}
|
||||
fi
|
||||
|
||||
${lib.optionalString config.home.activationGenerateGcRoot ''
|
||||
|
|
|
|||
|
|
@ -117,6 +117,17 @@ function checkHomeDirectory() {
|
|||
fi
|
||||
}
|
||||
|
||||
function checkUid() {
|
||||
local expectedUid="$1"
|
||||
local actualUid
|
||||
actualUid="$(id -u)"
|
||||
|
||||
if [[ "$actualUid" != "$expectedUid" ]]; then
|
||||
_iError 'Error: UID is "%s" but we expect "%s"' "$actualUid" "$expectedUid"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Note, the VERBOSE_ECHO variable is deprecated and should not be used inside
|
||||
# the Home Manager project. It is provided here for backwards compatibility.
|
||||
if [[ -v VERBOSE ]]; then
|
||||
|
|
|
|||
9
modules/misc/news/2025/10/2025-10-15_10-44-58.nix
Normal file
9
modules/misc/news/2025/10/2025-10-15_10-44-58.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
time = "2025-10-14T23:44:58+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `services.colima`
|
||||
|
||||
Colima is a tool for orchestrating container runtimes under a linux VM.
|
||||
'';
|
||||
}
|
||||
10
modules/misc/news/2025/11/2025-11-27_08-22-14.nix
Normal file
10
modules/misc/news/2025/11/2025-11-27_08-22-14.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
time = "2025-11-27T07:22:14+00:00";
|
||||
condition = pkgs.stdenv.hostPlatform.isDarwin;
|
||||
message = ''
|
||||
A new module is available: 'programs.infat'.
|
||||
Infat is a command line tool to set default openers
|
||||
for file formats and url schemes on macOS.
|
||||
'';
|
||||
}
|
||||
16
modules/misc/news/2025/12/2025-12-01_09-35-38.nix
Normal file
16
modules/misc/news/2025/12/2025-12-01_09-35-38.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
time = "2025-12-01T12:35:38+00:00";
|
||||
condition = config.services.ludusavi.enable;
|
||||
message = ''
|
||||
BREAKING CHANGE:
|
||||
|
||||
The `ludusavi` module has changed its default backup and restore path.
|
||||
The new module implements a mechanism to automatically migrate the backups
|
||||
to the new path, but if it doesn't work and you can't find your backups in
|
||||
`ludusavi`, they should be in the old path: ~/\$XDG_STATE_HOME/backups/ludusavi/
|
||||
(that means a directory literally called $XDG_STATE_HOME in your home, rather than
|
||||
the env var expanded). For more info, see pull #8234.
|
||||
'';
|
||||
}
|
||||
12
modules/misc/news/2025/12/2025-12-03_10-14-53.nix
Normal file
12
modules/misc/news/2025/12/2025-12-03_10-14-53.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
time = "2025-12-03T13:14:53+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `programs.calibre`
|
||||
|
||||
Calibre is a powerful and easy to use e-book manager. Users say it’s outstanding
|
||||
and a must-have. It’ll allow you to do nearly everything and it takes things a
|
||||
step beyond normal e-book software. It’s also completely free and open source
|
||||
and great for both casual users and computer experts.
|
||||
'';
|
||||
}
|
||||
12
modules/misc/news/2025/12/2025-12-04_16-34-38.nix
Normal file
12
modules/misc/news/2025/12/2025-12-04_16-34-38.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
time = "2025-12-04T19:34:38+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `programs.screen`
|
||||
|
||||
GNU Screen is a terminal multiplexer, a software application that can
|
||||
be used to multiplex several virtual consoles, allowing a user to access
|
||||
multiple separate login sessions inside a single terminal window, or detach
|
||||
and reattach sessions from a terminal.
|
||||
'';
|
||||
}
|
||||
12
modules/misc/news/2025/12/2025-12-04_22-50-03.nix
Normal file
12
modules/misc/news/2025/12/2025-12-04_22-50-03.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
time = "2025-12-05T01:50:03+00:00";
|
||||
condition = pkgs.stdenv.hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: `programs.hyprlauncher`
|
||||
|
||||
Hyprlauncher is a multipurpose and versatile launcher/picker
|
||||
for hyprland. It’s fast, simple, and provides various modules.
|
||||
'';
|
||||
}
|
||||
10
modules/misc/news/2025/12/2025-12-06_11-03-01.nix
Normal file
10
modules/misc/news/2025/12/2025-12-06_11-03-01.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
time = "2025-12-06T10:03:01+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `programs.npm`
|
||||
|
||||
It allows you manage your npm user configuration (`.npmrc`)
|
||||
and install a specific version of the package.
|
||||
'';
|
||||
}
|
||||
10
modules/misc/news/2025/12/2025-12-06_11-05-43.nix
Normal file
10
modules/misc/news/2025/12/2025-12-06_11-05-43.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
time = "2025-12-06T10:05:43+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `programs.ty`
|
||||
|
||||
It allows to manage the configuration and package
|
||||
of the Python language server `ty` by Astral.
|
||||
'';
|
||||
}
|
||||
32
modules/misc/news/2025/12/2025-12-11_13-04-30.nix
Normal file
32
modules/misc/news/2025/12/2025-12-11_13-04-30.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
time = "2025-12-11T19:04:30+00:00";
|
||||
condition =
|
||||
let
|
||||
helixEnabled = config.programs.helix.enable && config.programs.helix.defaultEditor;
|
||||
kakouneEnabled = config.programs.kakoune.enable && config.programs.kakoune.defaultEditor;
|
||||
neovimEnabled = config.programs.neovim.enable && config.programs.neovim.defaultEditor;
|
||||
vimEnabled = config.programs.vim.enable && config.programs.vim.defaultEditor;
|
||||
emacsEnabled = config.services.emacs.enable && config.services.emacs.defaultEditor;
|
||||
in
|
||||
helixEnabled || kakouneEnabled || neovimEnabled || vimEnabled || emacsEnabled;
|
||||
message = ''
|
||||
The 'defaultEditor' option now sets both {env}`EDITOR` and {env}`VISUAL`
|
||||
environment variables.
|
||||
|
||||
Previously, only {env}`EDITOR` was set. The {env}`VISUAL` variable is now
|
||||
also configured to point to the same editor, which is the expected behavior
|
||||
for modern terminal editors.
|
||||
|
||||
This change affects the following modules:
|
||||
- programs.helix
|
||||
- programs.kakoune
|
||||
- programs.neovim
|
||||
- programs.vim
|
||||
- services.emacs
|
||||
|
||||
No action is required. This change should improve compatibility with tools
|
||||
that check {env}`VISUAL` before {env}`EDITOR`.
|
||||
'';
|
||||
}
|
||||
12
modules/misc/news/2025/12/2025-12-12_19-20-28.nix
Normal file
12
modules/misc/news/2025/12/2025-12-12_19-20-28.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
time = "2025-12-12T19:20:28+00:00";
|
||||
condition = config.xsession.windowManager.herbstluftwm.enable;
|
||||
message = ''
|
||||
It is now possible to disable the `herbstclient` alias in the autostart
|
||||
script by setting `xsession.windowManagers.herbsluftwm.enableAlias = false`.
|
||||
This makes it possible to use the `herbstclient` command in bash functions,
|
||||
though may cause flickering while the autostart script runs.
|
||||
'';
|
||||
}
|
||||
|
|
@ -8,6 +8,10 @@
|
|||
let
|
||||
cfg = config.qt;
|
||||
|
||||
qtctFormat = pkgs.formats.ini {
|
||||
listToValue = values: lib.concatStringsSep ", " values;
|
||||
};
|
||||
|
||||
# Map platform names to their packages.
|
||||
platformPackages = with pkgs; {
|
||||
gnome = [
|
||||
|
|
@ -286,7 +290,34 @@ in
|
|||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
// (lib.genAttrs' [ "qt5ct" "qt6ct" ] (
|
||||
name:
|
||||
lib.nameValuePair "${name}Settings" (
|
||||
lib.mkOption {
|
||||
type = lib.types.nullOr qtctFormat.type;
|
||||
default = null;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
Appearance = {
|
||||
style = "kvantum";
|
||||
icon_theme = "Papirus-Dark";
|
||||
standar_dialogs = "xdgdesktopportal";
|
||||
};
|
||||
Fonts = {
|
||||
fixed = "\"DejaVuSansM Nerd Font Mono,12\"";
|
||||
general = "\"DejaVu Sans,12\"";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Qtct configuration. Writes settings to `${name}/${name}.conf`
|
||||
file. Lists will be translated to comma-separated strings.
|
||||
Fonts must be quoted (see example).
|
||||
'';
|
||||
}
|
||||
)
|
||||
));
|
||||
};
|
||||
|
||||
config =
|
||||
|
|
@ -397,5 +428,18 @@ in
|
|||
]
|
||||
++ lib.optionals (platformTheme.name != null) [ "QT_QPA_PLATFORMTHEME" ]
|
||||
++ lib.optionals (cfg.style.name != null) [ "QT_STYLE_OVERRIDE" ];
|
||||
|
||||
xdg.configFile =
|
||||
lib.pipe
|
||||
[ "qt5ct" "qt6ct" ]
|
||||
[
|
||||
(lib.filter (qtct: cfg."${qtct}Settings" != null))
|
||||
(lib.flip lib.genAttrs' (
|
||||
qtct:
|
||||
lib.nameValuePair "${qtct}/${qtct}.conf" {
|
||||
source = qtctFormat.generate "${qtct}-config" cfg."${qtct}Settings";
|
||||
}
|
||||
))
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ msgstr ""
|
|||
"Project-Id-Version: Home Manager Modules\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
|
||||
"PO-Revision-Date: 2025-03-07 18:58+0000\n"
|
||||
"Last-Translator: 807 <s10855168@gmail.com>\n"
|
||||
"PO-Revision-Date: 2025-12-04 04:17+0000\n"
|
||||
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
|
||||
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
|
||||
"projects/home-manager/modules/zh_Hant/>\n"
|
||||
"Language: zh_Hant\n"
|
||||
|
|
@ -17,7 +17,7 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 5.10.3-dev\n"
|
||||
"X-Generator: Weblate 5.15-dev\n"
|
||||
|
||||
#: modules/files.nix:206
|
||||
msgid "Creating home file links in %s"
|
||||
|
|
@ -25,15 +25,15 @@ msgstr "正在 %s 中建立家目錄檔案連結"
|
|||
|
||||
#: modules/files.nix:219
|
||||
msgid "Cleaning up orphan links from %s"
|
||||
msgstr "正在從 %s 清理孤立連結"
|
||||
msgstr "正在清理 %s 中的孤立連結"
|
||||
|
||||
#: modules/home-environment.nix:647
|
||||
msgid "Creating new profile generation"
|
||||
msgstr "正在建立新一代的配置文件中"
|
||||
msgstr "正在建立新的世代設定檔"
|
||||
|
||||
#: modules/home-environment.nix:650
|
||||
msgid "No change so reusing latest profile generation"
|
||||
msgstr "為發生改變,請重新使用新一代的配置文件"
|
||||
msgstr "沒有變更,將重複使用最新的設定檔世代"
|
||||
|
||||
#: modules/home-environment.nix:699
|
||||
msgid ""
|
||||
|
|
@ -50,18 +50,18 @@ msgid ""
|
|||
"\n"
|
||||
"Then try activating your Home Manager configuration again."
|
||||
msgstr ""
|
||||
"糟糕,Nix 未能安裝您的新 Home Manager 配置文件!\n"
|
||||
"糟糕,Nix 無法安裝您的新 Home Manager 設定檔!\n"
|
||||
"\n"
|
||||
"也許這裏和使用 \"%s\" 安裝的包有衝突?\n"
|
||||
"嘗試運行\n"
|
||||
"可能與使用 \"%s\" 安裝的套件衝突?\n"
|
||||
"請嘗試執行\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"如果有衝突的包,你可以用\n"
|
||||
"如果有衝突的套件,您可以使用以下指令移除\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"來移除。然後嘗試再次啟用您的 Home Manager 配置。"
|
||||
"然後再次嘗試啟用您的 Home Manager 設定。"
|
||||
|
||||
#: modules/home-environment.nix:735
|
||||
msgid "Activating %s"
|
||||
|
|
@ -69,27 +69,27 @@ msgstr "正在啟用 %s"
|
|||
|
||||
#: modules/home-environment.nix:807
|
||||
msgid "%s: unknown option '%s'"
|
||||
msgstr ""
|
||||
msgstr "%s:未知選項 '%s'"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:22
|
||||
msgid "Migrating profile from %s to %s"
|
||||
msgstr "正在從 %S 配置文件轉移到 %s 中"
|
||||
msgstr "正在將設定檔從 %s 遷移至 %s"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:54
|
||||
msgid "Could not find suitable profile directory, tried %s and %s"
|
||||
msgstr "找不到合適的 profile 目錄,已經嘗試 %s 和 %s"
|
||||
msgstr "找不到合適的設定檔目錄,已嘗試 %s 和 %s"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:106
|
||||
msgid "Error: USER is set to \"%s\" but we expect \"%s\""
|
||||
msgstr "錯誤:USER 被設定為 「%s」但我們希望是 「%s」"
|
||||
msgstr "錯誤:USER 被設定為「%s」,但我們的預期為「%s」"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:115
|
||||
msgid "Error: HOME is set to \"%s\" but we expect \"%s\""
|
||||
msgstr "錯誤:HOME 被設定為 「%s」但我們預期得到 「%s」"
|
||||
msgstr "錯誤:HOME 被設定為「%s」,但我們的預期為「%s」"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:132
|
||||
msgid "Starting Home Manager activation"
|
||||
msgstr "正在啟動 Home Manager 初始化程式"
|
||||
msgstr "正在進行 Home Manager 啟用程序"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:136
|
||||
msgid "Sanity checking Nix"
|
||||
|
|
@ -97,19 +97,19 @@ msgstr "正在進行 Nix 完整性檢查"
|
|||
|
||||
#: modules/lib-bash/activation-init.sh:149
|
||||
msgid "This is a dry run"
|
||||
msgstr "這是試運行"
|
||||
msgstr "這是模擬執行"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:153
|
||||
msgid "This is a live run"
|
||||
msgstr "這是在實際運行"
|
||||
msgstr "這是實際執行"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:159
|
||||
msgid "Using Nix version: %s"
|
||||
msgstr "正在使用的 Nix 版本: %s"
|
||||
msgstr "使用中的 Nix 版本:%s"
|
||||
|
||||
#: modules/lib-bash/activation-init.sh:162
|
||||
msgid "Activation variables:"
|
||||
msgstr "啟用的變數:"
|
||||
msgstr "啟用變數:"
|
||||
|
||||
#~ msgid "Creating profile generation %s"
|
||||
#~ msgstr "正在建立配置檔案世代 %s"
|
||||
|
|
|
|||
44
modules/programs/calibre.nix
Normal file
44
modules/programs/calibre.nix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
types
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
;
|
||||
|
||||
cfg = config.programs.calibre;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
|
||||
options.programs.calibre = {
|
||||
enable = mkEnableOption "calibre";
|
||||
package = mkPackageOption pkgs "calibre" { nullable = true; };
|
||||
plugins = mkOption {
|
||||
type = with types; listOf path;
|
||||
default = [ ];
|
||||
description = "List of plugins to install for calibre";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
xdg.configFile = mkIf (cfg.plugins != [ ]) (
|
||||
let
|
||||
symlinkedPlugins = pkgs.symlinkJoin {
|
||||
name = "calibre-plugins";
|
||||
paths = cfg.plugins;
|
||||
};
|
||||
in
|
||||
lib.mapAttrs' (
|
||||
k: _: lib.nameValuePair "calibre/plugins/${k}" { source = (symlinkedPlugins + "/${k}"); }
|
||||
) (builtins.readDir symlinkedPlugins)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ let
|
|||
|
||||
finalPackage = mkOption {
|
||||
inherit visible;
|
||||
type = types.package;
|
||||
type = types.nullOr types.package;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Resulting customized ${name} package
|
||||
|
|
@ -220,15 +220,22 @@ let
|
|||
};
|
||||
|
||||
in
|
||||
|
||||
lib.mkIf cfg.enable {
|
||||
programs.${browser}.finalPackage = lib.mkIf (cfg.package != null) (
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(cfg.package == null && cfg.commandLineArgs != [ ]);
|
||||
message = "Cannot set `commandLineArgs` when `package` is null for ${browser}.";
|
||||
}
|
||||
];
|
||||
|
||||
programs.${browser}.finalPackage =
|
||||
if cfg.commandLineArgs != [ ] then
|
||||
cfg.package.override {
|
||||
commandLineArgs = lib.concatStringsSep " " cfg.commandLineArgs;
|
||||
}
|
||||
else
|
||||
cfg.package
|
||||
);
|
||||
cfg.package;
|
||||
|
||||
home.packages = lib.mkIf (cfg.finalPackage != null) [
|
||||
cfg.finalPackage
|
||||
|
|
|
|||
|
|
@ -197,6 +197,47 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
rules = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.either lib.types.lines lib.types.path);
|
||||
default = { };
|
||||
description = ''
|
||||
Modular rule files for Claude Code.
|
||||
The attribute name becomes the rule filename, and the value is either:
|
||||
- Inline content as a string
|
||||
- A path to a file containing the rule content
|
||||
Rules are stored in .claude/rules/ directory.
|
||||
All markdown files in .claude/rules/ are automatically loaded as project memory.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
code-style = '''
|
||||
# Code Style Guidelines
|
||||
|
||||
- Use consistent formatting
|
||||
- Follow language conventions
|
||||
''';
|
||||
testing = '''
|
||||
# Testing Conventions
|
||||
|
||||
- Write tests for all new features
|
||||
- Maintain test coverage above 80%
|
||||
''';
|
||||
security = ./rules/security.md;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
rulesDir = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a directory containing rule files for Claude Code.
|
||||
Rule files from this directory will be symlinked to .claude/rules/.
|
||||
All markdown files in this directory are automatically loaded as project memory.
|
||||
'';
|
||||
example = lib.literalExpression "./rules";
|
||||
};
|
||||
|
||||
agentsDir = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
|
|
@ -325,6 +366,10 @@ in
|
|||
assertion = !(cfg.memory.text != null && cfg.memory.source != null);
|
||||
message = "Cannot specify both `programs.claude-code.memory.text` and `programs.claude-code.memory.source`";
|
||||
}
|
||||
{
|
||||
assertion = !(cfg.rules != { } && cfg.rulesDir != null);
|
||||
message = "Cannot specify both `programs.claude-code.rules` and `programs.claude-code.rulesDir`";
|
||||
}
|
||||
{
|
||||
assertion = !(cfg.agents != { } && cfg.agentsDir != null);
|
||||
message = "Cannot specify both `programs.claude-code.agents` and `programs.claude-code.agentsDir`";
|
||||
|
|
@ -348,7 +393,7 @@ in
|
|||
makeWrapperArgs = lib.flatten (
|
||||
lib.filter (x: x != [ ]) [
|
||||
(lib.optional (cfg.mcpServers != { }) [
|
||||
"--add-flags"
|
||||
"--append-flags"
|
||||
"--mcp-config ${jsonFormat.generate "claude-code-mcp-config.json" { inherit (cfg) mcpServers; }}"
|
||||
])
|
||||
]
|
||||
|
|
@ -386,6 +431,11 @@ in
|
|||
if cfg.memory.text != null then { text = cfg.memory.text; } else { source = cfg.memory.source; }
|
||||
);
|
||||
|
||||
".claude/rules" = lib.mkIf (cfg.rulesDir != null) {
|
||||
source = cfg.rulesDir;
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
".claude/agents" = lib.mkIf (cfg.agentsDir != null) {
|
||||
source = cfg.agentsDir;
|
||||
recursive = true;
|
||||
|
|
@ -406,6 +456,12 @@ in
|
|||
recursive = true;
|
||||
};
|
||||
}
|
||||
// lib.mapAttrs' (
|
||||
name: content:
|
||||
lib.nameValuePair ".claude/rules/${name}.md" (
|
||||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) cfg.rules
|
||||
// lib.mapAttrs' (
|
||||
name: content:
|
||||
lib.nameValuePair ".claude/agents/${name}.md" (
|
||||
|
|
|
|||
|
|
@ -68,8 +68,15 @@ in
|
|||
in
|
||||
lib.mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
# Auto-enable git integration if programs.git.diff-highlight.enable was set to true
|
||||
programs.diff-highlight.enableGitIntegration = lib.mkIf oldOptionEnabled (lib.mkOverride 1490 true);
|
||||
assertions = [
|
||||
{
|
||||
assertion = !cfg.enableGitIntegration || config.programs.git.package != null;
|
||||
message = ''
|
||||
programs.diff-highlight.enableGitIntegration requires programs.git.package to be set.
|
||||
Please set programs.git.package to a valid git package.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
lib.optional
|
||||
|
|
@ -77,9 +84,12 @@ in
|
|||
cfg.enableGitIntegration && options.programs.diff-highlight.enableGitIntegration.highestPrio == 1490
|
||||
)
|
||||
"`programs.diff-highlight.enableGitIntegration` automatic enablement is deprecated. Please explicitly set `programs.diff-highlight.enableGitIntegration = true`.";
|
||||
|
||||
# Auto-enable git integration if programs.git.diff-highlight.enable was set to true
|
||||
programs.diff-highlight.enableGitIntegration = lib.mkIf oldOptionEnabled (lib.mkOverride 1490 true);
|
||||
})
|
||||
|
||||
(mkIf (cfg.enable && cfg.enableGitIntegration) {
|
||||
(mkIf (cfg.enable && cfg.enableGitIntegration && config.programs.git.package != null) {
|
||||
programs.git = {
|
||||
enable = lib.mkDefault true;
|
||||
iniContent =
|
||||
|
|
|
|||
|
|
@ -21,14 +21,19 @@ in
|
|||
settings = lib.mkOption {
|
||||
inherit (jsonFormat) type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
"theme": "Default",
|
||||
"vimMode": true,
|
||||
"preferredEditor": "nvim",
|
||||
"autoAccept": true
|
||||
}
|
||||
'';
|
||||
example = {
|
||||
ui.theme = "Default";
|
||||
general = {
|
||||
vimMode = true;
|
||||
preferredEditor = "nvim";
|
||||
previewFeatures = true;
|
||||
};
|
||||
ide.enabled = true;
|
||||
privacy.usageStatisticsEnabled = false;
|
||||
tools.autoAccept = false;
|
||||
context.loadMemoryFromIncludeDirectories = true;
|
||||
security.auth.selectedType = "oauth-personal";
|
||||
};
|
||||
description = "JSON config for gemini-cli";
|
||||
};
|
||||
|
||||
|
|
@ -81,12 +86,12 @@ in
|
|||
};
|
||||
|
||||
defaultModel = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "gemini-2.5-pro";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "gemini-2.5-flash";
|
||||
description = ''
|
||||
The default model to use for the CLI.
|
||||
Will be set as $GEMINI_MODEL.
|
||||
Will be set as $GEMINI_MODEL when configured.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -138,7 +143,9 @@ in
|
|||
file.".gemini/settings.json" = lib.mkIf (cfg.settings != { }) {
|
||||
source = jsonFormat.generate "gemini-cli-settings.json" cfg.settings;
|
||||
};
|
||||
sessionVariables.GEMINI_MODEL = cfg.defaultModel;
|
||||
sessionVariables = lib.mkIf (cfg.defaultModel != null) {
|
||||
GEMINI_MODEL = cfg.defaultModel;
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ in
|
|||
enable = mkEnableOption "Git";
|
||||
|
||||
package = lib.mkPackageOption pkgs "git" {
|
||||
nullable = true;
|
||||
example = "pkgs.gitFull";
|
||||
extraDescription = ''
|
||||
Use {var}`pkgs.gitFull`
|
||||
|
|
@ -328,7 +329,7 @@ in
|
|||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
home.packages = lib.optionals (cfg.package != null) [ cfg.package ];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
|
|
@ -516,7 +517,7 @@ in
|
|||
Type = "oneshot";
|
||||
ExecStart =
|
||||
let
|
||||
exe = lib.getExe cfg.package;
|
||||
exe = if cfg.package != null then lib.getExe cfg.package else "git";
|
||||
in
|
||||
''
|
||||
"${exe}" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i
|
||||
|
|
@ -553,7 +554,7 @@ in
|
|||
launchd.agents =
|
||||
let
|
||||
baseArguments = [
|
||||
"${lib.getExe cfg.package}"
|
||||
"${if cfg.package != null then lib.getExe cfg.package else "git"}"
|
||||
"for-each-repo"
|
||||
"--keep-going"
|
||||
"--config=maintenance.repo"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@ in
|
|||
default = false;
|
||||
description = ''
|
||||
Whether to configure {command}`hx` as the default
|
||||
editor using the {env}`EDITOR` environment variable.
|
||||
editor using the {env}`EDITOR` and {env}`VISUAL`
|
||||
environment variables.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -225,7 +226,10 @@ in
|
|||
else
|
||||
[ cfg.package ];
|
||||
|
||||
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "hx"; };
|
||||
home.sessionVariables = mkIf cfg.defaultEditor {
|
||||
EDITOR = "hx";
|
||||
VISUAL = "hx";
|
||||
};
|
||||
|
||||
xdg.configFile =
|
||||
let
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ let
|
|||
jsonFormat = pkgs.formats.json { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.perchun ];
|
||||
meta.maintainers = [ lib.maintainers.PerchunPak ];
|
||||
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "programs" "hyprpanel" "dontAssertNotificationDaemons " ] ''
|
||||
|
|
|
|||
81
modules/programs/infat.nix
Normal file
81
modules/programs/infat.nix
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.infat;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
configDir =
|
||||
if config.xdg.enable then
|
||||
config.xdg.configHome
|
||||
else
|
||||
"${config.home.homeDirectory}/Library/Application Support";
|
||||
|
||||
configFile = "${configDir}/infat/config.toml";
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
mirkolenz
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.infat = {
|
||||
enable = lib.mkEnableOption "infat";
|
||||
package = lib.mkPackageOption pkgs "infat" { nullable = true; };
|
||||
settings = lib.mkOption {
|
||||
type = tomlFormat.type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
extensions = {
|
||||
md = "TextEdit";
|
||||
html = "Safari";
|
||||
pdf = "Preview";
|
||||
};
|
||||
schemes = {
|
||||
mailto = "Mail";
|
||||
web = "Safari";
|
||||
};
|
||||
types = {
|
||||
plain-text = "VSCode";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to
|
||||
{file}`$XDG_CONFIG_HOME/infat/config.toml`.
|
||||
'';
|
||||
};
|
||||
autoActivate = lib.mkEnableOption "auto-activate infat" // {
|
||||
default = true;
|
||||
example = false;
|
||||
description = ''
|
||||
Automatically activate infat on startup.
|
||||
This is useful if you want to use infat as a
|
||||
default application handler for certain file types.
|
||||
If you don't want this, set this to false.
|
||||
This option is only effective if `settings` is set.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.infat" pkgs lib.platforms.darwin)
|
||||
];
|
||||
home = {
|
||||
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
file.${configFile} = lib.mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "infat-settings.toml" cfg.settings;
|
||||
};
|
||||
activation = lib.mkIf (cfg.settings != { } && cfg.package != null && cfg.autoActivate) {
|
||||
infat = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
run ${lib.getExe cfg.package} --config "${configFile}" $VERBOSE_ARG
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -705,7 +705,8 @@ in
|
|||
default = false;
|
||||
description = ''
|
||||
Whether to configure {command}`kak` as the default
|
||||
editor using the {env}`EDITOR` environment variable.
|
||||
editor using the {env}`EDITOR` and {env}`VISUAL`
|
||||
environment variables.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -755,7 +756,10 @@ in
|
|||
programs.kakoune.finalPackage = lib.mkIf (cfg.package != null) kakouneWithPlugins;
|
||||
|
||||
home.packages = lib.mkIf (cfg.finalPackage != null) [ cfg.finalPackage ];
|
||||
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; };
|
||||
home.sessionVariables = mkIf cfg.defaultEditor {
|
||||
EDITOR = "kak";
|
||||
VISUAL = "kak";
|
||||
};
|
||||
xdg.configFile = lib.mkMerge [
|
||||
{ "kak/kakrc".source = configFile; }
|
||||
(mkIf (cfg.colorSchemePackage != null) {
|
||||
|
|
|
|||
|
|
@ -37,13 +37,17 @@ in
|
|||
options = lib.mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
]);
|
||||
default = { };
|
||||
description = "GNU-style options to be set via {env}`$LESS`.";
|
||||
let
|
||||
scalar = oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
];
|
||||
attrs = attrsOf (either scalar (listOf scalar));
|
||||
in
|
||||
coercedTo attrs (lib.cli.toGNUCommandLine { }) (listOf str);
|
||||
default = [ ];
|
||||
description = "Options to be set via {env}`$LESS`.";
|
||||
example = {
|
||||
RAW-CONTROL-CHARS = true;
|
||||
quiet = true;
|
||||
|
|
@ -58,10 +62,10 @@ in
|
|||
|
||||
xdg.configFile."lesskey" = lib.mkIf (cfg.config != "") { text = cfg.config; };
|
||||
|
||||
programs.less.config = lib.mkIf (cfg.options != { }) (
|
||||
programs.less.config = lib.mkIf (cfg.options != [ ]) (
|
||||
lib.mkBefore ''
|
||||
#env
|
||||
LESS = ${lib.cli.toGNUCommandLineShell { } cfg.options}
|
||||
LESS = ${lib.concatStringsSep " " cfg.options}
|
||||
''
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,121 +7,46 @@
|
|||
|
||||
let
|
||||
inherit (lib)
|
||||
concatMapStringsSep
|
||||
literalExpression
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
mkRemovedOptionModule
|
||||
mkPackageOption
|
||||
optionals
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.neovim;
|
||||
|
||||
fileType =
|
||||
(import ../lib/file-type.nix {
|
||||
inherit (config.home) homeDirectory;
|
||||
inherit lib pkgs;
|
||||
}).fileType;
|
||||
inherit
|
||||
(
|
||||
(import ../lib/file-type.nix {
|
||||
inherit (config.home) homeDirectory;
|
||||
inherit lib pkgs;
|
||||
})
|
||||
)
|
||||
fileType
|
||||
;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
pluginWithConfigType = types.submodule {
|
||||
options = {
|
||||
config = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
description = "Script to configure this plugin. The scripting language should match type.";
|
||||
default = null;
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.either (types.enum [
|
||||
"lua"
|
||||
"viml"
|
||||
"teal"
|
||||
"fennel"
|
||||
]) types.str;
|
||||
description = "Language used in config. Configurations are aggregated per-language.";
|
||||
default = "viml";
|
||||
};
|
||||
|
||||
optional = mkEnableOption "optional" // {
|
||||
description = "Don't load by default (load with :packadd)";
|
||||
};
|
||||
|
||||
plugin = lib.mkPackageOption pkgs.vimPlugins "plugin" {
|
||||
default = null;
|
||||
example = "pkgs.vimPlugins.nvim-treesitter";
|
||||
pkgsText = "pkgs.vimPlugins";
|
||||
};
|
||||
|
||||
runtime = mkOption {
|
||||
default = { };
|
||||
# passing actual "${xdg.configHome}/nvim" as basePath was a bit tricky
|
||||
# due to how fileType.target is implemented
|
||||
type = fileType "programs.neovim.plugins._.runtime" "{var}`xdg.configHome/nvim`" "nvim";
|
||||
example = literalExpression ''
|
||||
{ "ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; }
|
||||
'';
|
||||
description = ''
|
||||
Set of files that have to be linked in nvim config folder.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
allPlugins =
|
||||
cfg.plugins
|
||||
++ lib.optional cfg.coc.enable {
|
||||
type = "viml";
|
||||
plugin = cfg.coc.package;
|
||||
config = cfg.coc.pluginConfig;
|
||||
optional = false;
|
||||
};
|
||||
|
||||
luaPackages = cfg.finalPackage.unwrapped.lua.pkgs;
|
||||
resolvedExtraLuaPackages = cfg.extraLuaPackages luaPackages;
|
||||
|
||||
extraMakeWrapperArgs = lib.optionalString (
|
||||
cfg.extraPackages != [ ]
|
||||
) ''--suffix PATH : "${lib.makeBinPath cfg.extraPackages}"'';
|
||||
extraMakeWrapperLuaCArgs =
|
||||
lib.optionalString (resolvedExtraLuaPackages != [ ])
|
||||
''--suffix LUA_CPATH ";" "${
|
||||
lib.concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages
|
||||
}"'';
|
||||
extraMakeWrapperLuaArgs =
|
||||
lib.optionalString (resolvedExtraLuaPackages != [ ])
|
||||
''--suffix LUA_PATH ";" "${
|
||||
lib.concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages
|
||||
}"'';
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ khaneliman ];
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [
|
||||
"programs"
|
||||
"neovim"
|
||||
"withPython"
|
||||
] "Python2 support has been removed from neovim.")
|
||||
(mkRemovedOptionModule [
|
||||
"programs"
|
||||
"neovim"
|
||||
"extraPythonPackages"
|
||||
] "Python2 support has been removed from neovim.")
|
||||
(mkRemovedOptionModule [ "programs" "neovim" "configure" ] ''
|
||||
programs.neovim.configure is deprecated.
|
||||
Other programs.neovim options can override its settings or ignore them.
|
||||
Please use the other options at your disposal:
|
||||
configure.packages.*.opt -> programs.neovim.plugins = [ { plugin = ...; optional = true; }]
|
||||
configure.packages.*.start -> programs.neovim.plugins = [ { plugin = ...; }]
|
||||
configure.customRC -> programs.neovim.extraConfig
|
||||
'')
|
||||
];
|
||||
options = {
|
||||
programs.neovim = {
|
||||
enable = mkEnableOption "Neovim";
|
||||
|
||||
package = mkPackageOption pkgs "neovim" { default = "neovim-unwrapped"; };
|
||||
|
||||
finalPackage = mkOption {
|
||||
type = types.package;
|
||||
readOnly = true;
|
||||
description = "Resulting customized neovim package.";
|
||||
};
|
||||
|
||||
# Aliases
|
||||
viAlias = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
|
@ -146,6 +71,17 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
defaultEditor = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to configure {command}`nvim` as the default
|
||||
editor using the {env}`EDITOR` and {env}`VISUAL`
|
||||
environment variables.
|
||||
'';
|
||||
};
|
||||
|
||||
# Providers & Runtimes
|
||||
withNodeJs = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
|
@ -155,11 +91,12 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
withRuby = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = true;
|
||||
withPerl = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable ruby provider.
|
||||
Enable perl provider. Set to `true` to
|
||||
use Perl plugins.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -172,21 +109,16 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
withRuby = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable ruby provider.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPython3Packages = mkOption {
|
||||
# In case we get a plain list, we need to turn it into a function,
|
||||
# as expected by the function in nixpkgs.
|
||||
# The only way to do so is to call `const`, which will ignore its input.
|
||||
type =
|
||||
let
|
||||
fromType = types.listOf types.package;
|
||||
in
|
||||
types.coercedTo fromType (lib.flip lib.warn lib.const ''
|
||||
Assigning a plain list to extraPython3Packages is deprecated.
|
||||
Please assign a function taking a package set as argument, so
|
||||
extraPython3Packages = [ pkgs.python3Packages.xxx ];
|
||||
should become
|
||||
extraPython3Packages = ps: [ ps.xxx ];
|
||||
'') (types.functionTo fromType);
|
||||
type = types.functionTo (types.listOf types.package);
|
||||
default = _: [ ];
|
||||
defaultText = literalExpression "ps: [ ]";
|
||||
example = literalExpression "pyPkgs: with pyPkgs; [ python-language-server ]";
|
||||
|
|
@ -198,21 +130,8 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
# We get the Lua package from the final package and use its
|
||||
# Lua packageset to evaluate the function that this option was set to.
|
||||
# This ensures that we always use the same Lua version as the Neovim package.
|
||||
extraLuaPackages = mkOption {
|
||||
type =
|
||||
let
|
||||
fromType = types.listOf types.package;
|
||||
in
|
||||
types.coercedTo fromType (lib.flip lib.warn lib.const ''
|
||||
Assigning a plain list to extraLuaPackages is deprecated.
|
||||
Please assign a function taking a package set as argument, so
|
||||
extraLuaPackages = [ pkgs.lua51Packages.xxx ];
|
||||
should become
|
||||
extraLuaPackages = ps: [ ps.xxx ];
|
||||
'') (types.functionTo fromType);
|
||||
type = types.functionTo (types.listOf types.package);
|
||||
default = _: [ ];
|
||||
defaultText = literalExpression "ps: [ ]";
|
||||
example = literalExpression "luaPkgs: with luaPkgs; [ luautf8 ]";
|
||||
|
|
@ -224,8 +143,34 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
# Wrapper Configuration
|
||||
extraName = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra name appended to the wrapper package name.
|
||||
'';
|
||||
};
|
||||
|
||||
autowrapRuntimeDeps = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to automatically wrap the binary with the runtime dependencies of the plugins.
|
||||
'';
|
||||
};
|
||||
|
||||
waylandSupport = mkOption {
|
||||
type = types.bool;
|
||||
default = pkgs.stdenv.isLinux;
|
||||
defaultText = literalExpression "pkgs.stdenv.isLinux";
|
||||
description = ''
|
||||
Whether to enable Wayland clipboard support.
|
||||
'';
|
||||
};
|
||||
|
||||
extraWrapperArgs = mkOption {
|
||||
type = with types; listOf str;
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[
|
||||
|
|
@ -246,53 +191,14 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
generatedConfigViml = mkOption {
|
||||
type = types.lines;
|
||||
visible = true;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Generated vimscript config.
|
||||
'';
|
||||
};
|
||||
|
||||
generatedConfigs = mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
visible = true;
|
||||
readOnly = true;
|
||||
example = literalExpression ''
|
||||
{
|
||||
viml = '''
|
||||
" Generated by home-manager
|
||||
map <leader> ,
|
||||
''';
|
||||
|
||||
lua = '''
|
||||
-- Generated by home-manager
|
||||
vim.opt.background = "dark"
|
||||
''';
|
||||
}'';
|
||||
description = ''
|
||||
Generated configurations with as key their language (set via type).
|
||||
'';
|
||||
};
|
||||
|
||||
package = lib.mkPackageOption pkgs "neovim" { default = "neovim-unwrapped"; };
|
||||
|
||||
finalPackage = mkOption {
|
||||
type = types.package;
|
||||
readOnly = true;
|
||||
description = "Resulting customized neovim package.";
|
||||
};
|
||||
|
||||
defaultEditor = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to configure {command}`nvim` as the default
|
||||
editor using the {env}`EDITOR` environment variable.
|
||||
'';
|
||||
extraPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
example = literalExpression "[ pkgs.shfmt ]";
|
||||
description = "Extra packages available to nvim.";
|
||||
};
|
||||
|
||||
# Configuration & Plugins
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
|
|
@ -315,37 +221,78 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = [ ];
|
||||
example = literalExpression "[ pkgs.shfmt ]";
|
||||
description = "Extra packages available to nvim.";
|
||||
};
|
||||
plugins =
|
||||
let
|
||||
pluginWithConfigType = types.submodule {
|
||||
options = {
|
||||
config = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
description = "Script to configure this plugin. The scripting language should match type.";
|
||||
default = null;
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = with types; listOf (either package pluginWithConfigType);
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
with pkgs.vimPlugins; [
|
||||
yankring
|
||||
vim-nix
|
||||
{ plugin = vim-startify;
|
||||
config = "let g:startify_change_to_vcs_root = 0";
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of vim plugins to install optionally associated with
|
||||
configuration to be placed in init.vim.
|
||||
type = mkOption {
|
||||
type = types.either (types.enum [
|
||||
"lua"
|
||||
"viml"
|
||||
"teal"
|
||||
"fennel"
|
||||
]) types.str;
|
||||
description = "Language used in config. Configurations are aggregated per-language.";
|
||||
default = "viml";
|
||||
};
|
||||
|
||||
This option is mutually exclusive with {var}`configure`.
|
||||
'';
|
||||
};
|
||||
optional = mkEnableOption "optional" // {
|
||||
description = "Don't load by default (load with :packadd)";
|
||||
};
|
||||
|
||||
plugin = mkPackageOption pkgs.vimPlugins "plugin" {
|
||||
default = null;
|
||||
example = "pkgs.vimPlugins.nvim-treesitter";
|
||||
pkgsText = "pkgs.vimPlugins";
|
||||
};
|
||||
|
||||
runtime = mkOption {
|
||||
default = { };
|
||||
# passing actual "${xdg.configHome}/nvim" as basePath was a bit tricky
|
||||
# due to how fileType.target is implemented
|
||||
type = fileType "programs.neovim.plugins._.runtime" "{var}`xdg.configHome/nvim`" "nvim";
|
||||
example = literalExpression ''
|
||||
{ "ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; }
|
||||
'';
|
||||
description = ''
|
||||
Set of files that have to be linked in nvim config folder.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
mkOption {
|
||||
type = types.listOf (types.either types.package pluginWithConfigType);
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
with pkgs.vimPlugins;
|
||||
[
|
||||
yankring
|
||||
vim-nix
|
||||
{ plugin = vim-startify;
|
||||
config = "let g:startify_change_to_vcs_root = 0";
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of vim plugins to install optionally associated with
|
||||
configuration to be placed in init.vim.
|
||||
|
||||
This option is mutually exclusive with {var}`configure`.
|
||||
'';
|
||||
};
|
||||
|
||||
coc = {
|
||||
enable = mkEnableOption "Coc";
|
||||
|
||||
package = lib.mkPackageOption pkgs "coc-nvim" {
|
||||
package = mkPackageOption pkgs "coc-nvim" {
|
||||
default = [
|
||||
"vimPlugins"
|
||||
"coc-nvim"
|
||||
|
|
@ -375,7 +322,7 @@ in
|
|||
filetypes = [ "haskell" "lhaskell" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Extra configuration lines to add to
|
||||
|
|
@ -392,11 +339,52 @@ in
|
|||
description = "Script to configure CoC. Must be viml.";
|
||||
};
|
||||
};
|
||||
|
||||
# Generated / Read-Only
|
||||
generatedConfigViml = mkOption {
|
||||
type = types.lines;
|
||||
visible = true;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Generated vimscript config.
|
||||
'';
|
||||
};
|
||||
|
||||
generatedConfigs = mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
visible = true;
|
||||
readOnly = true;
|
||||
example = literalExpression ''
|
||||
{
|
||||
viml = '''
|
||||
" Generated by home-manager
|
||||
map <leader> ,
|
||||
''';
|
||||
|
||||
lua = '''
|
||||
-- Generated by home-manager
|
||||
vim.opt.background = "dark"
|
||||
''';
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Generated configurations with as key their language (set via type).
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
config = mkIf cfg.enable (
|
||||
let
|
||||
allPlugins =
|
||||
cfg.plugins
|
||||
++ lib.optional cfg.coc.enable {
|
||||
type = "viml";
|
||||
plugin = cfg.coc.package;
|
||||
config = cfg.coc.pluginConfig;
|
||||
optional = false;
|
||||
};
|
||||
|
||||
defaultPlugin = {
|
||||
type = "viml";
|
||||
plugin = null;
|
||||
|
|
@ -412,11 +400,38 @@ 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
|
||||
;
|
||||
|
|
@ -428,54 +443,63 @@ in
|
|||
wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package (
|
||||
neovimConfig
|
||||
// {
|
||||
inherit (cfg)
|
||||
extraName
|
||||
autowrapRuntimeDeps
|
||||
waylandSupport
|
||||
withNodeJs
|
||||
;
|
||||
wrapperArgs =
|
||||
(lib.escapeShellArgs (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs))
|
||||
+ " "
|
||||
+ extraMakeWrapperArgs
|
||||
+ " "
|
||||
+ extraMakeWrapperLuaCArgs
|
||||
+ " "
|
||||
+ extraMakeWrapperLuaArgs;
|
||||
neovimConfig.wrapperArgs
|
||||
++ cfg.extraWrapperArgs
|
||||
++ extraMakeWrapperArgs
|
||||
++ extraMakeWrapperLuaCArgs
|
||||
++ extraMakeWrapperLuaArgs;
|
||||
wrapRc = false;
|
||||
}
|
||||
);
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
{
|
||||
programs.neovim = {
|
||||
generatedConfigViml = neovimConfig.neovimRcContent;
|
||||
|
||||
programs.neovim.generatedConfigViml = neovimConfig.neovimRcContent;
|
||||
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.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;
|
||||
finalPackage = wrappedNeovim';
|
||||
};
|
||||
|
||||
home.packages = [ cfg.finalPackage ];
|
||||
home = {
|
||||
packages = [ cfg.finalPackage ];
|
||||
|
||||
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "nvim"; };
|
||||
sessionVariables = mkIf cfg.defaultEditor {
|
||||
EDITOR = "nvim";
|
||||
VISUAL = "nvim";
|
||||
};
|
||||
|
||||
home.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
|
||||
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" =
|
||||
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/init.lua" = mkIf (luaRcContent != "") { text = luaRcContent; };
|
||||
|
||||
"nvim/coc-settings.json" = mkIf cfg.coc.enable {
|
||||
source = jsonFormat.generate "coc-settings.json" cfg.coc.settings;
|
||||
|
|
@ -483,7 +507,6 @@ in
|
|||
}
|
||||
]
|
||||
);
|
||||
|
||||
programs.neovim.finalPackage = wrappedNeovim';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
74
modules/programs/npm.nix
Normal file
74
modules/programs/npm.nix
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/programs/npm.nix
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.npm;
|
||||
|
||||
xdgConfigHome = lib.removePrefix config.home.homeDirectory config.xdg.configHome;
|
||||
configFile = if config.home.preferXdgDirectories then "${xdgConfigHome}/npm/npmrc" else ".npmrc";
|
||||
|
||||
iniFormat = pkgs.formats.ini {
|
||||
listsAsDuplicateKeys = true;
|
||||
};
|
||||
|
||||
toNpmrc =
|
||||
let
|
||||
mkLine = lib.generators.mkKeyValueDefault { } "=";
|
||||
mkLines = k: v: if lib.isList v then map (x: mkLine "${k}[]" x) v else [ (mkLine k v) ];
|
||||
in
|
||||
attrs: lib.concatLines (lib.concatLists (lib.mapAttrsToList mkLines attrs));
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ mirkolenz ];
|
||||
|
||||
options = {
|
||||
programs.npm = {
|
||||
enable = lib.mkEnableOption "{command}`npm` user config";
|
||||
|
||||
package = lib.mkPackageOption pkgs [ "nodejs" ] {
|
||||
example = "nodejs_24";
|
||||
nullable = true;
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.attrsOf iniFormat.lib.types.atom;
|
||||
description = ''
|
||||
The user-specific npm configuration.
|
||||
See <https://docs.npmjs.com/cli/using-npm/config> and
|
||||
<https://docs.npmjs.com/cli/configuring-npm/npmrc>
|
||||
for more information.
|
||||
'';
|
||||
default = {
|
||||
prefix = "\${HOME}/.npm";
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
color = true;
|
||||
include = [
|
||||
"dev"
|
||||
"prod"
|
||||
];
|
||||
init-license = "MIT";
|
||||
prefix = "''${HOME}/.npm";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home = {
|
||||
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
file.${configFile} = lib.mkIf (cfg.settings != { }) {
|
||||
text = toNpmrc cfg.settings;
|
||||
};
|
||||
sessionVariables = lib.mkIf (cfg.settings != { }) {
|
||||
NPM_CONFIG_USERCONFIG = "${config.home.homeDirectory}/${configFile}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ in
|
|||
options.programs.parallel = {
|
||||
enable = mkEnableOption "GNU Parallel";
|
||||
|
||||
package = lib.mkPackageOption pkgs "parallel-full" { };
|
||||
package = lib.mkPackageOption pkgs "parallel-full" { nullable = true; };
|
||||
|
||||
will-cite = mkOption {
|
||||
type = types.bool;
|
||||
|
|
@ -33,7 +33,7 @@ in
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
home = {
|
||||
packages = [ cfg.package ];
|
||||
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)";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
localStorage = calendar: name: acc: {
|
||||
name = "storage";
|
||||
params = [ "${name}-local" ];
|
||||
params = [ "${if calendar then "calendar" else "contacts"}-${name}-local" ];
|
||||
children =
|
||||
(attrsToDirectives {
|
||||
inherit (acc.local) path;
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
|
||||
remoteStorage = calendar: name: acc: {
|
||||
name = "storage";
|
||||
params = [ "${name}-remote" ];
|
||||
params = [ "${if calendar then "calendar" else "contacts"}-${name}-remote" ];
|
||||
children =
|
||||
(attrsToDirectives {
|
||||
inherit (acc.remote) url;
|
||||
|
|
@ -91,8 +91,8 @@
|
|||
params = lib.singleton "${if calendar then "calendar" else "contacts"}-${name}";
|
||||
children =
|
||||
(attrsToDirectives {
|
||||
storage_a = "${name}-local";
|
||||
storage_b = "${name}-remote";
|
||||
storage_a = "${if calendar then "calendar" else "contacts"}-${name}-local";
|
||||
storage_b = "${if calendar then "calendar" else "contacts"}-${name}-remote";
|
||||
})
|
||||
++ acc.pimsync.extraPairDirectives;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ in
|
|||
default = { };
|
||||
apply = lib.mergeAttrs {
|
||||
vfs-cache-mode = "full";
|
||||
cache-dir = "%C";
|
||||
cache-dir = "%C/rclone";
|
||||
};
|
||||
description = ''
|
||||
An attribute set of option values passed to `rclone mount`. To set
|
||||
|
|
|
|||
55
modules/programs/screen.nix
Normal file
55
modules/programs/screen.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
types
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
;
|
||||
|
||||
cfg = config.programs.screen;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
|
||||
options.programs.screen = {
|
||||
enable = mkEnableOption "screen";
|
||||
package = mkPackageOption pkgs "screen" { nullable = true; };
|
||||
screenrc = mkOption {
|
||||
type = with types; nullOr (either path lines);
|
||||
default = null;
|
||||
example = ''
|
||||
screen -t rtorrent rtorrent
|
||||
screen -t irssi irssi
|
||||
screen -t centerim centerim
|
||||
screen -t ncmpc ncmpc -c
|
||||
screen -t bash4
|
||||
screen -t bash5
|
||||
screen -t bash6
|
||||
screen -t bash7
|
||||
screen -t bash8
|
||||
screen -t bash9
|
||||
altscreen on
|
||||
term screen-256color
|
||||
bind ',' prev
|
||||
bind '.' next
|
||||
'';
|
||||
description = ''
|
||||
Config file for GNU Screen. All the details can be found here:
|
||||
<https://www.gnu.org/software/screen/manual/screen.html>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
home.file.".screenrc" = mkIf (cfg.screenrc != null) {
|
||||
source = if lib.isPath cfg.screenrc then cfg.screenrc else pkgs.writeText "screenrc" cfg.screenrc;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ in
|
|||
eval "$(sheldon source)"
|
||||
'';
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
eval "$(sheldon source)"
|
||||
'';
|
||||
|
||||
|
|
|
|||
|
|
@ -151,14 +151,7 @@ let
|
|||
identityFile = mkOption {
|
||||
type = with types; either (listOf str) (nullOr str);
|
||||
default = [ ];
|
||||
apply =
|
||||
p:
|
||||
if p == null then
|
||||
[ ]
|
||||
else if lib.isString p then
|
||||
[ p ]
|
||||
else
|
||||
p;
|
||||
apply = p: if p == null then [ ] else lib.toList p;
|
||||
description = ''
|
||||
Specifies files from which the user identity is read.
|
||||
Identities will be tried in the given order.
|
||||
|
|
@ -168,14 +161,7 @@ let
|
|||
identityAgent = mkOption {
|
||||
type = with types; either (listOf str) (nullOr str);
|
||||
default = [ ];
|
||||
apply =
|
||||
p:
|
||||
if p == null then
|
||||
[ ]
|
||||
else if lib.isString p then
|
||||
[ p ]
|
||||
else
|
||||
p;
|
||||
apply = p: if p == null then [ ] else lib.toList p;
|
||||
description = ''
|
||||
Specifies the location of the ssh identity agent.
|
||||
'';
|
||||
|
|
@ -265,14 +251,7 @@ let
|
|||
certificateFile = mkOption {
|
||||
type = with types; either (listOf str) (nullOr str);
|
||||
default = [ ];
|
||||
apply =
|
||||
p:
|
||||
if p == null then
|
||||
[ ]
|
||||
else if lib.isString p then
|
||||
[ p ]
|
||||
else
|
||||
p;
|
||||
apply = p: if p == null then [ ] else lib.toList p;
|
||||
description = ''
|
||||
Specifies files from which the user certificate is read.
|
||||
'';
|
||||
|
|
@ -451,7 +430,13 @@ let
|
|||
++ map (f: " LocalForward" + addressPort f.bind + addressPort f.host) cf.localForwards
|
||||
++ map (f: " RemoteForward" + addressPort f.bind + addressPort f.host) cf.remoteForwards
|
||||
++ map (f: " DynamicForward" + addressPort f) cf.dynamicForwards
|
||||
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
|
||||
++ [
|
||||
(lib.generators.toKeyValue {
|
||||
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";
|
||||
listsAsDuplicateKeys = true;
|
||||
indent = " ";
|
||||
} cf.extraOptions)
|
||||
]
|
||||
);
|
||||
|
||||
in
|
||||
|
|
|
|||
|
|
@ -106,13 +106,13 @@ in
|
|||
];
|
||||
|
||||
programs.bash.initExtra = lib.mkIf cfg.enableBashIntegration ''
|
||||
eval "$(${lib.getExe cfg.package} init bash)"
|
||||
source ${cfg.package}/share/television/completion.bash
|
||||
'';
|
||||
programs.zsh.initContent = lib.mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${lib.getExe cfg.package} init zsh)"
|
||||
source ${cfg.package}/share/television/completion.zsh
|
||||
'';
|
||||
programs.fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init fish | source
|
||||
source ${cfg.package}/share/television/completion.fish
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ let
|
|||
attrValues
|
||||
concatStringsSep
|
||||
filter
|
||||
flatten
|
||||
length
|
||||
literalExpression
|
||||
mapAttrsToList
|
||||
|
|
@ -918,7 +919,14 @@ in
|
|||
calendarAccounts = getAccountsForProfile name enabledCalendarAccountsWithId;
|
||||
contactAccounts = getAccountsForProfile name enabledContactAccountsWithId;
|
||||
|
||||
smtp = filter (a: a.smtp != null) emailAccounts;
|
||||
accountsSmtp = filter (a: a.smtp != null) emailAccounts;
|
||||
aliasesSmtp =
|
||||
let
|
||||
getAliasesWithSmtp = a: filter (al: builtins.isAttrs al && al.smtp != null) a.aliases;
|
||||
getAliasesWithId = a: map (al: al // { id = getId a al; }) (getAliasesWithSmtp a);
|
||||
in
|
||||
flatten (map getAliasesWithId emailAccounts);
|
||||
smtp = accountsSmtp ++ aliasesSmtp;
|
||||
|
||||
feedAccounts = addId (attrValues profile.feedAccounts);
|
||||
|
||||
|
|
|
|||
51
modules/programs/ty.nix
Normal file
51
modules/programs/ty.nix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
literalExpression
|
||||
;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
cfg = config.programs.ty;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ mirkolenz ];
|
||||
|
||||
options.programs.ty = {
|
||||
enable = mkEnableOption "ty";
|
||||
|
||||
package = mkPackageOption pkgs "ty" { nullable = true; };
|
||||
|
||||
settings = mkOption {
|
||||
type = tomlFormat.type;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
rules.index-out-of-bounds = "ignore";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to
|
||||
{file}`$XDG_CONFIG_HOME/ty/ty.toml`.
|
||||
See <https://docs.astral.sh/ty/configuration/>
|
||||
and <https://docs.astral.sh/ty/reference/configuration/>
|
||||
for more information.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."ty/ty.toml" = lib.mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "ty-config.toml" cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -162,7 +162,8 @@ in
|
|||
default = false;
|
||||
description = ''
|
||||
Whether to configure {command}`vim` as the default
|
||||
editor using the {env}`EDITOR` environment variable.
|
||||
editor using the {env}`EDITOR` and {env}`VISUAL`
|
||||
environment variables.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
@ -213,7 +214,10 @@ in
|
|||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.sessionVariables = lib.mkIf cfg.defaultEditor { EDITOR = "vim"; };
|
||||
home.sessionVariables = lib.mkIf cfg.defaultEditor {
|
||||
EDITOR = "vim";
|
||||
VISUAL = "vim";
|
||||
};
|
||||
|
||||
programs.vim = {
|
||||
package = vim;
|
||||
|
|
|
|||
266
modules/services/colima.nix
Normal file
266
modules/services/colima.nix
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.colima;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.hm.maintainers.will-lol
|
||||
];
|
||||
|
||||
options.services.colima = {
|
||||
enable = lib.mkEnableOption "Colima, a container runtime";
|
||||
|
||||
package = lib.mkPackageOption pkgs "colima" { };
|
||||
dockerPackage = lib.mkPackageOption pkgs "docker" {
|
||||
extraDescription = "Used by colima to activate profiles. Not needed if no profile is set to isActive.";
|
||||
};
|
||||
perlPackage = lib.mkPackageOption pkgs "perl" {
|
||||
extraDescription = "Used by colima during image download for the shasum command.";
|
||||
};
|
||||
sshPackage = lib.mkPackageOption pkgs "openssh" {
|
||||
extraDescription = "Used by colima to manage the vm.";
|
||||
};
|
||||
coreutilsPackage = lib.mkPackageOption pkgs "coreutils" {
|
||||
extraDescription = "Used in various ways by colima.";
|
||||
};
|
||||
curlPackage = lib.mkPackageOption pkgs "curl" {
|
||||
extraDescription = "Used by colima to donwload images.";
|
||||
};
|
||||
bashPackage = lib.mkPackageOption pkgs "bashNonInteractive" {
|
||||
extraDescription = "Used by colima's internal scripts.";
|
||||
};
|
||||
|
||||
profiles = lib.mkOption {
|
||||
default = {
|
||||
default = {
|
||||
isActive = true;
|
||||
isService = true;
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Profiles allow multiple colima configurations. The default profile is active by default.
|
||||
If you have used colima before, you may need to delete existing configuration using `colima delete` or use a different profile.
|
||||
|
||||
Note that removing a configured profile will not delete the corresponding Colima instance.
|
||||
You will need to manually run `colima delete <profile-name>` to remove the instance and release resources.
|
||||
'';
|
||||
example = ''
|
||||
{
|
||||
default = {
|
||||
isActive = true;
|
||||
isService = true;
|
||||
};
|
||||
rosetta = {
|
||||
isService = true;
|
||||
settings.rosetta = true;
|
||||
};
|
||||
powerful = {
|
||||
settings.cpu = 8;
|
||||
};
|
||||
};
|
||||
'';
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
readOnly = true;
|
||||
description = "The profile's name.";
|
||||
};
|
||||
|
||||
isService = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether this profile will run as a service.
|
||||
'';
|
||||
};
|
||||
|
||||
isActive = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to set this profile as:
|
||||
- active docker context
|
||||
- active kubernetes context
|
||||
- active incus remote
|
||||
Exactly one or zero profiles should have this option set.
|
||||
'';
|
||||
};
|
||||
|
||||
logFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${config.home.homeDirectory}/.local/state/colima-${name}.log";
|
||||
defaultText = lib.literalExpression "\${config.home.homeDirectory}/.local/state/colima-\${name}.log";
|
||||
description = "Combined stdout and stderr log file for the Colima service.";
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
inherit (yamlFormat) type;
|
||||
default = { };
|
||||
description = "Colima configuration settings, see <https://github.com/abiosoft/colima/blob/main/embedded/defaults/colima.yaml> or run `colima template`.";
|
||||
example = ''
|
||||
{
|
||||
cpu = 2;
|
||||
disk = 100;
|
||||
memory = 2;
|
||||
arch = "host";
|
||||
runtime = "docker";
|
||||
hostname = null;
|
||||
kubernetes = {
|
||||
enabled = false;
|
||||
version = "v1.33.3+k3s1";
|
||||
k3sArgs = [ "--disable=traefik" ];
|
||||
port = 0;
|
||||
};
|
||||
autoActivate = true;
|
||||
network = {
|
||||
address = false;
|
||||
mode = "shared";
|
||||
interface = "en0";
|
||||
preferredRoute = false;
|
||||
dns = [ ];
|
||||
dnsHosts = {
|
||||
"host.docker.internal" = "host.lima.internal";
|
||||
};
|
||||
hostAddresses = false;
|
||||
};
|
||||
forwardAgent = false;
|
||||
docker = { };
|
||||
vmType = "qemu";
|
||||
portForwarder = "ssh";
|
||||
rosetta = false;
|
||||
binfmt = true;
|
||||
nestedVirtualization = false;
|
||||
mountType = "sshfs";
|
||||
mountInotify = false;
|
||||
cpuType = "host";
|
||||
provision = [ ];
|
||||
sshConfig = true;
|
||||
sshPort = 0;
|
||||
mounts = [ ];
|
||||
diskImage = "";
|
||||
rootDisk = 20;
|
||||
env = { };
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable ({
|
||||
assertions = [
|
||||
{
|
||||
assertion = (lib.count (p: p.isActive) (lib.attrValues cfg.profiles)) <= 1;
|
||||
message = "Only one Colima profile can be active at a time.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file = lib.mkMerge (
|
||||
lib.mapAttrsToList (profileName: profile: {
|
||||
".colima/${profileName}/colima.yaml" = {
|
||||
source = yamlFormat.generate "colima.yaml" profile.settings;
|
||||
};
|
||||
}) (lib.filterAttrs (name: profile: profile.settings != { }) cfg.profiles)
|
||||
);
|
||||
|
||||
programs.docker-cli.settings.currentContext =
|
||||
let
|
||||
activeProfile = lib.findFirst (p: p.isActive) null (lib.attrValues cfg.profiles);
|
||||
in
|
||||
lib.mkIf (activeProfile != null) (
|
||||
if activeProfile.name != "default" then "colima-${activeProfile.name}" else "colima"
|
||||
);
|
||||
|
||||
launchd.agents = lib.mkIf pkgs.stdenv.isDarwin (
|
||||
lib.mapAttrs' (
|
||||
name: profile:
|
||||
lib.nameValuePair "colima-${name}" {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [
|
||||
"${lib.getExe cfg.package}"
|
||||
"start"
|
||||
name
|
||||
"-f"
|
||||
"--activate=${if profile.isActive then "true" else "false"}"
|
||||
"--save-config=false"
|
||||
];
|
||||
KeepAlive = true;
|
||||
RunAtLoad = true;
|
||||
EnvironmentVariables.PATH = lib.makeBinPath [
|
||||
cfg.package
|
||||
cfg.perlPackage
|
||||
cfg.dockerPackage
|
||||
cfg.sshPackage
|
||||
cfg.coreutilsPackage
|
||||
cfg.curlPackage
|
||||
cfg.bashPackage
|
||||
pkgs.darwin.DarwinTools
|
||||
];
|
||||
StandardOutPath = profile.logFile;
|
||||
StandardErrorPath = profile.logFile;
|
||||
};
|
||||
}
|
||||
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
|
||||
);
|
||||
|
||||
systemd.user.services = lib.mkIf pkgs.stdenv.isLinux (
|
||||
lib.mapAttrs' (
|
||||
name: profile:
|
||||
lib.nameValuePair "colima-${name}" {
|
||||
Unit = {
|
||||
Description = "Colima container runtime (${name} profile)";
|
||||
After = [ "network-online.target" ];
|
||||
Wants = [ "network-online.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = ''
|
||||
${lib.getExe cfg.package} start ${name} \
|
||||
-f \
|
||||
--activate=${if profile.isActive then "true" else "false"} \
|
||||
--save-config=false
|
||||
'';
|
||||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
Environment = [
|
||||
"PATH=${
|
||||
lib.makeBinPath [
|
||||
cfg.package
|
||||
cfg.perlPackage
|
||||
cfg.dockerPackage
|
||||
cfg.sshPackage
|
||||
cfg.coreutilsPackage
|
||||
cfg.curlPackage
|
||||
cfg.bashPackage
|
||||
]
|
||||
}"
|
||||
];
|
||||
StandardOutput = "append:${profile.logFile}";
|
||||
StandardError = "append:${profile.logFile}";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
}
|
||||
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
@ -113,7 +113,8 @@ in
|
|||
example = !default;
|
||||
description = ''
|
||||
Whether to configure {command}`emacsclient` as the default
|
||||
editor using the {env}`EDITOR` environment variable.
|
||||
editor using the {env}`EDITOR` and {env}`VISUAL`
|
||||
environment variables.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
@ -121,11 +122,16 @@ in
|
|||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
home.sessionVariables = mkIf cfg.defaultEditor {
|
||||
EDITOR = lib.getBin (
|
||||
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
|
||||
);
|
||||
};
|
||||
home.sessionVariables =
|
||||
let
|
||||
editorBin = lib.getBin (
|
||||
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
|
||||
);
|
||||
in
|
||||
mkIf cfg.defaultEditor {
|
||||
EDITOR = editorBin;
|
||||
VISUAL = editorBin;
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf pkgs.stdenv.isLinux {
|
||||
|
|
|
|||
86
modules/services/hyprlauncher.nix
Normal file
86
modules/services/hyprlauncher.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
;
|
||||
|
||||
cfg = config.services.hyprlauncher;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
|
||||
|
||||
options.services.hyprlauncher = {
|
||||
enable = mkEnableOption "hyprlauncher";
|
||||
package = mkPackageOption pkgs "hyprlauncher" { nullable = true; };
|
||||
settings = mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
let
|
||||
valueType =
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
(listOf valueType)
|
||||
])
|
||||
// {
|
||||
description = "Hyprland configuration value";
|
||||
};
|
||||
in
|
||||
valueType;
|
||||
default = { };
|
||||
example = {
|
||||
general.grab_focus = true;
|
||||
cache.enabled = true;
|
||||
ui.window_size = "400 260";
|
||||
finders = {
|
||||
math_prefix = "=";
|
||||
desktop_icons = true;
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Configuration settings for hyprlauncher. All the available options can be found here:
|
||||
<https://wiki.hypr.land/Hypr-Ecosystem/hyprlauncher/#config>
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "services.hyprlauncher" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
xdg.configFile."hypr/hyprlauncher.conf" = mkIf (cfg.settings != { }) {
|
||||
text = lib.hm.generators.toHyprconf { attrs = cfg.settings; };
|
||||
};
|
||||
systemd.user.services.hyprlauncher = mkIf (cfg.package != null) {
|
||||
Install.WantedBy = [ config.wayland.systemd.target ];
|
||||
Unit = {
|
||||
Description = "hyprlauncher";
|
||||
After = [ config.wayland.systemd.target ];
|
||||
PartOf = [ config.wayland.systemd.target ];
|
||||
X-Restart-Triggers = lib.mkIf (cfg.settings != { }) [
|
||||
"${config.xdg.configFile."hypr/hyprlauncher.conf".source}"
|
||||
];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe cfg.package} -d";
|
||||
Restart = "always";
|
||||
RestartSec = "10";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -49,9 +49,17 @@ in
|
|||
default = {
|
||||
manifest.url = "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml";
|
||||
roots = [ ];
|
||||
backup.path = "$XDG_STATE_HOME/backups/ludusavi";
|
||||
restore.path = "$XDG_STATE_HOME/backups/ludusavi";
|
||||
backup.path = "${config.xdg.stateHome}/backups/ludusavi";
|
||||
restore.path = "${config.xdg.stateHome}/backups/ludusavi";
|
||||
};
|
||||
defaultText = ''
|
||||
{
|
||||
manifest.url = "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml";
|
||||
roots = [ ];
|
||||
backup.path = "$XDG_STATE_HOME/backups/ludusavi";
|
||||
restore.path = "$XDG_STATE_HOME/backups/ludusavi";
|
||||
}
|
||||
'';
|
||||
example = {
|
||||
language = "en-US";
|
||||
theme = "light";
|
||||
|
|
@ -94,6 +102,24 @@ in
|
|||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${lib.getExe cfg.package} backup --force";
|
||||
ExecStartPre = "${pkgs.writeShellScript "ludusavi-migrate-backup" ''
|
||||
old_base_dir="${config.home.homeDirectory}/\$XDG_STATE_HOME"
|
||||
old_dir="$old_base_dir/backups/ludusavi"
|
||||
new_base_dir="${config.xdg.stateHome}/backups"
|
||||
new_dir="$new_base_dir/ludusavi"
|
||||
|
||||
if [[ -d "$old_base_dir" ]]; then
|
||||
echo "Migrating old Ludusavi's backup... (See home-manager/#8234)"
|
||||
if [[ ! -d "$new_base_dir" ]]; then
|
||||
mkdir -p "$new_base_dir"
|
||||
fi
|
||||
|
||||
mv "$old_dir" "$new_dir"
|
||||
rmdir "$old_base_dir/backups"
|
||||
rmdir "$old_base_dir"
|
||||
echo "Migration completed successfully."
|
||||
fi
|
||||
''}";
|
||||
}
|
||||
// lib.optionalAttrs cfg.backupNotification {
|
||||
ExecStartPost = "${lib.getExe pkgs.libnotify} 'Ludusavi' 'Backup completed' -i com.mtkennerly.ludusavi -a 'Ludusavi'";
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ in
|
|||
Description = "pimsync calendar and contacts synchronization";
|
||||
PartOf = [ "network-online.target" ];
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
Service = {
|
||||
# TODO: make use of the readiness notification
|
||||
Type = "simple";
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ in
|
|||
CacheDirectoryMode = "0700";
|
||||
PrivateTmp = true;
|
||||
|
||||
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C" ];
|
||||
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C/${serviceName}" ];
|
||||
|
||||
ExecStart =
|
||||
lib.optional doBackup backupCmd
|
||||
|
|
@ -591,7 +591,7 @@ in
|
|||
lib.concatLines
|
||||
]}
|
||||
|
||||
RESTIC_CACHE_DIR=$HOME/.cache/${serviceName}
|
||||
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
|
||||
|
||||
PATH=${
|
||||
lib.pipe environment [
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
let
|
||||
cfg = config.services.snixembed;
|
||||
waybarCfg = config.programs.waybar;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.DamienCassou ];
|
||||
|
|
@ -32,6 +33,10 @@ in
|
|||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "services.snixembed" pkgs lib.platforms.linux)
|
||||
];
|
||||
warnings = lib.optional waybarCfg.enable ''
|
||||
snixembed and waybar should not be enabled at the same time.
|
||||
You may experience inconsistent tray behavior as a result.
|
||||
'';
|
||||
|
||||
systemd.user.services.snixembed = {
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
|
|
|
|||
|
|
@ -84,13 +84,11 @@ in
|
|||
'';
|
||||
in
|
||||
{
|
||||
bash.initExtra = lib.mkIf cfg.enableBashIntegration bashIntegration;
|
||||
|
||||
zsh.initContent = lib.mkIf cfg.enableZshIntegration bashIntegration;
|
||||
|
||||
fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration fishIntegration;
|
||||
|
||||
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration nushellIntegration;
|
||||
# $SSH_AUTH_SOCK has to be set early since other tools rely on it
|
||||
bash.profileExtra = lib.mkIf cfg.enableBashIntegration (lib.mkOrder 900 bashIntegration);
|
||||
fish.shellInit = lib.mkIf cfg.enableFishIntegration (lib.mkOrder 900 fishIntegration);
|
||||
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration (lib.mkOrder 900 nushellIntegration);
|
||||
zsh.envExtra = lib.mkIf cfg.enableZshIntegration (lib.mkOrder 900 bashIntegration);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,21 +42,30 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
eventModule = {
|
||||
eventsModule = {
|
||||
options = {
|
||||
event = mkOption {
|
||||
type = types.enum [
|
||||
"before-sleep"
|
||||
"after-resume"
|
||||
"lock"
|
||||
"unlock"
|
||||
];
|
||||
description = "Event name.";
|
||||
before-sleep = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Command to run before suspending.";
|
||||
};
|
||||
|
||||
command = mkOption {
|
||||
type = types.str;
|
||||
description = "Command to run when event occurs.";
|
||||
after-resume = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Command to run after resuming.";
|
||||
};
|
||||
|
||||
lock = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Command to run when the logind session is locked.";
|
||||
};
|
||||
|
||||
unlock = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Command to run when the logind session is unlocked.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -80,13 +89,31 @@ in
|
|||
};
|
||||
|
||||
events = mkOption {
|
||||
type = with types; listOf (submodule eventModule);
|
||||
default = [ ];
|
||||
type =
|
||||
with types;
|
||||
(coercedTo (listOf attrs)) (
|
||||
events:
|
||||
lib.warn
|
||||
''
|
||||
The syntax of services.swayidle.events has changed. While it
|
||||
previously accepted a list of events, it now accepts an attrset
|
||||
keyed by the event name.
|
||||
''
|
||||
(
|
||||
lib.listToAttrs (
|
||||
map (e: {
|
||||
name = e.event;
|
||||
value = e.command;
|
||||
}) events
|
||||
)
|
||||
)
|
||||
) (submodule eventsModule);
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
[
|
||||
{ event = "before-sleep"; command = "''${pkgs.swaylock}/bin/swaylock -fF"; }
|
||||
{ event = "lock"; command = "lock"; }
|
||||
]
|
||||
{
|
||||
"before-sleep" = "''${pkgs.swaylock}/bin/swaylock -fF";
|
||||
"lock" = "lock";
|
||||
}
|
||||
'';
|
||||
description = "Run command on occurrence of a event.";
|
||||
};
|
||||
|
|
@ -144,13 +171,17 @@ in
|
|||
t.resumeCommand
|
||||
];
|
||||
|
||||
mkEvent = e: [
|
||||
e.event
|
||||
e.command
|
||||
mkEvent = event: command: [
|
||||
event
|
||||
command
|
||||
];
|
||||
|
||||
nonemptyEvents = lib.filterAttrs (event: command: command != null) cfg.events;
|
||||
|
||||
args =
|
||||
cfg.extraArgs ++ (lib.concatMap mkTimeout cfg.timeouts) ++ (lib.concatMap mkEvent cfg.events);
|
||||
cfg.extraArgs
|
||||
++ (lib.concatMap mkTimeout cfg.timeouts)
|
||||
++ (lib.flatten (lib.mapAttrsToList mkEvent nonemptyEvents));
|
||||
in
|
||||
"${lib.getExe cfg.package} ${lib.escapeShellArgs args}";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ let
|
|||
cfg = config.services.tldr-update;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.perchun ];
|
||||
meta.maintainers = [ lib.maintainers.PerchunPak ];
|
||||
|
||||
options.services.tldr-update = {
|
||||
enable = lib.mkEnableOption ''
|
||||
|
|
|
|||
|
|
@ -119,6 +119,24 @@ in
|
|||
{file}`$XDG_CONFIG_HOME/herbstluftwm/autostart`.
|
||||
'';
|
||||
};
|
||||
|
||||
enableAlias = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Set an alias for the {command}`herbstclient` command in the
|
||||
{file}`autostart` script that only stores its arguments and executes
|
||||
them all at once at the end of the {file}`autostart` script.
|
||||
|
||||
This reduces the amount of flickering you get while all options are
|
||||
being applied and improves the performance.
|
||||
|
||||
On the other hand, this makes it more difficult to write bash functions
|
||||
that call {command}`herbstclient`. You can work around this by calling
|
||||
{command}`command herbstclient` in your functions to still get some of
|
||||
the benefits of enabling this alias.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
|
@ -131,11 +149,13 @@ in
|
|||
xsession.windowManager.command = "${cfg.package}/bin/herbstluftwm --locked";
|
||||
|
||||
xdg.configFile."herbstluftwm/autostart".source = pkgs.writeShellScript "herbstluftwm-autostart" ''
|
||||
shopt -s expand_aliases
|
||||
${lib.optionalString cfg.enableAlias ''
|
||||
shopt -s expand_aliases
|
||||
|
||||
# shellcheck disable=SC2142
|
||||
alias herbstclient='set -- "$@" ";"'
|
||||
set --
|
||||
# shellcheck disable=SC2142
|
||||
alias herbstclient='set -- "$@" ";"'
|
||||
set --
|
||||
''}
|
||||
|
||||
herbstclient emit_hook reload
|
||||
|
||||
|
|
@ -169,7 +189,9 @@ in
|
|||
|
||||
herbstclient unlock
|
||||
|
||||
${cfg.package}/bin/herbstclient chain ";" "$@"
|
||||
${lib.optionalString cfg.enableAlias ''
|
||||
${cfg.package}/bin/herbstclient chain ";" "$@"
|
||||
''}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
# For OS-specific configuration, please edit nixos/default.nix or nix-darwin/default.nix instead.
|
||||
|
||||
{
|
||||
options,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
|
|
@ -36,7 +35,7 @@ let
|
|||
|
||||
modules = [
|
||||
(
|
||||
{ name, ... }:
|
||||
{ name, options, ... }:
|
||||
{
|
||||
imports =
|
||||
import ../modules/modules.nix {
|
||||
|
|
@ -48,22 +47,31 @@ let
|
|||
++ cfg.sharedModules;
|
||||
|
||||
config = {
|
||||
submoduleSupport.enable = true;
|
||||
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||
submoduleSupport = {
|
||||
enable = true;
|
||||
externalPackageInstall = cfg.useUserPackages;
|
||||
};
|
||||
|
||||
home.username = config.users.users.${name}.name;
|
||||
home.homeDirectory = config.users.users.${name}.home;
|
||||
home = {
|
||||
username = config.users.users.${name}.name;
|
||||
homeDirectory = config.users.users.${name}.home;
|
||||
uid = mkIf (options.users.users.${name}.uid.isDefined or false) config.users.users.${name}.uid;
|
||||
};
|
||||
|
||||
# Forward `nix.enable` from the OS configuration. The
|
||||
# conditional is to check whether nix-darwin is new enough
|
||||
# to have the `nix.enable` option; it was previously a
|
||||
# `mkRemovedOptionModule` error, which we can crudely detect
|
||||
# by `visible` being set to `false`.
|
||||
nix.enable = mkIf (options.nix.enable.visible or true) config.nix.enable;
|
||||
nix = {
|
||||
# Forward `nix.enable` from the OS configuration. The
|
||||
# conditional is to check whether nix-darwin is new enough
|
||||
# to have the `nix.enable` option; it was previously a
|
||||
# `mkRemovedOptionModule` error, which we can crudely detect
|
||||
# by `visible` being set to `false`.
|
||||
enable = mkIf (options.nix.enable.visible or true) config.nix.enable;
|
||||
|
||||
# Make activation script use same version of Nix as system as a whole.
|
||||
# This avoids problems with Nix not being in PATH.
|
||||
nix.package = config.nix.package;
|
||||
# Make activation script use same version of Nix as system as a whole.
|
||||
# This avoids problems with Nix not being in PATH.
|
||||
# Only set package when nix is enabled to avoid errors when
|
||||
# nix-darwin has nix.enable = false (e.g., Determinate Nix users).
|
||||
package = mkIf config.nix.enable config.nix.package;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
|
|
@ -160,30 +168,28 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = (
|
||||
lib.mkMerge [
|
||||
# Fix potential recursion when configuring home-manager users based on values in users.users #594
|
||||
(mkIf (cfg.useUserPackages && cfg.users != { }) {
|
||||
users.users = (lib.mapAttrs (_username: usercfg: { packages = [ usercfg.home.path ]; }) cfg.users);
|
||||
environment.pathsToLink = [ "/etc/profile.d" ];
|
||||
})
|
||||
(mkIf (cfg.users != { }) {
|
||||
warnings = lib.flatten (
|
||||
flip lib.mapAttrsToList cfg.users (
|
||||
user: config: flip map config.warnings (warning: "${user} profile: ${warning}")
|
||||
)
|
||||
);
|
||||
config = lib.mkMerge [
|
||||
# Fix potential recursion when configuring home-manager users based on values in users.users #594
|
||||
(mkIf (cfg.useUserPackages && cfg.users != { }) {
|
||||
users.users = lib.mapAttrs (_username: usercfg: { packages = [ usercfg.home.path ]; }) cfg.users;
|
||||
environment.pathsToLink = [ "/etc/profile.d" ];
|
||||
})
|
||||
(mkIf (cfg.users != { }) {
|
||||
warnings = lib.flatten (
|
||||
flip lib.mapAttrsToList cfg.users (
|
||||
user: config: flip map config.warnings (warning: "${user} profile: ${warning}")
|
||||
)
|
||||
);
|
||||
|
||||
assertions = lib.flatten (
|
||||
flip lib.mapAttrsToList cfg.users (
|
||||
user: config:
|
||||
flip map config.assertions (assertion: {
|
||||
inherit (assertion) assertion;
|
||||
message = "${user} profile: ${assertion.message}";
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
]
|
||||
);
|
||||
assertions = lib.flatten (
|
||||
flip lib.mapAttrsToList cfg.users (
|
||||
user: config:
|
||||
flip map config.assertions (assertion: {
|
||||
inherit (assertion) assertion;
|
||||
message = "${user} profile: ${assertion.message}";
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ let
|
|||
"broot"
|
||||
"browserpass"
|
||||
"btop"
|
||||
"calibre"
|
||||
"carapace"
|
||||
"cava"
|
||||
"claude-code"
|
||||
|
|
@ -96,6 +97,7 @@ let
|
|||
"lf"
|
||||
"lieer"
|
||||
"lsd"
|
||||
"ludusavi"
|
||||
"mbsync"
|
||||
"meli"
|
||||
"mergiraf"
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ in
|
|||
|
||||
def make_backup(time):
|
||||
global snapshot_count
|
||||
machine.succeed(f"timedatectl set-time '{time}'")
|
||||
machine.succeed(f"date --set='{time}'")
|
||||
systemctl_succeed_as_alice("start restic-backups-prune-me.service")
|
||||
snapshot_count += 1
|
||||
actual = \
|
||||
|
|
|
|||
|
|
@ -2,4 +2,7 @@
|
|||
home-session-path = ./session-path.nix;
|
||||
home-session-search-variables = ./session-search-variables.nix;
|
||||
home-session-variables = ./session-variables.nix;
|
||||
home-nixpkgs-release-check-pkgs = ./nixpkgs-release-check-pkgs.nix;
|
||||
home-uid = ./uid.nix;
|
||||
home-uid-null = ./uid-null.nix;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
releaseInfo = lib.importJSON ../../../release.json;
|
||||
hmRelease = releaseInfo.release;
|
||||
pkgsRelease = "<invalid>";
|
||||
in
|
||||
{
|
||||
test.asserts.warnings.expected = [
|
||||
''
|
||||
You are using
|
||||
|
||||
Home Manager version: ${hmRelease}
|
||||
Nixpkgs version used to evaluate Home Manager: ${hmRelease}
|
||||
Nixpkgs version used for packages (`pkgs`): ${pkgsRelease}
|
||||
|
||||
Using mismatched versions is likely to cause errors and unexpected
|
||||
behavior. It is therefore highly recommended to use a release of Home
|
||||
Manager that corresponds with your chosen release of Nixpkgs.
|
||||
|
||||
If you insist then you can disable this warning by adding
|
||||
|
||||
home.enableNixpkgsReleaseCheck = false;
|
||||
|
||||
to your configuration.
|
||||
''
|
||||
];
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
lib = prev.lib.extend (
|
||||
final: prev: {
|
||||
trivial = prev.trivial // {
|
||||
release = pkgsRelease;
|
||||
};
|
||||
}
|
||||
);
|
||||
})
|
||||
];
|
||||
}
|
||||
7
tests/modules/home-environment/uid-null.nix
Normal file
7
tests/modules/home-environment/uid-null.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
# home.uid defaults to null, so checkUid should not be called in the activation script
|
||||
|
||||
nmt.script = ''
|
||||
assertFileNotRegex activate "checkUid [0-9]+"
|
||||
'';
|
||||
}
|
||||
7
tests/modules/home-environment/uid.nix
Normal file
7
tests/modules/home-environment/uid.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
home.uid = 1000;
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains activate "checkUid 1000"
|
||||
'';
|
||||
}
|
||||
|
|
@ -4,4 +4,7 @@
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
13
tests/modules/misc/qt/qt-qt5ct-settings.nix
Normal file
13
tests/modules/misc/qt/qt-qt5ct-settings.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
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"
|
||||
'';
|
||||
}
|
||||
13
tests/modules/misc/qt/qt-qt6ct-settings.nix
Normal file
13
tests/modules/misc/qt/qt-qt6ct-settings.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
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"
|
||||
'';
|
||||
}
|
||||
16
tests/modules/misc/qt/qt-qtct-settings.nix
Normal file
16
tests/modules/misc/qt/qt-qtct-settings.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
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"
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
# Anki is currently marked as broken on Darwin (2025/06/23)
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
||||
{
|
||||
anki-minimal-config = ./minimal-config.nix;
|
||||
anki-full-config = ./full-config.nix;
|
||||
}
|
||||
|
|
|
|||
1
tests/modules/programs/calibre/default.nix
Normal file
1
tests/modules/programs/calibre/default.nix
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ calibre-settings = ./settings.nix; }
|
||||
0
tests/modules/programs/calibre/plugins/a/a.zip
Normal file
0
tests/modules/programs/calibre/plugins/a/a.zip
Normal file
0
tests/modules/programs/calibre/plugins/b/b.zip
Normal file
0
tests/modules/programs/calibre/plugins/b/b.zip
Normal file
14
tests/modules/programs/calibre/settings.nix
Normal file
14
tests/modules/programs/calibre/settings.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
programs.calibre = {
|
||||
enable = true;
|
||||
plugins = [
|
||||
./plugins/a
|
||||
./plugins/b
|
||||
];
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/calibre/plugins/a.zip
|
||||
assertFileExists home-files/.config/calibre/plugins/b.zip
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
programs.docker-cli = {
|
||||
programs.cargo = {
|
||||
settings = {
|
||||
net = {
|
||||
git-fetch-with-cli = true;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
claude-code-assertion = ./assertion.nix;
|
||||
claude-code-memory-management = ./memory-management.nix;
|
||||
claude-code-memory-from-source = ./memory-from-source.nix;
|
||||
claude-code-rules-dir = ./rules-dir.nix;
|
||||
claude-code-rules-path = ./rules-path.nix;
|
||||
claude-code-agents-dir = ./agents-dir.nix;
|
||||
claude-code-commands-dir = ./commands-dir.nix;
|
||||
claude-code-hooks-dir = ./hooks-dir.nix;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
#! /nix/store/00000000000000000000000000000000-bash/bin/bash -e
|
||||
exec -a "$0" "/nix/store/00000000000000000000000000000000-claude-code/bin/.claude-wrapped" --mcp-config /nix/store/00000000000000000000000000000000-claude-code-mcp-config.json "$@"
|
||||
exec -a "$0" "/nix/store/00000000000000000000000000000000-claude-code/bin/.claude-wrapped" "$@" --mcp-config /nix/store/00000000000000000000000000000000-claude-code-mcp-config.json
|
||||
|
|
|
|||
14
tests/modules/programs/claude-code/rules-dir.nix
Normal file
14
tests/modules/programs/claude-code/rules-dir.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
programs.claude-code = {
|
||||
enable = true;
|
||||
rulesDir = ./rules;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.claude/rules/test-rule.md
|
||||
assertLinkExists home-files/.claude/rules/test-rule.md
|
||||
assertFileContent \
|
||||
home-files/.claude/rules/test-rule.md \
|
||||
${./rules/test-rule.md}
|
||||
'';
|
||||
}
|
||||
20
tests/modules/programs/claude-code/rules-path.nix
Normal file
20
tests/modules/programs/claude-code/rules-path.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
programs.claude-code = {
|
||||
enable = true;
|
||||
rules = {
|
||||
test-rule = ./test-rule.md;
|
||||
inline-rule = ''
|
||||
# Inline Rule
|
||||
|
||||
This is an inline rule for testing.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.claude/rules/test-rule.md
|
||||
assertFileContent home-files/.claude/rules/test-rule.md \
|
||||
${./test-rule.md}
|
||||
assertFileExists home-files/.claude/rules/inline-rule.md
|
||||
'';
|
||||
}
|
||||
9
tests/modules/programs/claude-code/rules/test-rule.md
Normal file
9
tests/modules/programs/claude-code/rules/test-rule.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Test Rule from Directory
|
||||
|
||||
This is a test rule loaded from a directory.
|
||||
Used to verify rulesDir support functionality.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Write clean code
|
||||
- Test thoroughly
|
||||
9
tests/modules/programs/claude-code/test-rule.md
Normal file
9
tests/modules/programs/claude-code/test-rule.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Test Rule
|
||||
|
||||
This is a test rule loaded from a file path.
|
||||
Used to verify path support functionality for rules.
|
||||
|
||||
## Guidelines
|
||||
|
||||
- Follow test conventions
|
||||
- Maintain code quality
|
||||
|
|
@ -2,4 +2,5 @@
|
|||
diff-highlight-basic = ./diff-highlight-basic.nix;
|
||||
diff-highlight-with-git-integration = ./diff-highlight-with-git-integration.nix;
|
||||
diff-highlight-migration = ./diff-highlight-migration.nix;
|
||||
diff-highlight-git-package-null-assertion = ./diff-highlight-git-package-null-assertion.nix;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
programs.diff-highlight = {
|
||||
enable = true;
|
||||
enableGitIntegration = true;
|
||||
};
|
||||
|
||||
programs.git = {
|
||||
enable = true;
|
||||
package = null;
|
||||
};
|
||||
|
||||
test.asserts.assertions.expected = [
|
||||
''
|
||||
programs.diff-highlight.enableGitIntegration requires programs.git.package to be set.
|
||||
Please set programs.git.package to a valid git package.
|
||||
''
|
||||
];
|
||||
}
|
||||
|
|
@ -41,5 +41,9 @@
|
|||
assertFileExists home-files/.gemini/CONTEXT.md
|
||||
assertFileContent home-files/.gemini/CONTEXT.md \
|
||||
${./context-additional.md}
|
||||
|
||||
assertFileExists home-path/etc/profile.d/hm-session-vars.sh
|
||||
assertFileNotRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
"GEMINI_MODEL"
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
programs.gemini-cli = {
|
||||
enable = true;
|
||||
defaultModel = "gemini-2.5-flash";
|
||||
settings = {
|
||||
theme = "Default";
|
||||
vimMode = true;
|
||||
|
|
@ -28,5 +29,9 @@
|
|||
${./changelog.toml}
|
||||
assertFileContent home-files/.gemini/commands/git/fix.toml \
|
||||
${./fix.toml}
|
||||
|
||||
assertFileExists home-path/etc/profile.d/hm-session-vars.sh
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export GEMINI_MODEL="gemini-2.5-flash"'
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
6
tests/modules/programs/infat/default.nix
Normal file
6
tests/modules/programs/infat/default.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin {
|
||||
infat-example-settings = ./example-settings.nix;
|
||||
infat-no-settings = ./no-settings.nix;
|
||||
}
|
||||
39
tests/modules/programs/infat/example-settings.nix
Normal file
39
tests/modules/programs/infat/example-settings.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.infat = {
|
||||
enable = true;
|
||||
settings = {
|
||||
extensions = {
|
||||
md = "TextEdit";
|
||||
};
|
||||
schemes = {
|
||||
web = "Safari";
|
||||
};
|
||||
types = {
|
||||
plain-text = "VSCode";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
test.stubs.infat = { };
|
||||
|
||||
nmt.script =
|
||||
let
|
||||
expectedConfigPath = "home-files/.config/infat/config.toml";
|
||||
expectedConfigContent = pkgs.writeText "infat.config.expected" ''
|
||||
[extensions]
|
||||
md = "TextEdit"
|
||||
|
||||
[schemes]
|
||||
web = "Safari"
|
||||
|
||||
[types]
|
||||
plain-text = "VSCode"
|
||||
'';
|
||||
in
|
||||
''
|
||||
assertFileExists "${expectedConfigPath}"
|
||||
assertFileContent "${expectedConfigPath}" "${expectedConfigContent}"
|
||||
'';
|
||||
}
|
||||
13
tests/modules/programs/infat/no-settings.nix
Normal file
13
tests/modules/programs/infat/no-settings.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
programs.infat.enable = true;
|
||||
|
||||
test.stubs.infat = { };
|
||||
|
||||
nmt.script =
|
||||
let
|
||||
expectedConfigPath = "home-files/.config/infat/config.toml";
|
||||
in
|
||||
''
|
||||
assertPathNotExists "${expectedConfigPath}"
|
||||
'';
|
||||
}
|
||||
30
tests/modules/programs/less/correct-option-order.nix
Normal file
30
tests/modules/programs/less/correct-option-order.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
programs.less = {
|
||||
enable = true;
|
||||
options = lib.mkMerge [
|
||||
{
|
||||
quiet = true;
|
||||
use-color = true;
|
||||
}
|
||||
(lib.mkAfter {
|
||||
color = [
|
||||
"HkK" # header: gray
|
||||
"Mkb" # marks: blue
|
||||
];
|
||||
})
|
||||
(lib.mkOrder 2000 {
|
||||
prompt = "s%f";
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/lesskey
|
||||
assertFileContent home-files/.config/lesskey ${builtins.toFile "lesskey.expected" ''
|
||||
#env
|
||||
LESS = --quiet --use-color --color HkK --color Mkb --prompt s%f
|
||||
''}
|
||||
'';
|
||||
}
|
||||
|
|
@ -12,7 +12,10 @@ in
|
|||
options = {
|
||||
RAW-CONTROL-CHARS = true;
|
||||
quiet = true;
|
||||
wheel-lines = 3;
|
||||
wheel-lines = [
|
||||
3
|
||||
1
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -20,7 +23,7 @@ in
|
|||
assertFileExists home-files/.config/lesskey
|
||||
assertFileContent home-files/.config/lesskey ${builtins.toFile "less.expected" ''
|
||||
#env
|
||||
LESS = --RAW-CONTROL-CHARS --quiet --wheel-lines 3
|
||||
LESS = --RAW-CONTROL-CHARS --quiet --wheel-lines 3 --wheel-lines 1
|
||||
|
||||
${config}''}
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@
|
|||
options = {
|
||||
RAW-CONTROL-CHARS = true;
|
||||
quiet = true;
|
||||
wheel-lines = 3;
|
||||
wheel-lines = [
|
||||
3
|
||||
1
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -12,7 +15,7 @@
|
|||
assertFileExists home-files/.config/lesskey
|
||||
assertFileContent home-files/.config/lesskey ${builtins.toFile "lesskey.expected" ''
|
||||
#env
|
||||
LESS = --RAW-CONTROL-CHARS --quiet --wheel-lines 3
|
||||
LESS = --RAW-CONTROL-CHARS --quiet --wheel-lines 3 --wheel-lines 1
|
||||
''}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
less-correct-option-order = ./correct-option-order.nix;
|
||||
less-custom-config = ./custom-config.nix;
|
||||
less-custom-options = ./custom-options.nix;
|
||||
less-custom-options-and-config = ./custom-options-and-config.nix;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
neovim-plugin-config = ./plugin-config.nix;
|
||||
neovim-coc-config = ./coc-config.nix;
|
||||
neovim-runtime = ./runtime.nix;
|
||||
neovim-wrapper-args = ./wrapper-args.nix;
|
||||
|
||||
# waiting for a nixpkgs patch
|
||||
neovim-no-init = ./no-init.nix;
|
||||
|
|
|
|||
|
|
@ -34,15 +34,25 @@ lib.mkIf config.test.enableBig {
|
|||
|
||||
_module.args.pkgs = lib.mkForce realPkgs;
|
||||
|
||||
nmt.script = ''
|
||||
vimout=$(mktemp)
|
||||
echo "redir >> /dev/stdout | echo g:hmExtraConfig | echo g:hmPlugins | redir END" \
|
||||
| ${pkgs.neovim}/bin/nvim -es -u "$TESTED/home-files/.config/nvim/init.lua" \
|
||||
> "$vimout" || true
|
||||
assertFileContains "$vimout" "HM_EXTRA_CONFIG"
|
||||
assertFileContains "$vimout" "HM_PLUGINS_CONFIG"
|
||||
nmt.script =
|
||||
let
|
||||
# Force evaluation of generatedConfigs.
|
||||
luaConfig = config.programs.neovim.generatedConfigs.lua;
|
||||
vimlConfig = config.programs.neovim.generatedConfigs.viml;
|
||||
in
|
||||
''
|
||||
vimout=$(mktemp)
|
||||
echo "redir >> /dev/stdout | echo g:hmExtraConfig | echo g:hmPlugins | redir END" \
|
||||
| ${pkgs.neovim}/bin/nvim -es -u "$TESTED/home-files/.config/nvim/init.lua" \
|
||||
> "$vimout" || true
|
||||
assertFileContains "$vimout" "HM_EXTRA_CONFIG"
|
||||
assertFileContains "$vimout" "HM_PLUGINS_CONFIG"
|
||||
|
||||
initLua="$TESTED/home-files/.config/nvim/init.lua"
|
||||
assertFileContent $(normalizeStorePaths "$initLua") ${./plugin-config.expected}
|
||||
'';
|
||||
initLua="$TESTED/home-files/.config/nvim/init.lua"
|
||||
assertFileContent $(normalizeStorePaths "$initLua") ${./plugin-config.expected}
|
||||
|
||||
# Verify generatedConfigs evaluated properly (issue #8371)
|
||||
echo "Lua config length: ${toString (builtins.stringLength luaConfig)}"
|
||||
echo "Viml config length: ${toString (builtins.stringLength vimlConfig)}"
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
83
tests/modules/programs/neovim/wrapper-args.nix
Normal file
83
tests/modules/programs/neovim/wrapper-args.nix
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs.stdenv.hostPlatform) isLinux;
|
||||
|
||||
dummyDep = pkgs.runCommand "dummy-dep" { } ''
|
||||
mkdir -p $out/bin
|
||||
echo "echo dummy" > $out/bin/dummy-dep-bin
|
||||
chmod +x $out/bin/dummy-dep-bin
|
||||
'';
|
||||
|
||||
dummyPlugin = pkgs.vimUtils.buildVimPlugin {
|
||||
pname = "dummy-plugin";
|
||||
version = "1.0";
|
||||
src = pkgs.writeTextDir "plugin/dummy.vim" "\" dummy";
|
||||
runtimeDeps = [ dummyDep ];
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ ./stubs.nix ];
|
||||
tests.stubs.wl-clipboard = { };
|
||||
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
extraName = "-my-suffix";
|
||||
withPerl = true;
|
||||
withPython3 = true;
|
||||
withRuby = true;
|
||||
withNodeJs = true;
|
||||
autowrapRuntimeDeps = true;
|
||||
waylandSupport = isLinux;
|
||||
plugins = [ dummyPlugin ];
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
nvimBin="home-path/bin/nvim"
|
||||
|
||||
assertBinaryContains() {
|
||||
local file="$TESTED/$1"
|
||||
if [[ $1 == /* ]]; then file="$1"; fi
|
||||
|
||||
if ! grep -a -qF -- "$2" "$file"; then
|
||||
fail "Expected binary file '$1' to contain '$2' but it did not."
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure the main binary exists
|
||||
assertFileExists "$nvimBin"
|
||||
|
||||
# 1. extraName: Check if the suffix is in the rplugin manifest path within the wrapper
|
||||
assertBinaryContains "$nvimBin" "-my-suffix/rplugin.vim"
|
||||
|
||||
# 2. withPerl: Check if nvim-perl binary exists and host prog is set
|
||||
assertFileExists "home-path/bin/nvim-perl"
|
||||
assertBinaryContains "$nvimBin" "perl_host_prog="
|
||||
|
||||
# 3. withPython3: Check if nvim-python3 binary exists and host prog is set
|
||||
assertFileExists "home-path/bin/nvim-python3"
|
||||
assertBinaryContains "$nvimBin" "python3_host_prog="
|
||||
|
||||
# 4. withRuby: Check if nvim-ruby binary exists, GEM_HOME and host prog are set
|
||||
assertFileExists "home-path/bin/nvim-ruby"
|
||||
assertBinaryContains "$nvimBin" "GEM_HOME="
|
||||
assertBinaryContains "$nvimBin" "ruby_host_prog="
|
||||
|
||||
# 5. withNodeJs: Check if nvim-node binary exists and host prog is set
|
||||
assertFileExists "home-path/bin/nvim-node"
|
||||
assertBinaryContains "$nvimBin" "node_host_prog="
|
||||
|
||||
# 6. waylandSupport: Check for wl-clipboard path in wrapper's PATH modification
|
||||
# We check for the store path of wl-clipboard in the current pkgs
|
||||
${lib.optionalString isLinux ''
|
||||
assertBinaryContains "$nvimBin" "wl-clipboard-"
|
||||
''}
|
||||
|
||||
# 7. autowrapRuntimeDeps: Check for dummyDep path in wrapper's PATH modification
|
||||
assertBinaryContains "$nvimBin" "${dummyDep}/bin"
|
||||
'';
|
||||
}
|
||||
4
tests/modules/programs/npm/default.nix
Normal file
4
tests/modules/programs/npm/default.nix
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
npm-example-settings = ./example-settings.nix;
|
||||
npm-no-settings = ./no-settings.nix;
|
||||
}
|
||||
36
tests/modules/programs/npm/example-settings.nix
Normal file
36
tests/modules/programs/npm/example-settings.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.npm = {
|
||||
enable = true;
|
||||
settings = {
|
||||
color = true;
|
||||
include = [
|
||||
"dev"
|
||||
"prod"
|
||||
];
|
||||
init-license = "MIT";
|
||||
prefix = "\${HOME}/.npm";
|
||||
};
|
||||
};
|
||||
|
||||
test.stubs.nodejs = { };
|
||||
|
||||
nmt.script =
|
||||
let
|
||||
configPath = "home-files/.npmrc";
|
||||
expectedConfig = pkgs.writeText "npmrc-expected" ''
|
||||
color=true
|
||||
include[]=dev
|
||||
include[]=prod
|
||||
init-license=MIT
|
||||
prefix=''${HOME}/.npm
|
||||
'';
|
||||
in
|
||||
''
|
||||
assertFileExists "${configPath}"
|
||||
assertFileContent "${configPath}" "${expectedConfig}"
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NPM_CONFIG_USERCONFIG="/home/hm-user/.npmrc"'
|
||||
'';
|
||||
}
|
||||
17
tests/modules/programs/npm/no-settings.nix
Normal file
17
tests/modules/programs/npm/no-settings.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{ ... }:
|
||||
|
||||
{
|
||||
programs.npm = {
|
||||
enable = true;
|
||||
settings = { };
|
||||
};
|
||||
|
||||
test.stubs.nodejs = { };
|
||||
|
||||
nmt.script = ''
|
||||
assertPathNotExists home-files/.npmrc
|
||||
assertFileExists home-path/etc/profile.d/hm-session-vars.sh
|
||||
assertFileNotRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
"export NPM_CONFIG_USERCONFIG="
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
accounts.calendar = {
|
||||
accounts.caldav = {
|
||||
accounts.mine = {
|
||||
pimsync.enable = true;
|
||||
remote = {
|
||||
passwordCommand = [
|
||||
|
|
@ -22,6 +22,22 @@
|
|||
basePath = ".local/state/calendar";
|
||||
};
|
||||
|
||||
accounts.contact = {
|
||||
accounts.mine = {
|
||||
pimsync.enable = true;
|
||||
remote = {
|
||||
passwordCommand = [
|
||||
"pass"
|
||||
"carddav"
|
||||
];
|
||||
type = "carddav";
|
||||
url = "https://carddav.example.com";
|
||||
userName = "bob";
|
||||
};
|
||||
};
|
||||
basePath = ".local/state/contact";
|
||||
};
|
||||
|
||||
programs.pimsync = {
|
||||
enable = true;
|
||||
settings = [
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
storage caldav-local {
|
||||
fileext .ics
|
||||
path /home/hm-user/.local/state/calendar/caldav
|
||||
type vdir/icalendar
|
||||
}
|
||||
storage http-local {
|
||||
storage calendar-http-local {
|
||||
fileext .ics
|
||||
path /home/hm-user/.local/state/calendar/http
|
||||
type vdir/icalendar
|
||||
}
|
||||
storage caldav-remote {
|
||||
storage calendar-mine-local {
|
||||
fileext .ics
|
||||
path /home/hm-user/.local/state/calendar/mine
|
||||
type vdir/icalendar
|
||||
}
|
||||
storage calendar-http-remote {
|
||||
type webcal
|
||||
url https://example.com/calendar
|
||||
}
|
||||
storage calendar-mine-remote {
|
||||
type caldav
|
||||
url https://caldav.example.com
|
||||
username alice
|
||||
|
|
@ -16,16 +20,29 @@ storage caldav-remote {
|
|||
cmd pass caldav
|
||||
}
|
||||
}
|
||||
storage http-remote {
|
||||
type webcal
|
||||
url https://example.com/calendar
|
||||
}
|
||||
pair calendar-caldav {
|
||||
storage_a caldav-local
|
||||
storage_b caldav-remote
|
||||
}
|
||||
pair calendar-http {
|
||||
storage_a http-local
|
||||
storage_b http-remote
|
||||
storage_a calendar-http-local
|
||||
storage_b calendar-http-remote
|
||||
}
|
||||
pair calendar-mine {
|
||||
storage_a calendar-mine-local
|
||||
storage_b calendar-mine-remote
|
||||
}
|
||||
storage contacts-mine-local {
|
||||
fileext .vcf
|
||||
path /home/hm-user/.local/state/contact/mine
|
||||
type vdir/vcard
|
||||
}
|
||||
storage contacts-mine-remote {
|
||||
type carddav
|
||||
url https://carddav.example.com
|
||||
username bob
|
||||
password {
|
||||
cmd pass carddav
|
||||
}
|
||||
}
|
||||
pair contacts-mine {
|
||||
storage_a contacts-mine-local
|
||||
storage_b contacts-mine-remote
|
||||
}
|
||||
status_path /test/dir
|
||||
|
|
|
|||
|
|
@ -1,9 +1,19 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
programs.radicle.enable = true;
|
||||
|
||||
test.stubs.radicle-node = {
|
||||
buildScript = ''
|
||||
mkdir -p "$out/bin"
|
||||
cat > "$out/bin/rad" << 'EOF'
|
||||
#!/bin/sh
|
||||
# Stub rad command that does nothing
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$out/bin/rad"
|
||||
'';
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.radicle/config.json \
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue