mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-12 01:59: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"
|
interval: "weekly"
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "ci:"
|
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
|
Home Manager is developed against `nixpkgs-unstable` branch, which often causes
|
||||||
it to contain tweaks for changes/packages not yet released in stable [NixOS][].
|
it to contain tweaks for changes/packages not yet released in stable [NixOS][].
|
||||||
To avoid breaking users' configurations, Home Manager is released in branches
|
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
|
fixes, but usually not new modules. If you need a module to be backported, then
|
||||||
feel free to open an issue.
|
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
|
overwritten was from a previous Home Manager generation or from manual
|
||||||
configuration.
|
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
|
stable version), it may or may not work on other Linux distributions and NixOS
|
||||||
versions.
|
versions.
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ $ nix-channel --add https://github.com/nix-community/home-manager/archive/master
|
|||||||
$ nix-channel --update
|
$ 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
|
``` 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
|
$ nix-channel --update
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ home-manager.users.eve = { pkgs, ... }: {
|
|||||||
|
|
||||||
# The state version is required and should stay at the version you
|
# The state version is required and should stay at the version you
|
||||||
# originally installed.
|
# 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
|
$ 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
|
``` 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
|
$ 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
|
# The state version is required and should stay at the version you
|
||||||
# originally installed.
|
# originally installed.
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
$ nix-channel --update
|
$ 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
|
``` 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
|
$ nix-channel --update
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Home Manager Manual {#home-manager-manual}
|
# Home Manager Manual {#home-manager-manual}
|
||||||
|
|
||||||
## Version 24.05 (unstable)
|
## Version 25.05 (unstable)
|
||||||
|
|
||||||
|
|
||||||
```{=include=} preface
|
```{=include=} preface
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ then to generate and activate a basic configuration run the command
|
|||||||
$ nix run home-manager/master -- init --switch
|
$ nix run home-manager/master -- init --switch
|
||||||
```
|
```
|
||||||
|
|
||||||
For Nixpkgs or NixOS version 24.05 run
|
For Nixpkgs or NixOS version 24.11 run
|
||||||
|
|
||||||
``` shell
|
``` 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
|
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
|
$ 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
|
After the initial activation has completed successfully then building
|
||||||
and activating your flake-based configuration is as simple as
|
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
|
# You can update Home Manager without changing this value. See
|
||||||
# the Home Manager release notes for a list of state version
|
# the Home Manager release notes for a list of state version
|
||||||
# changes in each release.
|
# changes in each release.
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
# Let Home Manager install and manage itself.
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
@@ -65,7 +65,7 @@ follows:
|
|||||||
# You can update Home Manager without changing this value. See
|
# You can update Home Manager without changing this value. See
|
||||||
# the Home Manager release notes for a list of state version
|
# the Home Manager release notes for a list of state version
|
||||||
# changes in each release.
|
# changes in each release.
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
# Let Home Manager install and manage itself.
|
||||||
programs.home-manager.enable = true;
|
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.
|
and the current unstable version.
|
||||||
|
|
||||||
```{=include=} chapters
|
```{=include=} chapters
|
||||||
|
rl-2505.md
|
||||||
rl-2411.md
|
rl-2411.md
|
||||||
rl-2405.md
|
rl-2405.md
|
||||||
rl-2311.md
|
rl-2311.md
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Release 24.11 {#sec-release-24.11}
|
# Release 24.11 {#sec-release-24.11}
|
||||||
|
|
||||||
This is the current unstable branch and the information in this section
|
The 24.05 release branch became stable in November, 2024.
|
||||||
is therefore not final.
|
|
||||||
|
|
||||||
## Highlights {#sec-release-24.11-highlights}
|
## 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
|
changes are only active if the `home.stateVersion` option is set to
|
||||||
\"24.11\" or later.
|
\"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": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731139594,
|
"lastModified": 1733212471,
|
||||||
"narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=",
|
"narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2",
|
"rev": "55d15ad12a74eb7d4646254e13638ad0c4128776",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
14
format
14
format
@@ -23,23 +23,9 @@ for arg do
|
|||||||
esac
|
esac
|
||||||
done
|
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_root=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
git ls-files -z --cached --others --full-name -- "${files[@]}" |
|
git ls-files -z --cached --others --full-name -- "${files[@]}" |
|
||||||
grep -z '\.nix$' |
|
grep -z '\.nix$' |
|
||||||
grep -z -v "${exclude_args[@]}" |
|
|
||||||
sed -z "s|^|$git_root/|" |
|
sed -z "s|^|$git_root/|" |
|
||||||
xargs -0 nixfmt "${nixfmt_args[@]}"
|
xargs -0 nixfmt "${nixfmt_args[@]}"
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ function hasFlakeSupport() {
|
|||||||
| grep -q nix-command
|
| 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.
|
# Attempts to set the HOME_MANAGER_CONFIG global variable.
|
||||||
#
|
#
|
||||||
# If no configuration file can be found then this function will print
|
# 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
|
# Check FQDN, long, and short hostnames; long first to preserve
|
||||||
# pre-existing behaviour in case both happen to be defined.
|
# pre-existing behaviour in case both happen to be defined.
|
||||||
for n in "$USER@$(hostname -f)" "$USER@$(hostname)" "$USER@$(hostname -s)"; do
|
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"
|
name="$n"
|
||||||
if [[ -v VERBOSE ]]; then
|
if [[ -v VERBOSE ]]; then
|
||||||
echo "Using flake homeConfiguration for $name"
|
echo "Using flake homeConfiguration for $name"
|
||||||
@@ -210,7 +215,7 @@ function setFlakeAttribute() {
|
|||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$name\""
|
export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$(printf %s "$name" | jq -sRr @uri)\""
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,8 +354,8 @@ function doInit() {
|
|||||||
{
|
{
|
||||||
# Home Manager needs a bit of information about you and the paths it should
|
# Home Manager needs a bit of information about you and the paths it should
|
||||||
# manage.
|
# manage.
|
||||||
home.username = "$USER";
|
home.username = "$(escapeForNix "$USER")";
|
||||||
home.homeDirectory = "$HOME";
|
home.homeDirectory = "$(escapeForNix "$HOME")";
|
||||||
$xdgVars
|
$xdgVars
|
||||||
# This value determines the Home Manager release that your configuration is
|
# This value determines the Home Manager release that your configuration is
|
||||||
# compatible with. This helps avoid breakage when a new Home Manager release
|
# 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
|
# 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
|
# want to update the value, then make sure to first check the Home Manager
|
||||||
# release notes.
|
# 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
|
# The home.packages option allows you to install Nix packages into your
|
||||||
# environment.
|
# environment.
|
||||||
@@ -439,7 +444,7 @@ EOF
|
|||||||
mkdir -p "$confDir"
|
mkdir -p "$confDir"
|
||||||
cat > "$flakeFile" <<EOF
|
cat > "$flakeFile" <<EOF
|
||||||
{
|
{
|
||||||
description = "Home Manager configuration of $USER";
|
description = "Home Manager configuration of $(escapeForNix "$USER")";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
# Specify the source of Home Manager and Nixpkgs.
|
# Specify the source of Home Manager and Nixpkgs.
|
||||||
@@ -455,7 +460,7 @@ EOF
|
|||||||
system = "$nixSystem";
|
system = "$nixSystem";
|
||||||
pkgs = nixpkgs.legacyPackages.\${system};
|
pkgs = nixpkgs.legacyPackages.\${system};
|
||||||
in {
|
in {
|
||||||
homeConfigurations."$USER" = home-manager.lib.homeManagerConfiguration {
|
homeConfigurations."$(escapeForNix "$USER")" = home-manager.lib.homeManagerConfiguration {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
|
|
||||||
# Specify your home configuration modules here, for example,
|
# Specify your home configuration modules here, for example,
|
||||||
@@ -855,9 +860,9 @@ function doUninstall() {
|
|||||||
cat > "$HOME_MANAGER_CONFIG" <<EOF
|
cat > "$HOME_MANAGER_CONFIG" <<EOF
|
||||||
{
|
{
|
||||||
uninstall = true;
|
uninstall = true;
|
||||||
home.username = "$USER";
|
home.username = "$(escapeForNix "$USER")";
|
||||||
home.homeDirectory = "$HOME";
|
home.homeDirectory = "$(escapeForNix "$HOME")";
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
# shellcheck disable=2064
|
# shellcheck disable=2064
|
||||||
@@ -1044,7 +1049,7 @@ while [[ $# -gt 0 ]]; do
|
|||||||
export VERBOSE=1
|
export VERBOSE=1
|
||||||
;;
|
;;
|
||||||
--version)
|
--version)
|
||||||
echo 24.11-pre
|
echo 25.05-pre
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: Home Manager\n"
|
"Project-Id-Version: Home Manager\n"
|
||||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||||
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
||||||
"PO-Revision-Date: 2024-05-31 17:09+0000\n"
|
"PO-Revision-Date: 2024-12-03 13:00+0000\n"
|
||||||
"Last-Translator: jarre johansson <jarre@johansson.today>\n"
|
"Last-Translator: Ricky Tigg <ricky.tigg@gmail.com>\n"
|
||||||
"Language-Team: Finnish <https://hosted.weblate.org/projects/home-manager/cli/"
|
"Language-Team: Finnish <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||||
"fi/>\n"
|
"fi/>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\n"
|
||||||
@@ -17,7 +17,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\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"
|
#. translators: For example: "home-manager: missing argument for --cores"
|
||||||
#: home-manager/home-manager:16
|
#: home-manager/home-manager:16
|
||||||
@@ -26,7 +26,7 @@ msgstr "%s: puuttuva argumentti kohteelle %s"
|
|||||||
|
|
||||||
#: home-manager/home-manager:64
|
#: home-manager/home-manager:64
|
||||||
msgid "No configuration file found at %s"
|
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
|
#. translators: The first '%s' specifier will be replaced by either
|
||||||
#. 'home.nix' or 'flake.nix'.
|
#. 'home.nix' or 'flake.nix'.
|
||||||
@@ -36,10 +36,12 @@ msgid ""
|
|||||||
"Keeping your Home Manager %s in %s is deprecated,\n"
|
"Keeping your Home Manager %s in %s is deprecated,\n"
|
||||||
"please move it to %s"
|
"please move it to %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Home Managerin %s pitäminen %s:ssa on vanhentunut.\n"
|
||||||
|
"ole hyvä ja siirrä se %s:een"
|
||||||
|
|
||||||
#: home-manager/home-manager:92
|
#: home-manager/home-manager:92
|
||||||
msgid "No configuration file found. Please create one at %s"
|
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
|
#: home-manager/home-manager:107
|
||||||
msgid "Home Manager not found at %s."
|
msgid "Home Manager not found at %s."
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: Home Manager\n"
|
"Project-Id-Version: Home Manager\n"
|
||||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||||
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
||||||
"PO-Revision-Date: 2024-02-29 10:10+0000\n"
|
"PO-Revision-Date: 2024-11-18 15:00+0000\n"
|
||||||
"Last-Translator: FedFer98123 <fede.ferrari123@gmail.com>\n"
|
"Last-Translator: Lorenzo Bevilacqua <lorenzobevilacqua02@gmail.com>\n"
|
||||||
"Language-Team: Italian <https://hosted.weblate.org/projects/home-manager/cli/"
|
"Language-Team: Italian <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||||
"it/>\n"
|
"it/>\n"
|
||||||
"Language: it\n"
|
"Language: it\n"
|
||||||
@@ -17,12 +17,12 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\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"
|
#. translators: For example: "home-manager: missing argument for --cores"
|
||||||
#: home-manager/home-manager:16
|
#: home-manager/home-manager:16
|
||||||
msgid "%s: missing argument for %s"
|
msgid "%s: missing argument for %s"
|
||||||
msgstr ""
|
msgstr "%s: argomento mancante per %s"
|
||||||
|
|
||||||
#: home-manager/home-manager:64
|
#: home-manager/home-manager:64
|
||||||
msgid "No configuration file found at %s"
|
msgid "No configuration file found at %s"
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: Home Manager\n"
|
"Project-Id-Version: Home Manager\n"
|
||||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||||
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
||||||
"PO-Revision-Date: 2024-02-18 14:02+0000\n"
|
"PO-Revision-Date: 2024-11-18 15:00+0000\n"
|
||||||
"Last-Translator: Сергій <sergiy.goncharuk.1@gmail.com>\n"
|
"Last-Translator: wadsaek <wadsaek@gmail.com>\n"
|
||||||
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/home-manager/"
|
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/home-manager/"
|
||||||
"cli/uk/>\n"
|
"cli/uk/>\n"
|
||||||
"Language: uk\n"
|
"Language: uk\n"
|
||||||
@@ -18,12 +18,12 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
"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"
|
"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"
|
#. translators: For example: "home-manager: missing argument for --cores"
|
||||||
#: home-manager/home-manager:16
|
#: home-manager/home-manager:16
|
||||||
msgid "%s: missing argument for %s"
|
msgid "%s: missing argument for %s"
|
||||||
msgstr ""
|
msgstr "%s: відсутній аргумент для %s"
|
||||||
|
|
||||||
#: home-manager/home-manager:64
|
#: home-manager/home-manager:64
|
||||||
msgid "No configuration file found at %s"
|
msgid "No configuration file found at %s"
|
||||||
|
|||||||
@@ -45,6 +45,17 @@ let
|
|||||||
gtk config generation for {option}`home.pointerCursor`
|
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 {
|
(mkIf cfg.x11.enable {
|
||||||
xsession.initExtra = ''
|
xsession.profileExtra = ''
|
||||||
${pkgs.xorg.xsetroot}/bin/xsetroot -xcf ${cursorPath} ${
|
${pkgs.xorg.xsetroot}/bin/xsetroot -xcf ${cursorPath} ${
|
||||||
toString cfg.size
|
toString cfg.size
|
||||||
}
|
}
|
||||||
@@ -178,5 +189,13 @@ in {
|
|||||||
(mkIf cfg.gtk.enable {
|
(mkIf cfg.gtk.enable {
|
||||||
gtk.cursorTheme = mkDefault { inherit (cfg) package name size; };
|
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;
|
homeDirectory = config.home.homeDirectory;
|
||||||
|
|
||||||
fileType = (import lib/file-type.nix {
|
fileType =
|
||||||
inherit homeDirectory lib pkgs;
|
(import lib/file-type.nix { inherit homeDirectory lib pkgs; }).fileType;
|
||||||
}).fileType;
|
|
||||||
|
|
||||||
sourceStorePath = file:
|
sourceStorePath = file:
|
||||||
let
|
let
|
||||||
sourcePath = toString file.source;
|
sourcePath = toString file.source;
|
||||||
sourceName = config.lib.strings.storeFileName (baseNameOf sourcePath);
|
sourceName = config.lib.strings.storeFileName (baseNameOf sourcePath);
|
||||||
in
|
in if builtins.hasContext sourcePath then
|
||||||
if builtins.hasContext sourcePath
|
file.source
|
||||||
then file.source
|
else
|
||||||
else builtins.path { path = file.source; name = sourceName; };
|
builtins.path {
|
||||||
|
path = file.source;
|
||||||
|
name = sourceName;
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in {
|
||||||
|
|
||||||
{
|
|
||||||
options = {
|
options = {
|
||||||
home.file = mkOption {
|
home.file = mkOption {
|
||||||
description = "Attribute set of files to link into the user home.";
|
description = "Attribute set of files to link into the user home.";
|
||||||
default = {};
|
default = { };
|
||||||
type = fileType "home.file" "{env}`HOME`" homeDirectory;
|
type = fileType "home.file" "{env}`HOME`" homeDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,16 +39,14 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
assertions = [(
|
assertions = [
|
||||||
let
|
(let
|
||||||
dups =
|
dups = attrNames (filterAttrs (n: v: v > 1)
|
||||||
attrNames
|
(foldAttrs (acc: v: acc + v) 0
|
||||||
(filterAttrs (n: v: v > 1)
|
|
||||||
(foldAttrs (acc: v: acc + v) 0
|
|
||||||
(mapAttrsToList (n: v: { ${v.target} = 1; }) cfg)));
|
(mapAttrsToList (n: v: { ${v.target} = 1; }) cfg)));
|
||||||
dupsStr = concatStringsSep ", " dups;
|
dupsStr = concatStringsSep ", " dups;
|
||||||
in {
|
in {
|
||||||
assertion = dups == [];
|
assertion = dups == [ ];
|
||||||
message = ''
|
message = ''
|
||||||
Conflicting managed target files: ${dupsStr}
|
Conflicting managed target files: ${dupsStr}
|
||||||
|
|
||||||
@@ -65,19 +63,17 @@ in
|
|||||||
let
|
let
|
||||||
pathStr = toString path;
|
pathStr = toString path;
|
||||||
name = hm.strings.storeFileName (baseNameOf pathStr);
|
name = hm.strings.storeFileName (baseNameOf pathStr);
|
||||||
in
|
in pkgs.runCommandLocal name { } "ln -s ${escapeShellArg pathStr} $out";
|
||||||
pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out'';
|
|
||||||
|
|
||||||
# This verifies that the links we are about to create will not
|
# This verifies that the links we are about to create will not
|
||||||
# overwrite an existing file.
|
# overwrite an existing file.
|
||||||
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
|
home.activation.checkLinkTargets = hm.dag.entryBefore [ "writeBoundary" ]
|
||||||
let
|
(let
|
||||||
# Paths that should be forcibly overwritten by Home Manager.
|
# Paths that should be forcibly overwritten by Home Manager.
|
||||||
# Caveat emptor!
|
# Caveat emptor!
|
||||||
forcedPaths =
|
forcedPaths =
|
||||||
concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'')
|
concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'')
|
||||||
(mapAttrsToList (n: v: v.target)
|
(mapAttrsToList (n: v: v.target) (filterAttrs (n: v: v.force) cfg));
|
||||||
(filterAttrs (n: v: v.force) cfg));
|
|
||||||
|
|
||||||
storeDir = escapeShellArg builtins.storeDir;
|
storeDir = escapeShellArg builtins.storeDir;
|
||||||
|
|
||||||
@@ -87,8 +83,7 @@ in
|
|||||||
inherit (config.lib.bash) initHomeManagerLib;
|
inherit (config.lib.bash) initHomeManagerLib;
|
||||||
inherit forcedPaths storeDir;
|
inherit forcedPaths storeDir;
|
||||||
};
|
};
|
||||||
in
|
in ''
|
||||||
''
|
|
||||||
function checkNewGenCollision() {
|
function checkNewGenCollision() {
|
||||||
local newGenFiles
|
local newGenFiles
|
||||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
@@ -97,8 +92,7 @@ in
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkNewGenCollision || exit 1
|
checkNewGenCollision || exit 1
|
||||||
''
|
'');
|
||||||
);
|
|
||||||
|
|
||||||
# This activation script will
|
# This activation script will
|
||||||
#
|
#
|
||||||
@@ -121,129 +115,127 @@ in
|
|||||||
# and a failure during the intermediate state FA ∩ FB will not
|
# and a failure during the intermediate state FA ∩ FB will not
|
||||||
# result in lost links because this set of links are in both the
|
# result in lost links because this set of links are in both the
|
||||||
# source and target generation.
|
# source and target generation.
|
||||||
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
|
home.activation.linkGeneration = hm.dag.entryAfter [ "writeBoundary" ] (let
|
||||||
let
|
link = pkgs.writeShellScript "link" ''
|
||||||
link = pkgs.writeShellScript "link" ''
|
${config.lib.bash.initHomeManagerLib}
|
||||||
${config.lib.bash.initHomeManagerLib}
|
|
||||||
|
|
||||||
newGenFiles="$1"
|
newGenFiles="$1"
|
||||||
shift
|
shift
|
||||||
for sourcePath in "$@" ; do
|
for sourcePath in "$@" ; do
|
||||||
relativePath="''${sourcePath#$newGenFiles/}"
|
relativePath="''${sourcePath#$newGenFiles/}"
|
||||||
targetPath="$HOME/$relativePath"
|
targetPath="$HOME/$relativePath"
|
||||||
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||||
# The target exists, back it up
|
# The target exists, back it up
|
||||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||||
run mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
|
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"
|
|
||||||
fi
|
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"] (
|
cleanup = pkgs.writeShellScript "cleanup" ''
|
||||||
let
|
${config.lib.bash.initHomeManagerLib}
|
||||||
homeDirArg = escapeShellArg homeDirectory;
|
|
||||||
|
# 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 ''
|
in ''
|
||||||
function _cmp() {
|
function _cmp() {
|
||||||
if [[ -d $1 && -d $2 ]]; then
|
if [[ -d $1 && -d $2 ]]; then
|
||||||
@@ -261,14 +253,12 @@ in
|
|||||||
_cmp ${sourceArg} ${homeDirArg}/${targetArg} \
|
_cmp ${sourceArg} ${homeDirArg}/${targetArg} \
|
||||||
&& changedFiles[${targetArg}]=0 \
|
&& changedFiles[${targetArg}]=0 \
|
||||||
|| changedFiles[${targetArg}]=1
|
|| changedFiles[${targetArg}]=1
|
||||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
'') (filter (v: v.onChange != "") (attrValues cfg)) + ''
|
||||||
+ ''
|
unset -f _cmp
|
||||||
unset -f _cmp
|
'');
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
|
home.activation.onFilesChange = hm.dag.entryAfter [ "linkGeneration" ]
|
||||||
concatMapStrings (v: ''
|
(concatMapStrings (v: ''
|
||||||
if (( ''${changedFiles[${escapeShellArg v.target}]} == 1 )); then
|
if (( ''${changedFiles[${escapeShellArg v.target}]} == 1 )); then
|
||||||
if [[ -v DRY_RUN || -v VERBOSE ]]; then
|
if [[ -v DRY_RUN || -v VERBOSE ]]; then
|
||||||
echo "Running onChange hook for" ${escapeShellArg v.target}
|
echo "Running onChange hook for" ${escapeShellArg v.target}
|
||||||
@@ -277,90 +267,83 @@ in
|
|||||||
${v.onChange}
|
${v.onChange}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
'') (filter (v: v.onChange != "") (attrValues cfg)));
|
||||||
);
|
|
||||||
|
|
||||||
# Symlink directories and files that have the right execute bit.
|
# Symlink directories and files that have the right execute bit.
|
||||||
# Copy files that need their execute bit changed.
|
# Copy files that need their execute bit changed.
|
||||||
home-files = pkgs.runCommandLocal
|
home-files = pkgs.runCommandLocal "home-manager-files" {
|
||||||
"home-manager-files"
|
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
||||||
{
|
} (''
|
||||||
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
mkdir -p $out
|
||||||
}
|
|
||||||
(''
|
|
||||||
mkdir -p $out
|
|
||||||
|
|
||||||
# Needed in case /nix is a symbolic link.
|
# Needed in case /nix is a symbolic link.
|
||||||
realOut="$(realpath -m "$out")"
|
realOut="$(realpath -m "$out")"
|
||||||
|
|
||||||
function insertFile() {
|
function insertFile() {
|
||||||
local source="$1"
|
local source="$1"
|
||||||
local relTarget="$2"
|
local relTarget="$2"
|
||||||
local executable="$3"
|
local executable="$3"
|
||||||
local recursive="$4"
|
local recursive="$4"
|
||||||
|
|
||||||
# If the target already exists then we have a collision. Note, this
|
# If the target already exists then we have a collision. Note, this
|
||||||
# should not happen due to the assertion found in the 'files' module.
|
# should not happen due to the assertion found in the 'files' module.
|
||||||
# We therefore simply log the conflict and otherwise ignore it, mainly
|
# We therefore simply log the conflict and otherwise ignore it, mainly
|
||||||
# to make the `files-target-config` test work as expected.
|
# to make the `files-target-config` test work as expected.
|
||||||
if [[ -e "$realOut/$relTarget" ]]; then
|
if [[ -e "$realOut/$relTarget" ]]; then
|
||||||
echo "File conflict for file '$relTarget'" >&2
|
echo "File conflict for file '$relTarget'" >&2
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Figure out the real absolute path to the target.
|
# Figure out the real absolute path to the target.
|
||||||
local target
|
local target
|
||||||
target="$(realpath -m "$realOut/$relTarget")"
|
target="$(realpath -m "$realOut/$relTarget")"
|
||||||
|
|
||||||
# Target path must be within $HOME.
|
# Target path must be within $HOME.
|
||||||
if [[ ! $target == $realOut* ]] ; then
|
if [[ ! $target == $realOut* ]] ; then
|
||||||
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$(dirname "$target")"
|
mkdir -p "$(dirname "$target")"
|
||||||
if [[ -d $source ]]; then
|
if [[ -d $source ]]; then
|
||||||
if [[ $recursive ]]; then
|
if [[ $recursive ]]; then
|
||||||
mkdir -p "$target"
|
mkdir -p "$target"
|
||||||
lndir -silent "$source" "$target"
|
lndir -silent "$source" "$target"
|
||||||
else
|
|
||||||
ln -s "$source" "$target"
|
|
||||||
fi
|
|
||||||
else
|
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,
|
# Link the file into the home file directory if possible,
|
||||||
# i.e., if the executable bit of the source is the same we
|
# i.e., if the executable bit of the source is the same we
|
||||||
# expect for the target. Otherwise, we copy the file and
|
# expect for the target. Otherwise, we copy the file and
|
||||||
# set the executable bit to the expected value.
|
# set the executable bit to the expected value.
|
||||||
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||||
ln -s "$source" "$target"
|
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
|
else
|
||||||
cp "$source" "$target"
|
chmod -x "$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
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
fi
|
||||||
'' + concatStrings (
|
}
|
||||||
mapAttrsToList (n: v: ''
|
'' + concatStrings (mapAttrsToList (n: v: ''
|
||||||
insertFile ${
|
insertFile ${
|
||||||
escapeShellArgs [
|
escapeShellArgs [
|
||||||
(sourceStorePath v)
|
(sourceStorePath v)
|
||||||
v.target
|
v.target
|
||||||
(if v.executable == null
|
(if v.executable == null then "inherit" else toString v.executable)
|
||||||
then "inherit"
|
(toString v.recursive)
|
||||||
else toString v.executable)
|
]
|
||||||
(toString v.recursive)
|
}
|
||||||
]}
|
'') cfg));
|
||||||
'') cfg
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,10 +113,10 @@ let
|
|||||||
options = {
|
options = {
|
||||||
layout = mkOption {
|
layout = mkOption {
|
||||||
type = with types; nullOr str;
|
type = with types; nullOr str;
|
||||||
default =
|
default = if versionAtLeast config.home.stateVersion "19.09" then
|
||||||
if versionAtLeast config.home.stateVersion "19.09"
|
null
|
||||||
then null
|
else
|
||||||
else "us";
|
"us";
|
||||||
defaultText = literalExpression "null";
|
defaultText = literalExpression "null";
|
||||||
description = ''
|
description = ''
|
||||||
Keyboard layout. If `null`, then the system
|
Keyboard layout. If `null`, then the system
|
||||||
@@ -138,8 +138,8 @@ let
|
|||||||
|
|
||||||
options = mkOption {
|
options = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [];
|
default = [ ];
|
||||||
example = ["grp:caps_toggle" "grp_led:scroll"];
|
example = [ "grp:caps_toggle" "grp_led:scroll" ];
|
||||||
description = ''
|
description = ''
|
||||||
X keyboard options; layout switching goes here.
|
X keyboard options; layout switching goes here.
|
||||||
'';
|
'';
|
||||||
@@ -148,9 +148,7 @@ let
|
|||||||
variant = mkOption {
|
variant = mkOption {
|
||||||
type = with types; nullOr str;
|
type = with types; nullOr str;
|
||||||
default =
|
default =
|
||||||
if versionAtLeast config.home.stateVersion "19.09"
|
if versionAtLeast config.home.stateVersion "19.09" then null else "";
|
||||||
then null
|
|
||||||
else "";
|
|
||||||
defaultText = literalExpression "null";
|
defaultText = literalExpression "null";
|
||||||
example = "colemak";
|
example = "colemak";
|
||||||
description = ''
|
description = ''
|
||||||
@@ -164,9 +162,7 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in {
|
||||||
|
|
||||||
{
|
|
||||||
meta.maintainers = [ maintainers.rycee ];
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
@@ -217,7 +213,7 @@ in
|
|||||||
|
|
||||||
home.language = mkOption {
|
home.language = mkOption {
|
||||||
type = languageSubModule;
|
type = languageSubModule;
|
||||||
default = {};
|
default = { };
|
||||||
description = "Language configuration.";
|
description = "Language configuration.";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -255,9 +251,12 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
home.sessionVariables = mkOption {
|
home.sessionVariables = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
type = with types; lazyAttrsOf (oneOf [ str path int float ]);
|
type = with types; lazyAttrsOf (oneOf [ str path int float ]);
|
||||||
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
example = {
|
||||||
|
EDITOR = "emacs";
|
||||||
|
GS_OPTIONS = "-sPAPERSIZE=a4";
|
||||||
|
};
|
||||||
description = ''
|
description = ''
|
||||||
Environment variables to always set at login.
|
Environment variables to always set at login.
|
||||||
|
|
||||||
@@ -332,13 +331,13 @@ in
|
|||||||
|
|
||||||
home.packages = mkOption {
|
home.packages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [];
|
default = [ ];
|
||||||
description = "The set of packages to appear in the user environment.";
|
description = "The set of packages to appear in the user environment.";
|
||||||
};
|
};
|
||||||
|
|
||||||
home.extraOutputsToInstall = mkOption {
|
home.extraOutputsToInstall = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [];
|
default = [ ];
|
||||||
example = [ "doc" "info" "devdoc" ];
|
example = [ "doc" "info" "devdoc" ];
|
||||||
description = ''
|
description = ''
|
||||||
List of additional package outputs of the packages
|
List of additional package outputs of the packages
|
||||||
@@ -371,7 +370,7 @@ in
|
|||||||
|
|
||||||
home.activation = mkOption {
|
home.activation = mkOption {
|
||||||
type = hm.types.dagOf types.str;
|
type = hm.types.dagOf types.str;
|
||||||
default = {};
|
default = { };
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||||
@@ -494,77 +493,60 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
warnings =
|
warnings = let
|
||||||
let
|
hmRelease = config.home.version.release;
|
||||||
hmRelease = config.home.version.release;
|
nixpkgsRelease = lib.trivial.release;
|
||||||
nixpkgsRelease = lib.trivial.release;
|
releaseMismatch = config.home.enableNixpkgsReleaseCheck && hmRelease
|
||||||
releaseMismatch =
|
!= nixpkgsRelease;
|
||||||
config.home.enableNixpkgsReleaseCheck
|
in optional releaseMismatch ''
|
||||||
&& hmRelease != nixpkgsRelease;
|
You are using
|
||||||
in
|
|
||||||
optional releaseMismatch ''
|
|
||||||
You are using
|
|
||||||
|
|
||||||
Home Manager version ${hmRelease} and
|
Home Manager version ${hmRelease} and
|
||||||
Nixpkgs version ${nixpkgsRelease}.
|
Nixpkgs version ${nixpkgsRelease}.
|
||||||
|
|
||||||
Using mismatched versions is likely to cause errors and unexpected
|
Using mismatched versions is likely to cause errors and unexpected
|
||||||
behavior. It is therefore highly recommended to use a release of Home
|
behavior. It is therefore highly recommended to use a release of Home
|
||||||
Manager that corresponds with your chosen release of Nixpkgs.
|
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 =
|
home.username = mkIf (versionOlder config.home.stateVersion "20.09")
|
||||||
mkIf (versionOlder config.home.stateVersion "20.09")
|
(mkDefault (builtins.getEnv "USER"));
|
||||||
(mkDefault (builtins.getEnv "USER"));
|
home.homeDirectory = mkIf (versionOlder config.home.stateVersion "20.09")
|
||||||
home.homeDirectory =
|
(mkDefault (builtins.getEnv "HOME"));
|
||||||
mkIf (versionOlder config.home.stateVersion "20.09")
|
|
||||||
(mkDefault (builtins.getEnv "HOME"));
|
|
||||||
|
|
||||||
home.profileDirectory =
|
home.profileDirectory = if config.submoduleSupport.enable
|
||||||
if config.submoduleSupport.enable
|
&& config.submoduleSupport.externalPackageInstall then
|
||||||
&& config.submoduleSupport.externalPackageInstall
|
"/etc/profiles/per-user/${cfg.username}"
|
||||||
then "/etc/profiles/per-user/${cfg.username}"
|
else if config.nix.enable
|
||||||
else if config.nix.enable && (config.nix.settings.use-xdg-base-directories or false)
|
&& (config.nix.settings.use-xdg-base-directories or false) then
|
||||||
then "${config.xdg.stateHome}/nix/profile"
|
"${config.xdg.stateHome}/nix/profile"
|
||||||
else cfg.homeDirectory + "/.nix-profile";
|
else
|
||||||
|
cfg.homeDirectory + "/.nix-profile";
|
||||||
|
|
||||||
programs.bash.shellAliases = cfg.shellAliases;
|
programs.bash.shellAliases = cfg.shellAliases;
|
||||||
programs.zsh.shellAliases = cfg.shellAliases;
|
programs.zsh.shellAliases = cfg.shellAliases;
|
||||||
programs.fish.shellAliases = cfg.shellAliases;
|
programs.fish.shellAliases = cfg.shellAliases;
|
||||||
|
|
||||||
home.sessionVariables =
|
home.sessionVariables =
|
||||||
let
|
let maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
||||||
maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
in (maybeSet "LANG" cfg.language.base)
|
||||||
in
|
// (maybeSet "LC_CTYPE" cfg.language.ctype)
|
||||||
(maybeSet "LANG" cfg.language.base)
|
// (maybeSet "LC_NUMERIC" cfg.language.numeric)
|
||||||
//
|
// (maybeSet "LC_TIME" cfg.language.time)
|
||||||
(maybeSet "LC_CTYPE" cfg.language.ctype)
|
// (maybeSet "LC_COLLATE" cfg.language.collate)
|
||||||
//
|
// (maybeSet "LC_MONETARY" cfg.language.monetary)
|
||||||
(maybeSet "LC_NUMERIC" cfg.language.numeric)
|
// (maybeSet "LC_MESSAGES" cfg.language.messages)
|
||||||
//
|
// (maybeSet "LC_PAPER" cfg.language.paper)
|
||||||
(maybeSet "LC_TIME" cfg.language.time)
|
// (maybeSet "LC_NAME" cfg.language.name)
|
||||||
//
|
// (maybeSet "LC_ADDRESS" cfg.language.address)
|
||||||
(maybeSet "LC_COLLATE" cfg.language.collate)
|
// (maybeSet "LC_TELEPHONE" cfg.language.telephone)
|
||||||
//
|
// (maybeSet "LC_MEASUREMENT" cfg.language.measurement);
|
||||||
(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.
|
# Provide a file holding all session variables.
|
||||||
home.sessionVariablesPackage = pkgs.writeTextFile {
|
home.sessionVariablesPackage = pkgs.writeTextFile {
|
||||||
@@ -602,148 +584,129 @@ in
|
|||||||
# In case the user has moved from a user-install of Home Manager
|
# In case the user has moved from a user-install of Home Manager
|
||||||
# to a submodule managed one we attempt to uninstall the
|
# to a submodule managed one we attempt to uninstall the
|
||||||
# `home-manager-path` package if it is installed.
|
# `home-manager-path` package if it is installed.
|
||||||
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
|
home.activation.installPackages = hm.dag.entryAfter [ "writeBoundary" ]
|
||||||
if config.submoduleSupport.externalPackageInstall
|
(if config.submoduleSupport.externalPackageInstall then ''
|
||||||
then
|
nixProfileRemove home-manager-path
|
||||||
''
|
'' else ''
|
||||||
nixProfileRemove home-manager-path
|
function nixReplaceProfile() {
|
||||||
''
|
local oldNix="$(command -v nix)"
|
||||||
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
|
if [[ -e ${cfg.profileDirectory}/manifest.json ]] ; then
|
||||||
INSTALL_CMD="nix profile install"
|
INSTALL_CMD="nix profile install"
|
||||||
INSTALL_CMD_ACTUAL="nixReplaceProfile"
|
INSTALL_CMD_ACTUAL="nixReplaceProfile"
|
||||||
LIST_CMD="nix profile list"
|
LIST_CMD="nix profile list"
|
||||||
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
|
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
|
||||||
else
|
else
|
||||||
INSTALL_CMD="nix-env -i"
|
INSTALL_CMD="nix-env -i"
|
||||||
INSTALL_CMD_ACTUAL="run nix-env -i"
|
INSTALL_CMD_ACTUAL="run nix-env -i"
|
||||||
LIST_CMD="nix-env -q"
|
LIST_CMD="nix-env -q"
|
||||||
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
|
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $INSTALL_CMD_ACTUAL ${cfg.path} ; then
|
if ! $INSTALL_CMD_ACTUAL ${cfg.path} ; then
|
||||||
echo
|
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"
|
_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
|
exit 1
|
||||||
fi
|
fi
|
||||||
unset -f nixReplaceProfile
|
unset -f nixReplaceProfile
|
||||||
unset INSTALL_CMD INSTALL_CMD_ACTUAL LIST_CMD REMOVE_CMD_SYNTAX
|
unset INSTALL_CMD INSTALL_CMD_ACTUAL LIST_CMD REMOVE_CMD_SYNTAX
|
||||||
''
|
'');
|
||||||
);
|
|
||||||
|
|
||||||
# Text containing Bash commands that will initialize the Home Manager Bash
|
# Text containing Bash commands that will initialize the Home Manager Bash
|
||||||
# library. Most importantly, this will prepare for using translated strings
|
# library. Most importantly, this will prepare for using translated strings
|
||||||
# in the `hm-modules` text domain.
|
# in the `hm-modules` text domain.
|
||||||
lib.bash.initHomeManagerLib =
|
lib.bash.initHomeManagerLib = let
|
||||||
let
|
domainDir = pkgs.runCommand "hm-modules-messages" {
|
||||||
domainDir = pkgs.runCommand "hm-modules-messages" {
|
nativeBuildInputs = [ pkgs.buildPackages.gettext ];
|
||||||
nativeBuildInputs = [ pkgs.buildPackages.gettext ];
|
} ''
|
||||||
} ''
|
for path in ${./po}/*.po; do
|
||||||
for path in ${./po}/*.po; do
|
lang="''${path##*/}"
|
||||||
lang="''${path##*/}"
|
lang="''${lang%%.*}"
|
||||||
lang="''${lang%%.*}"
|
mkdir -p "$out/$lang/LC_MESSAGES"
|
||||||
mkdir -p "$out/$lang/LC_MESSAGES"
|
msgfmt -o "$out/$lang/LC_MESSAGES/hm-modules.mo" "$path"
|
||||||
msgfmt -o "$out/$lang/LC_MESSAGES/hm-modules.mo" "$path"
|
done
|
||||||
done
|
'';
|
||||||
'';
|
in ''
|
||||||
in
|
export TEXTDOMAIN=hm-modules
|
||||||
''
|
export TEXTDOMAINDIR=${domainDir}
|
||||||
export TEXTDOMAIN=hm-modules
|
source ${../lib/bash/home-manager.sh}
|
||||||
export TEXTDOMAINDIR=${domainDir}
|
'';
|
||||||
source ${../lib/bash/home-manager.sh}
|
|
||||||
'';
|
|
||||||
|
|
||||||
home.activationPackage =
|
home.activationPackage = let
|
||||||
let
|
mkCmd = res: ''
|
||||||
mkCmd = res: ''
|
_iNote "Activating %s" "${res.name}"
|
||||||
_iNote "Activating %s" "${res.name}"
|
${res.data}
|
||||||
${res.data}
|
'';
|
||||||
'';
|
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||||
sortedCommands = hm.dag.topoSort cfg.activation;
|
activationCmds = if sortedCommands ? result then
|
||||||
activationCmds =
|
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||||
if sortedCommands ? result then
|
else
|
||||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
abort ("Dependency cycle in activation script: "
|
||||||
else
|
+ builtins.toJSON sortedCommands);
|
||||||
abort ("Dependency cycle in activation script: "
|
|
||||||
+ builtins.toJSON sortedCommands);
|
|
||||||
|
|
||||||
# Programs that always should be available on the activation
|
# Programs that always should be available on the activation
|
||||||
# script's PATH.
|
# script's PATH.
|
||||||
activationBinPaths = lib.makeBinPath (
|
activationBinPaths = lib.makeBinPath (with pkgs;
|
||||||
with pkgs; [
|
[
|
||||||
bash
|
bash
|
||||||
coreutils
|
coreutils
|
||||||
diffutils # For `cmp` and `diff`.
|
diffutils # For `cmp` and `diff`.
|
||||||
findutils
|
findutils
|
||||||
gettext
|
gettext
|
||||||
gnugrep
|
gnugrep
|
||||||
gnused
|
gnused
|
||||||
jq
|
jq
|
||||||
ncurses # For `tput`.
|
ncurses # For `tput`.
|
||||||
]
|
] ++ config.home.extraActivationPath) + (
|
||||||
++ config.home.extraActivationPath
|
|
||||||
)
|
|
||||||
+ (
|
|
||||||
# Add path of the Nix binaries, if a Nix package is configured, then
|
# 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.
|
# use that one, otherwise grab the path of the nix-env tool.
|
||||||
if config.nix.enable && config.nix.package != null then
|
if config.nix.enable && config.nix.package != null then
|
||||||
":${config.nix.package}/bin"
|
":${config.nix.package}/bin"
|
||||||
else
|
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";
|
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||||
|
|
||||||
activationScript = pkgs.writeShellScript "activation-script" ''
|
activationScript = pkgs.writeShellScript "activation-script" ''
|
||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
cd $HOME
|
cd $HOME
|
||||||
|
|
||||||
export PATH="${activationBinPaths}"
|
export PATH="${activationBinPaths}"
|
||||||
${config.lib.bash.initHomeManagerLib}
|
${config.lib.bash.initHomeManagerLib}
|
||||||
|
|
||||||
${builtins.readFile ./lib-bash/activation-init.sh}
|
${builtins.readFile ./lib-bash/activation-init.sh}
|
||||||
|
|
||||||
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
|
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
|
||||||
checkUsername ${escapeShellArg config.home.username}
|
checkUsername ${escapeShellArg config.home.username}
|
||||||
checkHomeDirectory ${escapeShellArg config.home.homeDirectory}
|
checkHomeDirectory ${escapeShellArg config.home.homeDirectory}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${activationCmds}
|
${activationCmds}
|
||||||
'';
|
'';
|
||||||
in
|
in pkgs.runCommand "home-manager-generation" { preferLocalBuild = true; } ''
|
||||||
pkgs.runCommand
|
mkdir -p $out
|
||||||
"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
|
mkdir $out/bin
|
||||||
ln -s $out/activate $out/bin/home-manager-generation
|
ln -s $out/activate $out/bin/home-manager-generation
|
||||||
|
|
||||||
substituteInPlace $out/activate \
|
substituteInPlace $out/activate \
|
||||||
--subst-var-by GENERATION_DIR $out
|
--subst-var-by GENERATION_DIR $out
|
||||||
|
|
||||||
ln -s ${config.home-files} $out/home-files
|
ln -s ${config.home-files} $out/home-files
|
||||||
ln -s ${cfg.path} $out/home-path
|
ln -s ${cfg.path} $out/home-path
|
||||||
|
|
||||||
${cfg.extraBuilderCommands}
|
${cfg.extraBuilderCommands}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
home.path = pkgs.buildEnv {
|
home.path = pkgs.buildEnv {
|
||||||
name = "home-manager-path";
|
name = "home-manager-path";
|
||||||
|
|||||||
@@ -1827,6 +1827,78 @@ in {
|
|||||||
as systemd services.
|
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 ];
|
gnome = [ qgnomeplatform qgnomeplatform-qt6 ];
|
||||||
adwaita = [ qadwaitadecorations qadwaitadecorations-qt6 ];
|
adwaita = [ qadwaitadecorations qadwaitadecorations-qt6 ];
|
||||||
gtk = [ libsForQt5.qtstyleplugins qt6Packages.qt6gtk2 ];
|
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 ];
|
lxqt = [ lxqt.lxqt-qtplugin lxqt.lxqt-config ];
|
||||||
qtct = [ libsForQt5.qt5ct qt6Packages.qt6ct ];
|
qtct = [ libsForQt5.qt5ct qt6Packages.qt6ct ];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ in {
|
|||||||
powermanagementprofilesrc.AC.HandleButtonEvents.lidAction = 32;
|
powermanagementprofilesrc.AC.HandleButtonEvents.lidAction = 32;
|
||||||
};
|
};
|
||||||
description = ''
|
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
|
The example value would cause the following command to run in the
|
||||||
activation script:
|
activation script:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
kwriteconfig5 --file $XDG_CONFIG_HOME/powermanagementprofilesrc \
|
kwriteconfig6 --file $XDG_CONFIG_HOME/powermanagementprofilesrc \
|
||||||
--group AC \
|
--group AC \
|
||||||
--group HandleButtonEvents \
|
--group HandleButtonEvents \
|
||||||
--group lidAction \
|
--group lidAction \
|
||||||
@@ -53,7 +53,7 @@ in {
|
|||||||
lib.mapAttrsToList
|
lib.mapAttrsToList
|
||||||
(group: value: toLine file (path ++ [ group ]) value) value
|
(group: value: toLine file (path ++ [ group ]) value) value
|
||||||
else
|
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.concatMapStringsSep " " (x: "--group ${x}")
|
||||||
(lib.lists.init path)
|
(lib.lists.init path)
|
||||||
} --key '${lib.lists.last path}' ${toValue value}";
|
} --key '${lib.lists.last path}' ${toValue value}";
|
||||||
@@ -62,7 +62,7 @@ in {
|
|||||||
in builtins.concatStringsSep "\n" lines}
|
in builtins.concatStringsSep "\n" lines}
|
||||||
|
|
||||||
# TODO: some way to only call the dbus calls needed
|
# 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
|
# the actual values are https://github.com/KDE/plasma-workspace/blob/c97dddf20df5702eb429b37a8c10b2c2d8199d4e/kcms/kcms-common_p.h#L13
|
||||||
for changeType in {0..10}; do
|
for changeType in {0..10}; do
|
||||||
# even if one of those calls fails the others keep running
|
# even if one of those calls fails the others keep running
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ in {
|
|||||||
config = mkIf config.uninstall {
|
config = mkIf config.uninstall {
|
||||||
home.packages = lib.mkForce [ ];
|
home.packages = lib.mkForce [ ];
|
||||||
home.file = lib.mkForce { };
|
home.file = lib.mkForce { };
|
||||||
home.stateVersion = lib.mkForce "24.05";
|
home.stateVersion = lib.mkForce "24.11";
|
||||||
home.enableNixpkgsReleaseCheck = lib.mkForce false;
|
home.enableNixpkgsReleaseCheck = lib.mkForce false;
|
||||||
manual.manpages.enable = lib.mkForce false;
|
manual.manpages.enable = lib.mkForce false;
|
||||||
news.display = lib.mkForce "silent";
|
news.display = lib.mkForce "silent";
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ let
|
|||||||
./programs/khard.nix
|
./programs/khard.nix
|
||||||
./programs/kitty.nix
|
./programs/kitty.nix
|
||||||
./programs/kodi.nix
|
./programs/kodi.nix
|
||||||
|
./programs/kubecolor.nix
|
||||||
./programs/lazygit.nix
|
./programs/lazygit.nix
|
||||||
./programs/ledger.nix
|
./programs/ledger.nix
|
||||||
./programs/less.nix
|
./programs/less.nix
|
||||||
@@ -176,6 +177,7 @@ let
|
|||||||
./programs/nh.nix
|
./programs/nh.nix
|
||||||
./programs/nheko.nix
|
./programs/nheko.nix
|
||||||
./programs/nix-index.nix
|
./programs/nix-index.nix
|
||||||
|
./programs/nix-your-shell.nix
|
||||||
./programs/nnn.nix
|
./programs/nnn.nix
|
||||||
./programs/noti.nix
|
./programs/noti.nix
|
||||||
./programs/notmuch.nix
|
./programs/notmuch.nix
|
||||||
|
|||||||
@@ -27,9 +27,6 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
assertions =
|
|
||||||
[ (hm.assertions.assertPlatform "programs.abook" pkgs platforms.linux) ];
|
|
||||||
|
|
||||||
home.packages = [ pkgs.abook ];
|
home.packages = [ pkgs.abook ];
|
||||||
|
|
||||||
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "alot" { };
|
||||||
|
|
||||||
hooks = mkOption {
|
hooks = mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
default = "";
|
default = "";
|
||||||
@@ -229,7 +231,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.packages = [ pkgs.alot ];
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
xdg.configFile."alot/config".text = configFile;
|
xdg.configFile."alot/config".text = configFile;
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ with lib;
|
|||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.programs.atuin;
|
cfg = config.programs.atuin;
|
||||||
|
daemonCfg = cfg.daemon;
|
||||||
|
|
||||||
tomlFormat = pkgs.formats.toml { };
|
tomlFormat = pkgs.formats.toml { };
|
||||||
|
|
||||||
|
inherit (pkgs.stdenv) isLinux isDarwin;
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ maintainers.hawkw ];
|
meta.maintainers = [ maintainers.hawkw maintainers.water-sucks ];
|
||||||
|
|
||||||
options.programs.atuin = {
|
options.programs.atuin = {
|
||||||
enable = mkEnableOption "atuin";
|
enable = mkEnableOption "atuin";
|
||||||
@@ -94,49 +96,137 @@ in {
|
|||||||
Whether to enable Nushell integration.
|
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;
|
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.
|
# If there are user-provided settings, generate the config file.
|
||||||
home.packages = [ cfg.package ];
|
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.
|
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||||
xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) {
|
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||||
source = tomlFormat.generate "atuin-config" cfg.settings;
|
source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
|
||||||
};
|
eval "$(${lib.getExe cfg.package} init bash ${flagsStr})"
|
||||||
|
fi
|
||||||
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
|
|
||||||
'';
|
'';
|
||||||
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
|
{ modulePath, name, description ? null, wrappedPackageName ? null
|
||||||
, unwrappedPackageName ? null, platforms, visible ? false }:
|
, unwrappedPackageName ? null, platforms, visible ? false
|
||||||
|
, enableBookmarks ? true }:
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
@@ -435,6 +436,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bookmarks = mkOption {
|
bookmarks = mkOption {
|
||||||
|
internal = !enableBookmarks;
|
||||||
type = let
|
type = let
|
||||||
bookmarkSubmodule = types.submodule ({ config, name, ... }: {
|
bookmarkSubmodule = types.submodule ({ config, name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ let
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
example = "pkgs.gnome.gnome-shell-extensions";
|
example = "pkgs.gnome-shell-extensions";
|
||||||
description = ''
|
description = ''
|
||||||
Package providing a GNOME Shell extension in
|
Package providing a GNOME Shell extension in
|
||||||
`$out/share/gnome-shell/extensions/''${id}`.
|
`$out/share/gnome-shell/extensions/''${id}`.
|
||||||
@@ -66,7 +66,7 @@ in {
|
|||||||
{ package = pkgs.gnomeExtensions.dash-to-panel; }
|
{ package = pkgs.gnomeExtensions.dash-to-panel; }
|
||||||
{
|
{
|
||||||
id = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
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 = [{
|
programs.gnome-shell.extensions = [{
|
||||||
id = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
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 ];
|
home.packages = [ cfg.theme.package ];
|
||||||
|
|||||||
@@ -658,12 +658,30 @@ in {
|
|||||||
{command}`nix-env -f '<nixpkgs>' -qaP -A kakounePlugins`.
|
{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 {
|
config = mkIf cfg.enable {
|
||||||
home.packages = [ kakouneWithPlugins ];
|
home.packages = [ kakouneWithPlugins ];
|
||||||
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; };
|
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)}
|
'') prefs)}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
modulePath = [ "programs" "librewolf" ];
|
||||||
|
|
||||||
|
mkFirefoxModule = import ./firefox/mkFirefoxModule.nix;
|
||||||
|
|
||||||
in {
|
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 = {
|
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 {
|
settings = mkOption {
|
||||||
type = with types; attrsOf (either bool (either int str));
|
type = with types; attrsOf (either bool (either int str));
|
||||||
default = { };
|
default = { };
|
||||||
@@ -38,7 +53,7 @@ in {
|
|||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
description = ''
|
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/>
|
<https://librewolf.net/docs/settings/>
|
||||||
for details on supported values.
|
for details on supported values.
|
||||||
'';
|
'';
|
||||||
@@ -51,9 +66,7 @@ in {
|
|||||||
lib.platforms.linux)
|
lib.platforms.linux)
|
||||||
];
|
];
|
||||||
|
|
||||||
home.packages = [ cfg.package ];
|
home.file.".librewolf/librewolf.overrides.cfg" =
|
||||||
|
lib.mkIf (cfg.settings != { }) { text = mkOverridesFile cfg.settings; };
|
||||||
home.file.".librewolf/librewolf.overrides.cfg".text =
|
|
||||||
mkOverridesFile cfg.settings;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ in {
|
|||||||
{
|
{
|
||||||
mpv = {
|
mpv = {
|
||||||
no_display = true;
|
no_display = true;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
description = ''
|
description = ''
|
||||||
|
|||||||
@@ -225,6 +225,8 @@ in {
|
|||||||
default = { };
|
default = { };
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
|
TLSType = "IMAP";
|
||||||
|
TLSVersions = [ "+1.3" "+1.2" "-1.1" ];
|
||||||
PipelineDepth = 10;
|
PipelineDepth = 10;
|
||||||
Timeout = 60;
|
Timeout = 60;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ let
|
|||||||
|
|
||||||
genTlsConfig = tls:
|
genTlsConfig = tls:
|
||||||
{
|
{
|
||||||
SSLType = if !tls.enable then
|
TLSType = if !tls.enable then
|
||||||
"None"
|
"None"
|
||||||
else if tls.useStartTls then
|
else if tls.useStartTls then
|
||||||
"STARTTLS"
|
"STARTTLS"
|
||||||
@@ -267,7 +267,7 @@ in {
|
|||||||
|
|
||||||
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
|
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
|
||||||
|
|
||||||
home.file.".mbsyncrc".text = let
|
xdg.configFile."isyncrc".text = let
|
||||||
accountsConfig = map genAccountConfig mbsyncAccounts;
|
accountsConfig = map genAccountConfig mbsyncAccounts;
|
||||||
# Only generate this kind of Group configuration if there are ANY accounts
|
# Only generate this kind of Group configuration if there are ANY accounts
|
||||||
# that do NOT have a per-account groups/channels option(s) specified.
|
# 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 {
|
in {
|
||||||
meta.maintainers = [ maintainers.Philipp-M maintainers.joaquintrinanes ];
|
meta.maintainers =
|
||||||
|
[ maintainers.Philipp-M maintainers.joaquintrinanes maintainers.aidalgol ];
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
(mkRemovedOptionModule [ "programs" "nushell" "settings" ] ''
|
(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 {
|
shellAliases = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = { };
|
default = { };
|
||||||
@@ -203,6 +213,20 @@ in {
|
|||||||
cfg.extraLogin
|
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";
|
starshipCmd = "${config.home.profileDirectory}/bin/starship";
|
||||||
|
|
||||||
|
initFish =
|
||||||
|
if cfg.enableInteractive then "interactiveShellInit" else "shellInitLast";
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ ];
|
meta.maintainers = [ ];
|
||||||
|
|
||||||
@@ -71,6 +73,17 @@ in {
|
|||||||
default = true;
|
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 {
|
enableTransience = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
@@ -104,9 +117,9 @@ in {
|
|||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
programs.fish.${initFish} = mkIf cfg.enableFishIntegration ''
|
||||||
if test "$TERM" != "dumb"
|
if test "$TERM" != "dumb"
|
||||||
eval (${starshipCmd} init fish)
|
${starshipCmd} init fish | source
|
||||||
${lib.optionalString cfg.enableTransience "enable_transience"}
|
${lib.optionalString cfg.enableTransience "enable_transience"}
|
||||||
end
|
end
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ let
|
|||||||
"mail.identity.id_${id}.openpgp_key_id" = account.gpg.key;
|
"mail.identity.id_${id}.openpgp_key_id" = account.gpg.key;
|
||||||
"mail.identity.id_${id}.protectSubject" = true;
|
"mail.identity.id_${id}.protectSubject" = true;
|
||||||
"mail.identity.id_${id}.sign_mail" = account.gpg.signByDefault;
|
"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;
|
} // account.thunderbird.perIdentitySettings id;
|
||||||
|
|
||||||
toThunderbirdAccount = account: profile:
|
toThunderbirdAccount = account: profile:
|
||||||
@@ -103,7 +105,6 @@ let
|
|||||||
"mail.server.server_${id}.type" = "imap";
|
"mail.server.server_${id}.type" = "imap";
|
||||||
"mail.server.server_${id}.userName" = account.userName;
|
"mail.server.server_${id}.userName" = account.userName;
|
||||||
} // optionalAttrs (account.smtp != null) {
|
} // optionalAttrs (account.smtp != null) {
|
||||||
"mail.identity.id_${id}.smtpServer" = "smtp_${id}";
|
|
||||||
"mail.smtpserver.smtp_${id}.authMethod" = 3;
|
"mail.smtpserver.smtp_${id}.authMethod" = 3;
|
||||||
"mail.smtpserver.smtp_${id}.hostname" = account.smtp.host;
|
"mail.smtpserver.smtp_${id}.hostname" = account.smtp.host;
|
||||||
"mail.smtpserver.smtp_${id}.port" =
|
"mail.smtpserver.smtp_${id}.port" =
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ let
|
|||||||
''}
|
''}
|
||||||
|
|
||||||
set -g mouse ${boolToStr cfg.mouse}
|
set -g mouse ${boolToStr cfg.mouse}
|
||||||
|
set -g focus-events ${boolToStr cfg.focusEvents}
|
||||||
setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
|
setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
|
||||||
setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
|
setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
|
||||||
set -s escape-time ${toString cfg.escapeTime}
|
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 {
|
historyLimit = mkOption {
|
||||||
default = 2000;
|
default = 2000;
|
||||||
example = 5000;
|
example = 5000;
|
||||||
@@ -239,7 +249,7 @@ in {
|
|||||||
|
|
||||||
sensibleOnTop = mkOption {
|
sensibleOnTop = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Run the sensible plugin at the top of the configuration. It
|
Run the sensible plugin at the top of the configuration. It
|
||||||
is possible to override the sensible settings using the
|
is possible to override the sensible settings using the
|
||||||
|
|||||||
@@ -77,16 +77,16 @@ in {
|
|||||||
default = { };
|
default = { };
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
input.keymap = [
|
input.prepend_keymap = [
|
||||||
{ exec = "close"; on = [ "<C-q>" ]; }
|
{ run = "close"; on = [ "<C-q>" ]; }
|
||||||
{ exec = "close --submit"; on = [ "<Enter>" ]; }
|
{ run = "close --submit"; on = [ "<Enter>" ]; }
|
||||||
{ exec = "escape"; on = [ "<Esc>" ]; }
|
{ run = "escape"; on = [ "<Esc>" ]; }
|
||||||
{ exec = "backspace"; on = [ "<Backspace>" ]; }
|
{ run = "backspace"; on = [ "<Backspace>" ]; }
|
||||||
];
|
];
|
||||||
manager.keymap = [
|
manager.prepend_keymap = [
|
||||||
{ exec = "escape"; on = [ "<Esc>" ]; }
|
{ run = "escape"; on = [ "<Esc>" ]; }
|
||||||
{ exec = "quit"; on = [ "q" ]; }
|
{ run = "quit"; on = [ "q" ]; }
|
||||||
{ exec = "close"; on = [ "<C-q>" ]; }
|
{ run = "close"; on = [ "<C-q>" ]; }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ in {
|
|||||||
|
|
||||||
package = mkPackageOption pkgs "zed-editor" { };
|
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 {
|
userSettings = mkOption {
|
||||||
type = jsonFormat.type;
|
type = jsonFormat.type;
|
||||||
default = { };
|
default = { };
|
||||||
@@ -76,7 +83,22 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
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 != { }) {
|
xdg.configFile."zed/settings.json" = (mkIf (mergedSettings != { }) {
|
||||||
source = jsonFormat.generate "zed-user-settings" mergedSettings;
|
source = jsonFormat.generate "zed-user-settings" mergedSettings;
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ let
|
|||||||
|
|
||||||
cfg = config.programs.zsh;
|
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
|
pluginsDir =
|
||||||
relToDotDir "plugins" else ".zsh/plugins";
|
if cfg.dotDir != null then relToDotDir "plugins" else ".zsh/plugins";
|
||||||
|
|
||||||
envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables;
|
envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables;
|
||||||
localVarsStr = config.lib.zsh.defineAll cfg.localVariables;
|
localVarsStr = config.lib.zsh.defineAll cfg.localVariables;
|
||||||
|
|
||||||
aliasesStr = concatStringsSep "\n" (
|
aliasesStr = concatStringsSep "\n" (mapAttrsToList
|
||||||
mapAttrsToList (k: v: "alias -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellAliases
|
(k: v: "alias -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}")
|
||||||
);
|
cfg.shellAliases);
|
||||||
|
|
||||||
dirHashesStr = concatStringsSep "\n" (
|
dirHashesStr = concatStringsSep "\n"
|
||||||
mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes
|
(mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes);
|
||||||
);
|
|
||||||
|
|
||||||
zdotdir = "$HOME/" + lib.escapeShellArg cfg.dotDir;
|
zdotdir = "$HOME/" + lib.escapeShellArg cfg.dotDir;
|
||||||
|
|
||||||
@@ -64,20 +64,22 @@ let
|
|||||||
|
|
||||||
path = mkOption {
|
path = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = if versionAtLeast stateVersion "20.03"
|
default = if versionAtLeast stateVersion "20.03" then
|
||||||
then "$HOME/.zsh_history"
|
"$HOME/.zsh_history"
|
||||||
else relToDotDir ".zsh_history";
|
else
|
||||||
|
relToDotDir ".zsh_history";
|
||||||
defaultText = literalExpression ''
|
defaultText = literalExpression ''
|
||||||
"$HOME/.zsh_history" if state version ≥ 20.03,
|
"$HOME/.zsh_history" if state version ≥ 20.03,
|
||||||
"$ZDOTDIR/.zsh_history" otherwise
|
"$ZDOTDIR/.zsh_history" otherwise
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''"''${config.xdg.dataHome}/zsh/zsh_history"'';
|
example =
|
||||||
|
literalExpression ''"''${config.xdg.dataHome}/zsh/zsh_history"'';
|
||||||
description = "History file location";
|
description = "History file location";
|
||||||
};
|
};
|
||||||
|
|
||||||
ignorePatterns = mkOption {
|
ignorePatterns = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [];
|
default = [ ];
|
||||||
example = literalExpression ''[ "rm *" "pkill *" ]'';
|
example = literalExpression ''[ "rm *" "pkill *" ]'';
|
||||||
description = ''
|
description = ''
|
||||||
Do not enter command lines into the history list
|
Do not enter command lines into the history list
|
||||||
@@ -170,7 +172,7 @@ let
|
|||||||
package = mkPackageOption pkgs "oh-my-zsh" { };
|
package = mkPackageOption pkgs "oh-my-zsh" { };
|
||||||
|
|
||||||
plugins = mkOption {
|
plugins = mkOption {
|
||||||
default = [];
|
default = [ ];
|
||||||
example = [ "git" "sudo" ];
|
example = [ "git" "sudo" ];
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = ''
|
description = ''
|
||||||
@@ -215,7 +217,7 @@ let
|
|||||||
options = {
|
options = {
|
||||||
enable = mkEnableOption "history substring search";
|
enable = mkEnableOption "history substring search";
|
||||||
searchUpKey = mkOption {
|
searchUpKey = mkOption {
|
||||||
type = with types; either (listOf str) str ;
|
type = with types; either (listOf str) str;
|
||||||
default = [ "^[[A" ];
|
default = [ "^[[A" ];
|
||||||
description = ''
|
description = ''
|
||||||
The key codes to be used when searching up.
|
The key codes to be used when searching up.
|
||||||
@@ -224,7 +226,7 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
searchDownKey = mkOption {
|
searchDownKey = mkOption {
|
||||||
type = with types; either (listOf str) str ;
|
type = with types; either (listOf str) str;
|
||||||
default = [ "^[[B" ];
|
default = [ "^[[B" ];
|
||||||
description = ''
|
description = ''
|
||||||
The key codes to be used when searching down.
|
The key codes to be used when searching down.
|
||||||
@@ -253,7 +255,7 @@ let
|
|||||||
|
|
||||||
patterns = mkOption {
|
patterns = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = {};
|
default = { };
|
||||||
example = { "rm -rf *" = "fg=white,bold,bg=red"; };
|
example = { "rm -rf *" = "fg=white,bold,bg=red"; };
|
||||||
description = ''
|
description = ''
|
||||||
Custom syntax highlighting for user-defined patterns.
|
Custom syntax highlighting for user-defined patterns.
|
||||||
@@ -263,7 +265,7 @@ let
|
|||||||
|
|
||||||
styles = mkOption {
|
styles = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = {};
|
default = { };
|
||||||
example = { comment = "fg=black,bold"; };
|
example = { comment = "fg=black,bold"; };
|
||||||
description = ''
|
description = ''
|
||||||
Custom styles for syntax highlighting.
|
Custom styles for syntax highlighting.
|
||||||
@@ -273,13 +275,25 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in {
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
(mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [ "programs" "zsh" "autosuggestion" "enable" ])
|
(mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [
|
||||||
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
|
"programs"
|
||||||
(mkRenamedOptionModule [ "programs" "zsh" "zproof" ] [ "programs" "zsh" "zprof" ])
|
"zsh"
|
||||||
|
"autosuggestion"
|
||||||
|
"enable"
|
||||||
|
])
|
||||||
|
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [
|
||||||
|
"programs"
|
||||||
|
"zsh"
|
||||||
|
"syntaxHighlighting"
|
||||||
|
"enable"
|
||||||
|
])
|
||||||
|
(mkRenamedOptionModule [ "programs" "zsh" "zproof" ] [
|
||||||
|
"programs"
|
||||||
|
"zsh"
|
||||||
|
"zprof"
|
||||||
|
])
|
||||||
];
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
@@ -297,7 +311,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
cdpath = mkOption {
|
cdpath = mkOption {
|
||||||
default = [];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
List of paths to autocomplete calls to {command}`cd`.
|
List of paths to autocomplete calls to {command}`cd`.
|
||||||
'';
|
'';
|
||||||
@@ -316,7 +330,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
shellAliases = mkOption {
|
shellAliases = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
ll = "ls -l";
|
ll = "ls -l";
|
||||||
@@ -331,7 +345,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
shellGlobalAliases = mkOption {
|
shellGlobalAliases = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
UUID = "$(uuidgen | tr -d \\n)";
|
UUID = "$(uuidgen | tr -d \\n)";
|
||||||
@@ -346,7 +360,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
dirHashes = mkOption {
|
dirHashes = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
docs = "$HOME/Documents";
|
docs = "$HOME/Documents";
|
||||||
@@ -374,7 +388,8 @@ in
|
|||||||
|
|
||||||
completionInit = mkOption {
|
completionInit = mkOption {
|
||||||
default = "autoload -U compinit && compinit";
|
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;
|
type = types.lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -387,13 +402,13 @@ in
|
|||||||
|
|
||||||
syntaxHighlighting = mkOption {
|
syntaxHighlighting = mkOption {
|
||||||
type = syntaxHighlightingModule;
|
type = syntaxHighlightingModule;
|
||||||
default = {};
|
default = { };
|
||||||
description = "Options related to zsh-syntax-highlighting.";
|
description = "Options related to zsh-syntax-highlighting.";
|
||||||
};
|
};
|
||||||
|
|
||||||
historySubstringSearch = mkOption {
|
historySubstringSearch = mkOption {
|
||||||
type = historySubstringSearchModule;
|
type = historySubstringSearchModule;
|
||||||
default = {};
|
default = { };
|
||||||
description = "Options related to zsh-history-substring-search.";
|
description = "Options related to zsh-history-substring-search.";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -415,7 +430,8 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
strategy = mkOption {
|
strategy = mkOption {
|
||||||
type = types.listOf (types.enum [ "history" "completion" "match_prev_cmd" ]);
|
type = types.listOf
|
||||||
|
(types.enum [ "history" "completion" "match_prev_cmd" ]);
|
||||||
default = [ "history" ];
|
default = [ "history" ];
|
||||||
description = ''
|
description = ''
|
||||||
`ZSH_AUTOSUGGEST_STRATEGY` is an array that specifies how suggestions should be generated.
|
`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
|
- `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
|
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`.
|
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 {
|
history = mkOption {
|
||||||
type = historyModule;
|
type = historyModule;
|
||||||
default = {};
|
default = { };
|
||||||
description = "Options related to commands history configuration.";
|
description = "Options related to commands history configuration.";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -445,7 +464,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
sessionVariables = mkOption {
|
sessionVariables = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
example = { MAILCHECK = 30; };
|
example = { MAILCHECK = 30; };
|
||||||
description = "Environment variables that will be set for zsh session.";
|
description = "Environment variables that will be set for zsh session.";
|
||||||
@@ -454,7 +473,8 @@ in
|
|||||||
initExtraBeforeCompInit = mkOption {
|
initExtraBeforeCompInit = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
type = types.lines;
|
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 {
|
initExtra = mkOption {
|
||||||
@@ -478,7 +498,8 @@ in
|
|||||||
profileExtra = mkOption {
|
profileExtra = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
type = types.lines;
|
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 {
|
loginExtra = mkOption {
|
||||||
@@ -490,12 +511,13 @@ in
|
|||||||
logoutExtra = mkOption {
|
logoutExtra = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
type = types.lines;
|
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 {
|
plugins = mkOption {
|
||||||
type = types.listOf pluginModule;
|
type = types.listOf pluginModule;
|
||||||
default = [];
|
default = [ ];
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -525,14 +547,14 @@ in
|
|||||||
|
|
||||||
oh-my-zsh = mkOption {
|
oh-my-zsh = mkOption {
|
||||||
type = ohMyZshModule;
|
type = ohMyZshModule;
|
||||||
default = {};
|
default = { };
|
||||||
description = "Options to configure oh-my-zsh.";
|
description = "Options to configure oh-my-zsh.";
|
||||||
};
|
};
|
||||||
|
|
||||||
localVariables = mkOption {
|
localVariables = mkOption {
|
||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
default = {};
|
default = { };
|
||||||
example = { POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=["dir" "vcs"]; };
|
example = { POWERLEVEL9K_LEFT_PROMPT_ELEMENTS = [ "dir" "vcs" ]; };
|
||||||
description = ''
|
description = ''
|
||||||
Extra local variables defined at the top of {file}`.zshrc`.
|
Extra local variables defined at the top of {file}`.zshrc`.
|
||||||
'';
|
'';
|
||||||
@@ -606,16 +628,16 @@ in
|
|||||||
cfg.initExtraFirst
|
cfg.initExtraFirst
|
||||||
"typeset -U path cdpath fpath manpath"
|
"typeset -U path cdpath fpath manpath"
|
||||||
|
|
||||||
(optionalString (cfg.cdpath != []) ''
|
(optionalString (cfg.cdpath != [ ]) ''
|
||||||
cdpath+=(${concatStringsSep " " cfg.cdpath})
|
cdpath+=(${concatStringsSep " " cfg.cdpath})
|
||||||
'')
|
'')
|
||||||
|
|
||||||
''
|
''
|
||||||
for profile in ''${(z)NIX_PROFILES}; do
|
for profile in ''${(z)NIX_PROFILES}; do
|
||||||
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
|
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
|
||||||
done
|
done
|
||||||
|
|
||||||
HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help"
|
HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help"
|
||||||
''
|
''
|
||||||
|
|
||||||
(optionalString (cfg.defaultKeymap != null) ''
|
(optionalString (cfg.defaultKeymap != null) ''
|
||||||
@@ -632,117 +654,136 @@ in
|
|||||||
'') cfg.plugins))
|
'') cfg.plugins))
|
||||||
|
|
||||||
''
|
''
|
||||||
# Oh-My-Zsh/Prezto calls compinit during initialization,
|
# Oh-My-Zsh/Prezto calls compinit during initialization,
|
||||||
# calling it twice causes slight start up slowdown
|
# calling it twice causes slight start up slowdown
|
||||||
# as all $fpath entries will be traversed again.
|
# as all $fpath entries will be traversed again.
|
||||||
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
|
${optionalString
|
||||||
cfg.completionInit
|
(cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
|
||||||
}''
|
cfg.completionInit}''
|
||||||
|
|
||||||
(optionalString cfg.autosuggestion.enable ''
|
(optionalString cfg.autosuggestion.enable ''
|
||||||
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
||||||
ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.autosuggestion.strategy})
|
${optionalString (cfg.autosuggestion.strategy != [ ]) ''
|
||||||
'')
|
ZSH_AUTOSUGGEST_STRATEGY=(${
|
||||||
(optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
|
concatStringsSep " " cfg.autosuggestion.strategy
|
||||||
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
|
})
|
||||||
|
''}
|
||||||
'')
|
'')
|
||||||
|
(optionalString
|
||||||
|
(cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
|
||||||
|
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
|
||||||
|
'')
|
||||||
|
|
||||||
(optionalString cfg.oh-my-zsh.enable ''
|
(optionalString cfg.oh-my-zsh.enable ''
|
||||||
# oh-my-zsh extra settings for plugins
|
# oh-my-zsh extra settings for plugins
|
||||||
${cfg.oh-my-zsh.extraConfig}
|
${cfg.oh-my-zsh.extraConfig}
|
||||||
# oh-my-zsh configuration generated by NixOS
|
# oh-my-zsh configuration generated by NixOS
|
||||||
${optionalString (cfg.oh-my-zsh.plugins != [])
|
${optionalString (cfg.oh-my-zsh.plugins != [ ])
|
||||||
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"
|
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"}
|
||||||
}
|
${optionalString (cfg.oh-my-zsh.custom != "")
|
||||||
${optionalString (cfg.oh-my-zsh.custom != "")
|
''ZSH_CUSTOM="${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}"''}
|
||||||
${optionalString (cfg.oh-my-zsh.theme != "")
|
source $ZSH/oh-my-zsh.sh
|
||||||
"ZSH_THEME=\"${cfg.oh-my-zsh.theme}\""
|
|
||||||
}
|
|
||||||
source $ZSH/oh-my-zsh.sh
|
|
||||||
'')
|
'')
|
||||||
|
|
||||||
''
|
''
|
||||||
${optionalString cfg.prezto.enable
|
${optionalString cfg.prezto.enable (builtins.readFile
|
||||||
(builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshrc")}
|
"${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshrc")}
|
||||||
|
|
||||||
${concatStrings (map (plugin: ''
|
${concatStrings (map (plugin: ''
|
||||||
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
|
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
|
||||||
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
|
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
|
||||||
fi
|
fi
|
||||||
'') cfg.plugins)}
|
'') cfg.plugins)}
|
||||||
|
|
||||||
# History options should be set in .zshrc and after oh-my-zsh sourcing.
|
# History options should be set in .zshrc and after oh-my-zsh sourcing.
|
||||||
# See https://github.com/nix-community/home-manager/issues/177.
|
# See https://github.com/nix-community/home-manager/issues/177.
|
||||||
HISTSIZE="${toString cfg.history.size}"
|
HISTSIZE="${toString cfg.history.size}"
|
||||||
SAVEHIST="${toString cfg.history.save}"
|
SAVEHIST="${toString cfg.history.save}"
|
||||||
${optionalString (cfg.history.ignorePatterns != []) "HISTORY_IGNORE=${lib.escapeShellArg "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"}"}
|
${optionalString (cfg.history.ignorePatterns != [ ])
|
||||||
${if versionAtLeast config.home.stateVersion "20.03"
|
"HISTORY_IGNORE=${
|
||||||
then ''HISTFILE="${cfg.history.path}"''
|
lib.escapeShellArg
|
||||||
else ''HISTFILE="$HOME/${cfg.history.path}"''}
|
"(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"
|
||||||
mkdir -p "$(dirname "$HISTFILE")"
|
}"}
|
||||||
|
${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
|
setopt HIST_FCNTL_LOCK
|
||||||
${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY
|
${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.ignoreDups then "setopt" else "unsetopt"
|
||||||
${if cfg.history.ignoreSpace then "setopt" else "unsetopt"} HIST_IGNORE_SPACE
|
} HIST_IGNORE_DUPS
|
||||||
${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.ignoreAllDups then "setopt" else "unsetopt"
|
||||||
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
|
} HIST_IGNORE_ALL_DUPS
|
||||||
${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}
|
${
|
||||||
|
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
|
# Aliases
|
||||||
${aliasesStr}
|
${aliasesStr}
|
||||||
''
|
''
|
||||||
]
|
] ++ (mapAttrsToList
|
||||||
++ (mapAttrsToList (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellGlobalAliases)
|
(k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}")
|
||||||
++ [ (''
|
cfg.shellGlobalAliases) ++ [
|
||||||
# Named Directory Hashes
|
(''
|
||||||
${dirHashesStr}
|
# Named Directory Hashes
|
||||||
'')
|
${dirHashesStr}
|
||||||
|
'')
|
||||||
|
|
||||||
(optionalString cfg.syntaxHighlighting.enable
|
(optionalString cfg.syntaxHighlighting.enable
|
||||||
# Load zsh-syntax-highlighting after all custom widgets have been created
|
# Load zsh-syntax-highlighting after all custom widgets have been created
|
||||||
# https://github.com/zsh-users/zsh-syntax-highlighting#faq
|
# https://github.com/zsh-users/zsh-syntax-highlighting#faq
|
||||||
''
|
''
|
||||||
source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||||||
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${lib.concatStringsSep " " (map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)})
|
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${
|
||||||
${lib.concatStringsSep "\n" (
|
lib.concatStringsSep " "
|
||||||
lib.mapAttrsToList
|
(map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)
|
||||||
(name: value: "ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
|
})
|
||||||
cfg.syntaxHighlighting.styles
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value:
|
||||||
)}
|
"ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${
|
||||||
${lib.concatStringsSep "\n" (
|
lib.escapeShellArg value
|
||||||
lib.mapAttrsToList
|
})") cfg.syntaxHighlighting.styles)}
|
||||||
(name: value: "ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value:
|
||||||
cfg.syntaxHighlighting.patterns
|
"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
|
# Load zsh-history-substring-search after zsh-syntax-highlighting
|
||||||
# https://github.com/zsh-users/zsh-history-substring-search#usage
|
# 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
|
source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh
|
||||||
${lib.concatMapStringsSep "\n"
|
${lib.concatMapStringsSep "\n"
|
||||||
(upKey: "bindkey \"${upKey}\" history-substring-search-up")
|
(upKey: ''bindkey "${upKey}" history-substring-search-up'')
|
||||||
(lib.toList cfg.historySubstringSearch.searchUpKey)
|
(lib.toList cfg.historySubstringSearch.searchUpKey)}
|
||||||
}
|
${lib.concatMapStringsSep "\n"
|
||||||
${lib.concatMapStringsSep "\n"
|
(downKey: ''bindkey "${downKey}" history-substring-search-down'')
|
||||||
(downKey: "bindkey \"${downKey}\" history-substring-search-down")
|
(lib.toList cfg.historySubstringSearch.searchDownKey)}
|
||||||
(lib.toList cfg.historySubstringSearch.searchDownKey)
|
'')
|
||||||
}
|
|
||||||
'')
|
|
||||||
|
|
||||||
(optionalString cfg.zprof.enable
|
(optionalString cfg.zprof.enable ''
|
||||||
''
|
zprof
|
||||||
zprof
|
'')
|
||||||
'')
|
]);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(mkIf cfg.oh-my-zsh.enable {
|
(mkIf cfg.oh-my-zsh.enable {
|
||||||
@@ -751,15 +792,14 @@ in
|
|||||||
home.file."${config.xdg.cacheHome}/oh-my-zsh/.keep".text = "";
|
home.file."${config.xdg.cacheHome}/oh-my-zsh/.keep".text = "";
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (cfg.plugins != []) {
|
(mkIf (cfg.plugins != [ ]) {
|
||||||
# Many plugins require compinit to be called
|
# Many plugins require compinit to be called
|
||||||
# but allow the user to opt out.
|
# but allow the user to opt out.
|
||||||
programs.zsh.enableCompletion = mkDefault true;
|
programs.zsh.enableCompletion = mkDefault true;
|
||||||
|
|
||||||
home.file =
|
home.file = foldl' (a: b: a // b) { }
|
||||||
foldl' (a: b: a // b) {}
|
|
||||||
(map (plugin: { "${pluginsDir}/${plugin.name}".source = plugin.src; })
|
(map (plugin: { "${pluginsDir}/${plugin.name}".source = plugin.src; })
|
||||||
cfg.plugins);
|
cfg.plugins);
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ in {
|
|||||||
enable =
|
enable =
|
||||||
mkEnableOption "zsh-abbr - zsh manager for auto-expanding abbreviations";
|
mkEnableOption "zsh-abbr - zsh manager for auto-expanding abbreviations";
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "zsh-abbr" { };
|
||||||
|
|
||||||
abbreviations = mkOption {
|
abbreviations = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = { };
|
default = { };
|
||||||
@@ -27,8 +29,8 @@ in {
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
programs.zsh.plugins = [{
|
programs.zsh.plugins = [{
|
||||||
name = "zsh-abbr";
|
name = "zsh-abbr";
|
||||||
src = pkgs.zsh-abbr;
|
src = cfg.package;
|
||||||
file = "/share/zsh/zsh-abbr/abbr.plugin.zsh";
|
file = "share/zsh/zsh-abbr/zsh-abbr.plugin.zsh";
|
||||||
}];
|
}];
|
||||||
|
|
||||||
xdg.configFile = {
|
xdg.configFile = {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ in with lib; {
|
|||||||
Service = {
|
Service = {
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RestartSec = "3";
|
RestartSec = "3";
|
||||||
ExecStart = toString ([ "${pkgs.conky}/bin/conky" ]
|
ExecStart = toString ([ "${cfg.package}/bin/conky" ]
|
||||||
++ optional (cfg.extraConfig != "")
|
++ optional (cfg.extraConfig != "")
|
||||||
"--config ${pkgs.writeText "conky.conf" cfg.extraConfig}");
|
"--config ${pkgs.writeText "conky.conf" cfg.extraConfig}");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ let
|
|||||||
# to work without wrapping it.
|
# to work without wrapping it.
|
||||||
socketDir = "%t/emacs";
|
socketDir = "%t/emacs";
|
||||||
socketPath = "${socketDir}/server";
|
socketPath = "${socketDir}/server";
|
||||||
|
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ maintainers.tadfisher ];
|
meta.maintainers = [ maintainers.tadfisher ];
|
||||||
|
|
||||||
@@ -112,12 +111,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (mkMerge [
|
config = mkIf cfg.enable (mkMerge [
|
||||||
{
|
(mkIf pkgs.stdenv.isLinux {
|
||||||
assertions = [
|
|
||||||
(lib.hm.assertions.assertPlatform "services.emacs" pkgs
|
|
||||||
lib.platforms.linux)
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.user.services.emacs = {
|
systemd.user.services.emacs = {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Emacs text editor";
|
Description = "Emacs text editor";
|
||||||
@@ -190,9 +184,9 @@ in {
|
|||||||
}/bin/emacsclient "''${@:---create-frame}"'');
|
}/bin/emacsclient "''${@:---create-frame}"'');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
})
|
||||||
|
|
||||||
(mkIf cfg.socketActivation.enable {
|
(mkIf (cfg.socketActivation.enable && pkgs.stdenv.isLinux) {
|
||||||
systemd.user.sockets.emacs = {
|
systemd.user.sockets.emacs = {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Emacs text editor";
|
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 {
|
serverUrl = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "https://api.etesync.com/";
|
default = "https://api.etebase.com/partner/etesync/";
|
||||||
description = "The URL to the etesync server.";
|
description = "The URL to the etesync server.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -235,15 +235,12 @@ in {
|
|||||||
example = literalExpression "pkgs.pinentry-gnome3";
|
example = literalExpression "pkgs.pinentry-gnome3";
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
Which pinentry interface to use. If not
|
Which pinentry interface to use. If not `null`, it sets
|
||||||
`null`, it sets
|
{option}`pinentry-program` in {file}`gpg-agent.conf`. Beware that
|
||||||
{option}`pinentry-program` in
|
`pinentry-gnome3` may not work on non-GNOME systems. You can fix it by
|
||||||
{file}`gpg-agent.conf`. Beware that
|
adding the following to your configuration:
|
||||||
`pinentry-gnome3` may not work on non-Gnome
|
|
||||||
systems. You can fix it by adding the following to your
|
|
||||||
system configuration:
|
|
||||||
```nix
|
```nix
|
||||||
services.dbus.packages = [ pkgs.gcr ];
|
home.packages = [ pkgs.gcr ];
|
||||||
```
|
```
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ in {
|
|||||||
Description = "hypridle";
|
Description = "hypridle";
|
||||||
After = [ "graphical-session-pre.target" ];
|
After = [ "graphical-session-pre.target" ];
|
||||||
PartOf = [ "graphical-session.target" ];
|
PartOf = [ "graphical-session.target" ];
|
||||||
X-Restart-Triggers =
|
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||||
[ "${config.xdg.configFile."hypr/hypridle.conf".source}" ];
|
[ "${config.xdg.configFile."hypr/hypridle.conf".source}" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ in {
|
|||||||
Description = "hyprpaper";
|
Description = "hyprpaper";
|
||||||
After = [ "graphical-session-pre.target" ];
|
After = [ "graphical-session-pre.target" ];
|
||||||
PartOf = [ "graphical-session.target" ];
|
PartOf = [ "graphical-session.target" ];
|
||||||
X-Restart-Triggers =
|
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||||
[ "${config.xdg.configFile."hypr/hyprpaper.conf".source}" ];
|
[ "${config.xdg.configFile."hypr/hyprpaper.conf".source}" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ let
|
|||||||
Restart = "always";
|
Restart = "always";
|
||||||
RestartSec = 30;
|
RestartSec = 30;
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
} // optionalAttrs account.notmuch.enable {
|
Environment = [ "PATH=${cfg.path}" ]
|
||||||
Environment =
|
++ optional account.notmuch.enable
|
||||||
"NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/default/config";
|
"NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/default/config";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,6 +97,17 @@ in {
|
|||||||
example = literalExpression "pkgs.imapnotify";
|
example = literalExpression "pkgs.imapnotify";
|
||||||
description = "The imapnotify package to use";
|
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 {
|
accounts.email.accounts = mkOption {
|
||||||
@@ -122,6 +133,12 @@ in {
|
|||||||
(checkAccounts (a: a.userName == null) "username")
|
(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);
|
systemd.user.services = listToAttrs (map genAccountUnit imapnotifyAccounts);
|
||||||
|
|
||||||
launchd.agents = listToAttrs (map genAccountAgent imapnotifyAccounts);
|
launchd.agents = listToAttrs (map genAccountAgent imapnotifyAccounts);
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ let
|
|||||||
else
|
else
|
||||||
throw "Unknown tags ${attrNames x}";
|
throw "Unknown tags ${attrNames x}";
|
||||||
|
|
||||||
directivesStr = ''
|
directivesStr = concatStringsSep "\n" (map tagToStr cfg.settings);
|
||||||
${concatStringsSep "\n" (map tagToStr cfg.settings)}
|
|
||||||
'';
|
|
||||||
|
|
||||||
oldDirectivesStr = ''
|
oldDirectivesStr = ''
|
||||||
${concatStringsSep "\n"
|
${concatStringsSep "\n"
|
||||||
@@ -332,11 +330,13 @@ in {
|
|||||||
{
|
{
|
||||||
home.packages = [ cfg.package ];
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
xdg.configFile."kanshi/config".text =
|
xdg.configFile."kanshi/config" = let
|
||||||
if cfg.profiles == { } && cfg.extraConfig == "" then
|
generatedConfigStr =
|
||||||
directivesStr
|
if cfg.profiles == { } && cfg.extraConfig == "" then
|
||||||
else
|
directivesStr
|
||||||
oldDirectivesStr;
|
else
|
||||||
|
oldDirectivesStr;
|
||||||
|
in mkIf (generatedConfigStr != "") { text = generatedConfigStr; };
|
||||||
|
|
||||||
systemd.user.services.kanshi = {
|
systemd.user.services.kanshi = {
|
||||||
Unit = {
|
Unit = {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ in {
|
|||||||
enable = mkEnableOption "KDE connect";
|
enable = mkEnableOption "KDE connect";
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.plasma5Packages.kdeconnect-kde;
|
default = pkgs.kdePackages.kdeconnect-kde;
|
||||||
example = literalExpression "pkgs.kdePackages.kdeconnect-kde";
|
example = literalExpression "pkgs.plasma5Packages.kdeconnect-kde";
|
||||||
description = "The KDE connect package to use";
|
description = "The KDE connect package to use";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ in {
|
|||||||
"%C/lorri"
|
"%C/lorri"
|
||||||
# Needs %C/nix/fetcher-cache-v1.sqlite
|
# Needs %C/nix/fetcher-cache-v1.sqlite
|
||||||
"%C/nix"
|
"%C/nix"
|
||||||
"/nix/var/nix/gcroots/per-user/%u"
|
|
||||||
];
|
];
|
||||||
CacheDirectory = [ "lorri" ];
|
CacheDirectory = [ "lorri" ];
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ let
|
|||||||
name = "mopidy-with-extensions-${pkgs.mopidy.version}";
|
name = "mopidy-with-extensions-${pkgs.mopidy.version}";
|
||||||
paths = closePropagation cfg.extensionPackages;
|
paths = closePropagation cfg.extensionPackages;
|
||||||
pathsToLink = [ "/${pkgs.mopidyPackages.python.sitePackages}" ];
|
pathsToLink = [ "/${pkgs.mopidyPackages.python.sitePackages}" ];
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
ignoreCollisions = true;
|
||||||
postBuild = ''
|
postBuild = ''
|
||||||
makeWrapper ${pkgs.mopidy}/bin/mopidy $out/bin/mopidy \
|
makeWrapper ${pkgs.mopidy}/bin/mopidy $out/bin/mopidy \
|
||||||
--prefix PYTHONPATH : $out/${pkgs.mopidyPackages.python.sitePackages}
|
--prefix PYTHONPATH : $out/${pkgs.mopidyPackages.python.sitePackages}
|
||||||
@@ -126,10 +127,13 @@ in {
|
|||||||
Description = "mopidy music player daemon";
|
Description = "mopidy music player daemon";
|
||||||
Documentation = [ "https://mopidy.com/" ];
|
Documentation = [ "https://mopidy.com/" ];
|
||||||
After = [ "network.target" "sound.target" ];
|
After = [ "network.target" "sound.target" ];
|
||||||
|
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||||
|
[ "${config.xdg.configFile."mopidy/mopidy.conf".source}" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
Service = {
|
Service = {
|
||||||
ExecStart = "${mopidyEnv}/bin/mopidy --config ${configFilePaths}";
|
ExecStart = "${mopidyEnv}/bin/mopidy --config ${configFilePaths}";
|
||||||
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
|
|
||||||
Install.WantedBy = [ "default.target" ];
|
Install.WantedBy = [ "default.target" ];
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
{
|
cfg = config.services.podman;
|
||||||
|
toml = pkgs.formats.toml { };
|
||||||
|
in {
|
||||||
meta.maintainers = with lib.hm.maintainers; [ bamhm182 n-hass ];
|
meta.maintainers = with lib.hm.maintainers; [ bamhm182 n-hass ];
|
||||||
|
|
||||||
imports =
|
imports =
|
||||||
@@ -8,10 +10,90 @@
|
|||||||
|
|
||||||
options.services.podman = {
|
options.services.podman = {
|
||||||
enable = lib.mkEnableOption "Podman, a daemonless container engine";
|
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 =
|
assertions =
|
||||||
[ (lib.hm.assertions.assertPlatform "podman" pkgs lib.platforms.linux) ];
|
[ (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" ]; };
|
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
|
let
|
||||||
|
|
||||||
cfg = config.services.syncthing;
|
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 = [
|
defaultSyncthingArgs = [
|
||||||
"${pkgs.syncthing}/bin/syncthing"
|
"${syncthing}"
|
||||||
"-no-browser"
|
"-no-browser"
|
||||||
"-no-restart"
|
"-no-restart"
|
||||||
|
"-no-upgrade"
|
||||||
|
"-gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress}"
|
||||||
"-logflags=0"
|
"-logflags=0"
|
||||||
];
|
];
|
||||||
|
|
||||||
syncthingArgs = defaultSyncthingArgs ++ cfg.extraOptions;
|
syncthingArgs = defaultSyncthingArgs ++ cfg.extraOptions;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ maintainers.rycee ];
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
options = {
|
options = with types; {
|
||||||
services.syncthing = {
|
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 {
|
cert = mkOption {
|
||||||
type = types.listOf types.str;
|
type = nullOr str;
|
||||||
default = [ ];
|
default = null;
|
||||||
example = [ "--gui-apikey=apiKey" ];
|
|
||||||
description = ''
|
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 {
|
tray = mkOption {
|
||||||
type = with types;
|
type = with types;
|
||||||
either bool (submodule {
|
either bool (submodule {
|
||||||
options = {
|
options = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to enable a syncthing tray service.";
|
description = "Whether to enable a syncthing tray service.";
|
||||||
};
|
};
|
||||||
|
|
||||||
command = mkOption {
|
command = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
default = "syncthingtray";
|
default = "syncthingtray";
|
||||||
defaultText = literalExpression "syncthingtray";
|
defaultText = literalExpression "syncthingtray";
|
||||||
example = literalExpression "qsyncthingtray";
|
example = literalExpression "qsyncthingtray";
|
||||||
@@ -50,7 +590,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = package;
|
||||||
default = pkgs.syncthingtray-minimal;
|
default = pkgs.syncthingtray-minimal;
|
||||||
defaultText = literalExpression "pkgs.syncthingtray-minimal";
|
defaultText = literalExpression "pkgs.syncthingtray-minimal";
|
||||||
example = literalExpression "pkgs.qsyncthingtray";
|
example = literalExpression "pkgs.qsyncthingtray";
|
||||||
@@ -78,10 +618,28 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Service = {
|
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;
|
ExecStart = escapeShellArgs syncthingArgs;
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
SuccessExitStatus = [ 3 4 ];
|
SuccessExitStatus = [ 3 4 ];
|
||||||
RestartForceExitStatus = [ 3 4 ];
|
RestartForceExitStatus = [ 3 4 ];
|
||||||
|
Environment =
|
||||||
|
mkIf (cfg.allProxy != null) { all_proxy = cfg.allProxy; };
|
||||||
|
|
||||||
# Sandboxing.
|
# Sandboxing.
|
||||||
LockPersonality = true;
|
LockPersonality = true;
|
||||||
@@ -95,6 +653,23 @@ in {
|
|||||||
|
|
||||||
Install = { WantedBy = [ "default.target" ]; };
|
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 = {
|
launchd.agents.syncthing = {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ let
|
|||||||
cfg = config.services.volnoti;
|
cfg = config.services.volnoti;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ maintainers.imalison ];
|
meta.maintainers = with maintainers; [ imalison tomodachi94 ];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
services.volnoti = {
|
services.volnoti = {
|
||||||
@@ -37,7 +37,7 @@ in {
|
|||||||
|
|
||||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
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
|
"isReleaseBranch": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ in import nmtSrc {
|
|||||||
./modules/programs/khal
|
./modules/programs/khal
|
||||||
./modules/programs/khard
|
./modules/programs/khard
|
||||||
./modules/programs/kitty
|
./modules/programs/kitty
|
||||||
|
./modules/programs/kubecolor
|
||||||
./modules/programs/ledger
|
./modules/programs/ledger
|
||||||
./modules/programs/less
|
./modules/programs/less
|
||||||
./modules/programs/lf
|
./modules/programs/lf
|
||||||
@@ -118,6 +119,7 @@ in import nmtSrc {
|
|||||||
./modules/programs/newsboat
|
./modules/programs/newsboat
|
||||||
./modules/programs/nheko
|
./modules/programs/nheko
|
||||||
./modules/programs/nix-index
|
./modules/programs/nix-index
|
||||||
|
./modules/programs/nix-your-shell
|
||||||
./modules/programs/nnn
|
./modules/programs/nnn
|
||||||
./modules/programs/nushell
|
./modules/programs/nushell
|
||||||
./modules/programs/oh-my-posh
|
./modules/programs/oh-my-posh
|
||||||
@@ -173,6 +175,7 @@ in import nmtSrc {
|
|||||||
./modules/xresources
|
./modules/xresources
|
||||||
] ++ lib.optionals isDarwin [
|
] ++ lib.optionals isDarwin [
|
||||||
./modules/launchd
|
./modules/launchd
|
||||||
|
./modules/services/emacs-darwin
|
||||||
./modules/services/espanso-darwin
|
./modules/services/espanso-darwin
|
||||||
./modules/services/git-sync-darwin
|
./modules/services/git-sync-darwin
|
||||||
./modules/services/imapnotify-darwin
|
./modules/services/imapnotify-darwin
|
||||||
@@ -286,6 +289,7 @@ in import nmtSrc {
|
|||||||
./modules/services/trayscale
|
./modules/services/trayscale
|
||||||
./modules/services/twmn
|
./modules/services/twmn
|
||||||
./modules/services/udiskie
|
./modules/services/udiskie
|
||||||
|
./modules/services/volnoti
|
||||||
./modules/services/window-managers/bspwm
|
./modules/services/window-managers/bspwm
|
||||||
./modules/services/window-managers/herbstluftwm
|
./modules/services/window-managers/herbstluftwm
|
||||||
./modules/services/window-managers/hyprland
|
./modules/services/window-managers/hyprland
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.alice = { ... }: {
|
home-manager.users.alice = { ... }: {
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
home.file.test.text = "testfile";
|
home.file.test.text = "testfile";
|
||||||
# Enable a light-weight systemd service.
|
# Enable a light-weight systemd service.
|
||||||
services.pueue.enable = true;
|
services.pueue.enable = true;
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
start_all()
|
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"):
|
with subtest("Home Manager file"):
|
||||||
# The file should be linked with the expected content.
|
# The file should be linked with the expected content.
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
fail_as_alice("pueue status")
|
fail_as_alice("pueue status")
|
||||||
|
|
||||||
machine.systemctl("restart home-manager-alice.service")
|
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")
|
actual = succeed_as_alice("pueue status")
|
||||||
expected = "running"
|
expected = "running"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
# You should not change this value, even if you update Home Manager. If you do
|
# 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
|
# want to update the value, then make sure to first check the Home Manager
|
||||||
# release notes.
|
# 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
|
# The home.packages option allows you to install Nix packages into your
|
||||||
# environment.
|
# environment.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
home.username = "alice";
|
home.username = "alice";
|
||||||
home.homeDirectory = "/home/alice";
|
home.homeDirectory = "/home/alice";
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
home.packages = [ pkgs.hello ];
|
home.packages = [ pkgs.hello ];
|
||||||
home.file.test.text = "test";
|
home.file.test.text = "test";
|
||||||
home.sessionVariables.EDITOR = "emacs";
|
home.sessionVariables.EDITOR = "emacs";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ ... }: {
|
{ ... }: {
|
||||||
home.username = "alice";
|
home.username = "alice";
|
||||||
home.homeDirectory = "/home/alice";
|
home.homeDirectory = "/home/alice";
|
||||||
home.stateVersion = "24.05";
|
home.stateVersion = "24.11";
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
# Let Home Manager install and manage itself.
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
home.username = "alice";
|
home.username = "alice";
|
||||||
home.homeDirectory = "/home/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.
|
# Let Home Manager install and manage itself.
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
i18n.inputMethod = {
|
i18n.inputMethod = {
|
||||||
enabled = "fcitx5";
|
enabled = "fcitx5";
|
||||||
fcitx5.addons = with pkgs; [ fcitx5-chinese-addons ];
|
fcitx5.addons = [ pkgs.libsForQt5.fcitx5-chinese-addons ];
|
||||||
};
|
};
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
config = {
|
nix = { package = config.lib.test.mkStubPackage { }; };
|
||||||
nix = { package = config.lib.test.mkStubPackage { }; };
|
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
assertPathNotExists home-files/.config/nix
|
assertPathNotExists home-files/.config/nix
|
||||||
assertPathNotExists home-files/.nix-defexpr/50-home-manager
|
assertPathNotExists home-files/.nix-defexpr/50-home-manager
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,21 +9,19 @@ let
|
|||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
config = {
|
nix = {
|
||||||
nix = {
|
package = config.lib.test.mkStubPackage {
|
||||||
package = config.lib.test.mkStubPackage {
|
version = lib.getVersion pkgs.nixVersions.stable;
|
||||||
version = lib.getVersion pkgs.nixVersions.stable;
|
|
||||||
};
|
|
||||||
channels.example = exampleChannel;
|
|
||||||
settings.use-xdg-base-directories = true;
|
|
||||||
};
|
};
|
||||||
|
channels.example = exampleChannel;
|
||||||
nmt.script = ''
|
settings.use-xdg-base-directories = true;
|
||||||
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
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 {
|
in {
|
||||||
config = {
|
nix = {
|
||||||
nix = {
|
package = config.lib.test.mkStubPackage { };
|
||||||
package = config.lib.test.mkStubPackage { };
|
channels.example = exampleChannel;
|
||||||
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
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 = {
|
||||||
nix = {
|
registry = {
|
||||||
registry = {
|
nixpkgs = {
|
||||||
nixpkgs = {
|
to = {
|
||||||
to = {
|
type = "github";
|
||||||
type = "github";
|
owner = "my-org";
|
||||||
owner = "my-org";
|
repo = "my-nixpkgs";
|
||||||
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, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
config = {
|
nix = {
|
||||||
nix = {
|
package = config.lib.test.mkStubPackage {
|
||||||
package = config.lib.test.mkStubPackage {
|
version = lib.getVersion pkgs.nixVersions.stable;
|
||||||
version = lib.getVersion pkgs.nixVersions.stable;
|
buildScript = ''
|
||||||
buildScript = ''
|
target=$out/bin/nix
|
||||||
target=$out/bin/nix
|
mkdir -p "$(dirname "$target")"
|
||||||
mkdir -p "$(dirname "$target")"
|
|
||||||
|
|
||||||
echo -n "true" > "$target"
|
echo -n "true" > "$target"
|
||||||
|
|
||||||
chmod +x "$target"
|
chmod +x "$target"
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
|
|
||||||
nixPath = [ "/a" "/b/c" ];
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
use-sandbox = true;
|
|
||||||
show-trace = true;
|
|
||||||
system-features = [ "big-parallel" "kvm" "recursive-nix" ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nmt.script = ''
|
nixPath = [ "/a" "/b/c" ];
|
||||||
assertFileContent \
|
|
||||||
home-files/.config/nix/nix.conf \
|
|
||||||
${./example-settings-expected.conf}
|
|
||||||
|
|
||||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
settings = {
|
||||||
'export NIX_PATH="/a:/b/c''${NIX_PATH:+:$NIX_PATH}"'
|
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, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
config = {
|
nix = {
|
||||||
nix = {
|
package = config.lib.test.mkStubPackage { };
|
||||||
package = config.lib.test.mkStubPackage { };
|
nixPath = [ "/a" "/b/c" ];
|
||||||
nixPath = [ "/a" "/b/c" ];
|
keepOldNixPath = false;
|
||||||
keepOldNixPath = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
|
||||||
'export NIX_PATH="/a:/b/c"'
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 = ''
|
nmt.script = ''
|
||||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
'QT_PLUGIN_PATH'
|
'QT_PLUGIN_PATH'
|
||||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
'QML2_IMPORT_PATH'
|
'QML2_IMPORT_PATH'
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,30 @@
|
|||||||
{
|
{
|
||||||
config = {
|
qt = {
|
||||||
qt = {
|
enable = true;
|
||||||
enable = true;
|
# Check if still backwards compatible
|
||||||
# Check if still backwards compatible
|
platformTheme = "gnome";
|
||||||
platformTheme = "gnome";
|
style.name = "adwaita";
|
||||||
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."
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 = {
|
imports = [ ../../i18n/input-method/fcitx5-stubs.nix ];
|
||||||
qt = {
|
|
||||||
enable = true;
|
|
||||||
platformTheme.name = "gtk";
|
|
||||||
};
|
|
||||||
i18n.inputMethod.enabled = "fcitx5";
|
|
||||||
|
|
||||||
nmt.script = ''
|
qt = {
|
||||||
assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \
|
enable = true;
|
||||||
'QT_QPA_PLATFORMTHEME="gtk2"'
|
platformTheme.name = "gtk";
|
||||||
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'
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 = {
|
||||||
qt = {
|
enable = true;
|
||||||
enable = true;
|
platformTheme.name = "gtk3";
|
||||||
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'
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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";
|
extraConfig = "test";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test.stubs.cmus = { };
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
assertFileContent \
|
assertFileContent \
|
||||||
home-files/.config/cmus/rc \
|
home-files/.config/cmus/rc \
|
||||||
|
|||||||
@@ -36,11 +36,7 @@ let
|
|||||||
|
|
||||||
in {
|
in {
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
(self: super: {
|
(final: prev: { gnome-shell-extensions = dummy-gnome-shell-extensions; })
|
||||||
gnome = super.gnome.overrideScope (gself: gsuper: {
|
|
||||||
gnome-shell-extensions = dummy-gnome-shell-extensions;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.gnome-shell.enable = true;
|
programs.gnome-shell.enable = true;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
source = pkgs.fetchurl {
|
source = pkgs.fetchurl {
|
||||||
url =
|
url =
|
||||||
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x44CF42371ADF842E12F116EAA9D3F98FCCF5460B";
|
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x44CF42371ADF842E12F116EAA9D3F98FCCF5460B";
|
||||||
hash = "sha256-u01QTYEFSY1feJWX3JJjXB6thiVO4WOnrqNmzg6vIDs=";
|
hash = "sha256-bSluCZh6ijwppigk8iF2BwWKZgq1WDbIjyYQRK772dM=";
|
||||||
};
|
};
|
||||||
trust = 1; # "unknown"
|
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
|
CertificateFile /etc/ssl/certs/ca-certificates.crt
|
||||||
Host imap.example.org
|
Host imap.example.org
|
||||||
PassCmd "password-command 2"
|
PassCmd "password-command 2"
|
||||||
SSLType IMAPS
|
TLSType IMAPS
|
||||||
User home.manager.jr
|
User home.manager.jr
|
||||||
|
|
||||||
IMAPStore hm-account-remote
|
IMAPStore hm-account-remote
|
||||||
@@ -56,8 +56,8 @@ IMAPAccount hm@example.com
|
|||||||
CertificateFile /etc/ssl/certs/ca-certificates.crt
|
CertificateFile /etc/ssl/certs/ca-certificates.crt
|
||||||
Host imap.example.com
|
Host imap.example.com
|
||||||
PassCmd password-command
|
PassCmd password-command
|
||||||
SSLType IMAPS
|
TLSType IMAPS
|
||||||
SSLVersions TLSv1.3 TLSv1.2
|
TLSVersions +1.3 +1.2 -1.1
|
||||||
User home.manager
|
User home.manager
|
||||||
|
|
||||||
IMAPStore hm@example.com-remote
|
IMAPStore hm@example.com-remote
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ with lib;
|
|||||||
accounts.email.accounts = {
|
accounts.email.accounts = {
|
||||||
"hm@example.com".mbsync = {
|
"hm@example.com".mbsync = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraConfig.account.SSLVersions = [ "TLSv1.3" "TLSv1.2" ];
|
extraConfig.account.TLSVersions = [ "+1.3" "+1.2" "-1.1" ];
|
||||||
groups.inboxes = {
|
groups.inboxes = {
|
||||||
channels = {
|
channels = {
|
||||||
inbox1 = {
|
inbox1 = {
|
||||||
@@ -79,8 +79,8 @@ with lib;
|
|||||||
test.stubs.isync = { };
|
test.stubs.isync = { };
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
assertFileExists home-files/.mbsyncrc
|
assertFileExists home-files/.config/isyncrc
|
||||||
assertFileContent home-files/.mbsyncrc ${./mbsync-expected.conf}
|
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 = {
|
shellAliases = {
|
||||||
"lsname" = "(ls | get name)";
|
"lsname" = "(ls | get name)";
|
||||||
"ll" = "ls -a";
|
"ll" = "ls -a";
|
||||||
@@ -41,8 +43,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
test.stubs.nushell = { };
|
|
||||||
|
|
||||||
nmt.script = let
|
nmt.script = let
|
||||||
configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then
|
configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then
|
||||||
"home-files/Library/Application Support/nushell"
|
"home-files/Library/Application Support/nushell"
|
||||||
@@ -58,5 +58,7 @@
|
|||||||
assertFileContent \
|
assertFileContent \
|
||||||
"${configDir}/login.nu" \
|
"${configDir}/login.nu" \
|
||||||
${./login-expected.nu}
|
${./login-expected.nu}
|
||||||
|
assertFileExists \
|
||||||
|
"${configDir}/plugin.msgpackz"
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,6 @@
|
|||||||
starship-settings = ./settings.nix;
|
starship-settings = ./settings.nix;
|
||||||
starship-fish-with-transience = ./fish_with_transience.nix;
|
starship-fish-with-transience = ./fish_with_transience.nix;
|
||||||
starship-fish-without-transience = ./fish_without_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.openpgp_key_id", "ABC");
|
||||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.protectSubject", true);
|
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.protectSubject", true);
|
||||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.sign_mail", false);
|
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.useremail", "home-manager@example.com");
|
||||||
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.valid", true);
|
user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.valid", true);
|
||||||
user_pref("mail.identity.id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.autoEncryptDrafts", false);
|
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 default-terminal "screen"
|
||||||
set -g base-index 0
|
set -g base-index 0
|
||||||
@@ -24,6 +19,7 @@ set -g mode-keys emacs
|
|||||||
|
|
||||||
|
|
||||||
set -g mouse off
|
set -g mouse off
|
||||||
|
set -g focus-events off
|
||||||
setw -g aggressive-resize off
|
setw -g aggressive-resize off
|
||||||
setw -g clock-mode-style 12
|
setw -g clock-mode-style 12
|
||||||
set -s escape-time 500
|
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 default-terminal "screen"
|
||||||
set -g base-index 0
|
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 mouse off
|
||||||
|
set -g focus-events off
|
||||||
setw -g aggressive-resize off
|
setw -g aggressive-resize off
|
||||||
setw -g clock-mode-style 12
|
setw -g clock-mode-style 12
|
||||||
set -s escape-time 500
|
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 default-terminal "screen"
|
||||||
set -g base-index 0
|
set -g base-index 0
|
||||||
@@ -24,6 +19,7 @@ set -g mode-keys emacs
|
|||||||
|
|
||||||
|
|
||||||
set -g mouse off
|
set -g mouse off
|
||||||
|
set -g focus-events off
|
||||||
setw -g aggressive-resize on
|
setw -g aggressive-resize on
|
||||||
setw -g clock-mode-style 24
|
setw -g clock-mode-style 24
|
||||||
set -s escape-time 500
|
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 default-terminal "screen"
|
||||||
set -g base-index 0
|
set -g base-index 0
|
||||||
@@ -22,6 +17,7 @@ set -g mode-keys emacs
|
|||||||
|
|
||||||
|
|
||||||
set -g mouse on
|
set -g mouse on
|
||||||
|
set -g focus-events off
|
||||||
setw -g aggressive-resize off
|
setw -g aggressive-resize off
|
||||||
setw -g clock-mode-style 12
|
setw -g clock-mode-style 12
|
||||||
set -s escape-time 500
|
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 default-terminal "screen"
|
||||||
set -g base-index 0
|
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 mouse off
|
||||||
|
set -g focus-events off
|
||||||
setw -g aggressive-resize off
|
setw -g aggressive-resize off
|
||||||
setw -g clock-mode-style 12
|
setw -g clock-mode-style 12
|
||||||
set -s escape-time 500
|
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