mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-11 17:39:37 +08:00
Compare commits
76 Commits
release-24
...
format-all
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a17d730ab5 | ||
|
|
3066cc58f5 | ||
|
|
e526fd2b1a | ||
|
|
15151bb5e7 | ||
|
|
6e5b2d9e80 | ||
|
|
f26aa4b76f | ||
|
|
c6a5fbfd99 | ||
|
|
8772bae58c | ||
|
|
e952e94955 | ||
|
|
77a792a041 | ||
|
|
9ebaa80a22 | ||
|
|
f63c15c137 | ||
|
|
d00c6f6d0a | ||
|
|
63eb786e04 | ||
|
|
0b42cc1b1c | ||
|
|
953521f759 | ||
|
|
65912bc684 | ||
|
|
0daaded612 | ||
|
|
86ee1290d7 | ||
|
|
1cd17a2f76 | ||
|
|
3a7fc9cd71 | ||
|
|
ad48eb25cd | ||
|
|
b1c19f1dcb | ||
|
|
30f66eaa32 | ||
|
|
6c3a7a0b72 | ||
|
|
8f4f57f9a6 | ||
|
|
7080328318 | ||
|
|
5b5de4338f | ||
|
|
256ec2653e | ||
|
|
92e644a95e | ||
|
|
dfdf59b2d5 | ||
|
|
f8bc330a13 | ||
|
|
c56aa0f51d | ||
|
|
33c236f1d5 | ||
|
|
092b81b956 | ||
|
|
bf23fe4108 | ||
|
|
873e39d5f4 | ||
|
|
d2e2bda6c0 | ||
|
|
c1fee8d4a6 | ||
|
|
8632735050 | ||
|
|
e71e678d18 | ||
|
|
7f78e2d1c6 | ||
|
|
441fae847d | ||
|
|
4964f3c6fc | ||
|
|
8eeda281e7 | ||
|
|
819f682269 | ||
|
|
2f7739d010 | ||
|
|
b721965238 | ||
|
|
de7d67b8ba | ||
|
|
21396857fd | ||
|
|
f83dc9f25a | ||
|
|
0941a2e144 | ||
|
|
a9953635d7 | ||
|
|
4d8d8c385e | ||
|
|
83002f1846 | ||
|
|
98bf8de65d | ||
|
|
f9fd45c512 | ||
|
|
9ae941a4cf | ||
|
|
5e2f47c5a5 | ||
|
|
bd58a1132e | ||
|
|
67cd4814a2 | ||
|
|
92fef254a9 | ||
|
|
ba9367b5a9 | ||
|
|
16fe78182e | ||
|
|
445d721ecf | ||
|
|
8cf9cb2ee7 | ||
|
|
a46e702093 | ||
|
|
d37f154dba | ||
|
|
a42fa14b53 | ||
|
|
705cf3763a | ||
|
|
094265fca0 | ||
|
|
0bd5e9c76c | ||
|
|
18462998b1 | ||
|
|
f3a2ff6958 | ||
|
|
05d3b6215a | ||
|
|
0918bb0238 |
8
.github/dependabot.yml
vendored
8
.github/dependabot.yml
vendored
@@ -15,3 +15,11 @@ updates:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci:"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "release-24.11"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci:"
|
||||
|
||||
@@ -28,7 +28,7 @@ Releases
|
||||
Home Manager is developed against `nixpkgs-unstable` branch, which often causes
|
||||
it to contain tweaks for changes/packages not yet released in stable [NixOS][].
|
||||
To avoid breaking users' configurations, Home Manager is released in branches
|
||||
corresponding to NixOS releases (e.g. `release-24.05`). These branches get
|
||||
corresponding to NixOS releases (e.g. `release-24.11`). These branches get
|
||||
fixes, but usually not new modules. If you need a module to be backported, then
|
||||
feel free to open an issue.
|
||||
|
||||
@@ -49,7 +49,7 @@ dconf store and cannot tell whether a configuration that it is about to be
|
||||
overwritten was from a previous Home Manager generation or from manual
|
||||
configuration.
|
||||
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 24.05 (the current
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 24.11 (the current
|
||||
stable version), it may or may not work on other Linux distributions and NixOS
|
||||
versions.
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ $ nix-channel --add https://github.com/nix-community/home-manager/archive/master
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 24.05 channel, you can run
|
||||
and if you follow a Nixpkgs version 24.11 channel, you can run
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
@@ -45,7 +45,7 @@ home-manager.users.eve = { pkgs, ... }: {
|
||||
|
||||
# The state version is required and should stay at the version you
|
||||
# originally installed.
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ $ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/m
|
||||
$ sudo nix-channel --update
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 24.05 channel, you can run
|
||||
and if you follow a Nixpkgs version 24.11 channel, you can run
|
||||
|
||||
``` shell
|
||||
$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager
|
||||
$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager
|
||||
$ sudo nix-channel --update
|
||||
```
|
||||
|
||||
@@ -44,7 +44,7 @@ home-manager.users.eve = { pkgs, ... }: {
|
||||
|
||||
# The state version is required and should stay at the version you
|
||||
# originally installed.
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 24.05 channel you can run
|
||||
and if you follow a Nixpkgs version 24.11 channel you can run
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Home Manager Manual {#home-manager-manual}
|
||||
|
||||
## Version 24.05 (unstable)
|
||||
## Version 25.05 (unstable)
|
||||
|
||||
|
||||
```{=include=} preface
|
||||
|
||||
@@ -11,10 +11,10 @@ then to generate and activate a basic configuration run the command
|
||||
$ nix run home-manager/master -- init --switch
|
||||
```
|
||||
|
||||
For Nixpkgs or NixOS version 24.05 run
|
||||
For Nixpkgs or NixOS version 24.11 run
|
||||
|
||||
``` shell
|
||||
$ nix run home-manager/release-24.05 -- init --switch
|
||||
$ nix run home-manager/release-24.11 -- init --switch
|
||||
```
|
||||
|
||||
This will generate a `flake.nix` and a `home.nix` file in
|
||||
@@ -30,7 +30,7 @@ $ # Edit files in ~/.config/home-manager
|
||||
$ nix run home-manager/$branch -- init --switch
|
||||
```
|
||||
|
||||
Where `$branch` is one of `master` or `release-24.05`.
|
||||
Where `$branch` is one of `master` or `release-24.11`.
|
||||
|
||||
After the initial activation has completed successfully then building
|
||||
and activating your flake-based configuration is as simple as
|
||||
|
||||
@@ -20,7 +20,7 @@ A fresh install of Home Manager will generate a minimal
|
||||
# You can update Home Manager without changing this value. See
|
||||
# the Home Manager release notes for a list of state version
|
||||
# changes in each release.
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
@@ -65,7 +65,7 @@ follows:
|
||||
# You can update Home Manager without changing this value. See
|
||||
# the Home Manager release notes for a list of state version
|
||||
# changes in each release.
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
@@ -4,6 +4,7 @@ This section lists the release notes for stable versions of Home Manager
|
||||
and the current unstable version.
|
||||
|
||||
```{=include=} chapters
|
||||
rl-2505.md
|
||||
rl-2411.md
|
||||
rl-2405.md
|
||||
rl-2311.md
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Release 24.11 {#sec-release-24.11}
|
||||
|
||||
This is the current unstable branch and the information in this section
|
||||
is therefore not final.
|
||||
The 24.05 release branch became stable in November, 2024.
|
||||
|
||||
## Highlights {#sec-release-24.11-highlights}
|
||||
|
||||
@@ -29,4 +28,4 @@ The state version in this release includes the changes below. These
|
||||
changes are only active if the `home.stateVersion` option is set to
|
||||
\"24.11\" or later.
|
||||
|
||||
- No changes.
|
||||
- There was no state version change in this release.
|
||||
|
||||
18
docs/release-notes/rl-2505.md
Normal file
18
docs/release-notes/rl-2505.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Release 25.05 {#sec-release-25.05}
|
||||
|
||||
This is the current unstable branch and the information in this
|
||||
section is therefore not final.
|
||||
|
||||
## Highlights {#sec-release-25.05-highlights}
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
- No changes.
|
||||
|
||||
## State Version Changes {#sec-release-25.05-state-version-changes}
|
||||
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the `home.stateVersion` option is set to
|
||||
\"25.05\" or later.
|
||||
|
||||
- No changes.
|
||||
6
flake.lock
generated
6
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1731139594,
|
||||
"narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=",
|
||||
"lastModified": 1733212471,
|
||||
"narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2",
|
||||
"rev": "55d15ad12a74eb7d4646254e13638ad0c4128776",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
14
format
14
format
@@ -23,23 +23,9 @@ for arg do
|
||||
esac
|
||||
done
|
||||
|
||||
# The excludes are for files touched by open pull requests and we want
|
||||
# to avoid merge conflicts.
|
||||
excludes=(
|
||||
modules/files.nix
|
||||
modules/home-environment.nix
|
||||
modules/programs/zsh.nix
|
||||
)
|
||||
|
||||
exclude_args=()
|
||||
for e in "${excludes[@]}"; do
|
||||
exclude_args+=(-e "$e")
|
||||
done
|
||||
|
||||
git_root=$(git rev-parse --show-toplevel)
|
||||
|
||||
git ls-files -z --cached --others --full-name -- "${files[@]}" |
|
||||
grep -z '\.nix$' |
|
||||
grep -z -v "${exclude_args[@]}" |
|
||||
sed -z "s|^|$git_root/|" |
|
||||
xargs -0 nixfmt "${nixfmt_args[@]}"
|
||||
|
||||
@@ -52,6 +52,11 @@ function hasFlakeSupport() {
|
||||
| grep -q nix-command
|
||||
}
|
||||
|
||||
# Escape string for use in Nix files.
|
||||
function escapeForNix() {
|
||||
printf %s "$1" | sed 's/["$\\]/\\\0/g'
|
||||
}
|
||||
|
||||
# Attempts to set the HOME_MANAGER_CONFIG global variable.
|
||||
#
|
||||
# If no configuration file can be found then this function will print
|
||||
@@ -201,7 +206,7 @@ function setFlakeAttribute() {
|
||||
# Check FQDN, long, and short hostnames; long first to preserve
|
||||
# pre-existing behaviour in case both happen to be defined.
|
||||
for n in "$USER@$(hostname -f)" "$USER@$(hostname)" "$USER@$(hostname -s)"; do
|
||||
if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$n\"")" == "true" ]]; then
|
||||
if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$(escapeForNix "$n")\"")" == "true" ]]; then
|
||||
name="$n"
|
||||
if [[ -v VERBOSE ]]; then
|
||||
echo "Using flake homeConfiguration for $name"
|
||||
@@ -210,7 +215,7 @@ function setFlakeAttribute() {
|
||||
done
|
||||
;;
|
||||
esac
|
||||
export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$name\""
|
||||
export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$(printf %s "$name" | jq -sRr @uri)\""
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -349,8 +354,8 @@ function doInit() {
|
||||
{
|
||||
# Home Manager needs a bit of information about you and the paths it should
|
||||
# manage.
|
||||
home.username = "$USER";
|
||||
home.homeDirectory = "$HOME";
|
||||
home.username = "$(escapeForNix "$USER")";
|
||||
home.homeDirectory = "$(escapeForNix "$HOME")";
|
||||
$xdgVars
|
||||
# This value determines the Home Manager release that your configuration is
|
||||
# compatible with. This helps avoid breakage when a new Home Manager release
|
||||
@@ -359,7 +364,7 @@ $xdgVars
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
home.stateVersion = "24.05"; # Please read the comment before changing.
|
||||
home.stateVersion = "24.11"; # Please read the comment before changing.
|
||||
|
||||
# The home.packages option allows you to install Nix packages into your
|
||||
# environment.
|
||||
@@ -439,7 +444,7 @@ EOF
|
||||
mkdir -p "$confDir"
|
||||
cat > "$flakeFile" <<EOF
|
||||
{
|
||||
description = "Home Manager configuration of $USER";
|
||||
description = "Home Manager configuration of $(escapeForNix "$USER")";
|
||||
|
||||
inputs = {
|
||||
# Specify the source of Home Manager and Nixpkgs.
|
||||
@@ -455,7 +460,7 @@ EOF
|
||||
system = "$nixSystem";
|
||||
pkgs = nixpkgs.legacyPackages.\${system};
|
||||
in {
|
||||
homeConfigurations."$USER" = home-manager.lib.homeManagerConfiguration {
|
||||
homeConfigurations."$(escapeForNix "$USER")" = home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
|
||||
# Specify your home configuration modules here, for example,
|
||||
@@ -855,9 +860,9 @@ function doUninstall() {
|
||||
cat > "$HOME_MANAGER_CONFIG" <<EOF
|
||||
{
|
||||
uninstall = true;
|
||||
home.username = "$USER";
|
||||
home.homeDirectory = "$HOME";
|
||||
home.stateVersion = "24.05";
|
||||
home.username = "$(escapeForNix "$USER")";
|
||||
home.homeDirectory = "$(escapeForNix "$HOME")";
|
||||
home.stateVersion = "24.11";
|
||||
}
|
||||
EOF
|
||||
# shellcheck disable=2064
|
||||
@@ -1044,7 +1049,7 @@ while [[ $# -gt 0 ]]; do
|
||||
export VERBOSE=1
|
||||
;;
|
||||
--version)
|
||||
echo 24.11-pre
|
||||
echo 25.05-pre
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -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: 2024-04-17 23:19+0200\n"
|
||||
"PO-Revision-Date: 2024-05-31 17:09+0000\n"
|
||||
"Last-Translator: jarre johansson <jarre@johansson.today>\n"
|
||||
"PO-Revision-Date: 2024-12-03 13:00+0000\n"
|
||||
"Last-Translator: Ricky Tigg <ricky.tigg@gmail.com>\n"
|
||||
"Language-Team: Finnish <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"fi/>\n"
|
||||
"Language: fi\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.6-dev\n"
|
||||
"X-Generator: Weblate 5.9-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -26,7 +26,7 @@ msgstr "%s: puuttuva argumentti kohteelle %s"
|
||||
|
||||
#: home-manager/home-manager:64
|
||||
msgid "No configuration file found at %s"
|
||||
msgstr "Konfiguraatiotiedostoa ei löytynyt sijainnista %s"
|
||||
msgstr "Kokoonpanotiedostoa ei löydy %s:sta"
|
||||
|
||||
#. translators: The first '%s' specifier will be replaced by either
|
||||
#. 'home.nix' or 'flake.nix'.
|
||||
@@ -36,10 +36,12 @@ msgid ""
|
||||
"Keeping your Home Manager %s in %s is deprecated,\n"
|
||||
"please move it to %s"
|
||||
msgstr ""
|
||||
"Home Managerin %s pitäminen %s:ssa on vanhentunut.\n"
|
||||
"ole hyvä ja siirrä se %s:een"
|
||||
|
||||
#: home-manager/home-manager:92
|
||||
msgid "No configuration file found. Please create one at %s"
|
||||
msgstr "Konfiguraatiotiedostoa ei löytynyt. Luo sellainen sijaintiin %s"
|
||||
msgstr "Kokoonpanotiedostoa ei löytynyt. Luo sellainen %s:lla"
|
||||
|
||||
#: home-manager/home-manager:107
|
||||
msgid "Home Manager not found at %s."
|
||||
|
||||
@@ -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: 2024-04-17 23:19+0200\n"
|
||||
"PO-Revision-Date: 2024-02-29 10:10+0000\n"
|
||||
"Last-Translator: FedFer98123 <fede.ferrari123@gmail.com>\n"
|
||||
"PO-Revision-Date: 2024-11-18 15:00+0000\n"
|
||||
"Last-Translator: Lorenzo Bevilacqua <lorenzobevilacqua02@gmail.com>\n"
|
||||
"Language-Team: Italian <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"it/>\n"
|
||||
"Language: it\n"
|
||||
@@ -17,12 +17,12 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.5-dev\n"
|
||||
"X-Generator: Weblate 5.9-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr ""
|
||||
msgstr "%s: argomento mancante per %s"
|
||||
|
||||
#: home-manager/home-manager:64
|
||||
msgid "No configuration file found at %s"
|
||||
|
||||
@@ -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: 2024-04-17 23:19+0200\n"
|
||||
"PO-Revision-Date: 2024-02-18 14:02+0000\n"
|
||||
"Last-Translator: Сергій <sergiy.goncharuk.1@gmail.com>\n"
|
||||
"PO-Revision-Date: 2024-11-18 15:00+0000\n"
|
||||
"Last-Translator: wadsaek <wadsaek@gmail.com>\n"
|
||||
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/home-manager/"
|
||||
"cli/uk/>\n"
|
||||
"Language: uk\n"
|
||||
@@ -18,12 +18,12 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 5.4\n"
|
||||
"X-Generator: Weblate 5.9-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr ""
|
||||
msgstr "%s: відсутній аргумент для %s"
|
||||
|
||||
#: home-manager/home-manager:64
|
||||
msgid "No configuration file found at %s"
|
||||
|
||||
@@ -45,6 +45,17 @@ let
|
||||
gtk config generation for {option}`home.pointerCursor`
|
||||
'';
|
||||
};
|
||||
|
||||
hyprcursor = {
|
||||
enable = mkEnableOption "hyprcursor config generation";
|
||||
|
||||
size = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
example = 32;
|
||||
default = null;
|
||||
description = "The cursor size for hyprcursor.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -163,7 +174,7 @@ in {
|
||||
}
|
||||
|
||||
(mkIf cfg.x11.enable {
|
||||
xsession.initExtra = ''
|
||||
xsession.profileExtra = ''
|
||||
${pkgs.xorg.xsetroot}/bin/xsetroot -xcf ${cursorPath} ${
|
||||
toString cfg.size
|
||||
}
|
||||
@@ -178,5 +189,13 @@ in {
|
||||
(mkIf cfg.gtk.enable {
|
||||
gtk.cursorTheme = mkDefault { inherit (cfg) package name size; };
|
||||
})
|
||||
|
||||
(mkIf cfg.hyprcursor.enable {
|
||||
home.sessionVariables = {
|
||||
HYPRCURSOR_THEME = cfg.name;
|
||||
HYPRCURSOR_SIZE =
|
||||
if cfg.hyprcursor.size != null then cfg.hyprcursor.size else cfg.size;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -8,26 +8,26 @@ let
|
||||
|
||||
homeDirectory = config.home.homeDirectory;
|
||||
|
||||
fileType = (import lib/file-type.nix {
|
||||
inherit homeDirectory lib pkgs;
|
||||
}).fileType;
|
||||
fileType =
|
||||
(import lib/file-type.nix { inherit homeDirectory lib pkgs; }).fileType;
|
||||
|
||||
sourceStorePath = file:
|
||||
let
|
||||
sourcePath = toString file.source;
|
||||
sourceName = config.lib.strings.storeFileName (baseNameOf sourcePath);
|
||||
in
|
||||
if builtins.hasContext sourcePath
|
||||
then file.source
|
||||
else builtins.path { path = file.source; name = sourceName; };
|
||||
in if builtins.hasContext sourcePath then
|
||||
file.source
|
||||
else
|
||||
builtins.path {
|
||||
path = file.source;
|
||||
name = sourceName;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options = {
|
||||
home.file = mkOption {
|
||||
description = "Attribute set of files to link into the user home.";
|
||||
default = {};
|
||||
default = { };
|
||||
type = fileType "home.file" "{env}`HOME`" homeDirectory;
|
||||
};
|
||||
|
||||
@@ -39,16 +39,14 @@ in
|
||||
};
|
||||
|
||||
config = {
|
||||
assertions = [(
|
||||
let
|
||||
dups =
|
||||
attrNames
|
||||
(filterAttrs (n: v: v > 1)
|
||||
(foldAttrs (acc: v: acc + v) 0
|
||||
assertions = [
|
||||
(let
|
||||
dups = attrNames (filterAttrs (n: v: v > 1)
|
||||
(foldAttrs (acc: v: acc + v) 0
|
||||
(mapAttrsToList (n: v: { ${v.target} = 1; }) cfg)));
|
||||
dupsStr = concatStringsSep ", " dups;
|
||||
in {
|
||||
assertion = dups == [];
|
||||
assertion = dups == [ ];
|
||||
message = ''
|
||||
Conflicting managed target files: ${dupsStr}
|
||||
|
||||
@@ -65,19 +63,17 @@ in
|
||||
let
|
||||
pathStr = toString path;
|
||||
name = hm.strings.storeFileName (baseNameOf pathStr);
|
||||
in
|
||||
pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out'';
|
||||
in pkgs.runCommandLocal name { } "ln -s ${escapeShellArg pathStr} $out";
|
||||
|
||||
# This verifies that the links we are about to create will not
|
||||
# overwrite an existing file.
|
||||
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
|
||||
let
|
||||
home.activation.checkLinkTargets = hm.dag.entryBefore [ "writeBoundary" ]
|
||||
(let
|
||||
# Paths that should be forcibly overwritten by Home Manager.
|
||||
# Caveat emptor!
|
||||
forcedPaths =
|
||||
concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'')
|
||||
(mapAttrsToList (n: v: v.target)
|
||||
(filterAttrs (n: v: v.force) cfg));
|
||||
(mapAttrsToList (n: v: v.target) (filterAttrs (n: v: v.force) cfg));
|
||||
|
||||
storeDir = escapeShellArg builtins.storeDir;
|
||||
|
||||
@@ -87,8 +83,7 @@ in
|
||||
inherit (config.lib.bash) initHomeManagerLib;
|
||||
inherit forcedPaths storeDir;
|
||||
};
|
||||
in
|
||||
''
|
||||
in ''
|
||||
function checkNewGenCollision() {
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
@@ -97,8 +92,7 @@ in
|
||||
}
|
||||
|
||||
checkNewGenCollision || exit 1
|
||||
''
|
||||
);
|
||||
'');
|
||||
|
||||
# This activation script will
|
||||
#
|
||||
@@ -121,129 +115,127 @@ in
|
||||
# and a failure during the intermediate state FA ∩ FB will not
|
||||
# result in lost links because this set of links are in both the
|
||||
# source and target generation.
|
||||
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
|
||||
let
|
||||
link = pkgs.writeShellScript "link" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
home.activation.linkGeneration = hm.dag.entryAfter [ "writeBoundary" ] (let
|
||||
link = pkgs.writeShellScript "link" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
newGenFiles="$1"
|
||||
shift
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
# The target exists, back it up
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
run mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
|
||||
fi
|
||||
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" ]] && cmp -s "$sourcePath" "$targetPath" ; then
|
||||
# The target exists but is identical – don't do anything.
|
||||
verboseEcho "Skipping '$targetPath' as it is identical to '$sourcePath'"
|
||||
else
|
||||
# Place that symlink, --force
|
||||
# This can still fail if the target is a directory, in which case we bail out.
|
||||
run mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
|
||||
run ln -Tsf $VERBOSE_ARG "$sourcePath" "$targetPath" || exit 1
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
cleanup = pkgs.writeShellScript "cleanup" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*"
|
||||
|
||||
newGenFiles="$1"
|
||||
shift 1
|
||||
for relativePath in "$@" ; do
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
||||
verboseEcho "Checking $targetPath: exists"
|
||||
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
warnEcho "Path '$targetPath' does not link into a Home Manager generation. Skipping delete."
|
||||
else
|
||||
verboseEcho "Checking $targetPath: gone (deleting)"
|
||||
run rm $VERBOSE_ARG "$targetPath"
|
||||
|
||||
# Recursively delete empty parent directories.
|
||||
targetDir="$(dirname "$relativePath")"
|
||||
if [[ "$targetDir" != "." ]] ; then
|
||||
pushd "$HOME" > /dev/null
|
||||
|
||||
# Call rmdir with a relative path excluding $HOME.
|
||||
# Otherwise, it might try to delete $HOME and exit
|
||||
# with a permission error.
|
||||
run rmdir $VERBOSE_ARG \
|
||||
-p --ignore-fail-on-non-empty \
|
||||
"$targetDir"
|
||||
|
||||
popd > /dev/null
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'';
|
||||
in
|
||||
''
|
||||
function linkNewGen() {
|
||||
_i "Creating home file links in %s" "$HOME"
|
||||
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${link} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
function cleanOldGen() {
|
||||
if [[ ! -v oldGenPath || ! -e "$oldGenPath/home-files" ]] ; then
|
||||
return
|
||||
fi
|
||||
|
||||
_i "Cleaning up orphan links from %s" "$HOME"
|
||||
|
||||
local newGenFiles oldGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
||||
|
||||
# Apply the cleanup script on each leaf in the old
|
||||
# generation. The find command below will print the
|
||||
# relative path of the entry.
|
||||
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \
|
||||
| xargs -0 bash ${cleanup} "$newGenFiles"
|
||||
}
|
||||
|
||||
cleanOldGen
|
||||
|
||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
_i "Creating profile generation %s" $newGenNum
|
||||
if [[ -e "$genProfilePath"/manifest.json ]] ; then
|
||||
# Remove all packages from "$genProfilePath"
|
||||
# `nix profile remove '.*' --profile "$genProfilePath"` was not working, so here is a workaround:
|
||||
nix profile list --profile "$genProfilePath" \
|
||||
| cut -d ' ' -f 4 \
|
||||
| xargs -rt $DRY_RUN_CMD nix profile remove $VERBOSE_ARG --profile "$genProfilePath"
|
||||
run nix profile install $VERBOSE_ARG --profile "$genProfilePath" "$newGenPath"
|
||||
else
|
||||
run nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||
fi
|
||||
|
||||
run --quiet nix-store --realise "$newGenPath" --add-root "$newGenGcPath" --indirect
|
||||
if [[ -e "$legacyGenGcPath" ]]; then
|
||||
run rm $VERBOSE_ARG "$legacyGenGcPath"
|
||||
fi
|
||||
else
|
||||
_i "No change so reusing latest profile generation %s" "$oldGenNum"
|
||||
newGenFiles="$1"
|
||||
shift
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
# The target exists, back it up
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
run mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
|
||||
fi
|
||||
|
||||
linkNewGen
|
||||
''
|
||||
);
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" ]] && cmp -s "$sourcePath" "$targetPath" ; then
|
||||
# The target exists but is identical – don't do anything.
|
||||
verboseEcho "Skipping '$targetPath' as it is identical to '$sourcePath'"
|
||||
else
|
||||
# Place that symlink, --force
|
||||
# This can still fail if the target is a directory, in which case we bail out.
|
||||
run mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
|
||||
run ln -Tsf $VERBOSE_ARG "$sourcePath" "$targetPath" || exit 1
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
|
||||
let
|
||||
homeDirArg = escapeShellArg homeDirectory;
|
||||
cleanup = pkgs.writeShellScript "cleanup" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern="$(readlink -e ${
|
||||
escapeShellArg builtins.storeDir
|
||||
})/*-home-manager-files/*"
|
||||
|
||||
newGenFiles="$1"
|
||||
shift 1
|
||||
for relativePath in "$@" ; do
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
||||
verboseEcho "Checking $targetPath: exists"
|
||||
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
warnEcho "Path '$targetPath' does not link into a Home Manager generation. Skipping delete."
|
||||
else
|
||||
verboseEcho "Checking $targetPath: gone (deleting)"
|
||||
run rm $VERBOSE_ARG "$targetPath"
|
||||
|
||||
# Recursively delete empty parent directories.
|
||||
targetDir="$(dirname "$relativePath")"
|
||||
if [[ "$targetDir" != "." ]] ; then
|
||||
pushd "$HOME" > /dev/null
|
||||
|
||||
# Call rmdir with a relative path excluding $HOME.
|
||||
# Otherwise, it might try to delete $HOME and exit
|
||||
# with a permission error.
|
||||
run rmdir $VERBOSE_ARG \
|
||||
-p --ignore-fail-on-non-empty \
|
||||
"$targetDir"
|
||||
|
||||
popd > /dev/null
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'';
|
||||
in ''
|
||||
function linkNewGen() {
|
||||
_i "Creating home file links in %s" "$HOME"
|
||||
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${link} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
function cleanOldGen() {
|
||||
if [[ ! -v oldGenPath || ! -e "$oldGenPath/home-files" ]] ; then
|
||||
return
|
||||
fi
|
||||
|
||||
_i "Cleaning up orphan links from %s" "$HOME"
|
||||
|
||||
local newGenFiles oldGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
||||
|
||||
# Apply the cleanup script on each leaf in the old
|
||||
# generation. The find command below will print the
|
||||
# relative path of the entry.
|
||||
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \
|
||||
| xargs -0 bash ${cleanup} "$newGenFiles"
|
||||
}
|
||||
|
||||
cleanOldGen
|
||||
|
||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
_i "Creating profile generation %s" $newGenNum
|
||||
if [[ -e "$genProfilePath"/manifest.json ]] ; then
|
||||
# Remove all packages from "$genProfilePath"
|
||||
# `nix profile remove '.*' --profile "$genProfilePath"` was not working, so here is a workaround:
|
||||
nix profile list --profile "$genProfilePath" \
|
||||
| cut -d ' ' -f 4 \
|
||||
| xargs -rt $DRY_RUN_CMD nix profile remove $VERBOSE_ARG --profile "$genProfilePath"
|
||||
run nix profile install $VERBOSE_ARG --profile "$genProfilePath" "$newGenPath"
|
||||
else
|
||||
run nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||
fi
|
||||
|
||||
run --quiet nix-store --realise "$newGenPath" --add-root "$newGenGcPath" --indirect
|
||||
if [[ -e "$legacyGenGcPath" ]]; then
|
||||
run rm $VERBOSE_ARG "$legacyGenGcPath"
|
||||
fi
|
||||
else
|
||||
_i "No change so reusing latest profile generation %s" "$oldGenNum"
|
||||
fi
|
||||
|
||||
linkNewGen
|
||||
'');
|
||||
|
||||
home.activation.checkFilesChanged = hm.dag.entryBefore [ "linkGeneration" ]
|
||||
(let homeDirArg = escapeShellArg homeDirectory;
|
||||
in ''
|
||||
function _cmp() {
|
||||
if [[ -d $1 && -d $2 ]]; then
|
||||
@@ -261,14 +253,12 @@ in
|
||||
_cmp ${sourceArg} ${homeDirArg}/${targetArg} \
|
||||
&& changedFiles[${targetArg}]=0 \
|
||||
|| changedFiles[${targetArg}]=1
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
+ ''
|
||||
unset -f _cmp
|
||||
''
|
||||
);
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg)) + ''
|
||||
unset -f _cmp
|
||||
'');
|
||||
|
||||
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
|
||||
concatMapStrings (v: ''
|
||||
home.activation.onFilesChange = hm.dag.entryAfter [ "linkGeneration" ]
|
||||
(concatMapStrings (v: ''
|
||||
if (( ''${changedFiles[${escapeShellArg v.target}]} == 1 )); then
|
||||
if [[ -v DRY_RUN || -v VERBOSE ]]; then
|
||||
echo "Running onChange hook for" ${escapeShellArg v.target}
|
||||
@@ -277,90 +267,83 @@ in
|
||||
${v.onChange}
|
||||
fi
|
||||
fi
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
);
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg)));
|
||||
|
||||
# Symlink directories and files that have the right execute bit.
|
||||
# Copy files that need their execute bit changed.
|
||||
home-files = pkgs.runCommandLocal
|
||||
"home-manager-files"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
||||
}
|
||||
(''
|
||||
mkdir -p $out
|
||||
home-files = pkgs.runCommandLocal "home-manager-files" {
|
||||
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
||||
} (''
|
||||
mkdir -p $out
|
||||
|
||||
# Needed in case /nix is a symbolic link.
|
||||
realOut="$(realpath -m "$out")"
|
||||
# Needed in case /nix is a symbolic link.
|
||||
realOut="$(realpath -m "$out")"
|
||||
|
||||
function insertFile() {
|
||||
local source="$1"
|
||||
local relTarget="$2"
|
||||
local executable="$3"
|
||||
local recursive="$4"
|
||||
function insertFile() {
|
||||
local source="$1"
|
||||
local relTarget="$2"
|
||||
local executable="$3"
|
||||
local recursive="$4"
|
||||
|
||||
# If the target already exists then we have a collision. Note, this
|
||||
# should not happen due to the assertion found in the 'files' module.
|
||||
# We therefore simply log the conflict and otherwise ignore it, mainly
|
||||
# to make the `files-target-config` test work as expected.
|
||||
if [[ -e "$realOut/$relTarget" ]]; then
|
||||
echo "File conflict for file '$relTarget'" >&2
|
||||
return
|
||||
fi
|
||||
# If the target already exists then we have a collision. Note, this
|
||||
# should not happen due to the assertion found in the 'files' module.
|
||||
# We therefore simply log the conflict and otherwise ignore it, mainly
|
||||
# to make the `files-target-config` test work as expected.
|
||||
if [[ -e "$realOut/$relTarget" ]]; then
|
||||
echo "File conflict for file '$relTarget'" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
# Figure out the real absolute path to the target.
|
||||
local target
|
||||
target="$(realpath -m "$realOut/$relTarget")"
|
||||
# Figure out the real absolute path to the target.
|
||||
local target
|
||||
target="$(realpath -m "$realOut/$relTarget")"
|
||||
|
||||
# Target path must be within $HOME.
|
||||
if [[ ! $target == $realOut* ]] ; then
|
||||
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Target path must be within $HOME.
|
||||
if [[ ! $target == $realOut* ]] ; then
|
||||
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$target")"
|
||||
if [[ -d $source ]]; then
|
||||
if [[ $recursive ]]; then
|
||||
mkdir -p "$target"
|
||||
lndir -silent "$source" "$target"
|
||||
else
|
||||
ln -s "$source" "$target"
|
||||
fi
|
||||
mkdir -p "$(dirname "$target")"
|
||||
if [[ -d $source ]]; then
|
||||
if [[ $recursive ]]; then
|
||||
mkdir -p "$target"
|
||||
lndir -silent "$source" "$target"
|
||||
else
|
||||
[[ -x $source ]] && isExecutable=1 || isExecutable=""
|
||||
ln -s "$source" "$target"
|
||||
fi
|
||||
else
|
||||
[[ -x $source ]] && isExecutable=1 || isExecutable=""
|
||||
|
||||
# Link the file into the home file directory if possible,
|
||||
# i.e., if the executable bit of the source is the same we
|
||||
# expect for the target. Otherwise, we copy the file and
|
||||
# set the executable bit to the expected value.
|
||||
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||
ln -s "$source" "$target"
|
||||
# Link the file into the home file directory if possible,
|
||||
# i.e., if the executable bit of the source is the same we
|
||||
# expect for the target. Otherwise, we copy the file and
|
||||
# set the executable bit to the expected value.
|
||||
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||
ln -s "$source" "$target"
|
||||
else
|
||||
cp "$source" "$target"
|
||||
|
||||
if [[ $executable == inherit ]]; then
|
||||
# Don't change file mode if it should match the source.
|
||||
:
|
||||
elif [[ $executable ]]; then
|
||||
chmod +x "$target"
|
||||
else
|
||||
cp "$source" "$target"
|
||||
|
||||
if [[ $executable == inherit ]]; then
|
||||
# Don't change file mode if it should match the source.
|
||||
:
|
||||
elif [[ $executable ]]; then
|
||||
chmod +x "$target"
|
||||
else
|
||||
chmod -x "$target"
|
||||
fi
|
||||
chmod -x "$target"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
'' + concatStrings (
|
||||
mapAttrsToList (n: v: ''
|
||||
insertFile ${
|
||||
escapeShellArgs [
|
||||
(sourceStorePath v)
|
||||
v.target
|
||||
(if v.executable == null
|
||||
then "inherit"
|
||||
else toString v.executable)
|
||||
(toString v.recursive)
|
||||
]}
|
||||
'') cfg
|
||||
));
|
||||
fi
|
||||
}
|
||||
'' + concatStrings (mapAttrsToList (n: v: ''
|
||||
insertFile ${
|
||||
escapeShellArgs [
|
||||
(sourceStorePath v)
|
||||
v.target
|
||||
(if v.executable == null then "inherit" else toString v.executable)
|
||||
(toString v.recursive)
|
||||
]
|
||||
}
|
||||
'') cfg));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -113,10 +113,10 @@ let
|
||||
options = {
|
||||
layout = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "us";
|
||||
default = if versionAtLeast config.home.stateVersion "19.09" then
|
||||
null
|
||||
else
|
||||
"us";
|
||||
defaultText = literalExpression "null";
|
||||
description = ''
|
||||
Keyboard layout. If `null`, then the system
|
||||
@@ -138,8 +138,8 @@ let
|
||||
|
||||
options = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = ["grp:caps_toggle" "grp_led:scroll"];
|
||||
default = [ ];
|
||||
example = [ "grp:caps_toggle" "grp_led:scroll" ];
|
||||
description = ''
|
||||
X keyboard options; layout switching goes here.
|
||||
'';
|
||||
@@ -148,9 +148,7 @@ let
|
||||
variant = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "";
|
||||
if versionAtLeast config.home.stateVersion "19.09" then null else "";
|
||||
defaultText = literalExpression "null";
|
||||
example = "colemak";
|
||||
description = ''
|
||||
@@ -164,9 +162,7 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
@@ -217,7 +213,7 @@ in
|
||||
|
||||
home.language = mkOption {
|
||||
type = languageSubModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = "Language configuration.";
|
||||
};
|
||||
|
||||
@@ -255,9 +251,12 @@ in
|
||||
};
|
||||
|
||||
home.sessionVariables = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = with types; lazyAttrsOf (oneOf [ str path int float ]);
|
||||
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
||||
example = {
|
||||
EDITOR = "emacs";
|
||||
GS_OPTIONS = "-sPAPERSIZE=a4";
|
||||
};
|
||||
description = ''
|
||||
Environment variables to always set at login.
|
||||
|
||||
@@ -332,13 +331,13 @@ in
|
||||
|
||||
home.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
default = [ ];
|
||||
description = "The set of packages to appear in the user environment.";
|
||||
};
|
||||
|
||||
home.extraOutputsToInstall = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "doc" "info" "devdoc" ];
|
||||
description = ''
|
||||
List of additional package outputs of the packages
|
||||
@@ -371,7 +370,7 @@ in
|
||||
|
||||
home.activation = mkOption {
|
||||
type = hm.types.dagOf types.str;
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||
@@ -494,77 +493,60 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
let
|
||||
hmRelease = config.home.version.release;
|
||||
nixpkgsRelease = lib.trivial.release;
|
||||
releaseMismatch =
|
||||
config.home.enableNixpkgsReleaseCheck
|
||||
&& hmRelease != nixpkgsRelease;
|
||||
in
|
||||
optional releaseMismatch ''
|
||||
You are using
|
||||
warnings = let
|
||||
hmRelease = config.home.version.release;
|
||||
nixpkgsRelease = lib.trivial.release;
|
||||
releaseMismatch = config.home.enableNixpkgsReleaseCheck && hmRelease
|
||||
!= nixpkgsRelease;
|
||||
in optional releaseMismatch ''
|
||||
You are using
|
||||
|
||||
Home Manager version ${hmRelease} and
|
||||
Nixpkgs version ${nixpkgsRelease}.
|
||||
Home Manager version ${hmRelease} and
|
||||
Nixpkgs version ${nixpkgsRelease}.
|
||||
|
||||
Using mismatched versions is likely to cause errors and unexpected
|
||||
behavior. It is therefore highly recommended to use a release of Home
|
||||
Manager that corresponds with your chosen release of Nixpkgs.
|
||||
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
|
||||
If you insist then you can disable this warning by adding
|
||||
|
||||
home.enableNixpkgsReleaseCheck = false;
|
||||
home.enableNixpkgsReleaseCheck = false;
|
||||
|
||||
to your configuration.
|
||||
'';
|
||||
to your configuration.
|
||||
'';
|
||||
|
||||
home.username =
|
||||
mkIf (versionOlder config.home.stateVersion "20.09")
|
||||
(mkDefault (builtins.getEnv "USER"));
|
||||
home.homeDirectory =
|
||||
mkIf (versionOlder config.home.stateVersion "20.09")
|
||||
(mkDefault (builtins.getEnv "HOME"));
|
||||
home.username = mkIf (versionOlder config.home.stateVersion "20.09")
|
||||
(mkDefault (builtins.getEnv "USER"));
|
||||
home.homeDirectory = mkIf (versionOlder config.home.stateVersion "20.09")
|
||||
(mkDefault (builtins.getEnv "HOME"));
|
||||
|
||||
home.profileDirectory =
|
||||
if config.submoduleSupport.enable
|
||||
&& config.submoduleSupport.externalPackageInstall
|
||||
then "/etc/profiles/per-user/${cfg.username}"
|
||||
else if config.nix.enable && (config.nix.settings.use-xdg-base-directories or false)
|
||||
then "${config.xdg.stateHome}/nix/profile"
|
||||
else cfg.homeDirectory + "/.nix-profile";
|
||||
home.profileDirectory = if config.submoduleSupport.enable
|
||||
&& config.submoduleSupport.externalPackageInstall then
|
||||
"/etc/profiles/per-user/${cfg.username}"
|
||||
else if config.nix.enable
|
||||
&& (config.nix.settings.use-xdg-base-directories or false) then
|
||||
"${config.xdg.stateHome}/nix/profile"
|
||||
else
|
||||
cfg.homeDirectory + "/.nix-profile";
|
||||
|
||||
programs.bash.shellAliases = cfg.shellAliases;
|
||||
programs.zsh.shellAliases = cfg.shellAliases;
|
||||
programs.fish.shellAliases = cfg.shellAliases;
|
||||
|
||||
home.sessionVariables =
|
||||
let
|
||||
maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
||||
in
|
||||
(maybeSet "LANG" cfg.language.base)
|
||||
//
|
||||
(maybeSet "LC_CTYPE" cfg.language.ctype)
|
||||
//
|
||||
(maybeSet "LC_NUMERIC" cfg.language.numeric)
|
||||
//
|
||||
(maybeSet "LC_TIME" cfg.language.time)
|
||||
//
|
||||
(maybeSet "LC_COLLATE" cfg.language.collate)
|
||||
//
|
||||
(maybeSet "LC_MONETARY" cfg.language.monetary)
|
||||
//
|
||||
(maybeSet "LC_MESSAGES" cfg.language.messages)
|
||||
//
|
||||
(maybeSet "LC_PAPER" cfg.language.paper)
|
||||
//
|
||||
(maybeSet "LC_NAME" cfg.language.name)
|
||||
//
|
||||
(maybeSet "LC_ADDRESS" cfg.language.address)
|
||||
//
|
||||
(maybeSet "LC_TELEPHONE" cfg.language.telephone)
|
||||
//
|
||||
(maybeSet "LC_MEASUREMENT" cfg.language.measurement);
|
||||
let maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
||||
in (maybeSet "LANG" cfg.language.base)
|
||||
// (maybeSet "LC_CTYPE" cfg.language.ctype)
|
||||
// (maybeSet "LC_NUMERIC" cfg.language.numeric)
|
||||
// (maybeSet "LC_TIME" cfg.language.time)
|
||||
// (maybeSet "LC_COLLATE" cfg.language.collate)
|
||||
// (maybeSet "LC_MONETARY" cfg.language.monetary)
|
||||
// (maybeSet "LC_MESSAGES" cfg.language.messages)
|
||||
// (maybeSet "LC_PAPER" cfg.language.paper)
|
||||
// (maybeSet "LC_NAME" cfg.language.name)
|
||||
// (maybeSet "LC_ADDRESS" cfg.language.address)
|
||||
// (maybeSet "LC_TELEPHONE" cfg.language.telephone)
|
||||
// (maybeSet "LC_MEASUREMENT" cfg.language.measurement);
|
||||
|
||||
# Provide a file holding all session variables.
|
||||
home.sessionVariablesPackage = pkgs.writeTextFile {
|
||||
@@ -602,148 +584,129 @@ in
|
||||
# In case the user has moved from a user-install of Home Manager
|
||||
# to a submodule managed one we attempt to uninstall the
|
||||
# `home-manager-path` package if it is installed.
|
||||
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
|
||||
if config.submoduleSupport.externalPackageInstall
|
||||
then
|
||||
''
|
||||
nixProfileRemove home-manager-path
|
||||
''
|
||||
else
|
||||
''
|
||||
function nixReplaceProfile() {
|
||||
local oldNix="$(command -v nix)"
|
||||
home.activation.installPackages = hm.dag.entryAfter [ "writeBoundary" ]
|
||||
(if config.submoduleSupport.externalPackageInstall then ''
|
||||
nixProfileRemove home-manager-path
|
||||
'' else ''
|
||||
function nixReplaceProfile() {
|
||||
local oldNix="$(command -v nix)"
|
||||
|
||||
nixProfileRemove 'home-manager-path'
|
||||
nixProfileRemove 'home-manager-path'
|
||||
|
||||
run $oldNix profile install $1
|
||||
}
|
||||
run $oldNix profile install $1
|
||||
}
|
||||
|
||||
if [[ -e ${cfg.profileDirectory}/manifest.json ]] ; then
|
||||
INSTALL_CMD="nix profile install"
|
||||
INSTALL_CMD_ACTUAL="nixReplaceProfile"
|
||||
LIST_CMD="nix profile list"
|
||||
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
|
||||
else
|
||||
INSTALL_CMD="nix-env -i"
|
||||
INSTALL_CMD_ACTUAL="run nix-env -i"
|
||||
LIST_CMD="nix-env -q"
|
||||
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
|
||||
fi
|
||||
if [[ -e ${cfg.profileDirectory}/manifest.json ]] ; then
|
||||
INSTALL_CMD="nix profile install"
|
||||
INSTALL_CMD_ACTUAL="nixReplaceProfile"
|
||||
LIST_CMD="nix profile list"
|
||||
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
|
||||
else
|
||||
INSTALL_CMD="nix-env -i"
|
||||
INSTALL_CMD_ACTUAL="run nix-env -i"
|
||||
LIST_CMD="nix-env -q"
|
||||
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
|
||||
fi
|
||||
|
||||
if ! $INSTALL_CMD_ACTUAL ${cfg.path} ; then
|
||||
echo
|
||||
_iError $'Oops, Nix failed to install your new Home Manager profile!\n\nPerhaps there is a conflict with a package that was installed using\n"%s"? Try running\n\n %s\n\nand if there is a conflicting package you can remove it with\n\n %s\n\nThen try activating your Home Manager configuration again.' "$INSTALL_CMD" "$LIST_CMD" "$REMOVE_CMD_SYNTAX"
|
||||
exit 1
|
||||
fi
|
||||
unset -f nixReplaceProfile
|
||||
unset INSTALL_CMD INSTALL_CMD_ACTUAL LIST_CMD REMOVE_CMD_SYNTAX
|
||||
''
|
||||
);
|
||||
if ! $INSTALL_CMD_ACTUAL ${cfg.path} ; then
|
||||
echo
|
||||
_iError $'Oops, Nix failed to install your new Home Manager profile!\n\nPerhaps there is a conflict with a package that was installed using\n"%s"? Try running\n\n %s\n\nand if there is a conflicting package you can remove it with\n\n %s\n\nThen try activating your Home Manager configuration again.' "$INSTALL_CMD" "$LIST_CMD" "$REMOVE_CMD_SYNTAX"
|
||||
exit 1
|
||||
fi
|
||||
unset -f nixReplaceProfile
|
||||
unset INSTALL_CMD INSTALL_CMD_ACTUAL LIST_CMD REMOVE_CMD_SYNTAX
|
||||
'');
|
||||
|
||||
# Text containing Bash commands that will initialize the Home Manager Bash
|
||||
# library. Most importantly, this will prepare for using translated strings
|
||||
# in the `hm-modules` text domain.
|
||||
lib.bash.initHomeManagerLib =
|
||||
let
|
||||
domainDir = pkgs.runCommand "hm-modules-messages" {
|
||||
nativeBuildInputs = [ pkgs.buildPackages.gettext ];
|
||||
} ''
|
||||
for path in ${./po}/*.po; do
|
||||
lang="''${path##*/}"
|
||||
lang="''${lang%%.*}"
|
||||
mkdir -p "$out/$lang/LC_MESSAGES"
|
||||
msgfmt -o "$out/$lang/LC_MESSAGES/hm-modules.mo" "$path"
|
||||
done
|
||||
'';
|
||||
in
|
||||
''
|
||||
export TEXTDOMAIN=hm-modules
|
||||
export TEXTDOMAINDIR=${domainDir}
|
||||
source ${../lib/bash/home-manager.sh}
|
||||
'';
|
||||
lib.bash.initHomeManagerLib = let
|
||||
domainDir = pkgs.runCommand "hm-modules-messages" {
|
||||
nativeBuildInputs = [ pkgs.buildPackages.gettext ];
|
||||
} ''
|
||||
for path in ${./po}/*.po; do
|
||||
lang="''${path##*/}"
|
||||
lang="''${lang%%.*}"
|
||||
mkdir -p "$out/$lang/LC_MESSAGES"
|
||||
msgfmt -o "$out/$lang/LC_MESSAGES/hm-modules.mo" "$path"
|
||||
done
|
||||
'';
|
||||
in ''
|
||||
export TEXTDOMAIN=hm-modules
|
||||
export TEXTDOMAINDIR=${domainDir}
|
||||
source ${../lib/bash/home-manager.sh}
|
||||
'';
|
||||
|
||||
home.activationPackage =
|
||||
let
|
||||
mkCmd = res: ''
|
||||
_iNote "Activating %s" "${res.name}"
|
||||
${res.data}
|
||||
'';
|
||||
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||
activationCmds =
|
||||
if sortedCommands ? result then
|
||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||
else
|
||||
abort ("Dependency cycle in activation script: "
|
||||
+ builtins.toJSON sortedCommands);
|
||||
home.activationPackage = let
|
||||
mkCmd = res: ''
|
||||
_iNote "Activating %s" "${res.name}"
|
||||
${res.data}
|
||||
'';
|
||||
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||
activationCmds = if sortedCommands ? result then
|
||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||
else
|
||||
abort ("Dependency cycle in activation script: "
|
||||
+ builtins.toJSON sortedCommands);
|
||||
|
||||
# Programs that always should be available on the activation
|
||||
# script's PATH.
|
||||
activationBinPaths = lib.makeBinPath (
|
||||
with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
diffutils # For `cmp` and `diff`.
|
||||
findutils
|
||||
gettext
|
||||
gnugrep
|
||||
gnused
|
||||
jq
|
||||
ncurses # For `tput`.
|
||||
]
|
||||
++ config.home.extraActivationPath
|
||||
)
|
||||
+ (
|
||||
# Programs that always should be available on the activation
|
||||
# script's PATH.
|
||||
activationBinPaths = lib.makeBinPath (with pkgs;
|
||||
[
|
||||
bash
|
||||
coreutils
|
||||
diffutils # For `cmp` and `diff`.
|
||||
findutils
|
||||
gettext
|
||||
gnugrep
|
||||
gnused
|
||||
jq
|
||||
ncurses # For `tput`.
|
||||
] ++ config.home.extraActivationPath) + (
|
||||
# Add path of the Nix binaries, if a Nix package is configured, then
|
||||
# use that one, otherwise grab the path of the nix-env tool.
|
||||
if config.nix.enable && config.nix.package != null then
|
||||
":${config.nix.package}/bin"
|
||||
else
|
||||
":$(${pkgs.coreutils}/bin/dirname $(${pkgs.coreutils}/bin/readlink -m $(type -p nix-env)))"
|
||||
)
|
||||
":$(${pkgs.coreutils}/bin/dirname $(${pkgs.coreutils}/bin/readlink -m $(type -p nix-env)))")
|
||||
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||
|
||||
activationScript = pkgs.writeShellScript "activation-script" ''
|
||||
set -eu
|
||||
set -o pipefail
|
||||
activationScript = pkgs.writeShellScript "activation-script" ''
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
cd $HOME
|
||||
cd $HOME
|
||||
|
||||
export PATH="${activationBinPaths}"
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
export PATH="${activationBinPaths}"
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
${builtins.readFile ./lib-bash/activation-init.sh}
|
||||
${builtins.readFile ./lib-bash/activation-init.sh}
|
||||
|
||||
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
|
||||
checkUsername ${escapeShellArg config.home.username}
|
||||
checkHomeDirectory ${escapeShellArg config.home.homeDirectory}
|
||||
fi
|
||||
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
|
||||
checkUsername ${escapeShellArg config.home.username}
|
||||
checkHomeDirectory ${escapeShellArg config.home.homeDirectory}
|
||||
fi
|
||||
|
||||
${activationCmds}
|
||||
'';
|
||||
in
|
||||
pkgs.runCommand
|
||||
"home-manager-generation"
|
||||
{
|
||||
preferLocalBuild = true;
|
||||
}
|
||||
''
|
||||
mkdir -p $out
|
||||
${activationCmds}
|
||||
'';
|
||||
in pkgs.runCommand "home-manager-generation" { preferLocalBuild = true; } ''
|
||||
mkdir -p $out
|
||||
|
||||
echo "${config.home.version.full}" > $out/hm-version
|
||||
echo "${config.home.version.full}" > $out/hm-version
|
||||
|
||||
cp ${activationScript} $out/activate
|
||||
cp ${activationScript} $out/activate
|
||||
|
||||
mkdir $out/bin
|
||||
ln -s $out/activate $out/bin/home-manager-generation
|
||||
mkdir $out/bin
|
||||
ln -s $out/activate $out/bin/home-manager-generation
|
||||
|
||||
substituteInPlace $out/activate \
|
||||
--subst-var-by GENERATION_DIR $out
|
||||
substituteInPlace $out/activate \
|
||||
--subst-var-by GENERATION_DIR $out
|
||||
|
||||
ln -s ${config.home-files} $out/home-files
|
||||
ln -s ${cfg.path} $out/home-path
|
||||
ln -s ${config.home-files} $out/home-files
|
||||
ln -s ${cfg.path} $out/home-path
|
||||
|
||||
${cfg.extraBuilderCommands}
|
||||
'';
|
||||
${cfg.extraBuilderCommands}
|
||||
'';
|
||||
|
||||
home.path = pkgs.buildEnv {
|
||||
name = "home-manager-path";
|
||||
|
||||
@@ -1827,6 +1827,78 @@ in {
|
||||
as systemd services.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2024-12-01T19:17:40+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.nix-your-shell'.
|
||||
|
||||
nix-your-shell is a wrapper for `nix develop` or `nix-shell` to retain
|
||||
the same shell inside the new environment.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2024-12-01T19:34:04+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.kubecolor'.
|
||||
|
||||
Kubecolor is a kubectl wrapper used to add colors to your kubectl
|
||||
output.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2024-12-04T20:00:00+00:00";
|
||||
condition = let
|
||||
sCfg = config.programs.starship;
|
||||
fCfg = config.programs.fish;
|
||||
in sCfg.enable && sCfg.enableFishIntegration && fCfg.enable;
|
||||
message = ''
|
||||
A new option 'programs.starship.enableInteractive' is available for
|
||||
the Fish shell that only enables starship if the shell is interactive.
|
||||
|
||||
Some plugins require this to be set to 'false' to function correctly.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2024-12-08T17:22:13+00:00";
|
||||
condition = let
|
||||
usingMbsync = any (a: a.mbsync.enable)
|
||||
(attrValues config.accounts.email.accounts);
|
||||
in usingMbsync;
|
||||
message = ''
|
||||
isync/mbsync 1.5.0 has changed several things.
|
||||
|
||||
isync gained support for using $XDG_CONFIG_HOME, and now places
|
||||
its config file in '$XDG_CONFIG_HOME/isyncrc'.
|
||||
|
||||
isync changed the configuration options SSLType and SSLVersion to
|
||||
TLSType and TLSVersion respectively.
|
||||
|
||||
All instances of
|
||||
'accounts.email.accounts.<account-name>.mbsync.extraConfig.account'
|
||||
that use 'SSLType' or 'SSLVersion' should be replaced with 'TLSType'
|
||||
or 'TLSVersion', respectively.
|
||||
|
||||
TLSType options are unchanged.
|
||||
|
||||
TLSVersions has a new syntax, requiring a change to the Nix syntax.
|
||||
Old Syntax: SSLVersions = [ "TLSv1.3" "TLSv1.2" ];
|
||||
New Syntax: TLSVersions = [ "+1.3" "+1.2" "-1.1" ];
|
||||
NOTE: The minus symbol means to NOT use that particular TLS version.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2024-12-10T22:20:10+00:00";
|
||||
condition = config.programs.nushell.enable;
|
||||
message = ''
|
||||
The module 'programs.nushell' can now manage the Nushell plugin
|
||||
registry with the option 'programs.nushell.plugins'.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@ let
|
||||
gnome = [ qgnomeplatform qgnomeplatform-qt6 ];
|
||||
adwaita = [ qadwaitadecorations qadwaitadecorations-qt6 ];
|
||||
gtk = [ libsForQt5.qtstyleplugins qt6Packages.qt6gtk2 ];
|
||||
kde = [ libsForQt5.plasma-integration libsForQt5.systemsettings ];
|
||||
kde = [
|
||||
libsForQt5.kio
|
||||
libsForQt5.plasma-integration
|
||||
libsForQt5.systemsettings
|
||||
];
|
||||
lxqt = [ lxqt.lxqt-qtplugin lxqt.lxqt-config ];
|
||||
qtct = [ libsForQt5.qt5ct qt6Packages.qt6ct ];
|
||||
};
|
||||
|
||||
@@ -17,13 +17,13 @@ in {
|
||||
powermanagementprofilesrc.AC.HandleButtonEvents.lidAction = 32;
|
||||
};
|
||||
description = ''
|
||||
A set of values to be modified by {command}`kwriteconfig5`.
|
||||
A set of values to be modified by {command}`kwriteconfig6`.
|
||||
|
||||
The example value would cause the following command to run in the
|
||||
activation script:
|
||||
|
||||
``` shell
|
||||
kwriteconfig5 --file $XDG_CONFIG_HOME/powermanagementprofilesrc \
|
||||
kwriteconfig6 --file $XDG_CONFIG_HOME/powermanagementprofilesrc \
|
||||
--group AC \
|
||||
--group HandleButtonEvents \
|
||||
--group lidAction \
|
||||
@@ -53,7 +53,7 @@ in {
|
||||
lib.mapAttrsToList
|
||||
(group: value: toLine file (path ++ [ group ]) value) value
|
||||
else
|
||||
"run test -f '${configHome}/${file}' && run ${pkgs.libsForQt5.kconfig}/bin/kwriteconfig5 --file '${configHome}/${file}' ${
|
||||
"run ${pkgs.kdePackages.kconfig}/bin/kwriteconfig6 --file '${configHome}/${file}' ${
|
||||
lib.concatMapStringsSep " " (x: "--group ${x}")
|
||||
(lib.lists.init path)
|
||||
} --key '${lib.lists.last path}' ${toValue value}";
|
||||
@@ -62,7 +62,7 @@ in {
|
||||
in builtins.concatStringsSep "\n" lines}
|
||||
|
||||
# TODO: some way to only call the dbus calls needed
|
||||
run ${pkgs.libsForQt5.qttools.bin}/bin/qdbus org.kde.KWin /KWin reconfigure || echo "KWin reconfigure failed"
|
||||
run ${pkgs.kdePackages.qttools}/bin/qdbus org.kde.KWin /KWin reconfigure || echo "KWin reconfigure failed"
|
||||
# the actual values are https://github.com/KDE/plasma-workspace/blob/c97dddf20df5702eb429b37a8c10b2c2d8199d4e/kcms/kcms-common_p.h#L13
|
||||
for changeType in {0..10}; do
|
||||
# even if one of those calls fails the others keep running
|
||||
|
||||
@@ -21,7 +21,7 @@ in {
|
||||
config = mkIf config.uninstall {
|
||||
home.packages = lib.mkForce [ ];
|
||||
home.file = lib.mkForce { };
|
||||
home.stateVersion = lib.mkForce "24.05";
|
||||
home.stateVersion = lib.mkForce "24.11";
|
||||
home.enableNixpkgsReleaseCheck = lib.mkForce false;
|
||||
manual.manpages.enable = lib.mkForce false;
|
||||
news.display = lib.mkForce "silent";
|
||||
|
||||
@@ -143,6 +143,7 @@ let
|
||||
./programs/khard.nix
|
||||
./programs/kitty.nix
|
||||
./programs/kodi.nix
|
||||
./programs/kubecolor.nix
|
||||
./programs/lazygit.nix
|
||||
./programs/ledger.nix
|
||||
./programs/less.nix
|
||||
@@ -176,6 +177,7 @@ let
|
||||
./programs/nh.nix
|
||||
./programs/nheko.nix
|
||||
./programs/nix-index.nix
|
||||
./programs/nix-your-shell.nix
|
||||
./programs/nnn.nix
|
||||
./programs/noti.nix
|
||||
./programs/notmuch.nix
|
||||
|
||||
@@ -27,9 +27,6 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions =
|
||||
[ (hm.assertions.assertPlatform "programs.abook" pkgs platforms.linux) ];
|
||||
|
||||
home.packages = [ pkgs.abook ];
|
||||
|
||||
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
||||
|
||||
@@ -132,6 +132,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "alot" { };
|
||||
|
||||
hooks = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
@@ -229,7 +231,7 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.alot ];
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."alot/config".text = configFile;
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@ with lib;
|
||||
let
|
||||
|
||||
cfg = config.programs.atuin;
|
||||
daemonCfg = cfg.daemon;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
inherit (pkgs.stdenv) isLinux isDarwin;
|
||||
in {
|
||||
meta.maintainers = [ maintainers.hawkw ];
|
||||
meta.maintainers = [ maintainers.hawkw maintainers.water-sucks ];
|
||||
|
||||
options.programs.atuin = {
|
||||
enable = mkEnableOption "atuin";
|
||||
@@ -94,49 +96,137 @@ in {
|
||||
Whether to enable Nushell integration.
|
||||
'';
|
||||
};
|
||||
|
||||
daemon = {
|
||||
enable = mkEnableOption "Atuin daemon";
|
||||
|
||||
logLevel = mkOption {
|
||||
default = null;
|
||||
type =
|
||||
types.nullOr (types.enum [ "trace" "debug" "info" "warn" "error" ]);
|
||||
description = ''
|
||||
Verbosity of Atuin daemon logging.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let flagsStr = escapeShellArgs cfg.flags;
|
||||
in mkIf cfg.enable {
|
||||
in mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
# Always add the configured `atuin` package.
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
# Always add the configured `atuin` package.
|
||||
home.packages = [ cfg.package ];
|
||||
# If there are user-provided settings, generate the config file.
|
||||
xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "atuin-config" cfg.settings;
|
||||
};
|
||||
|
||||
# If there are user-provided settings, generate the config file.
|
||||
xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "atuin-config" cfg.settings;
|
||||
};
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
|
||||
eval "$(${lib.getExe cfg.package} init bash ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init fish ${flagsStr} | source
|
||||
'';
|
||||
|
||||
programs.nushell = mkIf cfg.enableNushellIntegration {
|
||||
extraEnv = ''
|
||||
let atuin_cache = "${config.xdg.cacheHome}/atuin"
|
||||
if not ($atuin_cache | path exists) {
|
||||
mkdir $atuin_cache
|
||||
}
|
||||
${
|
||||
lib.getExe cfg.package
|
||||
} init nu ${flagsStr} | save --force ${config.xdg.cacheHome}/atuin/init.nu
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
|
||||
eval "$(${lib.getExe cfg.package} init bash ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
extraConfig = ''
|
||||
source ${config.xdg.cacheHome}/atuin/init.nu
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init fish ${flagsStr} | source
|
||||
'';
|
||||
|
||||
programs.nushell = mkIf cfg.enableNushellIntegration {
|
||||
extraEnv = ''
|
||||
let atuin_cache = "${config.xdg.cacheHome}/atuin"
|
||||
if not ($atuin_cache | path exists) {
|
||||
mkdir $atuin_cache
|
||||
}
|
||||
${
|
||||
lib.getExe cfg.package
|
||||
} init nu ${flagsStr} | save --force ${config.xdg.cacheHome}/atuin/init.nu
|
||||
'';
|
||||
extraConfig = ''
|
||||
source ${config.xdg.cacheHome}/atuin/init.nu
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf daemonCfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = versionAtLeast cfg.package.version "18.2.0";
|
||||
message = ''
|
||||
The Atuin daemon requires at least version 18.2.0 or later.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = isLinux || isDarwin;
|
||||
message =
|
||||
"The Atuin daemon can only be configured on either Linux or macOS.";
|
||||
}
|
||||
];
|
||||
|
||||
programs.atuin.settings = { daemon = { enabled = true; }; };
|
||||
}
|
||||
(mkIf isLinux {
|
||||
programs.atuin.settings = { daemon = { systemd_socket = true; }; };
|
||||
|
||||
systemd.user.services.atuin-daemon = {
|
||||
Unit = {
|
||||
Description = "Atuin daemon";
|
||||
Requires = [ "atuin-daemon.socket" ];
|
||||
};
|
||||
Install = {
|
||||
Also = [ "atuin-daemon.socket" ];
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe cfg.package} daemon";
|
||||
Environment = lib.optionals (daemonCfg.logLevel != null)
|
||||
[ "ATUIN_LOG=${daemonCfg.logLevel}" ];
|
||||
Restart = "on-failure";
|
||||
RestartSteps = 3;
|
||||
RestartMaxDelaySec = 6;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.sockets.atuin-daemon = let
|
||||
socket_dir = if versionAtLeast cfg.package.version "18.4.0" then
|
||||
"%t"
|
||||
else
|
||||
"%D/atuin";
|
||||
in {
|
||||
Unit = { Description = "Atuin daemon socket"; };
|
||||
Install = { WantedBy = [ "sockets.target" ]; };
|
||||
Socket = {
|
||||
ListenStream = "${socket_dir}/atuin.sock";
|
||||
SocketMode = "0600";
|
||||
RemoveOnStop = true;
|
||||
};
|
||||
};
|
||||
})
|
||||
(mkIf isDarwin {
|
||||
launchd.agents.atuin-daemon = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ "${lib.getExe cfg.package}" "daemon" ];
|
||||
EnvironmentVariables =
|
||||
lib.optionalAttrs (daemonCfg.logLevel != null) {
|
||||
ATUIN_LOG = daemonCfg.logLevel;
|
||||
};
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Background";
|
||||
};
|
||||
};
|
||||
})
|
||||
]))
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{ modulePath, name, description ? null, wrappedPackageName ? null
|
||||
, unwrappedPackageName ? null, platforms, visible ? false }:
|
||||
, unwrappedPackageName ? null, platforms, visible ? false
|
||||
, enableBookmarks ? true }:
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
@@ -435,6 +436,7 @@ in {
|
||||
};
|
||||
|
||||
bookmarks = mkOption {
|
||||
internal = !enableBookmarks;
|
||||
type = let
|
||||
bookmarkSubmodule = types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
|
||||
@@ -17,7 +17,7 @@ let
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
example = "pkgs.gnome.gnome-shell-extensions";
|
||||
example = "pkgs.gnome-shell-extensions";
|
||||
description = ''
|
||||
Package providing a GNOME Shell extension in
|
||||
`$out/share/gnome-shell/extensions/''${id}`.
|
||||
@@ -66,7 +66,7 @@ in {
|
||||
{ package = pkgs.gnomeExtensions.dash-to-panel; }
|
||||
{
|
||||
id = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
||||
package = pkgs.gnome.gnome-shell-extensions;
|
||||
package = pkgs.gnome-shell-extensions;
|
||||
}
|
||||
]
|
||||
'';
|
||||
@@ -106,7 +106,7 @@ in {
|
||||
|
||||
programs.gnome-shell.extensions = [{
|
||||
id = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
||||
package = pkgs.gnome.gnome-shell-extensions;
|
||||
package = pkgs.gnome-shell-extensions;
|
||||
}];
|
||||
|
||||
home.packages = [ cfg.theme.package ];
|
||||
|
||||
@@ -658,12 +658,30 @@ in {
|
||||
{command}`nix-env -f '<nixpkgs>' -qaP -A kakounePlugins`.
|
||||
'';
|
||||
};
|
||||
|
||||
colorSchemePackage = mkOption {
|
||||
type = with types; nullOr package;
|
||||
default = null;
|
||||
example = literalExpression "pkgs.kakounePlugins.kakoune-catppuccin";
|
||||
description = ''
|
||||
A kakoune color schemes to add to your colors folder. This works
|
||||
because kakoune recursively checks
|
||||
{file}`$XDG_CONFIG_HOME/kak/colors/`. To apply the color scheme use
|
||||
`programs.kakoune.config.colorScheme = "theme"`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ kakouneWithPlugins ];
|
||||
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; };
|
||||
xdg.configFile."kak/kakrc".source = configFile;
|
||||
xdg.configFile = mkMerge [
|
||||
{ "kak/kakrc".source = configFile; }
|
||||
(mkIf (cfg.colorSchemePackage != null) {
|
||||
"kak/colors/${cfg.colorSchemePackage.name}".source =
|
||||
cfg.colorSchemePackage;
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
87
modules/programs/kubecolor.nix
Normal file
87
modules/programs/kubecolor.nix
Normal file
@@ -0,0 +1,87 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.kubecolor;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ ajgon ];
|
||||
|
||||
options.programs.kubecolor = {
|
||||
enable = mkEnableOption "kubecolor - Colorize your kubectl output";
|
||||
|
||||
package = mkPackageOption pkgs "kubecolor" { };
|
||||
|
||||
enableAlias = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
When set to true, it will create an alias for kubectl pointing to
|
||||
kubecolor, thus making kubecolor the default kubectl client.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = yamlFormat.type;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
kubectl = lib.getExe pkgs.kubectl
|
||||
preset = "dark";
|
||||
paging = "auto";
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to {file}`~/.kube/color.yaml` (Linux)
|
||||
or {file}`Library/Application Support/kube/color.yaml` (Darwin).
|
||||
See <https://kubecolor.github.io/reference/config/> for supported
|
||||
values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
preferXdgDirectories = config.home.preferXdgDirectories
|
||||
&& (!isDarwin || config.xdg.enable);
|
||||
|
||||
# https://github.com/kubecolor/kubecolor/pull/145
|
||||
configPathSuffix = if cfg.package.pname == "kubecolor"
|
||||
&& lib.strings.toInt (lib.versions.major cfg.package.version) == 0
|
||||
&& lib.strings.toInt (lib.versions.minor cfg.package.version) < 4 then
|
||||
"kube/"
|
||||
else
|
||||
"kube/color.yaml";
|
||||
|
||||
in mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.sessionVariables = if preferXdgDirectories then {
|
||||
KUBECOLOR_CONFIG = "${config.xdg.configHome}/${configPathSuffix}";
|
||||
} else if isDarwin then {
|
||||
KUBECOLOR_CONFIG =
|
||||
"${config.home.homeDirectory}/Library/Application Support/${configPathSuffix}";
|
||||
} else
|
||||
{ };
|
||||
|
||||
xdg.configFile = mkIf preferXdgDirectories {
|
||||
"kube/color.yaml" = mkIf (cfg.settings != { }) {
|
||||
source = yamlFormat.generate "kubecolor-settings" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
home.file = mkIf (!preferXdgDirectories) {
|
||||
"Library/Application Support/kube/color.yaml" =
|
||||
mkIf (isDarwin && cfg.settings != { }) {
|
||||
source = yamlFormat.generate "kubecolor-settings" cfg.settings;
|
||||
};
|
||||
".kube/color.yaml" = mkIf (!isDarwin && cfg.settings != { }) {
|
||||
source = yamlFormat.generate "kubecolor-settings" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
home.shellAliases =
|
||||
lib.mkIf cfg.enableAlias { kubectl = lib.getExe cfg.package; };
|
||||
};
|
||||
}
|
||||
@@ -14,20 +14,35 @@ let
|
||||
'') prefs)}
|
||||
'';
|
||||
|
||||
modulePath = [ "programs" "librewolf" ];
|
||||
|
||||
mkFirefoxModule = import ./firefox/mkFirefoxModule.nix;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.onny ];
|
||||
meta.maintainers = [ maintainers.chayleaf maintainers.onny ];
|
||||
|
||||
imports = [
|
||||
(mkFirefoxModule {
|
||||
inherit modulePath;
|
||||
name = "LibreWolf";
|
||||
description = "LibreWolf is a privacy enhanced Firefox fork.";
|
||||
wrappedPackageName = "librewolf";
|
||||
unwrappedPackageName = "librewolf-unwrapped";
|
||||
|
||||
platforms.linux = {
|
||||
vendorPath = ".librewolf";
|
||||
configPath = ".librewolf";
|
||||
};
|
||||
platforms.darwin = {
|
||||
vendorPath = "Library/Application Support/LibreWolf";
|
||||
configPath = "Library/Application Support/LibreWolf";
|
||||
};
|
||||
|
||||
enableBookmarks = false;
|
||||
})
|
||||
];
|
||||
|
||||
options.programs.librewolf = {
|
||||
enable =
|
||||
mkEnableOption "Librewolf browser, a privacy enhanced Firefox fork";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.librewolf;
|
||||
defaultText = literalExpression "pkgs.librewolf";
|
||||
description = "The LibreWolf package to use.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
default = { };
|
||||
@@ -38,7 +53,7 @@ in {
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Attribute set of LibreWolf settings and overrides. Refer to
|
||||
Attribute set of global LibreWolf settings and overrides. Refer to
|
||||
<https://librewolf.net/docs/settings/>
|
||||
for details on supported values.
|
||||
'';
|
||||
@@ -51,9 +66,7 @@ in {
|
||||
lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.file.".librewolf/librewolf.overrides.cfg".text =
|
||||
mkOverridesFile cfg.settings;
|
||||
home.file.".librewolf/librewolf.overrides.cfg" =
|
||||
lib.mkIf (cfg.settings != { }) { text = mkOverridesFile cfg.settings; };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ in {
|
||||
{
|
||||
mpv = {
|
||||
no_display = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
|
||||
@@ -225,6 +225,8 @@ in {
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
TLSType = "IMAP";
|
||||
TLSVersions = [ "+1.3" "+1.2" "-1.1" ];
|
||||
PipelineDepth = 10;
|
||||
Timeout = 60;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ let
|
||||
|
||||
genTlsConfig = tls:
|
||||
{
|
||||
SSLType = if !tls.enable then
|
||||
TLSType = if !tls.enable then
|
||||
"None"
|
||||
else if tls.useStartTls then
|
||||
"STARTTLS"
|
||||
@@ -267,7 +267,7 @@ in {
|
||||
|
||||
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
|
||||
|
||||
home.file.".mbsyncrc".text = let
|
||||
xdg.configFile."isyncrc".text = let
|
||||
accountsConfig = map genAccountConfig mbsyncAccounts;
|
||||
# Only generate this kind of Group configuration if there are ANY accounts
|
||||
# that do NOT have a per-account groups/channels option(s) specified.
|
||||
|
||||
56
modules/programs/nix-your-shell.nix
Normal file
56
modules/programs/nix-your-shell.nix
Normal file
@@ -0,0 +1,56 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.nix-your-shell;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.terlar ];
|
||||
|
||||
options.programs.nix-your-shell = {
|
||||
enable = mkEnableOption ''
|
||||
{command}`nix-your-shell`, a wrapper for `nix develop` or `nix-shell`
|
||||
to retain the same shell inside the new environment'';
|
||||
|
||||
package = mkPackageOption pkgs "nix-your-shell" { };
|
||||
|
||||
enableFishIntegration = mkEnableOption "Fish integration" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
enableNushellIntegration = mkEnableOption "Nushell integration" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
enableZshIntegration = mkEnableOption "Zsh integration" // {
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
programs = {
|
||||
fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
${cfg.package}/bin/nix-your-shell fish | source
|
||||
'';
|
||||
|
||||
nushell = mkIf cfg.enableNushellIntegration {
|
||||
extraEnv = ''
|
||||
mkdir ${config.xdg.cacheHome}/nix-your-shell
|
||||
${cfg.package}/bin/nix-your-shell nu | save --force ${config.xdg.cacheHome}/nix-your-shell/init.nu
|
||||
'';
|
||||
|
||||
extraConfig = ''
|
||||
source ${config.xdg.cacheHome}/nix-your-shell/init.nu
|
||||
'';
|
||||
};
|
||||
|
||||
zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
${cfg.package}/bin/nix-your-shell zsh | source /dev/stdin
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -39,7 +39,8 @@ let
|
||||
};
|
||||
});
|
||||
in {
|
||||
meta.maintainers = [ maintainers.Philipp-M maintainers.joaquintrinanes ];
|
||||
meta.maintainers =
|
||||
[ maintainers.Philipp-M maintainers.joaquintrinanes maintainers.aidalgol ];
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "programs" "nushell" "settings" ] ''
|
||||
@@ -134,6 +135,15 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
example = lib.literalExpression "[ pkgs.nushellPlugins.formats ]";
|
||||
description = ''
|
||||
A list of nushell plugins to write to the plugin registry file.
|
||||
'';
|
||||
};
|
||||
|
||||
shellAliases = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
@@ -203,6 +213,20 @@ in {
|
||||
cfg.extraLogin
|
||||
];
|
||||
})
|
||||
|
||||
(let
|
||||
msgPackz = pkgs.runCommand "nushellMsgPackz" { } ''
|
||||
mkdir -p "$out"
|
||||
${lib.getExe cfg.package} \
|
||||
--plugin-config "$out/plugin.msgpackz" \
|
||||
--commands '${
|
||||
concatStringsSep "; "
|
||||
(map (plugin: "plugin add ${lib.getExe plugin}") cfg.plugins)
|
||||
}'
|
||||
'';
|
||||
in mkIf (cfg.plugins != [ ]) {
|
||||
"${configDir}/plugin.msgpackz".source = "${msgPackz}/plugin.msgpackz";
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ let
|
||||
|
||||
starshipCmd = "${config.home.profileDirectory}/bin/starship";
|
||||
|
||||
initFish =
|
||||
if cfg.enableInteractive then "interactiveShellInit" else "shellInitLast";
|
||||
in {
|
||||
meta.maintainers = [ ];
|
||||
|
||||
@@ -71,6 +73,17 @@ in {
|
||||
default = true;
|
||||
};
|
||||
|
||||
enableInteractive = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Only enable starship when the shell is interactive. This option is only
|
||||
valid for the Fish shell.
|
||||
|
||||
Some plugins require this to be set to `false` to function correctly.
|
||||
'';
|
||||
};
|
||||
|
||||
enableTransience = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -104,9 +117,9 @@ in {
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
programs.fish.${initFish} = mkIf cfg.enableFishIntegration ''
|
||||
if test "$TERM" != "dumb"
|
||||
eval (${starshipCmd} init fish)
|
||||
${starshipCmd} init fish | source
|
||||
${lib.optionalString cfg.enableTransience "enable_transience"}
|
||||
end
|
||||
'';
|
||||
|
||||
@@ -71,6 +71,8 @@ let
|
||||
"mail.identity.id_${id}.openpgp_key_id" = account.gpg.key;
|
||||
"mail.identity.id_${id}.protectSubject" = true;
|
||||
"mail.identity.id_${id}.sign_mail" = account.gpg.signByDefault;
|
||||
} // optionalAttrs (account.smtp != null) {
|
||||
"mail.identity.id_${id}.smtpServer" = "smtp_${account.id}";
|
||||
} // account.thunderbird.perIdentitySettings id;
|
||||
|
||||
toThunderbirdAccount = account: profile:
|
||||
@@ -103,7 +105,6 @@ let
|
||||
"mail.server.server_${id}.type" = "imap";
|
||||
"mail.server.server_${id}.userName" = account.userName;
|
||||
} // optionalAttrs (account.smtp != null) {
|
||||
"mail.identity.id_${id}.smtpServer" = "smtp_${id}";
|
||||
"mail.smtpserver.smtp_${id}.authMethod" = 3;
|
||||
"mail.smtpserver.smtp_${id}.hostname" = account.smtp.host;
|
||||
"mail.smtpserver.smtp_${id}.port" =
|
||||
|
||||
@@ -95,6 +95,7 @@ let
|
||||
''}
|
||||
|
||||
set -g mouse ${boolToStr cfg.mouse}
|
||||
set -g focus-events ${boolToStr cfg.focusEvents}
|
||||
setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
|
||||
setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
|
||||
set -s escape-time ${toString cfg.escapeTime}
|
||||
@@ -191,6 +192,15 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
focusEvents = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
On supported terminals, request focus events and pass them through to
|
||||
applications running in tmux.
|
||||
'';
|
||||
};
|
||||
|
||||
historyLimit = mkOption {
|
||||
default = 2000;
|
||||
example = 5000;
|
||||
@@ -239,7 +249,7 @@ in {
|
||||
|
||||
sensibleOnTop = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
default = false;
|
||||
description = ''
|
||||
Run the sensible plugin at the top of the configuration. It
|
||||
is possible to override the sensible settings using the
|
||||
|
||||
@@ -77,16 +77,16 @@ in {
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
input.keymap = [
|
||||
{ exec = "close"; on = [ "<C-q>" ]; }
|
||||
{ exec = "close --submit"; on = [ "<Enter>" ]; }
|
||||
{ exec = "escape"; on = [ "<Esc>" ]; }
|
||||
{ exec = "backspace"; on = [ "<Backspace>" ]; }
|
||||
input.prepend_keymap = [
|
||||
{ run = "close"; on = [ "<C-q>" ]; }
|
||||
{ run = "close --submit"; on = [ "<Enter>" ]; }
|
||||
{ run = "escape"; on = [ "<Esc>" ]; }
|
||||
{ run = "backspace"; on = [ "<Backspace>" ]; }
|
||||
];
|
||||
manager.keymap = [
|
||||
{ exec = "escape"; on = [ "<Esc>" ]; }
|
||||
{ exec = "quit"; on = [ "q" ]; }
|
||||
{ exec = "close"; on = [ "<C-q>" ]; }
|
||||
manager.prepend_keymap = [
|
||||
{ run = "escape"; on = [ "<Esc>" ]; }
|
||||
{ run = "quit"; on = [ "q" ]; }
|
||||
{ run = "close"; on = [ "<C-q>" ]; }
|
||||
];
|
||||
}
|
||||
'';
|
||||
|
||||
@@ -22,6 +22,13 @@ in {
|
||||
|
||||
package = mkPackageOption pkgs "zed-editor" { };
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = [ ];
|
||||
example = literalExpression "[ pkgs.nixd ]";
|
||||
description = "Extra packages available to Zed.";
|
||||
};
|
||||
|
||||
userSettings = mkOption {
|
||||
type = jsonFormat.type;
|
||||
default = { };
|
||||
@@ -76,7 +83,22 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
home.packages = if cfg.extraPackages != [ ] then
|
||||
[
|
||||
(pkgs.symlinkJoin {
|
||||
name =
|
||||
"${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}";
|
||||
paths = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/zeditor \
|
||||
--suffix PATH : ${lib.makeBinPath cfg.extraPackages}
|
||||
'';
|
||||
})
|
||||
]
|
||||
else
|
||||
[ cfg.package ];
|
||||
|
||||
xdg.configFile."zed/settings.json" = (mkIf (mergedSettings != { }) {
|
||||
source = jsonFormat.generate "zed-user-settings" mergedSettings;
|
||||
|
||||
@@ -6,21 +6,21 @@ let
|
||||
|
||||
cfg = config.programs.zsh;
|
||||
|
||||
relToDotDir = file: (optionalString (cfg.dotDir != null) (cfg.dotDir + "/")) + file;
|
||||
relToDotDir = file:
|
||||
(optionalString (cfg.dotDir != null) (cfg.dotDir + "/")) + file;
|
||||
|
||||
pluginsDir = if cfg.dotDir != null then
|
||||
relToDotDir "plugins" else ".zsh/plugins";
|
||||
pluginsDir =
|
||||
if cfg.dotDir != null then relToDotDir "plugins" else ".zsh/plugins";
|
||||
|
||||
envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables;
|
||||
localVarsStr = config.lib.zsh.defineAll cfg.localVariables;
|
||||
|
||||
aliasesStr = concatStringsSep "\n" (
|
||||
mapAttrsToList (k: v: "alias -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellAliases
|
||||
);
|
||||
aliasesStr = concatStringsSep "\n" (mapAttrsToList
|
||||
(k: v: "alias -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}")
|
||||
cfg.shellAliases);
|
||||
|
||||
dirHashesStr = concatStringsSep "\n" (
|
||||
mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes
|
||||
);
|
||||
dirHashesStr = concatStringsSep "\n"
|
||||
(mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes);
|
||||
|
||||
zdotdir = "$HOME/" + lib.escapeShellArg cfg.dotDir;
|
||||
|
||||
@@ -64,20 +64,22 @@ let
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
default = if versionAtLeast stateVersion "20.03"
|
||||
then "$HOME/.zsh_history"
|
||||
else relToDotDir ".zsh_history";
|
||||
default = if versionAtLeast stateVersion "20.03" then
|
||||
"$HOME/.zsh_history"
|
||||
else
|
||||
relToDotDir ".zsh_history";
|
||||
defaultText = literalExpression ''
|
||||
"$HOME/.zsh_history" if state version ≥ 20.03,
|
||||
"$ZDOTDIR/.zsh_history" otherwise
|
||||
'';
|
||||
example = literalExpression ''"''${config.xdg.dataHome}/zsh/zsh_history"'';
|
||||
example =
|
||||
literalExpression ''"''${config.xdg.dataHome}/zsh/zsh_history"'';
|
||||
description = "History file location";
|
||||
};
|
||||
|
||||
ignorePatterns = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = literalExpression ''[ "rm *" "pkill *" ]'';
|
||||
description = ''
|
||||
Do not enter command lines into the history list
|
||||
@@ -170,7 +172,7 @@ let
|
||||
package = mkPackageOption pkgs "oh-my-zsh" { };
|
||||
|
||||
plugins = mkOption {
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "git" "sudo" ];
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
@@ -215,7 +217,7 @@ let
|
||||
options = {
|
||||
enable = mkEnableOption "history substring search";
|
||||
searchUpKey = mkOption {
|
||||
type = with types; either (listOf str) str ;
|
||||
type = with types; either (listOf str) str;
|
||||
default = [ "^[[A" ];
|
||||
description = ''
|
||||
The key codes to be used when searching up.
|
||||
@@ -224,7 +226,7 @@ let
|
||||
'';
|
||||
};
|
||||
searchDownKey = mkOption {
|
||||
type = with types; either (listOf str) str ;
|
||||
type = with types; either (listOf str) str;
|
||||
default = [ "^[[B" ];
|
||||
description = ''
|
||||
The key codes to be used when searching down.
|
||||
@@ -253,7 +255,7 @@ let
|
||||
|
||||
patterns = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
default = { };
|
||||
example = { "rm -rf *" = "fg=white,bold,bg=red"; };
|
||||
description = ''
|
||||
Custom syntax highlighting for user-defined patterns.
|
||||
@@ -263,7 +265,7 @@ let
|
||||
|
||||
styles = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
default = { };
|
||||
example = { comment = "fg=black,bold"; };
|
||||
description = ''
|
||||
Custom styles for syntax highlighting.
|
||||
@@ -273,13 +275,25 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [ "programs" "zsh" "autosuggestion" "enable" ])
|
||||
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
|
||||
(mkRenamedOptionModule [ "programs" "zsh" "zproof" ] [ "programs" "zsh" "zprof" ])
|
||||
(mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [
|
||||
"programs"
|
||||
"zsh"
|
||||
"autosuggestion"
|
||||
"enable"
|
||||
])
|
||||
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [
|
||||
"programs"
|
||||
"zsh"
|
||||
"syntaxHighlighting"
|
||||
"enable"
|
||||
])
|
||||
(mkRenamedOptionModule [ "programs" "zsh" "zproof" ] [
|
||||
"programs"
|
||||
"zsh"
|
||||
"zprof"
|
||||
])
|
||||
];
|
||||
|
||||
options = {
|
||||
@@ -297,7 +311,7 @@ in
|
||||
};
|
||||
|
||||
cdpath = mkOption {
|
||||
default = [];
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of paths to autocomplete calls to {command}`cd`.
|
||||
'';
|
||||
@@ -316,7 +330,7 @@ in
|
||||
};
|
||||
|
||||
shellAliases = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
ll = "ls -l";
|
||||
@@ -331,7 +345,7 @@ in
|
||||
};
|
||||
|
||||
shellGlobalAliases = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
UUID = "$(uuidgen | tr -d \\n)";
|
||||
@@ -346,7 +360,7 @@ in
|
||||
};
|
||||
|
||||
dirHashes = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
docs = "$HOME/Documents";
|
||||
@@ -374,7 +388,8 @@ in
|
||||
|
||||
completionInit = mkOption {
|
||||
default = "autoload -U compinit && compinit";
|
||||
description = "Initialization commands to run when completion is enabled.";
|
||||
description =
|
||||
"Initialization commands to run when completion is enabled.";
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
@@ -387,13 +402,13 @@ in
|
||||
|
||||
syntaxHighlighting = mkOption {
|
||||
type = syntaxHighlightingModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = "Options related to zsh-syntax-highlighting.";
|
||||
};
|
||||
|
||||
historySubstringSearch = mkOption {
|
||||
type = historySubstringSearchModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = "Options related to zsh-history-substring-search.";
|
||||
};
|
||||
|
||||
@@ -415,7 +430,8 @@ in
|
||||
};
|
||||
|
||||
strategy = mkOption {
|
||||
type = types.listOf (types.enum [ "history" "completion" "match_prev_cmd" ]);
|
||||
type = types.listOf
|
||||
(types.enum [ "history" "completion" "match_prev_cmd" ]);
|
||||
default = [ "history" ];
|
||||
description = ''
|
||||
`ZSH_AUTOSUGGEST_STRATEGY` is an array that specifies how suggestions should be generated.
|
||||
@@ -427,13 +443,16 @@ in
|
||||
- `match_prev_cmd`: Like `history`, but chooses the most recent match whose preceding history item matches
|
||||
the most recently executed command. Note that this strategy won't work as expected with ZSH options that
|
||||
don't preserve the history order such as `HIST_IGNORE_ALL_DUPS` or `HIST_EXPIRE_DUPS_FIRST`.
|
||||
|
||||
Setting the option to an empty list `[]` will make ZSH_AUTOSUGGESTION_STRATEGY not be set automatically,
|
||||
allowing the variable to be declared in {option}`programs.zsh.localVariables` or {option}`programs.zsh.sessionVariables`
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
history = mkOption {
|
||||
type = historyModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = "Options related to commands history configuration.";
|
||||
};
|
||||
|
||||
@@ -445,7 +464,7 @@ in
|
||||
};
|
||||
|
||||
sessionVariables = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = types.attrs;
|
||||
example = { MAILCHECK = 30; };
|
||||
description = "Environment variables that will be set for zsh session.";
|
||||
@@ -454,7 +473,8 @@ in
|
||||
initExtraBeforeCompInit = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to {file}`.zshrc` before compinit.";
|
||||
description =
|
||||
"Extra commands that should be added to {file}`.zshrc` before compinit.";
|
||||
};
|
||||
|
||||
initExtra = mkOption {
|
||||
@@ -478,7 +498,8 @@ in
|
||||
profileExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to {file}`.zprofile`.";
|
||||
description =
|
||||
"Extra commands that should be added to {file}`.zprofile`.";
|
||||
};
|
||||
|
||||
loginExtra = mkOption {
|
||||
@@ -490,12 +511,13 @@ in
|
||||
logoutExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to {file}`.zlogout`.";
|
||||
description =
|
||||
"Extra commands that should be added to {file}`.zlogout`.";
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf pluginModule;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
@@ -525,14 +547,14 @@ in
|
||||
|
||||
oh-my-zsh = mkOption {
|
||||
type = ohMyZshModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = "Options to configure oh-my-zsh.";
|
||||
};
|
||||
|
||||
localVariables = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = { POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=["dir" "vcs"]; };
|
||||
default = { };
|
||||
example = { POWERLEVEL9K_LEFT_PROMPT_ELEMENTS = [ "dir" "vcs" ]; };
|
||||
description = ''
|
||||
Extra local variables defined at the top of {file}`.zshrc`.
|
||||
'';
|
||||
@@ -606,16 +628,16 @@ in
|
||||
cfg.initExtraFirst
|
||||
"typeset -U path cdpath fpath manpath"
|
||||
|
||||
(optionalString (cfg.cdpath != []) ''
|
||||
(optionalString (cfg.cdpath != [ ]) ''
|
||||
cdpath+=(${concatStringsSep " " cfg.cdpath})
|
||||
'')
|
||||
|
||||
''
|
||||
for profile in ''${(z)NIX_PROFILES}; do
|
||||
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
|
||||
done
|
||||
for profile in ''${(z)NIX_PROFILES}; do
|
||||
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
|
||||
done
|
||||
|
||||
HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help"
|
||||
HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help"
|
||||
''
|
||||
|
||||
(optionalString (cfg.defaultKeymap != null) ''
|
||||
@@ -632,117 +654,136 @@ in
|
||||
'') cfg.plugins))
|
||||
|
||||
''
|
||||
# Oh-My-Zsh/Prezto calls compinit during initialization,
|
||||
# calling it twice causes slight start up slowdown
|
||||
# as all $fpath entries will be traversed again.
|
||||
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
|
||||
cfg.completionInit
|
||||
}''
|
||||
# Oh-My-Zsh/Prezto calls compinit during initialization,
|
||||
# calling it twice causes slight start up slowdown
|
||||
# as all $fpath entries will be traversed again.
|
||||
${optionalString
|
||||
(cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
|
||||
cfg.completionInit}''
|
||||
|
||||
(optionalString cfg.autosuggestion.enable ''
|
||||
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
||||
ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.autosuggestion.strategy})
|
||||
'')
|
||||
(optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
|
||||
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
|
||||
${optionalString (cfg.autosuggestion.strategy != [ ]) ''
|
||||
ZSH_AUTOSUGGEST_STRATEGY=(${
|
||||
concatStringsSep " " cfg.autosuggestion.strategy
|
||||
})
|
||||
''}
|
||||
'')
|
||||
(optionalString
|
||||
(cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
|
||||
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
|
||||
'')
|
||||
|
||||
(optionalString cfg.oh-my-zsh.enable ''
|
||||
# oh-my-zsh extra settings for plugins
|
||||
${cfg.oh-my-zsh.extraConfig}
|
||||
# oh-my-zsh configuration generated by NixOS
|
||||
${optionalString (cfg.oh-my-zsh.plugins != [])
|
||||
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"
|
||||
}
|
||||
${optionalString (cfg.oh-my-zsh.custom != "")
|
||||
"ZSH_CUSTOM=\"${cfg.oh-my-zsh.custom}\""
|
||||
}
|
||||
${optionalString (cfg.oh-my-zsh.theme != "")
|
||||
"ZSH_THEME=\"${cfg.oh-my-zsh.theme}\""
|
||||
}
|
||||
source $ZSH/oh-my-zsh.sh
|
||||
# oh-my-zsh extra settings for plugins
|
||||
${cfg.oh-my-zsh.extraConfig}
|
||||
# oh-my-zsh configuration generated by NixOS
|
||||
${optionalString (cfg.oh-my-zsh.plugins != [ ])
|
||||
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"}
|
||||
${optionalString (cfg.oh-my-zsh.custom != "")
|
||||
''ZSH_CUSTOM="${cfg.oh-my-zsh.custom}"''}
|
||||
${optionalString (cfg.oh-my-zsh.theme != "")
|
||||
''ZSH_THEME="${cfg.oh-my-zsh.theme}"''}
|
||||
source $ZSH/oh-my-zsh.sh
|
||||
'')
|
||||
|
||||
''
|
||||
${optionalString cfg.prezto.enable
|
||||
(builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshrc")}
|
||||
${optionalString cfg.prezto.enable (builtins.readFile
|
||||
"${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshrc")}
|
||||
|
||||
${concatStrings (map (plugin: ''
|
||||
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
|
||||
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
|
||||
fi
|
||||
'') cfg.plugins)}
|
||||
${concatStrings (map (plugin: ''
|
||||
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
|
||||
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
|
||||
fi
|
||||
'') cfg.plugins)}
|
||||
|
||||
# History options should be set in .zshrc and after oh-my-zsh sourcing.
|
||||
# See https://github.com/nix-community/home-manager/issues/177.
|
||||
HISTSIZE="${toString cfg.history.size}"
|
||||
SAVEHIST="${toString cfg.history.save}"
|
||||
${optionalString (cfg.history.ignorePatterns != []) "HISTORY_IGNORE=${lib.escapeShellArg "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"}"}
|
||||
${if versionAtLeast config.home.stateVersion "20.03"
|
||||
then ''HISTFILE="${cfg.history.path}"''
|
||||
else ''HISTFILE="$HOME/${cfg.history.path}"''}
|
||||
mkdir -p "$(dirname "$HISTFILE")"
|
||||
# History options should be set in .zshrc and after oh-my-zsh sourcing.
|
||||
# See https://github.com/nix-community/home-manager/issues/177.
|
||||
HISTSIZE="${toString cfg.history.size}"
|
||||
SAVEHIST="${toString cfg.history.save}"
|
||||
${optionalString (cfg.history.ignorePatterns != [ ])
|
||||
"HISTORY_IGNORE=${
|
||||
lib.escapeShellArg
|
||||
"(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"
|
||||
}"}
|
||||
${if versionAtLeast config.home.stateVersion "20.03" then
|
||||
''HISTFILE="${cfg.history.path}"''
|
||||
else
|
||||
''HISTFILE="$HOME/${cfg.history.path}"''}
|
||||
mkdir -p "$(dirname "$HISTFILE")"
|
||||
|
||||
setopt HIST_FCNTL_LOCK
|
||||
${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY
|
||||
${if cfg.history.ignoreDups then "setopt" else "unsetopt"} HIST_IGNORE_DUPS
|
||||
${if cfg.history.ignoreAllDups then "setopt" else "unsetopt"} HIST_IGNORE_ALL_DUPS
|
||||
${if cfg.history.ignoreSpace then "setopt" else "unsetopt"} HIST_IGNORE_SPACE
|
||||
${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST
|
||||
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
|
||||
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
|
||||
${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}
|
||||
setopt HIST_FCNTL_LOCK
|
||||
${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY
|
||||
${
|
||||
if cfg.history.ignoreDups then "setopt" else "unsetopt"
|
||||
} HIST_IGNORE_DUPS
|
||||
${
|
||||
if cfg.history.ignoreAllDups then "setopt" else "unsetopt"
|
||||
} HIST_IGNORE_ALL_DUPS
|
||||
${
|
||||
if cfg.history.ignoreSpace then "setopt" else "unsetopt"
|
||||
} HIST_IGNORE_SPACE
|
||||
${
|
||||
if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"
|
||||
} HIST_EXPIRE_DUPS_FIRST
|
||||
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
|
||||
${
|
||||
if cfg.history.extended then "setopt" else "unsetopt"
|
||||
} EXTENDED_HISTORY
|
||||
${if cfg.autocd != null then
|
||||
"${if cfg.autocd then "setopt" else "unsetopt"} autocd"
|
||||
else
|
||||
""}
|
||||
|
||||
${cfg.initExtra}
|
||||
${cfg.initExtra}
|
||||
|
||||
# Aliases
|
||||
${aliasesStr}
|
||||
# Aliases
|
||||
${aliasesStr}
|
||||
''
|
||||
]
|
||||
++ (mapAttrsToList (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellGlobalAliases)
|
||||
++ [ (''
|
||||
# Named Directory Hashes
|
||||
${dirHashesStr}
|
||||
'')
|
||||
] ++ (mapAttrsToList
|
||||
(k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}")
|
||||
cfg.shellGlobalAliases) ++ [
|
||||
(''
|
||||
# Named Directory Hashes
|
||||
${dirHashesStr}
|
||||
'')
|
||||
|
||||
(optionalString cfg.syntaxHighlighting.enable
|
||||
# Load zsh-syntax-highlighting after all custom widgets have been created
|
||||
# https://github.com/zsh-users/zsh-syntax-highlighting#faq
|
||||
''
|
||||
source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||||
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${lib.concatStringsSep " " (map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)})
|
||||
${lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList
|
||||
(name: value: "ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
|
||||
cfg.syntaxHighlighting.styles
|
||||
)}
|
||||
${lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList
|
||||
(name: value: "ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
|
||||
cfg.syntaxHighlighting.patterns
|
||||
)}
|
||||
'')
|
||||
(optionalString cfg.syntaxHighlighting.enable
|
||||
# Load zsh-syntax-highlighting after all custom widgets have been created
|
||||
# https://github.com/zsh-users/zsh-syntax-highlighting#faq
|
||||
''
|
||||
source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||||
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${
|
||||
lib.concatStringsSep " "
|
||||
(map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)
|
||||
})
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value:
|
||||
"ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${
|
||||
lib.escapeShellArg value
|
||||
})") cfg.syntaxHighlighting.styles)}
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value:
|
||||
"ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${
|
||||
lib.escapeShellArg value
|
||||
})") cfg.syntaxHighlighting.patterns)}
|
||||
'')
|
||||
|
||||
(optionalString (cfg.historySubstringSearch.enable or false)
|
||||
(optionalString (cfg.historySubstringSearch.enable or false)
|
||||
# Load zsh-history-substring-search after zsh-syntax-highlighting
|
||||
# https://github.com/zsh-users/zsh-history-substring-search#usage
|
||||
''
|
||||
source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh
|
||||
${lib.concatMapStringsSep "\n"
|
||||
(upKey: "bindkey \"${upKey}\" history-substring-search-up")
|
||||
(lib.toList cfg.historySubstringSearch.searchUpKey)
|
||||
}
|
||||
${lib.concatMapStringsSep "\n"
|
||||
(downKey: "bindkey \"${downKey}\" history-substring-search-down")
|
||||
(lib.toList cfg.historySubstringSearch.searchDownKey)
|
||||
}
|
||||
'')
|
||||
''
|
||||
source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh
|
||||
${lib.concatMapStringsSep "\n"
|
||||
(upKey: ''bindkey "${upKey}" history-substring-search-up'')
|
||||
(lib.toList cfg.historySubstringSearch.searchUpKey)}
|
||||
${lib.concatMapStringsSep "\n"
|
||||
(downKey: ''bindkey "${downKey}" history-substring-search-down'')
|
||||
(lib.toList cfg.historySubstringSearch.searchDownKey)}
|
||||
'')
|
||||
|
||||
(optionalString cfg.zprof.enable
|
||||
''
|
||||
zprof
|
||||
'')
|
||||
]);
|
||||
(optionalString cfg.zprof.enable ''
|
||||
zprof
|
||||
'')
|
||||
]);
|
||||
}
|
||||
|
||||
(mkIf cfg.oh-my-zsh.enable {
|
||||
@@ -751,15 +792,14 @@ in
|
||||
home.file."${config.xdg.cacheHome}/oh-my-zsh/.keep".text = "";
|
||||
})
|
||||
|
||||
(mkIf (cfg.plugins != []) {
|
||||
(mkIf (cfg.plugins != [ ]) {
|
||||
# Many plugins require compinit to be called
|
||||
# but allow the user to opt out.
|
||||
programs.zsh.enableCompletion = mkDefault true;
|
||||
|
||||
home.file =
|
||||
foldl' (a: b: a // b) {}
|
||||
home.file = foldl' (a: b: a // b) { }
|
||||
(map (plugin: { "${pluginsDir}/${plugin.name}".source = plugin.src; })
|
||||
cfg.plugins);
|
||||
cfg.plugins);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ in {
|
||||
enable =
|
||||
mkEnableOption "zsh-abbr - zsh manager for auto-expanding abbreviations";
|
||||
|
||||
package = mkPackageOption pkgs "zsh-abbr" { };
|
||||
|
||||
abbreviations = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
@@ -27,8 +29,8 @@ in {
|
||||
config = mkIf cfg.enable {
|
||||
programs.zsh.plugins = [{
|
||||
name = "zsh-abbr";
|
||||
src = pkgs.zsh-abbr;
|
||||
file = "/share/zsh/zsh-abbr/abbr.plugin.zsh";
|
||||
src = cfg.package;
|
||||
file = "share/zsh/zsh-abbr/zsh-abbr.plugin.zsh";
|
||||
}];
|
||||
|
||||
xdg.configFile = {
|
||||
|
||||
@@ -41,7 +41,7 @@ in with lib; {
|
||||
Service = {
|
||||
Restart = "always";
|
||||
RestartSec = "3";
|
||||
ExecStart = toString ([ "${pkgs.conky}/bin/conky" ]
|
||||
ExecStart = toString ([ "${cfg.package}/bin/conky" ]
|
||||
++ optional (cfg.extraConfig != "")
|
||||
"--config ${pkgs.writeText "conky.conf" cfg.extraConfig}");
|
||||
};
|
||||
|
||||
@@ -41,7 +41,6 @@ let
|
||||
# to work without wrapping it.
|
||||
socketDir = "%t/emacs";
|
||||
socketPath = "${socketDir}/server";
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.tadfisher ];
|
||||
|
||||
@@ -112,12 +111,7 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "services.emacs" pkgs
|
||||
lib.platforms.linux)
|
||||
];
|
||||
|
||||
(mkIf pkgs.stdenv.isLinux {
|
||||
systemd.user.services.emacs = {
|
||||
Unit = {
|
||||
Description = "Emacs text editor";
|
||||
@@ -190,9 +184,9 @@ in {
|
||||
}/bin/emacsclient "''${@:---create-frame}"'');
|
||||
};
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
(mkIf cfg.socketActivation.enable {
|
||||
(mkIf (cfg.socketActivation.enable && pkgs.stdenv.isLinux) {
|
||||
systemd.user.sockets.emacs = {
|
||||
Unit = {
|
||||
Description = "Emacs text editor";
|
||||
@@ -222,5 +216,20 @@ in {
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf pkgs.stdenv.isDarwin {
|
||||
launchd.agents.emacs = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ "${cfg.package}/bin/emacs" "--fg-daemon" ]
|
||||
++ cfg.extraOptions;
|
||||
RunAtLoad = true;
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ in {
|
||||
|
||||
serverUrl = mkOption {
|
||||
type = types.str;
|
||||
default = "https://api.etesync.com/";
|
||||
default = "https://api.etebase.com/partner/etesync/";
|
||||
description = "The URL to the etesync server.";
|
||||
};
|
||||
|
||||
|
||||
@@ -235,15 +235,12 @@ in {
|
||||
example = literalExpression "pkgs.pinentry-gnome3";
|
||||
default = null;
|
||||
description = ''
|
||||
Which pinentry interface to use. If not
|
||||
`null`, it sets
|
||||
{option}`pinentry-program` in
|
||||
{file}`gpg-agent.conf`. Beware that
|
||||
`pinentry-gnome3` may not work on non-Gnome
|
||||
systems. You can fix it by adding the following to your
|
||||
system configuration:
|
||||
Which pinentry interface to use. If not `null`, it sets
|
||||
{option}`pinentry-program` in {file}`gpg-agent.conf`. Beware that
|
||||
`pinentry-gnome3` may not work on non-GNOME systems. You can fix it by
|
||||
adding the following to your configuration:
|
||||
```nix
|
||||
services.dbus.packages = [ pkgs.gcr ];
|
||||
home.packages = [ pkgs.gcr ];
|
||||
```
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ in {
|
||||
Description = "hypridle";
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
X-Restart-Triggers =
|
||||
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||
[ "${config.xdg.configFile."hypr/hypridle.conf".source}" ];
|
||||
};
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ in {
|
||||
Description = "hyprpaper";
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
X-Restart-Triggers =
|
||||
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||
[ "${config.xdg.configFile."hypr/hyprpaper.conf".source}" ];
|
||||
};
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ let
|
||||
Restart = "always";
|
||||
RestartSec = 30;
|
||||
Type = "simple";
|
||||
} // optionalAttrs account.notmuch.enable {
|
||||
Environment =
|
||||
Environment = [ "PATH=${cfg.path}" ]
|
||||
++ optional account.notmuch.enable
|
||||
"NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/default/config";
|
||||
};
|
||||
|
||||
@@ -97,6 +97,17 @@ in {
|
||||
example = literalExpression "pkgs.imapnotify";
|
||||
description = "The imapnotify package to use";
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.listOf types.package;
|
||||
apply = lib.makeBinPath;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of packages to provide in PATH for the imapnotify service.
|
||||
|
||||
Note, this does not apply to the Darwin launchd service.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
accounts.email.accounts = mkOption {
|
||||
@@ -122,6 +133,12 @@ in {
|
||||
(checkAccounts (a: a.userName == null) "username")
|
||||
];
|
||||
|
||||
services.imapnotify.path = lib.mkMerge [
|
||||
(lib.mkIf config.programs.notmuch.enable [ pkgs.notmuch ])
|
||||
(lib.mkIf config.programs.mbsync.enable
|
||||
[ config.programs.mbsync.package ])
|
||||
];
|
||||
|
||||
systemd.user.services = listToAttrs (map genAccountUnit imapnotifyAccounts);
|
||||
|
||||
launchd.agents = listToAttrs (map genAccountAgent imapnotifyAccounts);
|
||||
|
||||
@@ -38,9 +38,7 @@ let
|
||||
else
|
||||
throw "Unknown tags ${attrNames x}";
|
||||
|
||||
directivesStr = ''
|
||||
${concatStringsSep "\n" (map tagToStr cfg.settings)}
|
||||
'';
|
||||
directivesStr = concatStringsSep "\n" (map tagToStr cfg.settings);
|
||||
|
||||
oldDirectivesStr = ''
|
||||
${concatStringsSep "\n"
|
||||
@@ -332,11 +330,13 @@ in {
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."kanshi/config".text =
|
||||
if cfg.profiles == { } && cfg.extraConfig == "" then
|
||||
directivesStr
|
||||
else
|
||||
oldDirectivesStr;
|
||||
xdg.configFile."kanshi/config" = let
|
||||
generatedConfigStr =
|
||||
if cfg.profiles == { } && cfg.extraConfig == "" then
|
||||
directivesStr
|
||||
else
|
||||
oldDirectivesStr;
|
||||
in mkIf (generatedConfigStr != "") { text = generatedConfigStr; };
|
||||
|
||||
systemd.user.services.kanshi = {
|
||||
Unit = {
|
||||
|
||||
@@ -14,8 +14,8 @@ in {
|
||||
enable = mkEnableOption "KDE connect";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.plasma5Packages.kdeconnect-kde;
|
||||
example = literalExpression "pkgs.kdePackages.kdeconnect-kde";
|
||||
default = pkgs.kdePackages.kdeconnect-kde;
|
||||
example = literalExpression "pkgs.plasma5Packages.kdeconnect-kde";
|
||||
description = "The KDE connect package to use";
|
||||
};
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ in {
|
||||
"%C/lorri"
|
||||
# Needs %C/nix/fetcher-cache-v1.sqlite
|
||||
"%C/nix"
|
||||
"/nix/var/nix/gcroots/per-user/%u"
|
||||
];
|
||||
CacheDirectory = [ "lorri" ];
|
||||
Restart = "on-failure";
|
||||
|
||||
@@ -23,7 +23,8 @@ let
|
||||
name = "mopidy-with-extensions-${pkgs.mopidy.version}";
|
||||
paths = closePropagation cfg.extensionPackages;
|
||||
pathsToLink = [ "/${pkgs.mopidyPackages.python.sitePackages}" ];
|
||||
buildInputs = [ pkgs.makeWrapper ];
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
ignoreCollisions = true;
|
||||
postBuild = ''
|
||||
makeWrapper ${pkgs.mopidy}/bin/mopidy $out/bin/mopidy \
|
||||
--prefix PYTHONPATH : $out/${pkgs.mopidyPackages.python.sitePackages}
|
||||
@@ -126,10 +127,13 @@ in {
|
||||
Description = "mopidy music player daemon";
|
||||
Documentation = [ "https://mopidy.com/" ];
|
||||
After = [ "network.target" "sound.target" ];
|
||||
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||
[ "${config.xdg.configFile."mopidy/mopidy.conf".source}" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${mopidyEnv}/bin/mopidy --config ${configFilePaths}";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
let
|
||||
cfg = config.services.podman;
|
||||
toml = pkgs.formats.toml { };
|
||||
in {
|
||||
meta.maintainers = with lib.hm.maintainers; [ bamhm182 n-hass ];
|
||||
|
||||
imports =
|
||||
@@ -8,10 +10,90 @@
|
||||
|
||||
options.services.podman = {
|
||||
enable = lib.mkEnableOption "Podman, a daemonless container engine";
|
||||
|
||||
settings = {
|
||||
containers = lib.mkOption {
|
||||
type = toml.type;
|
||||
default = { };
|
||||
description = "containers.conf configuration";
|
||||
};
|
||||
|
||||
storage = lib.mkOption {
|
||||
type = toml.type;
|
||||
description = "storage.conf configuration";
|
||||
};
|
||||
|
||||
registries = {
|
||||
search = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "docker.io" ];
|
||||
description = ''
|
||||
List of repositories to search.
|
||||
'';
|
||||
};
|
||||
|
||||
insecure = lib.mkOption {
|
||||
default = [ ];
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
List of insecure repositories.
|
||||
'';
|
||||
};
|
||||
|
||||
block = lib.mkOption {
|
||||
default = [ ];
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
List of blocked repositories.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
policy = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrs;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
default = [ { type = "insecureAcceptAnything"; } ];
|
||||
transports = {
|
||||
docker-daemon = {
|
||||
"" = [ { type = "insecureAcceptAnything"; } ];
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Signature verification policy file.
|
||||
If this option is empty the default policy file from
|
||||
`skopeo` will be used.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.podman.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions =
|
||||
[ (lib.hm.assertions.assertPlatform "podman" pkgs lib.platforms.linux) ];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
services.podman.settings.storage = {
|
||||
storage.driver = lib.mkDefault "overlay";
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"containers/policy.json".source = if cfg.settings.policy != { } then
|
||||
pkgs.writeText "policy.json" (builtins.toJSON cfg.settings.policy)
|
||||
else
|
||||
"${pkgs.skopeo.policy}/default-policy.json";
|
||||
"containers/registries.conf".source = toml.generate "registries.conf" {
|
||||
registries =
|
||||
lib.mapAttrs (n: v: { registries = v; }) cfg.settings.registries;
|
||||
};
|
||||
"containers/storage.conf".source =
|
||||
toml.generate "storage.conf" cfg.settings.storage;
|
||||
"containers/containers.conf".source =
|
||||
toml.generate "containers.conf" cfg.settings.containers;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -61,5 +61,12 @@ in {
|
||||
Install = { WantedBy = [ "timers.target" ]; };
|
||||
};
|
||||
})
|
||||
({
|
||||
xdg.configFile."systemd/user/podman-user-wait-network-online.service.d/50-exec-search-path.conf".text =
|
||||
''
|
||||
[Service]
|
||||
ExecSearchPath=${pkgs.bashInteractive}/bin:${pkgs.systemd}/bin:/bin
|
||||
'';
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -5,44 +5,584 @@ with lib;
|
||||
let
|
||||
|
||||
cfg = config.services.syncthing;
|
||||
settingsFormat = pkgs.formats.json { };
|
||||
cleanedConfig =
|
||||
converge (filterAttrsRecursive (_: v: v != null && v != { })) cfg.settings;
|
||||
|
||||
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
|
||||
|
||||
# Syncthing supports serving the GUI over Unix sockets. If that happens, the
|
||||
# API is served over the Unix socket as well. This function returns the correct
|
||||
# curl arguments for the address portion of the curl command for both network
|
||||
# and Unix socket addresses.
|
||||
curlAddressArgs = path:
|
||||
if isUnixGui
|
||||
# if cfg.guiAddress is a unix socket, tell curl explicitly about it
|
||||
# note that the dot in front of `${path}` is the hostname, which is
|
||||
# required.
|
||||
then
|
||||
"--unix-socket ${cfg.guiAddress} http://.${path}"
|
||||
# no adjustements are needed if cfg.guiAddress is a network address
|
||||
else
|
||||
"${cfg.guiAddress}${path}";
|
||||
|
||||
devices = mapAttrsToList (_: device: device // { deviceID = device.id; })
|
||||
cfg.settings.devices;
|
||||
|
||||
folders = mapAttrsToList (_: folder:
|
||||
folder // {
|
||||
devices = map (device:
|
||||
if builtins.isString device then {
|
||||
deviceId = cfg.settings.devices.${device}.id;
|
||||
} else
|
||||
device) folder.devices;
|
||||
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
|
||||
|
||||
jq = "${pkgs.jq}/bin/jq";
|
||||
sleep = "${pkgs.coreutils}/bin/sleep";
|
||||
printf = "${pkgs.coreutils}/bin/printf";
|
||||
cat = "${pkgs.coreutils}/bin/cat";
|
||||
curl = "${pkgs.curl}/bin/curl";
|
||||
install = "${pkgs.coreutils}/bin/install";
|
||||
syncthing = "${pkgs.syncthing}/bin/syncthing";
|
||||
|
||||
updateConfig = pkgs.writers.writeBash "merge-syncthing-config" (''
|
||||
set -efu
|
||||
|
||||
# be careful not to leak secrets in the filesystem or in process listings
|
||||
umask 0077
|
||||
|
||||
curl() {
|
||||
# get the api key by parsing the config.xml
|
||||
while
|
||||
! ${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)' \
|
||||
''${XDG_STATE_HOME:-$HOME/.local/state}/syncthing/config.xml \
|
||||
>"$RUNTIME_DIRECTORY/api_key"
|
||||
do ${sleep} 1; done
|
||||
(${printf} "X-API-Key: "; ${cat} "$RUNTIME_DIRECTORY/api_key") >"$RUNTIME_DIRECTORY/headers"
|
||||
${curl} -sSLk -H "@$RUNTIME_DIRECTORY/headers" \
|
||||
--retry 1000 --retry-delay 1 --retry-all-errors \
|
||||
"$@"
|
||||
}
|
||||
'' +
|
||||
|
||||
/* Syncthing's rest API for the folders and devices is almost identical.
|
||||
Hence we iterate them using lib.pipe and generate shell commands for both at
|
||||
the same time.
|
||||
*/
|
||||
(lib.pipe {
|
||||
# The attributes below are the only ones that are different for devices /
|
||||
# folders.
|
||||
devs = {
|
||||
new_conf_IDs = map (v: v.id) devices;
|
||||
GET_IdAttrName = "deviceID";
|
||||
override = cfg.overrideDevices;
|
||||
conf = devices;
|
||||
baseAddress = curlAddressArgs "/rest/config/devices";
|
||||
};
|
||||
dirs = {
|
||||
new_conf_IDs = map (v: v.id) folders;
|
||||
GET_IdAttrName = "id";
|
||||
override = cfg.overrideFolders;
|
||||
conf = folders;
|
||||
baseAddress = curlAddressArgs "/rest/config/folders";
|
||||
};
|
||||
} [
|
||||
# Now for each of these attributes, write the curl commands that are
|
||||
# identical to both folders and devices.
|
||||
(mapAttrs (conf_type: s:
|
||||
# We iterate the `conf` list now, and run a curl -X POST command for each, that
|
||||
# should update that device/folder only.
|
||||
lib.pipe s.conf [
|
||||
# Quoting https://docs.syncthing.net/rest/config.html:
|
||||
#
|
||||
# > PUT takes an array and POST a single object. In both cases if a
|
||||
# given folder/device already exists, it’s replaced, otherwise a new
|
||||
# one is added.
|
||||
#
|
||||
# What's not documented, is that using PUT will remove objects that
|
||||
# don't exist in the array given. That's why we use here `POST`, and
|
||||
# only if s.override == true then we DELETE the relevant folders
|
||||
# afterwards.
|
||||
(map (new_cfg: ''
|
||||
curl -d ${
|
||||
lib.escapeShellArg (builtins.toJSON new_cfg)
|
||||
} -X POST ${s.baseAddress}
|
||||
''))
|
||||
(lib.concatStringsSep "\n")
|
||||
]
|
||||
/* If we need to override devices/folders, we iterate all currently configured
|
||||
IDs, via another `curl -X GET`, and we delete all IDs that are not part of
|
||||
the Nix configured list of IDs
|
||||
*/
|
||||
+ lib.optionalString s.override ''
|
||||
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
|
||||
--argjson new_ids ${
|
||||
lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)
|
||||
} \
|
||||
--raw-output \
|
||||
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
|
||||
)"
|
||||
for id in ''${stale_${conf_type}_ids}; do
|
||||
curl -X DELETE ${s.baseAddress}/$id
|
||||
done
|
||||
''))
|
||||
builtins.attrValues
|
||||
(lib.concatStringsSep "\n")
|
||||
]) +
|
||||
/* Now we update the other settings defined in cleanedConfig which are not
|
||||
"folders" or "devices".
|
||||
*/
|
||||
(lib.pipe cleanedConfig [
|
||||
builtins.attrNames
|
||||
(lib.subtractLists [ "folders" "devices" ])
|
||||
(map (subOption: ''
|
||||
curl -X PUT -d ${
|
||||
lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})
|
||||
} ${curlAddressArgs "/rest/config/${subOption}"}
|
||||
''))
|
||||
(lib.concatStringsSep "\n")
|
||||
]) + lib.optionalString (cfg.passwordFile != null) ''
|
||||
syncthing_password=$(${cat} ${cfg.passwordFile})
|
||||
curl -X PATCH -d '{"password": "'$syncthing_password'"}' ${
|
||||
curlAddressArgs "/rest/config/gui"
|
||||
}
|
||||
'' + ''
|
||||
# restart Syncthing if required
|
||||
if curl ${curlAddressArgs "/rest/config/restart-required"} |
|
||||
${jq} -e .requiresRestart > /dev/null; then
|
||||
curl -X POST ${curlAddressArgs "/rest/system/restart"}
|
||||
fi
|
||||
'');
|
||||
|
||||
defaultSyncthingArgs = [
|
||||
"${pkgs.syncthing}/bin/syncthing"
|
||||
"${syncthing}"
|
||||
"-no-browser"
|
||||
"-no-restart"
|
||||
"-no-upgrade"
|
||||
"-gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress}"
|
||||
"-logflags=0"
|
||||
];
|
||||
|
||||
syncthingArgs = defaultSyncthingArgs ++ cfg.extraOptions;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
options = with types; {
|
||||
services.syncthing = {
|
||||
enable = mkEnableOption "Syncthing continuous file synchronization";
|
||||
enable = mkEnableOption ''
|
||||
Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync.
|
||||
Further declarative configuration options only supported on Linux devices.
|
||||
'';
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--gui-apikey=apiKey" ];
|
||||
cert = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Extra command-line arguments to pass to {command}`syncthing`.
|
||||
Path to the `cert.pem` file, which will be copied into Syncthing's
|
||||
config directory.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the `key.pem` file, which will be copied into Syncthing's
|
||||
config directory.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the gui password file.
|
||||
'';
|
||||
};
|
||||
|
||||
overrideDevices = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the devices which are not configured via the
|
||||
[devices](#opt-services.syncthing.settings.devices) option.
|
||||
If set to `false`, devices added via the web
|
||||
interface will persist and will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
overrideFolders = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the folders which are not configured via the
|
||||
[folders](#opt-services.syncthing.settings.folders) option.
|
||||
If set to `false`, folders added via the web
|
||||
interface will persist and will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
# global options
|
||||
options = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
The options element contains all other global configuration options
|
||||
'';
|
||||
type = submodule ({ name, ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
localAnnounceEnabled = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to send announcements to the local LAN, also use such announcements to find other devices.
|
||||
'';
|
||||
};
|
||||
|
||||
localAnnouncePort = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
description = ''
|
||||
The port on which to listen and send IPv4 broadcast announcements to.
|
||||
'';
|
||||
};
|
||||
|
||||
relaysEnabled = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = ''
|
||||
When true, relays will be connected to and potentially used for device to device connections.
|
||||
'';
|
||||
};
|
||||
|
||||
urAccepted = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether the user has accepted to submit anonymous usage data.
|
||||
The default, 0, mean the user has not made a choice, and Syncthing will ask at some point in the future.
|
||||
"-1" means no, a number above zero means that that version of usage reporting has been accepted.
|
||||
'';
|
||||
};
|
||||
|
||||
limitBandwidthInLan = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
|
||||
'';
|
||||
};
|
||||
|
||||
maxFolderConcurrency = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
description = ''
|
||||
This option controls how many folders may concurrently be in I/O-intensive operations such as syncing or scanning.
|
||||
The mechanism is described in detail in a [separate chapter](https://docs.syncthing.net/advanced/option-max-concurrency.html).
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# device settings
|
||||
devices = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Peers/devices which Syncthing should communicate with.
|
||||
|
||||
Note that you can still add devices manually, but those changes
|
||||
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
|
||||
is enabled.
|
||||
'';
|
||||
example = {
|
||||
bigbox = {
|
||||
id =
|
||||
"7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
||||
addresses = [ "tcp://192.168.0.10:51820" ];
|
||||
};
|
||||
};
|
||||
type = attrsOf (submodule ({ name, ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
description = ''
|
||||
The name of the device.
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
|
||||
'';
|
||||
};
|
||||
|
||||
autoAcceptFolders = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Automatically create or share folders that this device advertises at the default path.
|
||||
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
# folder settings
|
||||
folders = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Folders which should be shared by Syncthing.
|
||||
|
||||
Note that you can still add folders manually, but those changes
|
||||
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
|
||||
is enabled.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
"/home/user/sync" = {
|
||||
id = "syncme";
|
||||
devices = [ "bigbox" ];
|
||||
};
|
||||
}
|
||||
'';
|
||||
type = attrsOf (submodule ({ name, ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to share this folder.
|
||||
This option is useful when you want to define all folders
|
||||
in one place, but not every machine should share all folders.
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = str // {
|
||||
check = x:
|
||||
str.check x
|
||||
&& (substring 0 1 x == "/" || substring 0 2 x == "~/");
|
||||
description = str.description + " starting with / or ~/";
|
||||
};
|
||||
default = name;
|
||||
description = ''
|
||||
The path to the folder which should be shared.
|
||||
Only absolute paths (starting with `/`) and paths relative to
|
||||
the user's home directory (starting with `~/`) are allowed.
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
description = ''
|
||||
The ID of the folder. Must be the same on all devices.
|
||||
'';
|
||||
};
|
||||
|
||||
label = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
description = ''
|
||||
The label of the folder.
|
||||
'';
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = enum [
|
||||
"sendreceive"
|
||||
"sendonly"
|
||||
"receiveonly"
|
||||
"receiveencrypted"
|
||||
];
|
||||
default = "sendreceive";
|
||||
description = ''
|
||||
Controls how the folder is handled by Syncthing.
|
||||
See <https://docs.syncthing.net/users/config.html#config-option-folder.type>.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
The devices this folder should be shared with. Each device must
|
||||
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
|
||||
'';
|
||||
};
|
||||
|
||||
versioning = mkOption {
|
||||
default = null;
|
||||
description = ''
|
||||
How to keep changed/deleted files with Syncthing.
|
||||
There are 4 different types of versioning with different parameters.
|
||||
See <https://docs.syncthing.net/users/versioning.html>.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
versioning = {
|
||||
type = "simple";
|
||||
params.keep = "10";
|
||||
};
|
||||
}
|
||||
{
|
||||
versioning = {
|
||||
type = "trashcan";
|
||||
params.cleanoutDays = "1000";
|
||||
};
|
||||
}
|
||||
{
|
||||
versioning = {
|
||||
type = "staggered";
|
||||
fsPath = "/syncthing/backup";
|
||||
params = {
|
||||
cleanInterval = "3600";
|
||||
maxAge = "31536000";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
versioning = {
|
||||
type = "external";
|
||||
params.versionsPath = pkgs.writers.writeBash "backup" '''
|
||||
folderpath="$1"
|
||||
filepath="$2"
|
||||
rm -rf "$folderpath/$filepath"
|
||||
''';
|
||||
};
|
||||
}
|
||||
]
|
||||
'';
|
||||
type = with types;
|
||||
nullOr (submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = enum [
|
||||
"external"
|
||||
"simple"
|
||||
"staggered"
|
||||
"trashcan"
|
||||
];
|
||||
description = ''
|
||||
The type of versioning.
|
||||
See <https://docs.syncthing.net/users/versioning.html>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
copyOwnershipFromParent = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
On Unix systems, tries to copy file/folder ownership from
|
||||
the parent directory (the directory it’s located in).
|
||||
Requires running Syncthing as a privileged user, or
|
||||
granting it additional capabilities (e.g. CAP_CHOWN on
|
||||
Linux).
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Extra configuration options for Syncthing.
|
||||
See <https://docs.syncthing.net/users/config.html>.
|
||||
Note that this attribute set does not exactly match the documented
|
||||
XML format. Instead, this is the format of the JSON REST API. There
|
||||
are slight differences. For example, this XML:
|
||||
```xml
|
||||
<options>
|
||||
<listenAddress>default</listenAddress>
|
||||
<minHomeDiskFree unit="%">1</minHomeDiskFree>
|
||||
</options>
|
||||
```
|
||||
corresponds to the Nix code:
|
||||
```nix
|
||||
{
|
||||
options = {
|
||||
listenAddresses = [
|
||||
"default"
|
||||
];
|
||||
minHomeDiskFree = {
|
||||
unit = "%";
|
||||
value = 1;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
'';
|
||||
example = {
|
||||
options.localAnnounceEnabled = false;
|
||||
gui.theme = "black";
|
||||
};
|
||||
};
|
||||
|
||||
guiAddress = mkOption {
|
||||
type = str;
|
||||
default = "127.0.0.1:8384";
|
||||
description = ''
|
||||
The address to serve the web interface at.
|
||||
'';
|
||||
};
|
||||
|
||||
allProxy = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "socks5://address.com:1234";
|
||||
description = ''
|
||||
Overwrites the {env}`all_proxy` environment variable for the Syncthing
|
||||
process to the given value. This is normally used to let Syncthing
|
||||
connect through a SOCKS5 proxy server. See
|
||||
<https://docs.syncthing.net/users/proxying.html>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "--reset-deltas" ];
|
||||
description = ''
|
||||
Extra command-line arguments to pass to {command}`syncthing`
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "syncthing" { };
|
||||
|
||||
tray = mkOption {
|
||||
type = with types;
|
||||
either bool (submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Whether to enable a syncthing tray service.";
|
||||
};
|
||||
|
||||
command = mkOption {
|
||||
type = types.str;
|
||||
type = str;
|
||||
default = "syncthingtray";
|
||||
defaultText = literalExpression "syncthingtray";
|
||||
example = literalExpression "qsyncthingtray";
|
||||
@@ -50,7 +590,7 @@ in {
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
type = package;
|
||||
default = pkgs.syncthingtray-minimal;
|
||||
defaultText = literalExpression "pkgs.syncthingtray-minimal";
|
||||
example = literalExpression "pkgs.qsyncthingtray";
|
||||
@@ -78,10 +618,28 @@ in {
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStartPre = mkIf (cfg.cert != null || cfg.key != null) "+${
|
||||
pkgs.writers.writeBash "syncthing-copy-keys" ''
|
||||
syncthing_dir="''${XDG_STATE_HOME:-$HOME/.local/state}/syncthing"
|
||||
${install} -dm700 "$syncthing_dir"
|
||||
${optionalString (cfg.cert != null) ''
|
||||
${install} -Dm400 ${
|
||||
toString cfg.cert
|
||||
} "$syncthing_dir/cert.pem"
|
||||
''}
|
||||
${optionalString (cfg.key != null) ''
|
||||
${install} -Dm400 ${
|
||||
toString cfg.key
|
||||
} "$syncthing_dir/key.pem"
|
||||
''}
|
||||
''
|
||||
}";
|
||||
ExecStart = escapeShellArgs syncthingArgs;
|
||||
Restart = "on-failure";
|
||||
SuccessExitStatus = [ 3 4 ];
|
||||
RestartForceExitStatus = [ 3 4 ];
|
||||
Environment =
|
||||
mkIf (cfg.allProxy != null) { all_proxy = cfg.allProxy; };
|
||||
|
||||
# Sandboxing.
|
||||
LockPersonality = true;
|
||||
@@ -95,6 +653,23 @@ in {
|
||||
|
||||
Install = { WantedBy = [ "default.target" ]; };
|
||||
};
|
||||
|
||||
syncthing-init = mkIf (cleanedConfig != { }) {
|
||||
Unit = {
|
||||
Description = "Syncthing configuration updater";
|
||||
Requires = [ "syncthing.service" ];
|
||||
After = [ "syncthing.service" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = updateConfig;
|
||||
RuntimeDirectory = "syncthing-init";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
|
||||
Install = { WantedBy = [ "default.target" ]; };
|
||||
};
|
||||
};
|
||||
|
||||
launchd.agents.syncthing = {
|
||||
|
||||
@@ -7,7 +7,7 @@ let
|
||||
cfg = config.services.volnoti;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.imalison ];
|
||||
meta.maintainers = with maintainers; [ imalison tomodachi94 ];
|
||||
|
||||
options = {
|
||||
services.volnoti = {
|
||||
@@ -37,7 +37,7 @@ in {
|
||||
|
||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||
|
||||
Service = { ExecStart = "${pkgs.volnoti}/bin/volnoti -v -n"; };
|
||||
Service = { ExecStart = "${lib.getExe cfg.package} -v -n"; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -99,6 +99,6 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
xsession.initExtra = xrdbMerge;
|
||||
xsession.profileExtra = xrdbMerge;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"release": "24.11",
|
||||
"release": "25.05",
|
||||
"isReleaseBranch": false
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ in import nmtSrc {
|
||||
./modules/programs/khal
|
||||
./modules/programs/khard
|
||||
./modules/programs/kitty
|
||||
./modules/programs/kubecolor
|
||||
./modules/programs/ledger
|
||||
./modules/programs/less
|
||||
./modules/programs/lf
|
||||
@@ -118,6 +119,7 @@ in import nmtSrc {
|
||||
./modules/programs/newsboat
|
||||
./modules/programs/nheko
|
||||
./modules/programs/nix-index
|
||||
./modules/programs/nix-your-shell
|
||||
./modules/programs/nnn
|
||||
./modules/programs/nushell
|
||||
./modules/programs/oh-my-posh
|
||||
@@ -173,6 +175,7 @@ in import nmtSrc {
|
||||
./modules/xresources
|
||||
] ++ lib.optionals isDarwin [
|
||||
./modules/launchd
|
||||
./modules/services/emacs-darwin
|
||||
./modules/services/espanso-darwin
|
||||
./modules/services/git-sync-darwin
|
||||
./modules/services/imapnotify-darwin
|
||||
@@ -286,6 +289,7 @@ in import nmtSrc {
|
||||
./modules/services/trayscale
|
||||
./modules/services/twmn
|
||||
./modules/services/udiskie
|
||||
./modules/services/volnoti
|
||||
./modules/services/window-managers/bspwm
|
||||
./modules/services/window-managers/herbstluftwm
|
||||
./modules/services/window-managers/hyprland
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
};
|
||||
|
||||
home-manager.users.alice = { ... }: {
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
home.file.test.text = "testfile";
|
||||
# Enable a light-weight systemd service.
|
||||
services.pueue.enable = true;
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("home-manager-alice.service")
|
||||
machine.wait_for_console_text("Finished Home Manager environment for alice.")
|
||||
|
||||
with subtest("Home Manager file"):
|
||||
# The file should be linked with the expected content.
|
||||
@@ -73,7 +73,7 @@
|
||||
fail_as_alice("pueue status")
|
||||
|
||||
machine.systemctl("restart home-manager-alice.service")
|
||||
machine.wait_for_unit("home-manager-alice.service")
|
||||
machine.wait_for_console_text("Finished Home Manager environment for alice.")
|
||||
|
||||
actual = succeed_as_alice("pueue status")
|
||||
expected = "running"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
home.stateVersion = "24.05"; # Please read the comment before changing.
|
||||
home.stateVersion = "24.11"; # Please read the comment before changing.
|
||||
|
||||
# The home.packages option allows you to install Nix packages into your
|
||||
# environment.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{
|
||||
home.username = "alice";
|
||||
home.homeDirectory = "/home/alice";
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
home.packages = [ pkgs.hello ];
|
||||
home.file.test.text = "test";
|
||||
home.sessionVariables.EDITOR = "emacs";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ ... }: {
|
||||
home.username = "alice";
|
||||
home.homeDirectory = "/home/alice";
|
||||
home.stateVersion = "24.05";
|
||||
home.stateVersion = "24.11";
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
home.username = "alice";
|
||||
home.homeDirectory = "/home/alice";
|
||||
|
||||
home.stateVersion = "24.05"; # Please read the comment before changing.
|
||||
home.stateVersion = "24.11"; # Please read the comment before changing.
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
i18n.inputMethod = {
|
||||
enabled = "fcitx5";
|
||||
fcitx5.addons = with pkgs; [ fcitx5-chinese-addons ];
|
||||
fcitx5.addons = [ pkgs.libsForQt5.fcitx5-chinese-addons ];
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
nix = { package = config.lib.test.mkStubPackage { }; };
|
||||
nix = { package = config.lib.test.mkStubPackage { }; };
|
||||
|
||||
nmt.script = ''
|
||||
assertPathNotExists home-files/.config/nix
|
||||
assertPathNotExists home-files/.nix-defexpr/50-home-manager
|
||||
'';
|
||||
};
|
||||
nmt.script = ''
|
||||
assertPathNotExists home-files/.config/nix
|
||||
assertPathNotExists home-files/.nix-defexpr/50-home-manager
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -9,21 +9,19 @@ let
|
||||
}
|
||||
'';
|
||||
in {
|
||||
config = {
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage {
|
||||
version = lib.getVersion pkgs.nixVersions.stable;
|
||||
};
|
||||
channels.example = exampleChannel;
|
||||
settings.use-xdg-base-directories = true;
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage {
|
||||
version = lib.getVersion pkgs.nixVersions.stable;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/home/hm-user/.local/state/nix/defexpr/50-home-manager''${NIX_PATH:+:$NIX_PATH}"'
|
||||
assertFileContent \
|
||||
home-files/.local/state/nix/defexpr/50-home-manager/example/default.nix \
|
||||
${exampleChannel}/default.nix
|
||||
'';
|
||||
channels.example = exampleChannel;
|
||||
settings.use-xdg-base-directories = true;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/home/hm-user/.local/state/nix/defexpr/50-home-manager''${NIX_PATH:+:$NIX_PATH}"'
|
||||
assertFileContent \
|
||||
home-files/.local/state/nix/defexpr/50-home-manager/example/default.nix \
|
||||
${exampleChannel}/default.nix
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -9,18 +9,16 @@ let
|
||||
}
|
||||
'';
|
||||
in {
|
||||
config = {
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
channels.example = exampleChannel;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/home/hm-user/.nix-defexpr/50-home-manager''${NIX_PATH:+:$NIX_PATH}"'
|
||||
assertFileContent \
|
||||
home-files/.nix-defexpr/50-home-manager/example/default.nix \
|
||||
${exampleChannel}/default.nix
|
||||
'';
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
channels.example = exampleChannel;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/home/hm-user/.nix-defexpr/50-home-manager''${NIX_PATH:+:$NIX_PATH}"'
|
||||
assertFileContent \
|
||||
home-files/.nix-defexpr/50-home-manager/example/default.nix \
|
||||
${exampleChannel}/default.nix
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
nix = {
|
||||
registry = {
|
||||
nixpkgs = {
|
||||
to = {
|
||||
type = "github";
|
||||
owner = "my-org";
|
||||
repo = "my-nixpkgs";
|
||||
};
|
||||
nix = {
|
||||
registry = {
|
||||
nixpkgs = {
|
||||
to = {
|
||||
type = "github";
|
||||
owner = "my-org";
|
||||
repo = "my-nixpkgs";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.config/nix/registry.json \
|
||||
${./example-registry-expected.json}
|
||||
'';
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.config/nix/registry.json \
|
||||
${./example-registry-expected.json}
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,38 +1,34 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
config = {
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage {
|
||||
version = lib.getVersion pkgs.nixVersions.stable;
|
||||
buildScript = ''
|
||||
target=$out/bin/nix
|
||||
mkdir -p "$(dirname "$target")"
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage {
|
||||
version = lib.getVersion pkgs.nixVersions.stable;
|
||||
buildScript = ''
|
||||
target=$out/bin/nix
|
||||
mkdir -p "$(dirname "$target")"
|
||||
|
||||
echo -n "true" > "$target"
|
||||
echo -n "true" > "$target"
|
||||
|
||||
chmod +x "$target"
|
||||
'';
|
||||
};
|
||||
|
||||
nixPath = [ "/a" "/b/c" ];
|
||||
|
||||
settings = {
|
||||
use-sandbox = true;
|
||||
show-trace = true;
|
||||
system-features = [ "big-parallel" "kvm" "recursive-nix" ];
|
||||
};
|
||||
chmod +x "$target"
|
||||
'';
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.config/nix/nix.conf \
|
||||
${./example-settings-expected.conf}
|
||||
nixPath = [ "/a" "/b/c" ];
|
||||
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/a:/b/c''${NIX_PATH:+:$NIX_PATH}"'
|
||||
'';
|
||||
settings = {
|
||||
use-sandbox = true;
|
||||
show-trace = true;
|
||||
system-features = [ "big-parallel" "kvm" "recursive-nix" ];
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.config/nix/nix.conf \
|
||||
${./example-settings-expected.conf}
|
||||
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/a:/b/c''${NIX_PATH:+:$NIX_PATH}"'
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
nixPath = [ "/a" "/b/c" ];
|
||||
keepOldNixPath = false;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/a:/b/c"'
|
||||
'';
|
||||
nix = {
|
||||
package = config.lib.test.mkStubPackage { };
|
||||
nixPath = [ "/a" "/b/c" ];
|
||||
keepOldNixPath = false;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'export NIX_PATH="/a:/b/c"'
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
{
|
||||
config = {
|
||||
qt.enable = true;
|
||||
qt.enable = true;
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
};
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
{
|
||||
config = {
|
||||
qt = {
|
||||
enable = true;
|
||||
# Check if still backwards compatible
|
||||
platformTheme = "gnome";
|
||||
style.name = "adwaita";
|
||||
};
|
||||
|
||||
test.stubs.qgnomeplatform = { };
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_QPA_PLATFORMTHEME="gnome"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_STYLE_OVERRIDE="adwaita"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
test.asserts.warnings.expected = [
|
||||
"The option `qt.platformTheme` has been renamed to `qt.platformTheme.name`."
|
||||
"The value `gnome` for option `qt.platformTheme` is deprecated. Use `adwaita` instead."
|
||||
];
|
||||
qt = {
|
||||
enable = true;
|
||||
# Check if still backwards compatible
|
||||
platformTheme = "gnome";
|
||||
style.name = "adwaita";
|
||||
};
|
||||
|
||||
test.stubs = {
|
||||
qgnomeplatform = { };
|
||||
qgnomeplatform-qt6 = { };
|
||||
adwaita-qt = { };
|
||||
adwaita-qt6 = { };
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_QPA_PLATFORMTHEME="gnome"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_STYLE_OVERRIDE="adwaita"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
test.asserts.warnings.expected = [
|
||||
"The option `qt.platformTheme` has been renamed to `qt.platformTheme.name`."
|
||||
"The value `gnome` for option `qt.platformTheme` is deprecated. Use `adwaita` instead."
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,18 +1,31 @@
|
||||
{
|
||||
config = {
|
||||
qt = {
|
||||
enable = true;
|
||||
platformTheme.name = "gtk";
|
||||
};
|
||||
i18n.inputMethod.enabled = "fcitx5";
|
||||
imports = [ ../../i18n/input-method/fcitx5-stubs.nix ];
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_QPA_PLATFORMTHEME="gtk2"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
qt = {
|
||||
enable = true;
|
||||
platformTheme.name = "gtk";
|
||||
};
|
||||
|
||||
i18n.inputMethod.enabled = "fcitx5";
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
libsForQt5 = prev.libsForQt5.overrideScope (qt5final: qt5prev: {
|
||||
qtstyleplugins = prev.mkStubPackage { outPath = null; };
|
||||
});
|
||||
|
||||
qt6Packages = prev.qt6Packages.overrideScope (qt6final: qt6prev: {
|
||||
qt6gtk2 = prev.mkStubPackage { outPath = null; };
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_QPA_PLATFORMTHEME="gtk2"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
{
|
||||
config = {
|
||||
qt = {
|
||||
enable = true;
|
||||
platformTheme.name = "gtk3";
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_QPA_PLATFORMTHEME="gtk3"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
qt = {
|
||||
enable = true;
|
||||
platformTheme.name = "gtk3";
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_QPA_PLATFORMTHEME="gtk3"'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QT_PLUGIN_PATH'
|
||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||
'QML2_IMPORT_PATH'
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
extraConfig = "test";
|
||||
};
|
||||
|
||||
test.stubs.cmus = { };
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.config/cmus/rc \
|
||||
|
||||
@@ -36,11 +36,7 @@ let
|
||||
|
||||
in {
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
gnome = super.gnome.overrideScope (gself: gsuper: {
|
||||
gnome-shell-extensions = dummy-gnome-shell-extensions;
|
||||
});
|
||||
})
|
||||
(final: prev: { gnome-shell-extensions = dummy-gnome-shell-extensions; })
|
||||
];
|
||||
|
||||
programs.gnome-shell.enable = true;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
source = pkgs.fetchurl {
|
||||
url =
|
||||
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x44CF42371ADF842E12F116EAA9D3F98FCCF5460B";
|
||||
hash = "sha256-u01QTYEFSY1feJWX3JJjXB6thiVO4WOnrqNmzg6vIDs=";
|
||||
hash = "sha256-bSluCZh6ijwppigk8iF2BwWKZgq1WDbIjyYQRK772dM=";
|
||||
};
|
||||
trust = 1; # "unknown"
|
||||
}
|
||||
|
||||
5
tests/modules/programs/kubecolor/default.nix
Normal file
5
tests/modules/programs/kubecolor/default.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
kubecolor-empty-config = ./empty-config.nix;
|
||||
kubecolor-example-config-default-paths = ./example-config-default-paths.nix;
|
||||
kubecolor-example-config-xdg-paths = ./example-config-xdg-paths.nix;
|
||||
}
|
||||
20
tests/modules/programs/kubecolor/empty-config.nix
Normal file
20
tests/modules/programs/kubecolor/empty-config.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
configDir =
|
||||
if pkgs.stdenv.isDarwin then "Library/Application Support" else ".config";
|
||||
in {
|
||||
programs.kubecolor = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "kubecolor";
|
||||
version = "0.4.0";
|
||||
};
|
||||
};
|
||||
|
||||
test.stubs.kubecolor = { };
|
||||
|
||||
nmt.script = ''
|
||||
assertPathNotExists 'home-files/${configDir}/kube/color.yaml'
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
configDir = if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/kube"
|
||||
else
|
||||
".kube";
|
||||
in {
|
||||
programs.kubecolor = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "kubecolor";
|
||||
version = "0.4.0";
|
||||
};
|
||||
settings = {
|
||||
kubectl = "kubectl";
|
||||
preset = "dark";
|
||||
objFreshThreshold = 0;
|
||||
paging = "auto";
|
||||
pager = "less";
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists 'home-files/${configDir}/color.yaml'
|
||||
assertFileContent 'home-files/${configDir}/color.yaml' \
|
||||
${
|
||||
builtins.toFile "expected.yaml" ''
|
||||
kubectl: kubectl
|
||||
objFreshThreshold: 0
|
||||
pager: less
|
||||
paging: auto
|
||||
preset: dark
|
||||
''
|
||||
}
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
xdg.enable = true;
|
||||
home.preferXdgDirectories = true;
|
||||
|
||||
programs.kubecolor = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "kubecolor";
|
||||
version = "0.4.0";
|
||||
};
|
||||
settings = {
|
||||
kubectl = "kubectl";
|
||||
preset = "dark";
|
||||
objFreshThreshold = 0;
|
||||
paging = "auto";
|
||||
pager = "less";
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists 'home-files/.config/kube/color.yaml'
|
||||
assertFileContent 'home-files/.config/kube/color.yaml' \
|
||||
${
|
||||
builtins.toFile "expected.yaml" ''
|
||||
kubectl: kubectl
|
||||
objFreshThreshold: 0
|
||||
pager: less
|
||||
paging: auto
|
||||
preset: dark
|
||||
''
|
||||
}
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ IMAPAccount hm-account
|
||||
CertificateFile /etc/ssl/certs/ca-certificates.crt
|
||||
Host imap.example.org
|
||||
PassCmd "password-command 2"
|
||||
SSLType IMAPS
|
||||
TLSType IMAPS
|
||||
User home.manager.jr
|
||||
|
||||
IMAPStore hm-account-remote
|
||||
@@ -56,8 +56,8 @@ IMAPAccount hm@example.com
|
||||
CertificateFile /etc/ssl/certs/ca-certificates.crt
|
||||
Host imap.example.com
|
||||
PassCmd password-command
|
||||
SSLType IMAPS
|
||||
SSLVersions TLSv1.3 TLSv1.2
|
||||
TLSType IMAPS
|
||||
TLSVersions +1.3 +1.2 -1.1
|
||||
User home.manager
|
||||
|
||||
IMAPStore hm@example.com-remote
|
||||
|
||||
@@ -21,7 +21,7 @@ with lib;
|
||||
accounts.email.accounts = {
|
||||
"hm@example.com".mbsync = {
|
||||
enable = true;
|
||||
extraConfig.account.SSLVersions = [ "TLSv1.3" "TLSv1.2" ];
|
||||
extraConfig.account.TLSVersions = [ "+1.3" "+1.2" "-1.1" ];
|
||||
groups.inboxes = {
|
||||
channels = {
|
||||
inbox1 = {
|
||||
@@ -79,8 +79,8 @@ with lib;
|
||||
test.stubs.isync = { };
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.mbsyncrc
|
||||
assertFileContent home-files/.mbsyncrc ${./mbsync-expected.conf}
|
||||
assertFileExists home-files/.config/isyncrc
|
||||
assertFileContent home-files/.config/isyncrc ${./mbsync-expected.conf}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
1
tests/modules/programs/nix-your-shell/default.nix
Normal file
1
tests/modules/programs/nix-your-shell/default.nix
Normal file
@@ -0,0 +1 @@
|
||||
{ nix-your-shell-enable-shells = ./enable-shells.nix; }
|
||||
48
tests/modules/programs/nix-your-shell/enable-shells.nix
Normal file
48
tests/modules/programs/nix-your-shell/enable-shells.nix
Normal file
@@ -0,0 +1,48 @@
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
{
|
||||
programs = {
|
||||
nix-your-shell = {
|
||||
enable = true;
|
||||
enableFishIntegration = true;
|
||||
enableNushellIntegration = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
fish.enable = true;
|
||||
nushell.enable = true;
|
||||
zsh.enable = true;
|
||||
};
|
||||
|
||||
test.stubs = {
|
||||
nix-your-shell = { };
|
||||
nushell = { };
|
||||
zsh = { };
|
||||
};
|
||||
|
||||
nmt.script = let
|
||||
nushellConfigDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then
|
||||
"home-files/Library/Application Support/nushell"
|
||||
else
|
||||
"home-files/.config/nushell";
|
||||
in ''
|
||||
assertFileExists home-files/.config/fish/config.fish
|
||||
assertFileContains \
|
||||
home-files/.config/fish/config.fish \
|
||||
'@nix-your-shell@/bin/nix-your-shell fish | source'
|
||||
|
||||
assertFileExists ${nushellConfigDir}/config.nu
|
||||
assertFileContains \
|
||||
${nushellConfigDir}/config.nu \
|
||||
'source ${config.xdg.cacheHome}/nix-your-shell/init.nu'
|
||||
|
||||
assertFileExists ${nushellConfigDir}/env.nu
|
||||
assertFileContains \
|
||||
${nushellConfigDir}/env.nu \
|
||||
'@nix-your-shell@/bin/nix-your-shell nu | save --force ${config.xdg.cacheHome}/nix-your-shell/init.nu'
|
||||
|
||||
assertFileExists home-files/.zshrc
|
||||
assertFileContains \
|
||||
home-files/.zshrc \
|
||||
'@nix-your-shell@/bin/nix-your-shell zsh | source /dev/stdin'
|
||||
'';
|
||||
}
|
||||
@@ -23,6 +23,8 @@
|
||||
}
|
||||
'';
|
||||
|
||||
plugins = [ pkgs.nushellPlugins.formats ];
|
||||
|
||||
shellAliases = {
|
||||
"lsname" = "(ls | get name)";
|
||||
"ll" = "ls -a";
|
||||
@@ -41,8 +43,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
test.stubs.nushell = { };
|
||||
|
||||
nmt.script = let
|
||||
configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then
|
||||
"home-files/Library/Application Support/nushell"
|
||||
@@ -58,5 +58,7 @@
|
||||
assertFileContent \
|
||||
"${configDir}/login.nu" \
|
||||
${./login-expected.nu}
|
||||
assertFileExists \
|
||||
"${configDir}/plugin.msgpackz"
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
starship-settings = ./settings.nix;
|
||||
starship-fish-with-transience = ./fish_with_transience.nix;
|
||||
starship-fish-without-transience = ./fish_without_transience.nix;
|
||||
starship-fish-with-interactive = ./fish_with_interactive.nix;
|
||||
starship-fish-without-interactive = ./fish_without_interactive.nix;
|
||||
}
|
||||
|
||||
27
tests/modules/programs/starship/fish_with_interactive.nix
Normal file
27
tests/modules/programs/starship/fish_with_interactive.nix
Normal file
@@ -0,0 +1,27 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
config = {
|
||||
programs = {
|
||||
fish.enable = true;
|
||||
starship.enable = true;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/fish/config.fish
|
||||
|
||||
export GOT="$(tail -n 5 `_abs home-files/.config/fish/config.fish`)"
|
||||
export NOT_EXPECTED="
|
||||
if test \"\$TERM\" != dumb
|
||||
/home/hm-user/.nix-profile/bin/starship init fish | source
|
||||
|
||||
end"
|
||||
|
||||
if [[ "$GOT" == "$NOT_EXPECTED" ]]; then
|
||||
fail "Expected starship init to be inside the 'is-interactive' block but it wasn't."
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
43
tests/modules/programs/starship/fish_without_interactive.nix
Normal file
43
tests/modules/programs/starship/fish_without_interactive.nix
Normal file
@@ -0,0 +1,43 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
config = {
|
||||
programs = {
|
||||
fish.enable = true;
|
||||
|
||||
starship = {
|
||||
enable = true;
|
||||
enableInteractive = false;
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/fish/config.fish
|
||||
|
||||
export GOT="$(tail -n 5 `_abs home-files/.config/fish/config.fish`)"
|
||||
export EXPECTED="
|
||||
if test \"\$TERM\" != dumb
|
||||
/home/hm-user/.nix-profile/bin/starship init fish | source
|
||||
|
||||
end"
|
||||
|
||||
export MESSAGE="
|
||||
==========
|
||||
Expected
|
||||
==========
|
||||
$EXPECTED
|
||||
==========
|
||||
Got
|
||||
==========
|
||||
$GOT
|
||||
==========
|
||||
"
|
||||
|
||||
if [[ "$GOT" != "$EXPECTED" ]]; then
|
||||
fail "$MESSAGE"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -18,6 +18,7 @@ user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ec
|
||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.openpgp_key_id", "ABC");
|
||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.protectSubject", true);
|
||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.sign_mail", false);
|
||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.smtpServer", "smtp_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f");
|
||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.useremail", "home-manager@example.com");
|
||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.valid", true);
|
||||
user_pref("mail.identity.id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.autoEncryptDrafts", false);
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# ============================================= #
|
||||
# Start with defaults from the Sensible plugin #
|
||||
# --------------------------------------------- #
|
||||
run-shell @sensible_rtp@
|
||||
# ============================================= #
|
||||
|
||||
set -g default-terminal "screen"
|
||||
set -g base-index 0
|
||||
@@ -24,6 +19,7 @@ set -g mode-keys emacs
|
||||
|
||||
|
||||
set -g mouse off
|
||||
set -g focus-events off
|
||||
setw -g aggressive-resize off
|
||||
setw -g clock-mode-style 12
|
||||
set -s escape-time 500
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# ============================================= #
|
||||
# Start with defaults from the Sensible plugin #
|
||||
# --------------------------------------------- #
|
||||
run-shell @sensible_rtp@
|
||||
# ============================================= #
|
||||
|
||||
set -g default-terminal "screen"
|
||||
set -g base-index 0
|
||||
@@ -24,6 +19,7 @@ bind-key -N "Kill the current pane" x kill-pane
|
||||
|
||||
|
||||
set -g mouse off
|
||||
set -g focus-events off
|
||||
setw -g aggressive-resize off
|
||||
setw -g clock-mode-style 12
|
||||
set -s escape-time 500
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# ============================================= #
|
||||
# Start with defaults from the Sensible plugin #
|
||||
# --------------------------------------------- #
|
||||
run-shell @tmuxplugin_sensible_rtp@
|
||||
# ============================================= #
|
||||
|
||||
set -g default-terminal "screen"
|
||||
set -g base-index 0
|
||||
@@ -24,6 +19,7 @@ set -g mode-keys emacs
|
||||
|
||||
|
||||
set -g mouse off
|
||||
set -g focus-events off
|
||||
setw -g aggressive-resize on
|
||||
setw -g clock-mode-style 24
|
||||
set -s escape-time 500
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# ============================================= #
|
||||
# Start with defaults from the Sensible plugin #
|
||||
# --------------------------------------------- #
|
||||
run-shell @sensible_rtp@
|
||||
# ============================================= #
|
||||
|
||||
set -g default-terminal "screen"
|
||||
set -g base-index 0
|
||||
@@ -22,6 +17,7 @@ set -g mode-keys emacs
|
||||
|
||||
|
||||
set -g mouse on
|
||||
set -g focus-events off
|
||||
setw -g aggressive-resize off
|
||||
setw -g clock-mode-style 12
|
||||
set -s escape-time 500
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# ============================================= #
|
||||
# Start with defaults from the Sensible plugin #
|
||||
# --------------------------------------------- #
|
||||
run-shell @sensible_rtp@
|
||||
# ============================================= #
|
||||
|
||||
set -g default-terminal "screen"
|
||||
set -g base-index 0
|
||||
@@ -27,6 +22,7 @@ bind -N "Send the prefix key through to the application" \
|
||||
|
||||
|
||||
set -g mouse off
|
||||
set -g focus-events off
|
||||
setw -g aggressive-resize off
|
||||
setw -g clock-mode-style 12
|
||||
set -s escape-time 500
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user