diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 22c23275a944..f5d434834530 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -249,6 +249,9 @@ Makefile @thiagokokada /modules/programs/pandoc.nix @kirelagin /tests/modules/programs/pandoc @kirelagin +/modules/programs/papis.nix @marsam +/tests/modules/programs/papis @marsam + /modules/programs/password-store.nix @pacien /modules/programs/pazi.nix @marsam @@ -273,6 +276,8 @@ Makefile @thiagokokada /modules/programs/pylint.nix @florpe +/modules/programs/rbenv.nix @marsam + /modules/programs/rbw.nix @ambroisie /tests/modules/programs/rbw @ambroisie @@ -330,6 +335,9 @@ Makefile @thiagokokada /modules/programs/topgrade.nix @msfjarvis /tests/modules/programs/topgrade @msfjarvis +/modules/programs/vim-vint.nix @tomodachi94 +/tests/modules/programs/vim-vint @tomodachi94 + /modules/programs/watson.nix @polykernel /tests/modules/programs/watson @polykernel @@ -355,6 +363,8 @@ Makefile @thiagokokada /modules/programs/zsh/prezto.nix @NickHu +/modules/services/autorandr.nix @GaetanLepage + /modules/services/barrier.nix @Kritnich /tests/modules/services/barrier @Kritnich @@ -369,6 +379,9 @@ Makefile @thiagokokada /modules/services/cbatticon.nix @pmiddend +/modules/services/clipman.nix @jwygoda +/tests/modules/services/clipman @jwygoda + /modules/services/clipmenu.nix @DamienCassou /modules/services/devilspie2.nix @dawidsowa diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml index b06db161fcf3..924287d769ce 100644 --- a/.github/workflows/update-flake.yml +++ b/.github/workflows/update-flake.yml @@ -14,7 +14,7 @@ jobs: - name: Install Nix uses: cachix/install-nix-action@v18 - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@v15 + uses: DeterminateSystems/update-flake-lock@v16 with: token: ${{ secrets.GH_TOKEN_FOR_UPDATES }} pr-labels: dependencies diff --git a/docs/contributing.adoc b/docs/contributing.adoc index 82a07a9a8b1e..7ab95289380e 100644 --- a/docs/contributing.adoc +++ b/docs/contributing.adoc @@ -28,6 +28,11 @@ Assuming your clone is at `$HOME/devel/home-manager` then you can make the `home [source,console] $ home-manager -I home-manager=$HOME/devel/home-manager + +or, if using <>: ++ +[source,console] +$ home-manager --override-input home-manager ~/devel/home-manager ++ or 2. changing the default path by ensuring your configuration includes diff --git a/docs/default.nix b/docs/default.nix index dc304ae23009..c04f733a3f0c 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -7,8 +7,8 @@ let nmdSrc = fetchTarball { url = - "https://gitlab.com/api/v4/projects/rycee%2Fnmd/repository/archive.tar.gz?sha=b75d312b4f33bd3294cd8ae5c2ca8c6da2afc169"; - sha256 = "0c2nq28rw4v559s3f1nf6y2p6fladgmbqgbsyf3vzs2przn5qn37"; + "https://git.sr.ht/~rycee/nmd/archive/590dd725f3b06fb3888311efaab7312e03f605d1.tar.gz"; + sha256 = "0hzg802rnxpfiwwvk12kxhqxnfhg3snin6h7lrq5yk626hj6n6jj"; }; nmd = import nmdSrc { inherit lib pkgs; }; diff --git a/docs/installation.adoc b/docs/installation.adoc index 6291fba04fb5..afdbe35e9a27 100644 --- a/docs/installation.adoc +++ b/docs/installation.adoc @@ -58,16 +58,6 @@ and if you follow a Nixpkgs version 22.11 channel you can run $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-22.11.tar.gz home-manager $ nix-channel --update ---- -+ -On non-NixOS, you may have to add -+ -[source,bash] -export NIX_PATH=$HOME/.nix-defexpr/channels:/nix/var/nix/profiles/per-user/root/channels${NIX_PATH:+:$NIX_PATH} -+ -to your shell (see https://github.com/NixOS/nix/issues/2033[nix#2033] -and -https://discourse.nixos.org/t/where-is-nix-path-supposed-to-be-set/16434/8[this -reply on the Nix Discourse]). 3. Run the Home Manager installation command and create the first Home Manager generation: diff --git a/docs/man-home-manager.xml b/docs/man-home-manager.xml index 513973e98cce..e83cab89880d 100644 --- a/docs/man-home-manager.xml +++ b/docs/man-home-manager.xml @@ -179,6 +179,10 @@ --no-out-link + + --refresh + + @@ -611,6 +615,18 @@ + + + + + + + Passed on to + nix-build + 1 + + + diff --git a/docs/nix-flakes.adoc b/docs/nix-flakes.adoc index d426e337f1c4..2e00c9e63e98 100644 --- a/docs/nix-flakes.adoc +++ b/docs/nix-flakes.adoc @@ -6,7 +6,7 @@ Home Manager includes a `flake.nix` file for compatibility with {nixos-wiki-flakes}[Nix Flakes]. The support is still experimental and may change in backwards incompatible ways. -[[sec-flakes-prerequisties]] +[[sec-flakes-prerequisites]] === Prerequisites * Install Nix 2.4 or later, or have it in `nix-shell`. diff --git a/docs/release-notes/rl-2305.adoc b/docs/release-notes/rl-2305.adoc index 8c737db12aba..befd1b649598 100644 --- a/docs/release-notes/rl-2305.adoc +++ b/docs/release-notes/rl-2305.adoc @@ -8,7 +8,16 @@ This is the current unstable branch and the information in this section is there This release has the following notable changes: -* No highlights. +* Firefox add-ons are now managed per-profile. +That is, if you are currently having ++ +[source,nix] +programs.firefox.extensions = [ foo bar ]; ++ +in your configuration then you must change it to ++ +[source,nix] +programs.firefox.profiles.myprofile.extensions = [ foo bar ]; [[sec-release-23.05-state-version-changes]] === State Version Changes @@ -16,4 +25,8 @@ This release has the following notable changes: The state version in this release includes the changes below. These changes are only active if the `home.stateVersion` option is set to "23.05" or later. -* No changes. +* The <>, +<>, +<>, +<>, options now default to `true` which +is consistent with the default values for those options used by `i3` and `sway`. diff --git a/flake.lock b/flake.lock index 483046f51d9f..f8d0f32e383b 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1671200928, - "narHash": "sha256-mZfzDyzojwj6I0wyooIjGIn81WtGVnx6+avU5Wv+VKU=", + "lastModified": 1675115703, + "narHash": "sha256-4zetAPSyY0D77x+Ww9QBe8RHn1akvIvHJ/kgg8kGDbk=", "owner": "nixos", "repo": "nixpkgs", - "rev": "757b82211463dd5ba1475b6851d3731dfe14d377", + "rev": "2caf4ef5005ecc68141ecb4aac271079f7371c44", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 512111702da4..e64b2ea7848a 100644 --- a/flake.nix +++ b/flake.nix @@ -56,7 +56,7 @@ - 'system' have been removed. Instead use the arguments 'pkgs' and - 'modules'. See the 22.11 release notes for more. + 'modules'. See the 22.11 release notes for more: https://nix-community.github.io/home-manager/release-notes.html#sec-release-22.11-highlights ''; throwForRemovedArgs = v: diff --git a/format b/format index 68751a3f78f4..ef5528b76588 100755 --- a/format +++ b/format @@ -21,7 +21,6 @@ find . -name '*.nix' \ ! -path ./modules/lib/default.nix \ ! -path ./modules/lib/file-type.nix \ ! -path ./modules/misc/news.nix \ - ! -path ./modules/programs/bash.nix \ ! -path ./modules/programs/ssh.nix \ ! -path ./modules/programs/zsh.nix \ ! -path ./tests/default.nix \ diff --git a/home-manager/completion.bash b/home-manager/completion.bash index c55122991744..152f8c3257f1 100644 --- a/home-manager/completion.bash +++ b/home-manager/completion.bash @@ -296,7 +296,7 @@ _home-manager_completions () "-L" "--print-build-logs" \ "--show-trace" "--substitute" "--builders" "--version" \ "--update-input" "--override-input" "--experimental-features" \ - "--extra-experimental-features" ) + "--extra-experimental-features" "--refresh") # ^ « home-manager »'s options. diff --git a/home-manager/completion.fish b/home-manager/completion.fish index 58ce386e69f3..3781d3a714e8 100644 --- a/home-manager/completion.fish +++ b/home-manager/completion.fish @@ -69,3 +69,4 @@ complete -c home-manager -f -l "update-input" complete -c home-manager -f -l "override-input" complete -c home-manager -f -l "experimental-features" complete -c home-manager -f -l "extra-experimental-features" +complete -c home-manager -f -l "refresh" -d "Consider all previously downloaded files out-of-date" diff --git a/home-manager/completion.zsh b/home-manager/completion.zsh index 3babc1feef21..c5d3b49369c0 100644 --- a/home-manager/completion.zsh +++ b/home-manager/completion.zsh @@ -63,6 +63,7 @@ case "$state" in '--show-trace[show trace]' \ '--substitute[substitute]' \ '--builders[builders]:SPEC:()' \ + '--refresh[refresh]' \ '--override-input[override flake input]:NAME VALUE:()' \ '--update-input[update flake input]:NAME:()' \ '--experimental-features[set experimental Nix features]:VALUE:()' \ diff --git a/home-manager/home-manager b/home-manager/home-manager index 86623972563e..9e0f4ae0ed70 100644 --- a/home-manager/home-manager +++ b/home-manager/home-manager @@ -87,7 +87,7 @@ function setHomeManagerNixPath() { "${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home-manager" \ "$HOME/.nixpkgs/home-manager" ; do if [[ -e "$path" || "$path" =~ ^https?:// ]] ; then - export NIX_PATH="home-manager=$path${NIX_PATH:+:}$NIX_PATH" + EXTRA_NIX_PATH+=("home-manager=$path") return fi done @@ -130,7 +130,6 @@ function doInspectOption() { exit 1 fi setConfigFile - setHomeManagerNixPath local extraArgs=("$@") @@ -170,7 +169,6 @@ function doInstantiate() { exit 1 fi setConfigFile - setHomeManagerNixPath local extraArgs=() @@ -192,7 +190,6 @@ function doInstantiate() { function doBuildAttr() { setConfigFile - setHomeManagerNixPath local extraArgs=("$@") @@ -559,6 +556,7 @@ function doHelp() { echo " --no-out-link Do not create a symlink to the output path" echo " --no-write-lock-file" echo " --builders VALUE" + echo " --refresh Consider all previously downloaded files out-of-date" echo echo "Commands" echo @@ -602,6 +600,8 @@ COMMAND="" COMMAND_ARGS=() FLAKE_ARG="" +setHomeManagerNixPath + while [[ $# -gt 0 ]]; do opt="$1" shift @@ -629,7 +629,7 @@ while [[ $# -gt 0 ]]; do FLAKE_ARG="$1" shift ;; - --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file) + --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file|--refresh) PASSTHROUGH_OPTS+=("$opt") ;; --update-input) diff --git a/home-manager/po/lt.po b/home-manager/po/lt.po new file mode 100644 index 000000000000..52b3cab63b3e --- /dev/null +++ b/home-manager/po/lt.po @@ -0,0 +1,186 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Home Manager contributors +# This file is distributed under the same license as the Home Manager package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2022-03-26 15:08+0100\n" +"PO-Revision-Date: 2023-01-09 11:33+0000\n" +"Last-Translator: Kornelijus Tvarijanavičius \n" +"Language-Team: Lithuanian \n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n % 10 == 1 && (n % 100 < 11 || n % 100 > " +"19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? " +"1 : 2);\n" +"X-Generator: Weblate 4.15.1-dev\n" + +#: home-manager/home-manager:60 +msgid "No configuration file found at %s" +msgstr "Nerastas konfigūracijos failas %s" + +#: home-manager/home-manager:79 +msgid "No configuration file found. Please create one at %s" +msgstr "Nerastas konfigūracijos failas. Sukurkite jį adresu %s" + +#: home-manager/home-manager:122 +msgid "Can't inspect options of a flake configuration" +msgstr "Negalima patikrinti flake konfigūracijos pasirinkimų" + +#: home-manager/home-manager:162 +msgid "Can't instantiate a flake configuration" +msgstr "Negalima sukurti pradinės flake konfigūracijos" + +#: home-manager/home-manager:237 +msgid "" +"There is %d unread and relevant news item.\n" +"Read it by running the command \"%s news\"." +msgid_plural "" +"There are %d unread and relevant news items.\n" +"Read them by running the command \"%s news\"." +msgstr[0] "" +"Yra %d neperskaityta ir aktuali naujiena.\n" +"Perskaitykite ją paleidus komandą \"%s news\"." +msgstr[1] "" +"Yra %d neperskaitytos ir aktualios naujienos.\n" +"Perskaitykite jas paleidus komandą \"%s news\"." +msgstr[2] "" +"Yra %d neperskaitytų ir aktualių naujienų.\n" +"Perskaitykite jas paleidus komandą \"%s news\"." + +#: home-manager/home-manager:251 +msgid "Unknown \"news.display\" setting \"%s\"." +msgstr "Nežinomas \"news.display\" nustatymas \"%s\"." + +#: home-manager/home-manager:258 +#, sh-format +msgid "Please set the $EDITOR environment variable" +msgstr "Prašome nustatyti $EDITOR aplinkos kintamąjį" + +#: home-manager/home-manager:273 +msgid "Cannot run build in read-only directory" +msgstr "" + +#: home-manager/home-manager:355 +msgid "No generation with ID %s" +msgstr "Nėra generacijos su ID %s" + +#: home-manager/home-manager:357 +msgid "Cannot remove the current generation %s" +msgstr "Negalima pašalinti esamos generacijos %s" + +#: home-manager/home-manager:359 +msgid "Removing generation %s" +msgstr "Pašalinama generacija %s" + +#: home-manager/home-manager:385 +msgid "No generations to expire" +msgstr "" + +#: home-manager/home-manager:396 +msgid "No home-manager packages seem to be installed." +msgstr "Nėra instaliuotų home-manager paketų." + +#: home-manager/home-manager:453 +msgid "Unknown argument %s" +msgstr "Nežinomas argumentas %s" + +#: home-manager/home-manager:469 +msgid "This will remove Home Manager from your system." +msgstr "Tai pašalins Home Manager iš jūsų sistemos." + +#: home-manager/home-manager:472 +msgid "This is a dry run, nothing will actually be uninstalled." +msgstr "Tai bandomasis paleidimas, niekas nebus ištrinta." + +#: home-manager/home-manager:476 +msgid "Really uninstall Home Manager?" +msgstr "Tikrai išdiegti Home Manager?" + +#: home-manager/home-manager:481 +msgid "Switching to empty Home Manager configuration..." +msgstr "Perjungiama į tuščią Home Manager konfigūraciją..." + +#: home-manager/home-manager:493 +msgid "Yay!" +msgstr "Valio!" + +#: home-manager/home-manager:500 +msgid "Remove all Home Manager generations?" +msgstr "Pašalinti visas Home Manager generacijas?" + +#: home-manager/home-manager:507 +msgid "All generations are now eligible for garbage collection." +msgstr "" +"Visos generacijos jau tinkamos šiukšlių surinkimui (garbage collection)." + +#: home-manager/home-manager:510 +msgid "Leaving generations but they may still be garbage collected." +msgstr "" + +#: home-manager/home-manager:514 +msgid "Home Manager is uninstalled but your home.nix is left untouched." +msgstr "Home Manager yra išdiegtas, bet jūsų home.nix liko nepaliestas." + +#: home-manager/home-manager:673 +msgid "%s: unknown option '%s'" +msgstr "%s: nežinomas pasirinkimas „%s“" + +#: home-manager/home-manager:674 +msgid "Run '%s --help' for usage help" +msgstr "Paleiskite „%s --help“, kad gautumėte naudojimosi instrukcijas" + +#: home-manager/home-manager:708 +msgid "expire-generations expects one argument, got %d." +msgstr "expire-generations tikisi vieno argumento, gauta %d." + +#: home-manager/home-manager:730 +msgid "Unknown command: %s" +msgstr "Nežinoma komanda: %s" + +#: home-manager/install.nix:22 +msgid "Creating initial Home Manager configuration..." +msgstr "Kuriama pradinė Home Manager konfigūracija..." + +#: home-manager/install.nix:66 +msgid "Creating initial Home Manager generation..." +msgstr "Kuriama pradinė Home Manager generacija..." + +#. translators: The "%s" specifier will be replaced by a file path. +#: home-manager/install.nix:71 +msgid "" +"All done! The home-manager tool should now be installed and you can edit\n" +"\n" +" %s\n" +"\n" +"to configure Home Manager. Run 'man home-configuration.nix' to\n" +"see all available options." +msgstr "" +"Viskas baigta! Įrankis home-manager turėtų būti įdiegtas ir dabar galite " +"redaguoti\n" +"\n" +". . . .%s\n" +"\n" +", kad konfigūruotumėte Home Manager. Paleiskite „man home-configuration.nix“," +"\n" +"jei norite pamatyti visus pasirinkimus." + +#. translators: The "%s" specifier will be replaced by a URL. +#: home-manager/install.nix:76 +msgid "" +"Uh oh, the installation failed! Please create an issue at\n" +"\n" +" %s\n" +"\n" +"if the error seems to be the fault of Home Manager." +msgstr "" + +#: home-manager/install.nix:83 +msgid "This derivation is not buildable, please run it using nix-shell." +msgstr "" diff --git a/home-manager/po/nb_NO.po b/home-manager/po/nb_NO.po index 55127791d390..4ab763af5609 100644 --- a/home-manager/po/nb_NO.po +++ b/home-manager/po/nb_NO.po @@ -8,16 +8,16 @@ msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2022-03-26 15:08+0100\n" -"PO-Revision-Date: 2021-12-13 20:50+0000\n" -"Last-Translator: Allan Nordhøy \n" -"Language-Team: Norwegian Bokmål \n" +"PO-Revision-Date: 2023-01-08 11:50+0000\n" +"Last-Translator: Petter K \n" +"Language-Team: Norwegian Bokmål \n" "Language: nb_NO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10-dev\n" +"X-Generator: Weblate 4.15.1-dev\n" #: home-manager/home-manager:60 msgid "No configuration file found at %s" @@ -139,12 +139,13 @@ msgid "Unknown command: %s" msgstr "Ukjent kommando: %s" #: home-manager/install.nix:22 +#, fuzzy msgid "Creating initial Home Manager configuration..." -msgstr "" +msgstr "Oppretter ny Home Manager-konfigurasjon..." #: home-manager/install.nix:66 msgid "Creating initial Home Manager generation..." -msgstr "" +msgstr "Oppretter ny Home Manager-generasjon..." #. translators: The "%s" specifier will be replaced by a file path. #: home-manager/install.nix:71 diff --git a/modules/config/home-cursor.nix b/modules/config/home-cursor.nix index d8cbb53903ed..18bc04c1e5ec 100644 --- a/modules/config/home-cursor.nix +++ b/modules/config/home-cursor.nix @@ -97,7 +97,7 @@ in { description = '' Cursor configuration. Set to null to disable. - Top-level options declared under this submodule are backend indepedent + Top-level options declared under this submodule are backend independent options. Options declared under namespaces such as x11 are backend specific options. By default, only backend independent cursor configurations are generated. If you need configurations for specific @@ -131,8 +131,8 @@ in { # https://github.com/nix-community/home-manager/issues/2812 # https://wiki.archlinux.org/title/Cursor_themes#Environment_variable home.sessionVariables = { - XCURSOR_PATH = "$XCURSOR_PATH\${XCURSOR_PATH:+:}" - + "${config.home.profileDirectory}/share/icons"; + XCURSOR_PATH = mkDefault ("$XCURSOR_PATH\${XCURSOR_PATH:+:}" + + "${config.home.profileDirectory}/share/icons"); }; } diff --git a/modules/files.nix b/modules/files.nix index a7fd67f57a0b..0f4207fe8c0e 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -4,7 +4,7 @@ with lib; let - cfg = config.home.file; + cfg = filterAttrs (n: f: f.enable) config.home.file; homeDirectory = config.home.homeDirectory; @@ -185,8 +185,9 @@ in $VERBOSE_ECHO "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. $DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")" - $DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath" + $DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$sourcePath" "$targetPath" || exit 1 fi done ''; diff --git a/modules/home-environment.nix b/modules/home-environment.nix index bf83f0d28601..098e10b21c08 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -256,7 +256,7 @@ in home.sessionVariables = mkOption { default = {}; - type = types.attrs; + type = with types; lazyAttrsOf (oneOf [ str path int float ]); example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; }; description = '' Environment variables to always set at login. diff --git a/modules/lib-bash/activation-init.sh b/modules/lib-bash/activation-init.sh old mode 100755 new mode 100644 index aadc88dd3555..3b0f5320ade9 --- a/modules/lib-bash/activation-init.sh +++ b/modules/lib-bash/activation-init.sh @@ -1,5 +1,3 @@ -#!/usr/bin/env bash - function setupVars() { local nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}" local profilesPath="$nixStateDir/profiles/per-user/$USER" diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix index cc23292ba006..b12b3262a160 100644 --- a/modules/lib/file-type.nix +++ b/modules/lib/file-type.nix @@ -15,6 +15,14 @@ in fileType = basePathDesc: basePath: types.attrsOf (types.submodule ( { name, config, ... }: { options = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether this file should be generated. This option allows specific + files to be disabled. + ''; + }; target = mkOption { type = types.str; apply = p: diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 382fe302733a..0b7784d43384 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -233,6 +233,12 @@ githubId = 1553581; name = "Josh Robson Chase"; }; + jwygoda = { + name = "Jarosław Wygoda"; + email = "jaroslaw@wygoda.me"; + github = "jwygoda"; + githubId = 20658981; + }; hawkw = { name = "Eliza Weisman"; email = "eliza@elizas.website"; @@ -351,9 +357,8 @@ matrix = "@soywod:matrix.org"; github = "soywod"; githubId = 10437171; - keys = [{ - fingerprint = "75F0 AB7C FE01 D077 AEE6 CAFD 353E 4A18 EE0F AB72"; - }]; + keys = + [{ fingerprint = "75F0 AB7C FE01 D077 AEE6 CAFD 353E 4A18 EE0F AB72"; }]; }; toastal = { email = "toastal+nix@posteo.net"; @@ -364,4 +369,11 @@ keys = [{ fingerprint = "7944 74B7 D236 DAB9 C9EF E7F9 5CCE 6F14 66D4 7C9E"; }]; }; + tomodachi94 = { + email = "tomodachi94+nixpkgs@protonmail.com"; + matrix = "@tomodachi94:matrix.org"; + github = "tomodachi94"; + githubId = 68489118; + name = "tomodachi94"; + }; } diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 1be3e26fa556..57c5574fdd79 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -869,6 +869,52 @@ in A new module is available: 'services.cachix-agent'. ''; } + + { + time = "2022-12-28T21:48:22+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.clipman'. + ''; + } + + { + time = "2023-01-07T10:47:03+00:00"; + condition = hostPlatform.isLinux; + message = '' + 'xsession.windowManager.i3.config.[window|floating].titlebar' and + 'wayland.windowManager.sway.config.[window|floating].titlebar' now default to 'true'. + ''; + } + + { + time = "2023-01-28T17:35:49+00:00"; + message = '' + A new module is available: 'programs.papis'. + ''; + } + + { + time = "2023-01-30T10:39:11+00:00"; + message = '' + A new module is available: 'programs.wlogout'. + ''; + } + + { + time = "2023-01-31T22:08:41+00:00"; + message = '' + A new module is available: 'programs.rbenv'. + ''; + } + + { + time = "2023-02-02T20:49:05+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.autorandr'. + ''; + } ]; }; } diff --git a/modules/misc/nix.nix b/modules/misc/nix.nix index 6ae28157a34f..785a7c044182 100644 --- a/modules/misc/nix.nix +++ b/modules/misc/nix.nix @@ -212,29 +212,28 @@ in { }; }; - config = mkIf cfg.enable { - assertions = [{ - assertion = cfg.settings == { } || cfg.package != null; - message = '' - A corresponding Nix package must be specified via `nix.package` for generating - nix.conf. - ''; - }]; - - xdg.configFile = { - "nix/registry.json" = mkIf (cfg.registry != { }) { - source = jsonFormat.generate "registry.json" { + config = mkIf cfg.enable (mkMerge [ + (mkIf (cfg.registry != { }) { + xdg.configFile."nix/registry.json".source = + jsonFormat.generate "registry.json" { version = cfg.registryVersion; flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry; }; - }; + }) + + (mkIf (cfg.settings != { } || cfg.extraOptions != "") { + assertions = [{ + assertion = cfg.package != null; + message = '' + A corresponding Nix package must be specified via `nix.package` for generating + nix.conf. + ''; + }]; - "nix/nix.conf" = mkIf (cfg.settings != { } || cfg.extraOptions != "") { - source = nixConf; - }; - }; - }; + xdg.configFile."nix/nix.conf".source = nixConf; + }) + ]); meta.maintainers = [ maintainers.polykernel ]; } diff --git a/modules/modules.nix b/modules/modules.nix index 44aa17da431e..391ad5bd7c4c 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -144,6 +144,7 @@ let ./programs/oh-my-posh.nix ./programs/opam.nix ./programs/pandoc.nix + ./programs/papis.nix ./programs/password-store.nix ./programs/pazi.nix ./programs/pet.nix @@ -185,12 +186,15 @@ let ./programs/topgrade.nix ./programs/urxvt.nix ./programs/vim.nix + ./programs/vim-vint.nix ./programs/vscode.nix ./programs/vscode/haskell.nix ./programs/pywal.nix + ./programs/rbenv.nix ./programs/watson.nix ./programs/waybar.nix ./programs/wezterm.nix + ./programs/wlogout.nix ./programs/xmobar.nix ./programs/yt-dlp.nix ./programs/z-lua.nix @@ -200,6 +204,7 @@ let ./programs/zplug.nix ./programs/zsh.nix ./programs/zsh/prezto.nix + ./services/autorandr.nix ./services/barrier.nix ./services/betterlockscreen.nix ./services/blueman-applet.nix @@ -207,6 +212,7 @@ let ./services/cachix-agent.nix ./services/caffeine.nix ./services/cbatticon.nix + ./services/clipman.nix ./services/clipmenu.nix ./services/devilspie2.nix ./services/dropbox.nix diff --git a/modules/po/lt.po b/modules/po/lt.po new file mode 100644 index 000000000000..166bf8085411 --- /dev/null +++ b/modules/po/lt.po @@ -0,0 +1,97 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Home Manager contributors +# This file is distributed under the same license as the Home Manager Modules package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager Modules\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2022-03-26 15:08+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/files.nix:233 +msgid "Creating home file links in %s" +msgstr "" + +#: modules/files.nix:246 +msgid "Cleaning up orphan links from %s" +msgstr "" + +#: modules/files.nix:262 +msgid "Creating profile generation %s" +msgstr "" + +#: modules/files.nix:276 +msgid "No change so reusing latest profile generation %s" +msgstr "" + +#: modules/home-environment.nix:607 +msgid "" +"Oops, Nix failed to install your new Home Manager profile!\n" +"\n" +"Perhaps there is a conflict with a package that was installed using\n" +"\"%s\"? Try running\n" +"\n" +" %s\n" +"\n" +"and if there is a conflicting package you can remove it with\n" +"\n" +" %s\n" +"\n" +"Then try activating your Home Manager configuration again." +msgstr "" + +#: modules/home-environment.nix:639 +msgid "Activating %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:31 +msgid "Sanity checking oldGenNum and oldGenPath" +msgstr "" + +#: modules/lib-bash/activation-init.sh:34 +msgid "" +"The previous generation number and path are in conflict! These\n" +"must be either both empty or both set but are now set to\n" +"\n" +" '%s' and '%s'\n" +"\n" +"If you don't mind losing previous profile generations then\n" +"the easiest solution is probably to run\n" +"\n" +" rm %s/home-manager*\n" +" rm %s/current-home\n" +"\n" +"and trying home-manager switch again. Good luck!" +msgstr "" + +#: modules/lib-bash/activation-init.sh:51 +msgid "Starting Home Manager activation" +msgstr "" + +#: modules/lib-bash/activation-init.sh:55 +msgid "Sanity checking Nix" +msgstr "" + +#: modules/lib-bash/activation-init.sh:61 +msgid "This is a dry run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:64 +msgid "This is a live run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:69 +msgid "Using Nix version: %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:72 +msgid "Activation variables:" +msgstr "" diff --git a/modules/po/zh_Hant.po b/modules/po/zh_Hant.po index 06f379e0987d..0e7fc6f84cb7 100644 --- a/modules/po/zh_Hant.po +++ b/modules/po/zh_Hant.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2022-03-26 15:08+0100\n" -"PO-Revision-Date: 2021-12-29 08:48+0000\n" -"Last-Translator: WhiredPlanck \n" +"PO-Revision-Date: 2023-01-08 11:50+0000\n" +"Last-Translator: Eric Ho \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.10.1\n" +"X-Generator: Weblate 4.15.1-dev\n" #: modules/files.nix:233 msgid "Creating home file links in %s" @@ -50,6 +50,18 @@ msgid "" "\n" "Then try activating your Home Manager configuration again." msgstr "" +"糟糕,Nix 未能安裝您的新 Home Manager 配置文件!\n" +"\n" +"也許這裏和使用 \"%s\" 安裝的包有衝突?\n" +"嘗試運行\n" +"\n" +" %s\n" +"\n" +"如果有衝突的包,你可以用\n" +"\n" +" %s\n" +"\n" +"來移除。然後嘗試再次啟用您的 Home Manager 配置。" #: modules/home-environment.nix:639 msgid "Activating %s" @@ -57,7 +69,7 @@ msgstr "正在啟用 %s" #: modules/lib-bash/activation-init.sh:31 msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" +msgstr "正在進行 oldGenNum 和 oldGenPath 的完整性檢查" #: modules/lib-bash/activation-init.sh:34 msgid "" @@ -81,20 +93,20 @@ msgstr "正在啟動 Home Manager 初始化程式" #: modules/lib-bash/activation-init.sh:55 msgid "Sanity checking Nix" -msgstr "" +msgstr "正在進行 Nix 完整性檢查" #: modules/lib-bash/activation-init.sh:61 msgid "This is a dry run" -msgstr "" +msgstr "這是試運行" #: modules/lib-bash/activation-init.sh:64 msgid "This is a live run" -msgstr "" +msgstr "這是在實際運行" #: modules/lib-bash/activation-init.sh:69 msgid "Using Nix version: %s" -msgstr "" +msgstr "正在使用的 Nix 版本: %s" #: modules/lib-bash/activation-init.sh:72 msgid "Activation variables:" -msgstr "" +msgstr "啟用的變數:" diff --git a/modules/programs/bash.nix b/modules/programs/bash.nix index 742087b7d8b1..0c0643da8458 100644 --- a/modules/programs/bash.nix +++ b/modules/programs/bash.nix @@ -6,16 +6,15 @@ let cfg = config.programs.bash; - writeBashScript = name: text: pkgs.writeTextFile { - inherit name text; - checkPhase = '' - ${pkgs.stdenv.shellDryRun} "$target" - ''; - }; - -in + writeBashScript = name: text: + pkgs.writeTextFile { + inherit name text; + checkPhase = '' + ${pkgs.stdenv.shellDryRun} "$target" + ''; + }; -{ +in { meta.maintainers = [ maintainers.rycee ]; imports = [ @@ -70,20 +69,18 @@ in }; historyControl = mkOption { - type = types.listOf (types.enum [ - "erasedups" - "ignoredups" - "ignorespace" - ]); - default = []; + type = + types.listOf (types.enum [ "erasedups" "ignoredups" "ignorespace" ]); + default = [ ]; description = "Controlling how commands are saved on the history list."; }; historyIgnore = mkOption { type = types.listOf types.str; - default = []; + default = [ ]; example = [ "ls" "cd" "exit" ]; - description = "List of commands that should not be saved to the history list."; + description = + "List of commands that should not be saved to the history list."; }; shellOptions = mkOption { @@ -103,10 +100,7 @@ in # Warn if closing shell with running jobs. "checkjobs" ]; - example = [ - "extglob" - "-cdspell" - ]; + example = [ "extglob" "-cdspell" ]; description = '' Shell options to set. Prefix an option with - to unset. @@ -114,7 +108,7 @@ in }; sessionVariables = mkOption { - default = {}; + default = { }; type = types.attrs; example = { MAILCHECK = 30; }; description = '' @@ -123,7 +117,7 @@ in }; shellAliases = mkOption { - default = {}; + default = { }; type = types.attrsOf types.str; example = literalExpression '' { @@ -175,80 +169,71 @@ in }; }; - config = ( - let - aliasesStr = concatStringsSep "\n" ( - mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}") cfg.shellAliases - ); - - shoptsStr = let - switch = v: if hasPrefix "-" v then "-u" else "-s"; - in concatStringsSep "\n" ( - map (v: "shopt ${switch v} ${removePrefix "-" v}") cfg.shellOptions - ); - - sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables; - - historyControlStr = - concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") ( - { - HISTFILESIZE = toString cfg.historyFileSize; - HISTSIZE = toString cfg.historySize; - } - // optionalAttrs (cfg.historyFile != null) { - HISTFILE = "\"${cfg.historyFile}\""; - } - // optionalAttrs (cfg.historyControl != []) { - HISTCONTROL = concatStringsSep ":" cfg.historyControl; - } - // optionalAttrs (cfg.historyIgnore != []) { - HISTIGNORE = escapeShellArg (concatStringsSep ":" cfg.historyIgnore); - } - )); - in mkIf cfg.enable { - home.file.".bash_profile".source = writeBashScript "bash_profile" '' - # include .profile if it exists - [[ -f ~/.profile ]] && . ~/.profile - - # include .bashrc if it exists - [[ -f ~/.bashrc ]] && . ~/.bashrc - ''; + config = let + aliasesStr = concatStringsSep "\n" + (mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}") + cfg.shellAliases); + + shoptsStr = let switch = v: if hasPrefix "-" v then "-u" else "-s"; + in concatStringsSep "\n" + (map (v: "shopt ${switch v} ${removePrefix "-" v}") cfg.shellOptions); + + sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables; + + historyControlStr = concatStringsSep "\n" + (mapAttrsToList (n: v: "${n}=${v}") ({ + HISTFILESIZE = toString cfg.historyFileSize; + HISTSIZE = toString cfg.historySize; + } // optionalAttrs (cfg.historyFile != null) { + HISTFILE = ''"${cfg.historyFile}"''; + } // optionalAttrs (cfg.historyControl != [ ]) { + HISTCONTROL = concatStringsSep ":" cfg.historyControl; + } // optionalAttrs (cfg.historyIgnore != [ ]) { + HISTIGNORE = escapeShellArg (concatStringsSep ":" cfg.historyIgnore); + })); + in mkIf cfg.enable { + home.file.".bash_profile".source = writeBashScript "bash_profile" '' + # include .profile if it exists + [[ -f ~/.profile ]] && . ~/.profile + + # include .bashrc if it exists + [[ -f ~/.bashrc ]] && . ~/.bashrc + ''; - # If completion is enabled then make sure it is sourced very early. This - # is to avoid problems if any other initialization code attempts to set up - # completion. - programs.bash.initExtra = mkIf cfg.enableCompletion (mkOrder 100 '' - if [[ ! -v BASH_COMPLETION_VERSINFO ]]; then - . "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" - fi - ''); + # If completion is enabled then make sure it is sourced very early. This + # is to avoid problems if any other initialization code attempts to set up + # completion. + programs.bash.initExtra = mkIf cfg.enableCompletion (mkOrder 100 '' + if [[ ! -v BASH_COMPLETION_VERSINFO ]]; then + . "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" + fi + ''); - home.file.".profile".source = writeBashScript "profile" '' - . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" + home.file.".profile".source = writeBashScript "profile" '' + . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" - ${sessionVarsStr} + ${sessionVarsStr} - ${cfg.profileExtra} - ''; + ${cfg.profileExtra} + ''; - home.file.".bashrc".source = writeBashScript "bashrc" '' - ${cfg.bashrcExtra} + home.file.".bashrc".source = writeBashScript "bashrc" '' + ${cfg.bashrcExtra} - # Commands that should be applied only for interactive shells. - [[ $- == *i* ]] || return + # Commands that should be applied only for interactive shells. + [[ $- == *i* ]] || return - ${historyControlStr} + ${historyControlStr} - ${shoptsStr} + ${shoptsStr} - ${aliasesStr} + ${aliasesStr} - ${cfg.initExtra} - ''; + ${cfg.initExtra} + ''; - home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") { - source = writeBashScript "bash_logout" cfg.logoutExtra; - }; - } - ); + home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") { + source = writeBashScript "bash_logout" cfg.logoutExtra; + }; + }; } diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index ad294b2e6c58..1d6ef2127d22 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -80,6 +80,15 @@ in { ''; }; + enableNushellIntegration = mkOption { + default = true; + type = types.bool; + readOnly = true; + description = '' + Whether to enable Nushell integration. + ''; + }; + nix-direnv = { enable = mkEnableOption '' . - Once you have NUR installed run - - - $ nix-env -f '<nixpkgs>' -qaP -A nur.repos.rycee.firefox-addons - - - to list the available Firefox add-ons. - - - - Note that it is necessary to manually enable these - extensions inside Firefox after the first installation. - - - - Extensions listed here will only be available in Firefox - profiles managed through the - - option. This is due to recent changes in the way Firefox - handles extension side-loading. - ''; - }; - profiles = mkOption { type = types.attrsOf (types.submodule ({ config, name, ... }: { options = { @@ -202,7 +176,10 @@ in { }; settings = mkOption { - type = with types; attrsOf (either bool (either int str)); + type = types.attrsOf (jsonFormat.type // { + description = + "Firefox preference (int, bool, string, and also attrs, list, float as a JSON string)"; + }); default = { }; example = literalExpression '' { @@ -212,9 +189,19 @@ in { "distribution.searchplugins.defaultLocale" = "en-GB"; "general.useragent.locale" = "en-GB"; "browser.bookmarks.showMobileBookmarks" = true; + "browser.newtabpage.pinned" = [{ + title = "NixOS"; + url = "https://nixos.org"; + }]; } ''; - description = "Attribute set of Firefox preferences."; + description = '' + Attribute set of Firefox preferences. + + Firefox only supports int, bool, and string types for + preferences, but home-manager will automatically + convert all other JSON-compatible values into strings. + ''; }; extraConfig = mkOption { @@ -434,6 +421,34 @@ in { ''; }; }; + + extensions = mkOption { + type = types.listOf types.package; + default = [ ]; + example = literalExpression '' + with pkgs.nur.repos.rycee.firefox-addons; [ + privacy-badger + ] + ''; + description = '' + List of Firefox add-on packages to install for this profile. + Some pre-packaged add-ons are accessible from NUR, + . + Once you have NUR installed run + + + $ nix-env -f '<nixpkgs>' -qaP -A nur.repos.rycee.firefox-addons + + + to list the available Firefox add-ons. + + + + Note that it is necessary to manually enable these extensions + inside Firefox after the first installation. + ''; + }; + }; })); default = { }; @@ -505,11 +520,6 @@ in { in [ package ]; home.file = mkMerge ([{ - "${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != [ ]) { - source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; - recursive = true; - }; - "${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != { }) { text = profilesIni; }; }] ++ flip mapAttrsToList cfg.profiles (_: profile: { @@ -534,79 +544,94 @@ in { source = let settings = { version = 6; - engines = let - allEngines = (profile.search.engines // - # If search.default isn't in search.engines, assume it's app - # provided and include it in the set of all engines - optionalAttrs (profile.search.default != null - && !(hasAttr profile.search.default - profile.search.engines)) { - ${profile.search.default} = { }; - }); - - # Map allEngines to a list and order by search.order - orderedEngineList = (imap (order: name: - let engine = allEngines.${name} or { }; - in engine // { - inherit name; - metaData = (engine.metaData or { }) // { inherit order; }; - }) profile.search.order) ++ (mapAttrsToList - (name: config: config // { inherit name; }) - (removeAttrs allEngines profile.search.order)); - - engines = map (config: - let - name = config.name; - isAppProvided = removeAttrs config [ "name" "metaData" ] - == { }; - metaData = config.metaData or { }; - in mapAttrs' (name: value: { - # Map nice field names to internal field names. This is - # intended to be exhaustive, but any future fields will - # either have to be specified with an underscore, or added - # to this map. - name = ((genAttrs [ - "name" - "isAppProvided" - "loadPath" - "hasPreferredIcon" - "updateInterval" - "updateURL" - "iconUpdateURL" - "iconURL" - "iconMapObj" - "metaData" - "orderHint" - "definedAliases" - "urls" - ] (name: "_${name}")) // { - "searchForm" = "__searchForm"; - }).${name} or name; + # Map of nice field names to internal field names. + # This is intended to be exhaustive and should be + # updated at every version bump. + internalFieldNames = (genAttrs [ + "name" + "isAppProvided" + "loadPath" + "hasPreferredIcon" + "updateInterval" + "updateURL" + "iconUpdateURL" + "iconURL" + "iconMapObj" + "metaData" + "orderHint" + "definedAliases" + "urls" + ] (name: "_${name}")) // { + searchForm = "__searchForm"; + }; + processCustomEngineInput = input: + (removeAttrs input [ "icon" ]) + // optionalAttrs (input ? icon) { + # Convenience to specify absolute path to icon + iconURL = "file://${input.icon}"; + } // (optionalAttrs (input ? iconUpdateURL) { + # Convenience to default iconURL to iconUpdateURL so + # the icon is immediately downloaded from the URL + iconURL = input.iconURL or input.iconUpdateURL; + } // { + # Required for custom engine configurations, loadPaths + # are unique identifiers that are generally formatted + # like: [source]/path/to/engine.xml + loadPath = '' + [home-manager]/programs.firefox.profiles.${profile.name}.search.engines."${ + replaceStrings [ "\\" ] [ "\\\\" ] input.name + }"''; + }); + + processEngineInput = name: input: + let + requiredInput = { + inherit name; + isAppProvided = input.isAppProvided or removeAttrs input + [ "metaData" ] == { }; + metaData = input.metaData or { }; + }; + in if requiredInput.isAppProvided then + requiredInput + else + processCustomEngineInput (input // requiredInput); + + buildEngineConfig = name: input: + mapAttrs' (name: value: { + name = internalFieldNames.${name} or name; inherit value; - }) ((removeAttrs config [ "icon" ]) - // (optionalAttrs (!isAppProvided) - (optionalAttrs (config ? iconUpdateURL) { - # Convenience to default iconURL to iconUpdateURL so - # the icon is immediately downloaded from the URL - iconURL = config.iconURL or config.iconUpdateURL; - } // optionalAttrs (config ? icon) { - # Convenience to specify absolute path to icon - iconURL = "file://${config.icon}"; - } // { - # Required for custom engine configurations, loadPaths - # are unique identifiers that are generally formatted - # like: [source]/path/to/engine.xml - loadPath = '' - [home-manager]/programs.firefox.profiles.${profile.name}.search.engines."${ - replaceStrings [ "\\" ] [ "\\\\" ] name - }"''; - })) // { - # Required fields for all engine configurations - inherit name isAppProvided metaData; - })) orderedEngineList; - in engines; + }) (processEngineInput name input); + + sortEngineConfigs = configs: + let + buildEngineConfigWithOrder = order: name: + let + config = configs.${name} or { + _name = name; + _isAppProvided = true; + _metaData = { }; + }; + in config // { + _metaData = config._metaData // { inherit order; }; + }; + + engineConfigsWithoutOrder = + attrValues (removeAttrs configs profile.search.order); + + sortedEngineConfigs = + (imap buildEngineConfigWithOrder profile.search.order) + ++ engineConfigsWithoutOrder; + in sortedEngineConfigs; + + engineInput = profile.search.engines // { + # Infer profile.search.default as an app provided + # engine if it's not in profile.search.engines + ${profile.search.default} = + profile.search.engines.${profile.search.default} or { }; + }; + in sortEngineConfigs (mapAttrs buildEngineConfig engineInput); metaData = optionalAttrs (profile.search.default != null) { current = profile.search.default; @@ -641,8 +666,13 @@ in { }; "${profilesPath}/${profile.path}/extensions" = - mkIf (cfg.extensions != [ ]) { - source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; + mkIf (profile.extensions != [ ]) { + source = let + extensionsEnvPkg = pkgs.buildEnv { + name = "hm-firefox-extensions"; + paths = profile.extensions; + }; + in "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; recursive = true; force = true; }; diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 55a7c1cc0d16..39dc246c05b2 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -150,7 +150,7 @@ let nativeBuildInputs = [ cfg.package ]; inherit text; passAsFile = [ "text" ]; - } "fish_indent < $textPath > $out"; + } "env HOME=$(mktemp -d) fish_indent < $textPath > $out"; in { imports = [ @@ -375,7 +375,7 @@ in { # Aliases ${aliasesStr} - # Interactive shell intialisation + # Interactive shell initialisation ${cfg.interactiveShellInit} end diff --git a/modules/programs/git.nix b/modules/programs/git.nix index 2b0d8a2f12e1..5bd828b306c1 100644 --- a/modules/programs/git.nix +++ b/modules/programs/git.nix @@ -527,10 +527,7 @@ in { "--background ${cfg.difftastic.background}" "--display ${cfg.difftastic.display}" ]; - in { - diff.external = difftCommand; - core.pager = "${pkgs.less}/bin/less -XF"; - }; + in { diff.external = difftCommand; }; }) (mkIf cfg.delta.enable { diff --git a/modules/programs/gitui.nix b/modules/programs/gitui.nix index ee6572bcaf13..710e3fd99836 100644 --- a/modules/programs/gitui.nix +++ b/modules/programs/gitui.nix @@ -41,6 +41,8 @@ in { selected_tab: Reset, command_fg: White, selection_bg: Blue, + selection_fg: White, + cmdbar_bg: Blue, cmdbar_extra_lines_bg: Blue, disabled_fg: DarkGray, diff_line_add: Green, @@ -55,6 +57,8 @@ in { danger_fg: Red, push_gauge_bg: Blue, push_gauge_fg: Reset, + tag_fg: LightMagenta, + branch_fg: LightYellow, ) ''; description = '' diff --git a/modules/programs/himalaya.nix b/modules/programs/himalaya.nix index 681f314a435a..96436b859ce9 100644 --- a/modules/programs/himalaya.nix +++ b/modules/programs/himalaya.nix @@ -7,19 +7,30 @@ let # attrs util that removes entries containing a null value compactAttrs = filterAttrs (_: val: !isNull val); + # aliases + himalaya = config.programs.himalaya; + himalaya-notify = config.services.himalaya-notify; + himalaya-watch = config.services.himalaya-watch; + globalCfg = { display-name = mkOption { type = nullOr str; default = null; example = "Jane Doe"; - description = "Name displayed when sending emails."; + description = '' + Name displayed when sending emails. + ''; }; signature-delim = mkOption { type = nullOr str; default = null; - example = "-- "; - description = "Delimiter used between the document and the signature."; + example = '' + -- + ''; + description = '' + Delimiter used between the document and the signature. + ''; }; signature = mkOption { @@ -27,53 +38,65 @@ let default = null; example = '' Regards, + Sent with Himalaya! + ''; + description = '' + Signature content (without delimiter). ''; - description = "Signature content (without delimiter)."; }; downloads-dir = mkOption { type = nullOr (oneOf [ path str ]); default = null; example = "~/Downloads"; - description = "Directory used to download email attachments."; + description = '' + Directory used to download email attachments. + ''; }; folder-listing-page-size = mkOption { type = nullOr int; default = null; example = "50"; - description = "Page size used when listing folders."; + description = '' + Page size used when listing folders. + ''; }; folder-aliases = mkOption { type = nullOr (attrsOf str); default = null; - example = ''{ + example = literalExpression '' + { inbox = "INBOX"; sent = "Sent"; drafts = "Drafts"; trash = "Trash"; - }''; - description = "Folder aliases."; + } + ''; + description = '' + Folder aliases. + ''; }; email-listing-page-size = mkOption { type = nullOr int; default = null; example = "50"; - description = "Page size used when listing emails."; + description = '' + Page size used when listing emails. + ''; }; email-reading-headers = mkOption { type = nullOr (listOf str); default = null; - example = ''[ - "From" - "To" - "Subject" - "Date" - ]''; - description = "Headers shown when reading emails."; + example = literalExpression '' + [ "From" "To" "Subject" "Date" ] + ''; + description = '' + Headers shown when reading emails. + ''; }; email-reading-format = mkOption { @@ -81,7 +104,9 @@ let default = null; example = "auto"; description = '' - Plain text format to use as defined in the RFC2646. + Plain text format to use as defined in the RFC + 2646. ''; }; @@ -106,12 +131,12 @@ let email-writing-headers = mkOption { type = nullOr (listOf str); default = null; - example = ''[ - "From" - "To" - "Subject" - ]''; - description = "Headers shown by default when writing emails."; + example = literalExpression '' + [ "From" "To" "Subject" ] + ''; + description = '' + Headers shown by default when writing emails. + ''; }; email-writing-sign-cmd = mkOption { @@ -126,32 +151,37 @@ let email-writing-encrypt-cmd = mkOption { type = nullOr str; default = null; - example = "gpg --output - --encrypt --quiet --armor --recipient "; + example = literalExpression '' + gpg --output - --encrypt --quiet --armor --recipient + ''; description = '' Command used to encrypt parts of an email. ''; }; - email-hooks = mkOption - { - type = nullOr (submodule { - options = { - pre-send = mkOption { - type = nullOr str; - default = null; - example = "bash compile-markdown.sh"; - description = "Command called just before sending an email."; - }; + email-hooks = mkOption { + type = nullOr (submodule { + options = { + pre-send = mkOption { + type = nullOr str; + default = null; + example = "bash compile-markdown.sh"; + description = '' + Command called just before sending an email. + ''; }; - }); - default = null; - example = ''{ + }; + }); + default = null; + example = literalExpression '' + { pre-send = "bash compile-markdown.sh"; - }''; - description = '' - Email processing lifecycle hooks. - ''; - }; + } + ''; + description = '' + Email processing lifecycle hooks. + ''; + }; }; accountCfg = globalCfg // { @@ -165,17 +195,38 @@ let primary = mkOption { type = nullOr bool; default = null; + example = "true"; description = '' Whether this is the primary account. Only one account may be set as primary. ''; }; - }; - imapCfg = { + sync = mkOption { + type = nullOr bool; + default = null; + example = "true"; + description = '' + Enable the synchronization feature for this account. + ''; + }; + + sync-dir = mkOption { + type = nullOr (oneOf [ path str ]); + default = null; + example = "~/.Mail"; + description = '' + Customize the Maildir folder used by the synchronization. + Default to $XDG_DATA_HOME/himalaya/. + ''; + }; + backend = mkOption { - type = nullOr (strMatching "imap"); + # TODO: notmuch (requires compile flag for himalaya, libnotmuch) + type = nullOr (enum [ "none" "imap" "maildir" ]); default = null; + example = "imap"; + description = "Backend used for this account."; }; imap-host = mkOption { @@ -190,7 +241,7 @@ let imap-port = mkOption { type = nullOr port; default = null; - example = 993; + example = "993"; description = '' The port on which the IMAP server listens. ''; @@ -199,7 +250,7 @@ let imap-ssl = mkOption { type = nullOr bool; default = null; - example = false; + example = "false"; description = '' Should enable SSL/TLS. ''; @@ -208,7 +259,7 @@ let imap-starttls = mkOption { type = nullOr bool; default = null; - example = false; + example = "false"; description = '' Should enable STARTTLS. ''; @@ -217,7 +268,7 @@ let imap-insecure = mkOption { type = nullOr bool; default = null; - example = false; + example = "false"; description = '' Should trust any certificate. ''; @@ -246,12 +297,13 @@ let imap-notify-cmd = mkOption { type = nullOr str; default = null; - example = '' - notify-send "📫 " "" + example = literalExpression '' + notify-send "📫 " "\" ''; - description = '' - Command used for real-time notifications. - Available placeholders: , or . + description = literalExpression '' + Command used for real-time notifications. Available + placeholders: , + or . ''; }; @@ -260,44 +312,39 @@ let default = null; example = "NOT SEEN"; description = '' - IMAP query used to fetch new emails - in order to by notified by notify-cmd. + IMAP query used to fetch new emails in order to by notified by + notify-cmd. ''; }; imap-watch-cmds = mkOption { type = nullOr (listOf str); default = null; - example = ''[ - "mbsync -a" - ]''; + example = literalExpression '' + [ "mbsync -a" ] + ''; description = '' Commands executed when changes occur on the IMAP server. ''; }; - }; - - maildirCfg = { - backend = mkOption { - type = nullOr (strMatching "maildir"); - default = null; - }; maildir-root-dir = mkOption { type = nullOr (oneOf [ path str ]); default = null; example = "~/.emails"; description = '' - Path to maildir directory where - emails for this account are stored. + Path to maildir directory where emails for this account are + stored. ''; }; - }; - smtpCfg = { sender = mkOption { - type = nullOr (strMatching "smtp"); + type = nullOr (enum [ "none" "smtp" "sendmail" ]); default = null; + example = "smtp"; + description = '' + Sender used for this account. + ''; }; smtp-host = mkOption { @@ -312,7 +359,7 @@ let smtp-port = mkOption { type = nullOr port; default = null; - example = 993; + example = "993"; description = '' The port on which the SMTP server listens. ''; @@ -321,7 +368,7 @@ let smtp-ssl = mkOption { type = nullOr bool; default = null; - example = false; + example = "false"; description = '' Should enable SSL/TLS. ''; @@ -330,7 +377,7 @@ let smtp-starttls = mkOption { type = nullOr bool; default = null; - example = false; + example = "false"; description = '' Should enable STARTTLS. ''; @@ -339,7 +386,7 @@ let smtp-insecure = mkOption { type = nullOr bool; default = null; - example = false; + example = "false"; description = '' Should trust any certificate. ''; @@ -364,16 +411,10 @@ let standard output. ''; }; - }; - - sendmailCfg = { - sender = mkOption { - type = nullOr (strMatching "sendmail"); - default = null; - }; sendmail-cmd = mkOption { - type = str; + type = nullOr str; + default = null; example = "msmtp"; description = '' Sendmail command used to send emails. @@ -381,103 +422,139 @@ let }; }; - globalCfgModule = submodule { - options = globalCfg; - }; + globalCfgModule = submodule { options = globalCfg; }; - accountCfgModule = - let - mergeAll = cfg: submodule { - options = accountCfg // cfg.backend // cfg.sender; - }; - cfgs = cartesianProductOfSets { - backend = [ imapCfg maildirCfg ]; - sender = [ smtpCfg sendmailCfg ]; - }; - in - oneOf (map mergeAll cfgs); + accountCfgModule = submodule { options = accountCfg; }; cfgFromAccount = _: account: - let - ifAppendSignature = cfg: - optionalAttrs (account.signature.showSignature == "append") (compactAttrs cfg); - ifImap = cfg: - optionalAttrs (!isNull account.imap) (compactAttrs cfg); - ifMaildir = cfg: - optionalAttrs (!isNull account.maildir) (compactAttrs cfg); - ifSmtp = cfg: - optionalAttrs (!isNull account.smtp) (compactAttrs cfg); - in { email = account.address; display-name = account.realName; default = account.primary; - folder-aliases = { + folder-aliases = compactAttrs { inbox = account.folders.inbox; sent = account.folders.sent; drafts = account.folders.drafts; trash = account.folders.trash; }; - } // ifAppendSignature { + } + + // optionalAttrs (account.signature.showSignature == "append") { # TODO: signature cannot be attached yet # https://todo.sr.ht/~soywod/himalaya/27 signature = account.signature.text; signature-delim = account.signature.delimiter; - } // ifImap { + } + + // optionalAttrs (!isNull account.imap) (compactAttrs { backend = "imap"; imap-host = account.imap.host; imap-port = account.imap.port; + imap-ssl = account.imap.tls.enable; imap-starttls = account.imap.tls.useStartTls; imap-login = account.userName; imap-passwd-cmd = builtins.concatStringsSep " " account.passwordCommand; - } // ifMaildir { + }) + + // optionalAttrs (isNull account.imap && !isNull account.maildir) + (compactAttrs { backend = "maildir"; maildir-root-dir = account.maildir.absPath; - } // ifSmtp { + }) + + // optionalAttrs (!isNull account.smtp) (compactAttrs { sender = "smtp"; smtp-host = account.smtp.host; smtp-port = account.smtp.port; + smtp-ssl = account.smtp.tls.enable; smtp-starttls = account.smtp.tls.useStartTls; smtp-login = account.userName; smtp-passwd-cmd = builtins.concatStringsSep " " account.passwordCommand; - } // compactAttrs account.himalaya.settings; + }) + + // optionalAttrs (isNull account.smtp) { sender = "sendmail"; } + + // compactAttrs account.himalaya.settings; -in -{ + mkService = desc: { + enable = mkEnableOption desc; + + account = mkOption { + type = nullOr str; + default = null; + example = "gmail"; + description = '' + Name of the account the notifier should be started for. If + no account is given, the default account will be used. + ''; + }; + + keepalive = mkOption { + type = nullOr int; + default = null; + example = "500"; + description = '' + Lifetime of the IDLE session (in seconds). + ''; + }; + + environment = mkOption { + type = attrsOf str; + default = { }; + example = literalExpression '' + { + "PASSWORD_STORE_DIR" = "~/.password-store"; + } + ''; + description = '' + Extra environment variables to be exported in the systemd + service. + ''; + }; + }; + +in { meta.maintainers = with hm.maintainers; [ soywod toastal ]; options = { programs.himalaya = { - enable = mkEnableOption "himalaya email client"; + enable = mkEnableOption "Enable the Himalaya email client."; package = mkOption { - type = types.package; + type = package; default = pkgs.himalaya; defaultText = literalExpression "pkgs.himalaya"; description = '' - Package providing the himalaya email client. + Package providing the himalaya CLI email + client. ''; }; settings = mkOption { type = globalCfgModule; + default = { }; description = '' - himalaya global configuration. + Himalaya global configuration. ''; }; }; + services = { + himalaya-notify = + mkService "Enable the Himalaya new emails notifier service."; + himalaya-watch = mkService "Enable the Himalaya watcher service."; + }; + accounts.email.accounts = mkOption { type = attrsOf (submodule { options.himalaya = { - enable = mkEnableOption '' - Enable himalaya for this email account. - ''; + enable = mkEnableOption "Enable Himalaya for this email account."; settings = mkOption { type = accountCfgModule; + default = { }; description = '' - himalaya configuration for this email account. + Himalaya configuration for this email account. ''; }; }; @@ -485,17 +562,58 @@ in }; }; - config = mkIf config.programs.himalaya.enable { - home.packages = [ config.programs.himalaya.package ]; - - xdg.configFile."himalaya/config.toml".source = - let - tomlFormat = pkgs.formats.toml { }; - enabledAccounts = filterAttrs (_: account: account.himalaya.enable) config.accounts.email.accounts; - globalCfg = compactAttrs config.programs.himalaya.settings; - accountsCfg = mapAttrs cfgFromAccount enabledAccounts; - cfg = globalCfg // accountsCfg; - in - tomlFormat.generate "himalaya-config.toml" cfg; + config = mkIf himalaya.enable { + home.packages = [ himalaya.package ]; + + xdg.configFile."himalaya/config.toml".source = let + tomlFormat = pkgs.formats.toml { }; + enabledAccounts = filterAttrs (_: account: account.himalaya.enable) + config.accounts.email.accounts; + globalCfg = compactAttrs himalaya.settings; + accountsCfg = mapAttrs cfgFromAccount enabledAccounts; + cfg = globalCfg // accountsCfg; + in tomlFormat.generate "himalaya-config.toml" cfg; + + systemd.user.services = { + himalaya-notify = mkIf himalaya-notify.enable { + Unit = { + Description = "Himalaya new emails notifier service"; + After = [ "network.target" ]; + }; + Install = { WantedBy = [ "default.target" ]; }; + Service = { + ExecStart = "${himalaya.package}/bin/himalaya" + + (lib.optionalString himalaya-notify.account + " --account ${himalaya-notify.account}") + " notify" + + (lib.optionalString himalaya-notify.keepalive + " --keepalive ${himalaya-notify.keepalive}"); + ExecSearchPath = "/bin"; + Environment = mapAttrsToList (key: val: "${key}=${val}") + himalaya-notify.environment; + Restart = "always"; + RestartSec = 10; + }; + }; + + himalaya-watch = mkIf himalaya-watch.enable { + Unit = { + Description = "Himalaya watcher service"; + After = [ "network.target" ]; + }; + Install = { WantedBy = [ "default.target" ]; }; + Service = { + ExecStart = "${himalaya.package}/bin/himalaya" + + (lib.optionalString himalaya-watch.account + " --account ${himalaya-watch.account}") + " watch" + + (lib.optionalString himalaya-watch.keepalive + " --keepalive ${himalaya-watch.keepalive}"); + ExecSearchPath = "/bin"; + Environment = mapAttrsToList (key: val: "${key}=${val}") + himalaya-watch.environment; + Restart = "always"; + RestartSec = 10; + }; + }; + }; }; } diff --git a/modules/programs/java.nix b/modules/programs/java.nix index 24467a2550b0..d10f64c54a27 100644 --- a/modules/programs/java.nix +++ b/modules/programs/java.nix @@ -36,6 +36,8 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; - home.sessionVariables.JAVA_HOME = cfg.package.home; + # some instances of `jdk-linux-base.nix` pass through `result` without turning it onto a path-string. + # while I suspect this is incorrect, the documentation is unclear. + home.sessionVariables.JAVA_HOME = "${cfg.package.home}"; }; } diff --git a/modules/programs/kakoune.nix b/modules/programs/kakoune.nix index 042b6ee3a576..32f718909e8a 100644 --- a/modules/programs/kakoune.nix +++ b/modules/programs/kakoune.nix @@ -10,13 +10,9 @@ let options = { name = mkOption { type = types.enum [ - "NormalBegin" "NormalIdle" - "NormalEnd" "NormalKey" - "InsertBegin" "InsertIdle" - "InsertEnd" "InsertKey" "InsertChar" "InsertDelete" @@ -48,8 +44,11 @@ let "RawKey" "InsertCompletionShow" "InsertCompletionHide" - "InsertCompletionSelect" "ModuleLoaded" + "ClientCreate" + "ClientClose" + "RegisterModified" + "User" ]; example = "SetOption"; description = '' diff --git a/modules/programs/kodi.nix b/modules/programs/kodi.nix index 0441eebceabe..bae862aeb27c 100644 --- a/modules/programs/kodi.nix +++ b/modules/programs/kodi.nix @@ -82,7 +82,7 @@ let attrsetToXml = attrs: name: stylesheet: pkgs.runCommand name { # Package splicing for libxslt does not work correctly leading to errors - # when cross-compiling. Use the version from buildPackages explicitely to + # when cross-compiling. Use the version from buildPackages explicitly to # fix this. nativeBuildInputs = [ pkgs.buildPackages.libxslt.bin ]; xml = builtins.toXML attrs; diff --git a/modules/programs/man.nix b/modules/programs/man.nix index f3134b37be68..69ae5cac7956 100644 --- a/modules/programs/man.nix +++ b/modules/programs/man.nix @@ -69,7 +69,7 @@ in { echo "MANDB_MAP ${manualPages}/share/man $out" > man.conf # Run mandb to generate cache files: - ${pkgs.man-db}/bin/mandb -C man.conf --no-straycats --create \ + ${cfg.package}/bin/mandb -C man.conf --no-straycats --create \ ${manualPages}/share/man ''; in '' diff --git a/modules/programs/mbsync.nix b/modules/programs/mbsync.nix index 373828a0b243..d43f645555c5 100644 --- a/modules/programs/mbsync.nix +++ b/modules/programs/mbsync.nix @@ -174,7 +174,7 @@ let flatten (optionals (group.channels != { }) ([ "Group ${group.name}" ] ++ (genChannelStrings group.name group.channels))); # Given set of groups, generates list of strings, where each string is one - # of the groups and its consituent channels. + # of the groups and its constituent channels. genGroupsStrings = mapAttrsToList (name: info: concatStringsSep "\n" (genGroupChannelString groups.${name})) groups; # Join all non-empty groups. diff --git a/modules/programs/mujmap.nix b/modules/programs/mujmap.nix index 9d290fefb424..291b96566e2f 100644 --- a/modules/programs/mujmap.nix +++ b/modules/programs/mujmap.nix @@ -186,7 +186,7 @@ let default = null; example = "https://jmap.example.com/.well-known/jmap"; description = '' - Sesion URL to connect to. + Session URL to connect to. Mutually exclusive with . diff --git a/modules/programs/ncmpcpp.nix b/modules/programs/ncmpcpp.nix index e37849519132..5f9bd36ebc11 100644 --- a/modules/programs/ncmpcpp.nix +++ b/modules/programs/ncmpcpp.nix @@ -62,7 +62,7 @@ in { }; mpdMusicDir = mkOption { - type = types.nullOr types.path; + type = with types; nullOr (coercedTo path toString str); default = let mpdCfg = config.services.mpd; in if pkgs.stdenv.hostPlatform.isLinux && mpdCfg.enable then mpdCfg.musicDirectory @@ -123,7 +123,7 @@ in { xdg.configFile = { "ncmpcpp/config" = let settings = cfg.settings // optionalAttrs (cfg.mpdMusicDir != null) { - mpd_music_dir = toString cfg.mpdMusicDir; + mpd_music_dir = cfg.mpdMusicDir; }; in mkIf (settings != { }) { text = renderSettings settings + "\n"; }; diff --git a/modules/programs/neovim.nix b/modules/programs/neovim.nix index 4560c930d511..df4b487d6c37 100644 --- a/modules/programs/neovim.nix +++ b/modules/programs/neovim.nix @@ -13,25 +13,6 @@ let jsonFormat = pkgs.formats.json { }; - extraPython3PackageType = mkOptionType { - name = "extra-python3-packages"; - description = "python3 packages in python.withPackages format"; - check = with types; - (x: if isFunction x then isList (x pkgs.python3Packages) else false); - merge = mergeOneOption; - }; - - # Currently, upstream Neovim is pinned on Lua 5.1 for LuaJIT support. - # This will need to be updated if Neovim ever migrates to a newer - # version of Lua. - extraLua51PackageType = mkOptionType { - name = "extra-lua51-packages"; - description = "lua5.1 packages in lua5_1.withPackages format"; - check = with types; - (x: if isFunction x then isList (x pkgs.lua51Packages) else false); - merge = mergeOneOption; - }; - pluginWithConfigType = types.submodule { options = { config = mkOption { @@ -80,19 +61,23 @@ let optional = false; }; + luaPackages = cfg.finalPackage.unwrapped.lua.pkgs; + resolvedExtraLuaPackages = cfg.extraLuaPackages luaPackages; + extraMakeWrapperArgs = lib.optionalString (cfg.extraPackages != [ ]) ''--suffix PATH : "${lib.makeBinPath cfg.extraPackages}"''; - extraMakeWrapperLuaCArgs = lib.optionalString (cfg.extraLuaPackages != [ ]) '' - --suffix LUA_CPATH ";" "${ - lib.concatMapStringsSep ";" pkgs.lua51Packages.getLuaCPath - cfg.extraLuaPackages - }"''; - extraMakeWrapperLuaArgs = lib.optionalString (cfg.extraLuaPackages != [ ]) '' - --suffix LUA_PATH ";" "${ - lib.concatMapStringsSep ";" pkgs.lua51Packages.getLuaPath - cfg.extraLuaPackages - }"''; - + extraMakeWrapperLuaCArgs = + lib.optionalString (resolvedExtraLuaPackages != [ ]) '' + --suffix LUA_CPATH ";" "${ + lib.concatMapStringsSep ";" luaPackages.getLuaCPath + resolvedExtraLuaPackages + }"''; + extraMakeWrapperLuaArgs = lib.optionalString (resolvedExtraLuaPackages != [ ]) + '' + --suffix LUA_PATH ";" "${ + lib.concatMapStringsSep ";" luaPackages.getLuaPath + resolvedExtraLuaPackages + }"''; in { imports = [ (mkRemovedOptionModule [ "programs" "neovim" "withPython" ] @@ -164,24 +149,51 @@ in { }; extraPython3Packages = mkOption { - type = with types; either extraPython3PackageType (listOf package); - default = (_: [ ]); + # In case we get a plain list, we need to turn it into a function, + # as expected by the function in nixpkgs. + # The only way to do so is to call `const`, which will ignore its input. + type = with types; + let fromType = listOf package; + in coercedTo fromType (flip warn const '' + Assigning a plain list to extraPython3Packages is deprecated. + Please assign a function taking a package set as argument, so + extraPython3Packages = [ pkgs.python3Packages.xxx ]; + should become + extraPython3Packages = ps: [ ps.xxx ]; + '') (functionTo fromType); + default = _: [ ]; defaultText = literalExpression "ps: [ ]"; - example = literalExpression "(ps: with ps; [ python-language-server ])"; + example = + literalExpression "pyPkgs: with pyPkgs; [ python-language-server ]"; description = '' - A function in python.withPackages format, which returns a - list of Python 3 packages required for your plugins to work. + The extra Python 3 packages required for your plugins to work. + This option accepts a function that takes a Python 3 package set as an argument, + and selects the required Python 3 packages from this package set. + See the example for more info. ''; }; + # We get the Lua package from the final package and use its + # Lua packageset to evaluate the function that this option was set to. + # This ensures that we always use the same Lua version as the Neovim package. extraLuaPackages = mkOption { - type = with types; either extraLua51PackageType (listOf package); - default = [ ]; - defaultText = literalExpression "[ ]"; - example = literalExpression "(ps: with ps; [ luautf8 ])"; + type = with types; + let fromType = listOf package; + in coercedTo fromType (flip warn const '' + Assigning a plain list to extraLuaPackages is deprecated. + Please assign a function taking a package set as argument, so + extraLuaPackages = [ pkgs.lua51Packages.xxx ]; + should become + extraLuaPackages = ps: [ ps.xxx ]; + '') (functionTo fromType); + default = _: [ ]; + defaultText = literalExpression "ps: [ ]"; + example = literalExpression "luaPkgs: with luaPkgs; [ luautf8 ]"; description = '' - A function in lua5_1.withPackages format, which returns a - list of Lua packages required for your plugins to work. + The extra Lua packages required for your plugins to work. + This option accepts a function that takes a Lua package set as an argument, + and selects the required Lua packages from this package set. + See the example for more info. ''; }; @@ -229,6 +241,15 @@ in { description = "Resulting customized neovim package."; }; + defaultEditor = mkOption { + type = types.bool; + default = false; + description = '' + Whether to configure nvim as the default + editor using the EDITOR environment variable. + ''; + }; + extraConfig = mkOption { type = types.lines; default = ""; @@ -240,6 +261,17 @@ in { ''; }; + extraLuaConfig = mkOption { + type = types.lines; + default = ""; + example = '' + vim.opt.nobackup = true + ''; + description = '' + Custom lua lines. + ''; + }; + extraPackages = mkOption { type = with types; listOf package; default = [ ]; @@ -280,7 +312,7 @@ in { }; settings = mkOption { - type = jsonFormat.type; + inherit (jsonFormat) type; default = { }; example = literalExpression '' { @@ -354,12 +386,14 @@ in { grouped = lib.lists.groupBy (x: x.type) pluginsNormalized; concatConfigs = lib.concatMapStrings (p: p.config); configsOnly = lib.foldl - (acc: p: if p.config != null then acc ++ [ (p.config) ] else acc) [ ]; + (acc: p: if p.config != null then acc ++ [ p.config ] else acc) [ ]; in mapAttrs (name: vals: lib.concatStringsSep "\n" (configsOnly vals)) grouped; home.packages = [ cfg.finalPackage ]; + home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "nvim"; }; + xdg.configFile = let hasLuaConfig = hasAttr "lua" config.programs.neovim.generatedConfigs; in mkMerge ( @@ -371,7 +405,8 @@ in { "vim.cmd [[source ${ pkgs.writeText "nvim-init-home-manager.vim" neovimConfig.neovimRcContent - }]]" + lib.optionalString hasLuaConfig + }]]" + config.programs.neovim.extraLuaConfig + + lib.optionalString hasLuaConfig config.programs.neovim.generatedConfigs.lua; in mkIf (luaRcContent != "") { text = luaRcContent; }; diff --git a/modules/programs/opam.nix b/modules/programs/opam.nix index 2916fb197ddf..0606d35b1ffd 100644 --- a/modules/programs/opam.nix +++ b/modules/programs/opam.nix @@ -56,7 +56,7 @@ in { ''; programs.fish.shellInit = mkIf cfg.enableFishIntegration '' - eval "$(${cfg.package}/bin/opam env --shell=fish)" + eval (${cfg.package}/bin/opam env --shell=fish) ''; }; } diff --git a/modules/programs/papis.nix b/modules/programs/papis.nix new file mode 100644 index 000000000000..8e127e269c53 --- /dev/null +++ b/modules/programs/papis.nix @@ -0,0 +1,91 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.papis; + + defaultLibraries = remove null + (mapAttrsToList (n: v: if v.isDefault then n else null) cfg.libraries); + + settingsIni = (lib.mapAttrs (n: v: v.settings) cfg.libraries) // { + settings = cfg.settings // { "default-library" = head defaultLibraries; }; + }; + +in { + meta.maintainers = [ maintainers.marsam ]; + + options.programs.papis = { + enable = mkEnableOption "papis"; + + settings = mkOption { + type = with types; attrsOf (oneOf [ bool int str ]); + default = { }; + example = literalExpression '' + { + editor = "nvim"; + file-browser = "ranger" + add-edit = true; + } + ''; + description = '' + Configuration written to + $XDG_CONFIG_HOME/papis/config. See + + for supported values. + ''; + }; + + libraries = mkOption { + type = types.attrsOf (types.submodule ({ config, name, ... }: { + options = { + name = mkOption { + type = types.str; + default = name; + readOnly = true; + description = "This library's name."; + }; + + isDefault = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Whether this is a default library. There must be exactly one + default library. + ''; + }; + + settings = mkOption { + type = with types; attrsOf (oneOf [ bool int str ]); + default = { }; + example = literalExpression '' + { + dir = "~/papers/"; + } + ''; + description = '' + Configuration for this library. + ''; + }; + }; + })); + }; + }; + + config = mkIf cfg.enable { + assertions = [{ + assertion = cfg.libraries == { } || length defaultLibraries == 1; + message = "Must have exactly one default papis library, but found " + + toString (length defaultLibraries) + + optionalString (length defaultLibraries > 1) + (", namely " + concatStringsSep "," defaultLibraries); + }]; + + home.packages = [ pkgs.papis ]; + + xdg.configFile."papis/config" = + mkIf (cfg.libraries != { }) { text = generators.toINI { } settingsIni; }; + }; +} diff --git a/modules/programs/password-store.nix b/modules/programs/password-store.nix index e2f463ece6fb..076db93e5b71 100644 --- a/modules/programs/password-store.nix +++ b/modules/programs/password-store.nix @@ -59,6 +59,9 @@ in { home.packages = [ cfg.package ]; home.sessionVariables = cfg.settings; + services.pass-secret-service.storePath = + mkDefault cfg.settings.PASSWORD_STORE_DIR; + xsession.importedVariables = mkIf config.xsession.enable (mapAttrsToList (name: value: name) cfg.settings); }; diff --git a/modules/programs/rbenv.nix b/modules/programs/rbenv.nix new file mode 100644 index 000000000000..b204d4f0b178 --- /dev/null +++ b/modules/programs/rbenv.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.rbenv; + + pluginModule = types.submodule { + options = { + src = mkOption { + type = types.path; + description = '' + Path to the plugin folder. + ''; + }; + name = mkOption { + type = types.str; + description = '' + Name of the plugin. + ''; + }; + }; + }; + +in { + meta.maintainers = [ maintainers.marsam ]; + + options.programs.rbenv = { + enable = mkEnableOption "rbenv"; + + package = mkPackageOption pkgs "rbenv" { }; + + plugins = mkOption { + type = types.listOf pluginModule; + default = [ ]; + example = literalExpression '' + [ + { + name = "ruby-build"; + src = pkgs.fetchFromGitHub { + owner = "rbenv"; + repo = "ruby-build"; + rev = "v20221225"; + hash = "sha256-Kuq0Z1kh2mvq7rHEgwVG9XwzR5ZUtU/h8SQ7W4/mBU0="; + }; + } + ] + ''; + description = '' + rbenv plugins to install in $HOME/.rbenv/plugins/. + + See + for the full list of plugins. + ''; + }; + + enableBashIntegration = mkEnableOption "Bash integration" // { + default = true; + }; + + enableZshIntegration = mkEnableOption "Zsh integration" // { + default = true; + }; + + enableFishIntegration = mkEnableOption "Fish integration" // { + default = true; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + home.file.".rbenv/plugins" = mkIf (cfg.plugins != [ ]) { + source = pkgs.linkFarm "rbenv-plugins" (builtins.map (p: { + name = p.name; + path = p.src; + }) cfg.plugins); + }; + + programs.bash.initExtra = mkIf cfg.enableBashIntegration '' + eval "$(${cfg.package}/bin/rbenv init - bash)" + ''; + + programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' + eval "$(${cfg.package}/bin/rbenv init - zsh)" + ''; + + programs.fish.shellInit = mkIf cfg.enableFishIntegration '' + ${cfg.package}/bin/rbenv init - fish | source + ''; + }; +} diff --git a/modules/programs/starship.nix b/modules/programs/starship.nix index 0a83a7b88eca..05763c0ba327 100644 --- a/modules/programs/starship.nix +++ b/modules/programs/starship.nix @@ -124,6 +124,12 @@ in { end ''; + programs.ion.initExtra = mkIf cfg.enableIonIntegration '' + if test $TERM != "dumb" && not exists -s INSIDE_EMACS || test $INSIDE_EMACS = "vterm" + eval $(${starshipCmd} init ion) + end + ''; + programs.nushell = mkIf cfg.enableNushellIntegration { # Unfortunately nushell doesn't allow conditionally sourcing nor # conditionally setting (global) environment variables, which is why the @@ -134,7 +140,7 @@ in { if not ($starship_cache | path exists) { mkdir $starship_cache } - ${starshipCmd} init nu | save ${config.xdg.cacheHome}/starship/init.nu + ${starshipCmd} init nu | save --force ${config.xdg.cacheHome}/starship/init.nu ''; extraConfig = '' source ${config.xdg.cacheHome}/starship/init.nu diff --git a/modules/programs/tmux.nix b/modules/programs/tmux.nix index bf98a3f37b20..df3ed11d5f0e 100644 --- a/modules/programs/tmux.nix +++ b/modules/programs/tmux.nix @@ -94,6 +94,7 @@ let bind-key -N "Kill the current pane" x kill-pane ''} + set -g mouse ${boolToStr cfg.mouse} setw -g aggressive-resize ${boolToStr cfg.aggressiveResize} setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"} set -s escape-time ${toString cfg.escapeTime} @@ -204,6 +205,8 @@ in { description = "VI or Emacs style shortcuts."; }; + mouse = mkEnableOption "mouse support"; + newSession = mkOption { default = false; type = types.bool; @@ -333,7 +336,7 @@ in { (mkIf cfg.secureSocket { home.sessionVariables = { - TMUX_TMPDIR = ''''${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}''; + TMUX_TMPDIR = ''''${XDG_RUNTIME_DIR:-"/run/user/$(id -u)"}''; }; }) diff --git a/modules/programs/vim-vint.nix b/modules/programs/vim-vint.nix new file mode 100644 index 000000000000..e44d96e4cf85 --- /dev/null +++ b/modules/programs/vim-vint.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.vim-vint; + + yamlFormat = pkgs.formats.yaml { }; + +in { + meta.maintainers = [ maintainers.tomodachi94 ]; + + options = { + programs.vim-vint = { + enable = mkEnableOption "the Vint linter for Vimscript"; + package = mkPackageOption pkgs "vim-vint" { }; + + settings = mkOption { + type = yamlFormat.type; + default = { }; + description = '' + Configuration written to + $XDG_CONFIG_HOME/.vintrc.yaml + ''; + }; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile.".vintrc.yaml".source = + yamlFormat.generate "vim-vint-config" cfg.settings; + }; +} diff --git a/modules/programs/vim.nix b/modules/programs/vim.nix index 46e5f95db103..e4d993a61912 100644 --- a/modules/programs/vim.nix +++ b/modules/programs/vim.nix @@ -127,9 +127,19 @@ in { packageConfigurable = mkOption { type = types.package; - description = "Configurable vim package"; - default = pkgs.vim_configurable; - defaultText = "pkgs.vim_configurable"; + description = "Vim package to customize"; + default = pkgs.vim-full or pkgs.vim_configurable; + defaultText = literalExpression "pkgs.vim-full"; + example = literalExpression "pkgs.vim"; + }; + + defaultEditor = mkOption { + type = types.bool; + default = false; + description = '' + Whether to configure vim as the default + editor using the EDITOR environment variable. + ''; }; }; }; @@ -170,6 +180,8 @@ in { home.packages = [ cfg.package ]; + home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "vim"; }; + programs.vim = { package = vim; plugins = defaultPlugins; diff --git a/modules/programs/vscode.nix b/modules/programs/vscode.nix index 27faf39bc45a..cdc66578af73 100644 --- a/modules/programs/vscode.nix +++ b/modules/programs/vscode.nix @@ -7,6 +7,7 @@ let cfg = config.programs.vscode; vscodePname = cfg.package.pname; + vscodeVersion = cfg.package.version; jsonFormat = pkgs.formats.json { }; @@ -34,6 +35,13 @@ let # TODO: On Darwin where are the extensions? extensionPath = ".${extensionDir}/extensions"; + extensionJson = pkgs.vscode-utils.toExtensionJson cfg.extensions; + extensionJsonFile = pkgs.writeTextFile { + name = "extensions-json"; + destination = "/share/vscode/extensions/extensions.json"; + text = extensionJson; + }; + mergedUserSettings = cfg.userSettings // optionalAttrs (!cfg.enableUpdateCheck) { "update.mode" = "none"; } // optionalAttrs (!cfg.enableExtensionUpdateCheck) { @@ -55,6 +63,7 @@ in { package = mkOption { type = types.package; default = pkgs.vscode; + defaultText = literalExpression "pkgs.vscode"; example = literalExpression "pkgs.vscodium"; description = '' Version of Visual Studio Code to install. @@ -211,12 +220,26 @@ in { else builtins.attrNames (builtins.readDir (ext + "/${subDir}"))); in if cfg.mutableExtensionsDir then - mkMerge (concatMap toPaths cfg.extensions) + mkMerge (concatMap toPaths cfg.extensions + ++ lib.optional (lib.versionAtLeast vscodeVersion "1.74.0") { + # Whenever our immutable extensions.json changes, force VSCode to regenerate + # extensions.json with both mutable and immutable extensions. + "${extensionPath}/.extensions-immutable.json" = { + text = extensionJson; + onChange = '' + $DRY_RUN_CMD rm $VERBOSE_ARG -f ${extensionPath}/{extensions.json,.init-default-profile-extensions} + $VERBOSE_ECHO "Regenerating VSCode extensions.json" + $DRY_RUN_CMD ${getExe cfg.package} --list-extensions > /dev/null + ''; + }; + }) else { "${extensionPath}".source = let combinedExtensionsDrv = pkgs.buildEnv { name = "vscode-extensions"; - paths = cfg.extensions; + paths = cfg.extensions + ++ lib.optional (lib.versionAtLeast vscodeVersion "1.74.0") + extensionJsonFile; }; in "${combinedExtensionsDrv}/${subDir}"; })) diff --git a/modules/programs/wlogout.nix b/modules/programs/wlogout.nix new file mode 100644 index 000000000000..49e59b078c48 --- /dev/null +++ b/modules/programs/wlogout.nix @@ -0,0 +1,151 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) all filterAttrs isStorePath literalExpression types; + inherit (lib.options) mkEnableOption mkPackageOption mkOption; + inherit (lib.modules) mkIf; + inherit (lib.strings) concatMapStrings; + inherit (builtins) toJSON; + + cfg = config.programs.wlogout; + + jsonFormat = pkgs.formats.json { }; + + wlogoutLayoutConfig = with types; + submodule { + freeformType = jsonFormat.type; + + options = { + label = mkOption { + type = str; + default = ""; + example = "shutdown"; + description = "CSS label of button."; + }; + + action = mkOption { + type = either path str; + default = ""; + example = "systemctl poweroff"; + description = "Command to execute when clicked."; + }; + + text = mkOption { + type = str; + default = ""; + example = "Shutdown"; + description = "Text displayed on button."; + }; + + keybind = mkOption { + type = str; + default = ""; + example = "s"; + description = "Keyboard character to trigger this action."; + }; + + height = mkOption { + type = nullOr (numbers.between 0 1); + default = null; + example = 0.5; + description = "Relative height of tile."; + }; + + width = mkOption { + type = nullOr (numbers.between 0 1); + default = null; + example = 0.5; + description = "Relative width of tile."; + }; + + circular = mkOption { + type = nullOr bool; + default = null; + example = true; + description = "Make button circular."; + }; + }; + }; +in { + meta.maintainers = [ lib.maintainers.Scrumplex ]; + + options.programs.wlogout = with lib.types; { + enable = mkEnableOption "wlogout"; + + package = mkPackageOption pkgs "wlogout" { }; + + layout = mkOption { + type = listOf wlogoutLayoutConfig; + default = [ ]; + description = '' + Layout configuration for wlogout, see + for supported values. + ''; + example = literalExpression '' + [ + { + label = "shutdown"; + action = "systemctl poweroff"; + text = "Shutdown"; + keybind = "s"; + } + ] + ''; + }; + + style = mkOption { + type = nullOr (either path str); + default = null; + description = '' + CSS style of the bar. + + + See + for the documentation. + + + If the value is set to a path literal, then the path will be used as the css file. + ''; + example = '' + window { + background: #16191C; + } + + button { + color: #AAB2BF; + } + ''; + }; + }; + + config = let + # Removes nulls because wlogout ignores them. + # This is not recursive. + removeTopLevelNulls = filterAttrs (_: v: v != null); + cleanJSON = foo: toJSON (removeTopLevelNulls foo); + + # wlogout doesn't want a JSON array, it just wants a list of JSON objects + layoutJsons = map cleanJSON cfg.layout; + layoutContent = concatMapStrings (l: l + "\n") layoutJsons; + + in mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "programs.wlogout" pkgs + lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + xdg.configFile."wlogout/layout" = mkIf (cfg.layout != [ ]) { + source = pkgs.writeText "wlogout/layout" layoutContent; + }; + + xdg.configFile."wlogout/style.css" = mkIf (cfg.style != null) { + source = if builtins.isPath cfg.style || isStorePath cfg.style then + cfg.style + else + pkgs.writeText "wlogout/style.css" cfg.style; + }; + }; +} diff --git a/modules/services/autorandr.nix b/modules/services/autorandr.nix new file mode 100644 index 000000000000..84791a667306 --- /dev/null +++ b/modules/services/autorandr.nix @@ -0,0 +1,53 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.autorandr; + +in { + + meta.maintainers = [ maintainers.GaetanLepage ]; + + options = { + services.autorandr = { + enable = mkEnableOption "" // { + description = '' + Whether to enable the Autorandr systemd service. + This module is complementary to programs.autorandr which handles the + configuration (profiles). + ''; + }; + + ignoreLid = mkOption { + default = false; + type = types.bool; + description = + "Treat outputs as connected even if their lids are closed."; + }; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.autorandr" pkgs + lib.platforms.linux) + ]; + + systemd.user.services.autorandr = { + Unit = { + Description = "autorandr"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "oneshot"; + ExecStart = "${pkgs.autorandr}/bin/autorandr --change ${ + optionalString cfg.ignoreLid "--ignore-lid" + }"; + }; + + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; +} diff --git a/modules/services/blueman-applet.nix b/modules/services/blueman-applet.nix index 460dd1677c5d..d81db1dbb58f 100644 --- a/modules/services/blueman-applet.nix +++ b/modules/services/blueman-applet.nix @@ -21,6 +21,11 @@ with lib; }; config = mkIf config.services.blueman-applet.enable { + assertions = [ + (hm.assertions.assertPlatform "services.blueman-applet" pkgs + platforms.linux) + ]; + systemd.user.services.blueman-applet = { Unit = { Description = "Blueman applet"; diff --git a/modules/services/borgmatic.nix b/modules/services/borgmatic.nix index f5368cdfca76..c2f2963a273b 100644 --- a/modules/services/borgmatic.nix +++ b/modules/services/borgmatic.nix @@ -63,6 +63,7 @@ in { ExecStart = '' ${pkgs.systemd}/bin/systemd-inhibit \ --who="borgmatic" \ + --what="sleep:shutdown" \ --why="Prevent interrupting scheduled backup" \ ${programConfig.package}/bin/borgmatic \ --stats \ diff --git a/modules/services/clipman.nix b/modules/services/clipman.nix new file mode 100644 index 000000000000..4afee9a3e4e5 --- /dev/null +++ b/modules/services/clipman.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.clipman; + +in { + meta.maintainers = [ maintainers.jwygoda ]; + + options.services.clipman = { + enable = mkEnableOption "clipman, a simple clipboard manager for Wayland"; + + package = mkPackageOption pkgs "clipman" { }; + + systemdTarget = mkOption { + type = types.str; + default = "graphical-session.target"; + example = "sway-session.target"; + description = '' + The systemd target that will automatically start the Waybar service. + + + When setting this value to "sway-session.target", + make sure to also enable , + otherwise the service may never be started. + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.clipman" pkgs + lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + systemd.user.services.clipman = { + Unit = { + Description = "Clipboard management daemon"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = + "${pkgs.wl-clipboard}/bin/wl-paste -t text --watch ${cfg.package}/bin/clipman store"; + ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR2 $MAINPID"; + Restart = "on-failure"; + KillMode = "mixed"; + }; + + Install = { WantedBy = [ cfg.systemdTarget ]; }; + }; + }; +} diff --git a/modules/services/dunst.nix b/modules/services/dunst.nix index b98b645e42ae..8606e24813bc 100644 --- a/modules/services/dunst.nix +++ b/modules/services/dunst.nix @@ -130,6 +130,10 @@ in { config = mkIf cfg.enable (mkMerge [ { + assertions = [ + (hm.assertions.assertPlatform "services.dunst" pkgs platforms.linux) + ]; + home.packages = [ cfg.package ]; xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source = diff --git a/modules/services/easyeffects.nix b/modules/services/easyeffects.nix index 001ff5d025a8..9dd01b94733f 100644 --- a/modules/services/easyeffects.nix +++ b/modules/services/easyeffects.nix @@ -20,6 +20,13 @@ in { to your system configuration for the daemon to work correctly''; + package = mkOption { + type = types.package; + default = pkgs.easyeffects; + defaultText = literalExpression "pkgs.easyeffects"; + description = "The easyeffects package to use."; + }; + preset = mkOption { type = types.str; default = ""; @@ -38,7 +45,7 @@ in { # running easyeffects will just attach itself to gapplication service # at-spi2-core is to minimize journalctl noise of: # "AT-SPI: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files" - home.packages = with pkgs; [ easyeffects at-spi2-core ]; + home.packages = with pkgs; [ cfg.package at-spi2-core ]; systemd.user.services.easyeffects = { Unit = { @@ -52,8 +59,8 @@ in { Service = { ExecStart = - "${pkgs.easyeffects}/bin/easyeffects --gapplication-service ${presetOpts}"; - ExecStop = "${pkgs.easyeffects}/bin/easyeffects --quit"; + "${cfg.package}/bin/easyeffects --gapplication-service ${presetOpts}"; + ExecStop = "${cfg.package}/bin/easyeffects --quit"; Restart = "on-failure"; RestartSec = 5; }; diff --git a/modules/services/gpg-agent.nix b/modules/services/gpg-agent.nix index ca70406f15c6..39e93669fb49 100644 --- a/modules/services/gpg-agent.nix +++ b/modules/services/gpg-agent.nix @@ -9,11 +9,18 @@ let homedir = config.programs.gpg.homedir; + gpgSshSupportStr = '' + ${gpgPkg}/bin/gpg-connect-agent updatestartuptty /bye > /dev/null + ''; + gpgInitStr = '' GPG_TTY="$(tty)" export GPG_TTY - '' + optionalString cfg.enableSshSupport - "${gpgPkg}/bin/gpg-connect-agent updatestartuptty /bye > /dev/null"; + '' + optionalString cfg.enableSshSupport gpgSshSupportStr; + + gpgFishInitStr = '' + set -gx GPG_TTY (tty) + '' + optionalString cfg.enableSshSupport gpgSshSupportStr; # mimic `gpgconf` output for use in `systemd` unit definitions. # we cannot use `gpgconf` directly because it heavily depends on system @@ -238,9 +245,8 @@ in { programs.bash.initExtra = mkIf cfg.enableBashIntegration gpgInitStr; programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgInitStr; - programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' - set -gx GPG_TTY (tty) - ''; + programs.fish.interactiveShellInit = + mkIf cfg.enableFishIntegration gpgFishInitStr; } (mkIf (cfg.sshKeys != null) { @@ -257,6 +263,10 @@ in { # # directory. { + assertions = [ + (hm.assertions.assertPlatform "services.gpg-agent" pkgs platforms.linux) + ]; + systemd.user.services.gpg-agent = { Unit = { Description = "GnuPG cryptographic agent and passphrase cache"; diff --git a/modules/services/kdeconnect.nix b/modules/services/kdeconnect.nix index 87c57c4e9b6b..0c6aac31e80f 100644 --- a/modules/services/kdeconnect.nix +++ b/modules/services/kdeconnect.nix @@ -27,6 +27,11 @@ in { (mkIf cfg.enable { home.packages = [ package ]; + assertions = [ + (hm.assertions.assertPlatform "services.kdeconnect" pkgs + platforms.linux) + ]; + systemd.user.services.kdeconnect = { Unit = { Description = @@ -46,6 +51,11 @@ in { }) (mkIf cfg.indicator { + assertions = [ + (hm.assertions.assertPlatform "services.kdeconnect" pkgs + platforms.linux) + ]; + systemd.user.services.kdeconnect-indicator = { Unit = { Description = "kdeconnect-indicator"; diff --git a/modules/services/keepassx.nix b/modules/services/keepassx.nix index dc37066e20ce..7f85823619d8 100644 --- a/modules/services/keepassx.nix +++ b/modules/services/keepassx.nix @@ -12,6 +12,10 @@ with lib; }; config = mkIf config.services.keepassx.enable { + assertions = [ + (hm.assertions.assertPlatform "services.keepassx" pkgs platforms.linux) + ]; + systemd.user.services.keepassx = { Unit = { Description = "KeePassX password manager"; diff --git a/modules/services/mako.nix b/modules/services/mako.nix index fc9e21610edb..fb711ca46e2f 100644 --- a/modules/services/mako.nix +++ b/modules/services/mako.nix @@ -130,8 +130,8 @@ in { description = '' Set margin of each edge specified in pixels. Specify single value to apply margin on all sides. Two comma-separated values will set - vertical and horizontal edges separately. Four comma-seperated will - give each edge a seperate value. + vertical and horizontal edges separately. Four comma-separated will + give each edge a separate value. For example: 10,20,5 will set top margin to 10, left and right to 20 and bottom to five. ''; @@ -143,8 +143,8 @@ in { description = '' Set padding of each edge specified in pixels. Specify single value to apply margin on all sides. Two comma-separated values will set - vertical and horizontal edges separately. Four comma-seperated will - give each edge a seperate value. + vertical and horizontal edges separately. Four comma-separated will + give each edge a separate value. For example: 10,20,5 will set top margin to 10, left and right to 20 and bottom to five. ''; diff --git a/modules/services/mpd-discord-rpc.nix b/modules/services/mpd-discord-rpc.nix index 5e7a6664b8a8..50bc824b095b 100644 --- a/modules/services/mpd-discord-rpc.nix +++ b/modules/services/mpd-discord-rpc.nix @@ -39,6 +39,11 @@ in { }; config = mkIf cfg.enable { + assertions = [ + (hm.assertions.assertPlatform "services.mpd-discord-rpc" pkgs + platforms.linux) + ]; + xdg.configFile."discord-rpc/config.toml".source = configFile; systemd.user.services.mpd-discord-rpc = { diff --git a/modules/services/owncloud-client.nix b/modules/services/owncloud-client.nix index d55d8ffa2a41..4eeafcf0a74c 100644 --- a/modules/services/owncloud-client.nix +++ b/modules/services/owncloud-client.nix @@ -8,6 +8,11 @@ with lib; }; config = mkIf config.services.owncloud-client.enable { + assertions = [ + (hm.assertions.assertPlatform "services.owncloud-client" pkgs + platforms.linux) + ]; + systemd.user.services.owncloud-client = { Unit = { Description = "Owncloud Client"; diff --git a/modules/services/parcellite.nix b/modules/services/parcellite.nix index 6ed9946b4dfb..39b81e8699bb 100644 --- a/modules/services/parcellite.nix +++ b/modules/services/parcellite.nix @@ -12,6 +12,15 @@ in { options.services.parcellite = { enable = mkEnableOption "Parcellite"; + extraOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--no-icon" ]; + description = '' + Command line arguments passed to Parcellite. + ''; + }; + package = mkOption { type = types.package; default = pkgs.parcellite; @@ -40,7 +49,9 @@ in { Install = { WantedBy = [ "graphical-session.target" ]; }; Service = { - ExecStart = "${cfg.package}/bin/${cfg.package.pname}"; + ExecStart = "${cfg.package}/bin/${cfg.package.pname} ${ + escapeShellArgs cfg.extraOptions + }"; Restart = "on-abort"; }; }; diff --git a/modules/services/pass-secret-service.nix b/modules/services/pass-secret-service.nix index 06b5be1f882e..8459099c8e19 100644 --- a/modules/services/pass-secret-service.nix +++ b/modules/services/pass-secret-service.nix @@ -2,31 +2,46 @@ with lib; -let serviceCfg = config.services.pass-secret-service; +let + cfg = config.services.pass-secret-service; + + serviceArgs = + optionalString (cfg.storePath != null) "--path ${cfg.storePath}"; in { - meta.maintainers = [ maintainers.cab404 ]; + meta.maintainers = with maintainers; [ cab404 houstdav000 ]; + options.services.pass-secret-service = { enable = mkEnableOption "Pass libsecret service"; + + package = mkPackageOption pkgs "pass-secret-service" { }; + + storePath = mkOption { + type = with types; nullOr str; + default = null; + defaultText = "~/.password-store"; + example = "/home/user/.local/share/password-store"; + description = "Absolute path to password store."; + }; }; - config = mkIf serviceCfg.enable { + + config = mkIf cfg.enable { assertions = [ (hm.assertions.assertPlatform "services.pass-secret-service" pkgs platforms.linux) - - { - assertion = config.programs.password-store.enable; - message = "The 'services.pass-secret-service' module requires" - + " 'programs.password-store.enable = true'."; - } ]; systemd.user.services.pass-secret-service = { - Unit = { Description = "Pass libsecret service"; }; + Unit = { + AssertFileIsExecutable = "${cfg.package}/bin/pass_secret_service"; + Description = "Pass libsecret service"; + Documentation = "https://github.com/mdellweg/pass_secret_service"; + PartOf = [ "default.target" ]; + }; + Service = { - # pass-secret-service doesn't use environment variables for some reason. - ExecStart = - "${pkgs.pass-secret-service}/bin/pass_secret_service --path ${config.programs.password-store.settings.PASSWORD_STORE_DIR}"; + ExecStart = "${cfg.package}/bin/pass_secret_service ${serviceArgs}"; }; + Install = { WantedBy = [ "default.target" ]; }; }; }; diff --git a/modules/services/pasystray.nix b/modules/services/pasystray.nix index 15c951e137ef..32922ad0fac3 100644 --- a/modules/services/pasystray.nix +++ b/modules/services/pasystray.nix @@ -10,6 +10,10 @@ with lib; }; config = mkIf config.services.pasystray.enable { + assertions = [ + (hm.assertions.assertPlatform "services.pasystray" pkgs platforms.linux) + ]; + systemd.user.services.pasystray = { Unit = { Description = "PulseAudio system tray"; diff --git a/modules/services/picom.nix b/modules/services/picom.nix index f4f8edb4301a..66f707c0a13c 100644 --- a/modules/services/picom.nix +++ b/modules/services/picom.nix @@ -270,6 +270,11 @@ in { }; config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.picom" pkgs + lib.platforms.linux) + ]; + services.picom.settings = mkDefaultAttrs { # fading fading = cfg.fade; diff --git a/modules/services/random-background.nix b/modules/services/random-background.nix index 9deee8deb5c1..16c869a9c52d 100644 --- a/modules/services/random-background.nix +++ b/modules/services/random-background.nix @@ -68,6 +68,11 @@ in { config = mkIf cfg.enable (mkMerge ([ { + assertions = [ + (hm.assertions.assertPlatform "services.random-background" pkgs + platforms.linux) + ]; + systemd.user.services.random-background = { Unit = { Description = "Set random desktop background using feh"; diff --git a/modules/services/stalonetray.nix b/modules/services/stalonetray.nix index 93fff3e7b5fe..172d6dd9dcf6 100644 --- a/modules/services/stalonetray.nix +++ b/modules/services/stalonetray.nix @@ -51,6 +51,11 @@ in { config = mkIf cfg.enable (mkMerge [ { + assertions = [ + (hm.assertions.assertPlatform "services.stalonetray" pkgs + platforms.linux) + ]; + home.packages = [ cfg.package ]; systemd.user.services.stalonetray = { diff --git a/modules/services/swayidle.nix b/modules/services/swayidle.nix index db54f9e27f79..6e8b55cb830d 100644 --- a/modules/services/swayidle.nix +++ b/modules/services/swayidle.nix @@ -108,6 +108,10 @@ in { }; config = mkIf cfg.enable { + assertions = [ + (hm.assertions.assertPlatform "services.swayidle" pkgs platforms.linux) + ]; + systemd.user.services.swayidle = { Unit = { Description = "Idle manager for Wayland"; diff --git a/modules/services/syncthing.nix b/modules/services/syncthing.nix index 2f9cecdb4f9b..bbe9f86609ae 100644 --- a/modules/services/syncthing.nix +++ b/modules/services/syncthing.nix @@ -98,6 +98,11 @@ in { }) (mkIf (isAttrs cfg.tray && cfg.tray.enable) { + assertions = [ + (hm.assertions.assertPlatform "services.syncthing.tray" pkgs + platforms.linux) + ]; + systemd.user.services = { ${cfg.tray.package.pname} = { Unit = { @@ -118,6 +123,11 @@ in { # deprecated (mkIf (isBool cfg.tray && cfg.tray) { + assertions = [ + (hm.assertions.assertPlatform "services.syncthing.tray" pkgs + platforms.linux) + ]; + systemd.user.services = { "syncthingtray" = { Unit = { diff --git a/modules/services/taffybar.nix b/modules/services/taffybar.nix index 088827b9554a..42ca5f7bb785 100644 --- a/modules/services/taffybar.nix +++ b/modules/services/taffybar.nix @@ -24,6 +24,10 @@ in { }; config = mkIf config.services.taffybar.enable { + assertions = [ + (hm.assertions.assertPlatform "services.taffybar" pkgs platforms.linux) + ]; + systemd.user.services.taffybar = { Unit = { Description = "Taffybar desktop bar"; diff --git a/modules/services/tahoe-lafs.nix b/modules/services/tahoe-lafs.nix index 742b779b270f..105ef3d03b28 100644 --- a/modules/services/tahoe-lafs.nix +++ b/modules/services/tahoe-lafs.nix @@ -10,6 +10,10 @@ with lib; }; config = mkIf config.services.tahoe-lafs.enable { + assertions = [ + (hm.assertions.assertPlatform "services.tahoe-lafs" pkgs platforms.linux) + ]; + systemd.user.services.tahoe-lafs = { Unit = { Description = "Tahoe-LAFS"; }; diff --git a/modules/services/udiskie.nix b/modules/services/udiskie.nix index d53d7cc8ab54..562297963d0b 100644 --- a/modules/services/udiskie.nix +++ b/modules/services/udiskie.nix @@ -98,6 +98,10 @@ in { }; config = mkIf config.services.udiskie.enable { + assertions = [ + (hm.assertions.assertPlatform "services.udiskie" pkgs platforms.linux) + ]; + xdg.configFile."udiskie/config.yml".source = yaml.generate "udiskie-config.yml" (mergeSets [ { diff --git a/modules/services/window-managers/fluxbox.nix b/modules/services/window-managers/fluxbox.nix index a41b97fc5a96..6b05d29587ec 100644 --- a/modules/services/window-managers/fluxbox.nix +++ b/modules/services/window-managers/fluxbox.nix @@ -112,7 +112,7 @@ in { ".fluxbox/menu" = mkIf (cfg.menu != "") { text = cfg.menu; }; ".fluxbox/slitlist" = mkIf (cfg.slitlist != "") { text = cfg.slitlist; }; ".fluxbox/windowmenu" = - mkIf (cfg.windowMenu != "") { text = cfg.windowmenu; }; + mkIf (cfg.windowmenu != "") { text = cfg.windowmenu; }; }; xsession.windowManager.command = concatStringsSep " " diff --git a/modules/services/window-managers/i3-sway/i3.nix b/modules/services/window-managers/i3-sway/i3.nix index 277cbe39424b..b4742c787cdc 100644 --- a/modules/services/window-managers/i3-sway/i3.nix +++ b/modules/services/window-managers/i3-sway/i3.nix @@ -9,7 +9,6 @@ let commonOptions = import ./lib/options.nix { inherit config lib cfg pkgs; moduleName = "i3"; - isGaps = cfg.package == pkgs.i3-gaps; }; configModule = types.submodule { @@ -105,7 +104,7 @@ let in lib.mkOptionDefault { "''${modifier}+Return" = "exec i3-sensible-terminal"; "''${modifier}+Shift+q" = "kill"; - "''${modifier}+d" = "exec \${pkgs.dmenu}/bin/dmenu_run"; + "''${modifier}+d" = "exec ''${pkgs.dmenu}/bin/dmenu_run"; } ''; }; @@ -161,7 +160,7 @@ let "floating_modifier ${floating.modifier}" (windowBorderString window floating) "hide_edge_borders ${window.hideEdgeBorders}" - "force_focus_wrapping ${lib.hm.booleans.yesNo focus.forceWrapping}" + "focus_wrapping ${focus.wrapping}" "focus_follows_mouse ${lib.hm.booleans.yesNo focus.followMouse}" "focus_on_window_activation ${focus.newWindow}" "mouse_warping ${if focus.mouseWarping then "output" else "none"}" @@ -209,16 +208,7 @@ in { xsession.windowManager.i3 = { enable = mkEnableOption "i3 window manager"; - package = mkOption { - type = types.package; - default = pkgs.i3; - defaultText = literalExpression "pkgs.i3"; - example = literalExpression "pkgs.i3-gaps"; - description = '' - i3 package to use. - If 'i3.config.gaps' settings are specified, 'pkgs.i3-gaps' will be set as a default package. - ''; - }; + package = mkPackageOption pkgs "i3" { }; config = mkOption { type = types.nullOr configModule; @@ -260,27 +250,21 @@ in { }; } - (mkIf (cfg.config != null) { - xsession.windowManager.i3.package = - mkDefault (if (cfg.config.gaps != null) then pkgs.i3-gaps else pkgs.i3); - }) - (mkIf (cfg.config != null) { warnings = (optional (isList cfg.config.fonts) "Specifying i3.config.fonts as a list is deprecated. Use the attrset version instead.") ++ flatten (map (b: optional (isList b.fonts) "Specifying i3.config.bars[].fonts as a list is deprecated. Use the attrset version instead.") - cfg.config.bars); + cfg.config.bars) ++ [ + (mkIf (any (s: s.workspace != null) cfg.config.startup) + ("'xsession.windowManager.i3.config.startup.*.workspace' is deprecated, " + + "use 'xsession.windowManager.i3.config.assigns' instead." + + "See https://github.com/nix-community/home-manager/issues/265.")) + (mkIf cfg.config.focus.forceWrapping + ("'xsession.windowManager.i3.config.focus.forceWrapping' is deprecated, " + + "use 'xsession.windowManager.i3.config.focus.wrapping' instead.")) + ]; }) - - (mkIf (cfg.config != null - && (any (s: s.workspace != null) cfg.config.startup)) { - warnings = [ - ("'xsession.windowManager.i3.config.startup.*.workspace' is deprecated, " - + "use 'xsession.windowManager.i3.config.assigns' instead." - + "See https://github.com/nix-community/home-manager/issues/265.") - ]; - }) ]); } diff --git a/modules/services/window-managers/i3-sway/lib/options.nix b/modules/services/window-managers/i3-sway/lib/options.nix index cae9c3a64b3c..3fe0b7551f5d 100644 --- a/modules/services/window-managers/i3-sway/lib/options.nix +++ b/modules/services/window-managers/i3-sway/lib/options.nix @@ -1,5 +1,4 @@ -{ config, lib, moduleName, cfg, pkgs, capitalModuleName ? moduleName -, isGaps ? true }: +{ config, lib, moduleName, cfg, pkgs, capitalModuleName ? moduleName }: with lib; @@ -7,6 +6,8 @@ let isI3 = moduleName == "i3"; isSway = !isI3; + inherit (config.home) stateVersion; + fontOptions = types.submodule { options = { names = mkOption { @@ -77,7 +78,7 @@ let barModule = types.submodule { options = let - versionAtLeast2009 = versionAtLeast config.home.stateVersion "20.09"; + versionAtLeast2009 = versionAtLeast stateVersion "20.09"; mkNullableOption = { type, default, ... }@args: mkOption (args // { type = types.nullOr type; @@ -158,7 +159,7 @@ let defaultText = "i3bar"; description = "Command that will be used to start a bar."; example = if isI3 then - "\${pkgs.i3-gaps}/bin/i3bar -t" + "\${pkgs.i3}/bin/i3bar -t" else "\${pkgs.waybar}/bin/waybar"; }; @@ -389,11 +390,17 @@ in { options = { titlebar = mkOption { type = types.bool; - default = !isGaps; - defaultText = if isI3 then - "xsession.windowManager.i3.package != nixpkgs.i3-gaps (titlebar should be disabled for i3-gaps)" + default = if versionOlder stateVersion "23.05" then + (isI3 && (cfg.config.gaps == null)) else - "false"; + true; + defaultText = if isI3 then '' + true for state version ≥ 23.05 + config.gaps == null for state version < 23.05 + '' else '' + true for state version ≥ 23.05 + false for state version < 23.05 + ''; description = "Whether to show window titlebars."; }; @@ -432,11 +439,17 @@ in { options = { titlebar = mkOption { type = types.bool; - default = !isGaps; - defaultText = if isI3 then - "xsession.windowManager.i3.package != nixpkgs.i3-gaps (titlebar should be disabled for i3-gaps)" + default = if versionOlder stateVersion "23.05" then + (isI3 && (cfg.config.gaps == null)) else - "false"; + true; + defaultText = if isI3 then '' + true for state version ≥ 23.05 + config.gaps == null for state version < 23.05 + '' else '' + true for state version ≥ 23.05 + false for state version < 23.05 + ''; description = "Whether to show floating window titlebars."; }; @@ -497,13 +510,28 @@ in { if (isSway && isBool val) then (lib.hm.booleans.yesNo val) else val; }; + wrapping = mkOption { + type = types.enum [ "yes" "no" "force" "workspace" ]; + default = { + i3 = if cfg.config.focus.forceWrapping then "force" else "yes"; + # the sway module's logic was inverted and incorrect, + # so preserve it for backwards compatibility purposes + sway = if cfg.config.focus.forceWrapping then "yes" else "no"; + }.${moduleName}; + description = '' + Whether the window focus commands automatically wrap around the edge of containers. + + See + ''; + }; + forceWrapping = mkOption { type = types.bool; default = false; description = '' - Whether to force focus wrapping in tabbed or stacked container. + Whether to force focus wrapping in tabbed or stacked containers. - See + This option is deprecated, use instead. ''; }; @@ -670,7 +698,7 @@ in { bars = mkOption { type = types.listOf barModule; - default = if versionAtLeast config.home.stateVersion "20.09" then [{ + default = if versionAtLeast stateVersion "20.09" then [{ mode = "dock"; hiddenState = "hide"; position = "bottom"; @@ -826,19 +854,14 @@ in { }; }); default = null; - description = if isSway then '' + description = '' Gaps related settings. - '' else '' - i3Gaps related settings. The i3-gaps package must be used for these features to work. ''; }; terminal = mkOption { type = types.str; - default = if isI3 then - "i3-sensible-terminal" - else - "${pkgs.rxvt-unicode-unwrapped}/bin/urxvt"; + default = if isI3 then "i3-sensible-terminal" else "${pkgs.foot}/bin/foot"; description = "Default terminal to run."; example = "alacritty"; }; diff --git a/modules/services/window-managers/i3-sway/sway.nix b/modules/services/window-managers/i3-sway/sway.nix index fdcbaabcd0cd..a18a4212dcba 100644 --- a/modules/services/window-managers/i3-sway/sway.nix +++ b/modules/services/window-managers/i3-sway/sway.nix @@ -271,7 +271,7 @@ let "floating_modifier ${floating.modifier}" (windowBorderString window floating) "hide_edge_borders ${window.hideEdgeBorders}" - "focus_wrapping ${lib.hm.booleans.yesNo focus.forceWrapping}" + "focus_wrapping ${focus.wrapping}" "focus_follows_mouse ${focus.followMouse}" "focus_on_window_activation ${focus.newWindow}" "mouse_warping ${ @@ -442,7 +442,10 @@ in { ++ flatten (map (b: optional (isList b.fonts) "Specifying sway.config.bars[].fonts as a list is deprecated. Use the attrset version instead.") - cfg.config.bars); + cfg.config.bars) ++ [ + (mkIf cfg.config.focus.forceWrapping + "sway.config.focus.forceWrapping is deprecated, use focus.wrapping instead.") + ]; }) { diff --git a/modules/services/xsuspender.nix b/modules/services/xsuspender.nix index 54f13c8d5a76..058f15471174 100644 --- a/modules/services/xsuspender.nix +++ b/modules/services/xsuspender.nix @@ -191,7 +191,7 @@ in { Service = { ExecStart = "${pkgs.xsuspender}/bin/xsuspender"; - Environment = mkIf cfg.debug [ "G_MESSAGE_DEBUG=all" ]; + Environment = mkIf cfg.debug [ "G_MESSAGES_DEBUG=all" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; }; diff --git a/modules/systemd.nix b/modules/systemd.nix index e4c36ae42051..456b22fd1640 100644 --- a/modules/systemd.nix +++ b/modules/systemd.nix @@ -10,16 +10,6 @@ let mkPathSafeName = lib.replaceStrings [ "@" ":" "\\" "[" "]" ] [ "-" "-" "-" "" "" ]; - enabled = cfg.services != { } # \ - || cfg.slices != { } # \ - || cfg.sockets != { } # \ - || cfg.targets != { } # \ - || cfg.timers != { } # \ - || cfg.paths != { } # \ - || cfg.mounts != { } # \ - || cfg.automounts != { } # \ - || cfg.sessionVariables != { }; - toSystemdIni = lib.generators.toINI { listsAsDuplicateKeys = true; mkKeyValue = key: value: @@ -239,92 +229,72 @@ in { }; }; - config = mkMerge [ - { - assertions = [{ - assertion = enabled -> pkgs.stdenv.isLinux; - message = let - names = lib.concatStringsSep ", " (lib.attrNames ( # \ - cfg.services # \ - // cfg.slices # \ - // cfg.sockets # \ - // cfg.targets # \ - // cfg.timers # \ - // cfg.paths # \ - // cfg.mounts # \ - // cfg.sessionVariables)); - in "Must use Linux for modules that require systemd: " + names; - }]; - } - - # If we run under a Linux system we assume that systemd is - # available, in particular we assume that systemctl is in PATH. - # Do not install any user services if username is root. - (mkIf (pkgs.stdenv.isLinux && config.home.username != "root") { - xdg.configFile = mkMerge [ - (lib.listToAttrs ((buildServices "service" cfg.services) - ++ (buildServices "slice" cfg.slices) - ++ (buildServices "socket" cfg.sockets) - ++ (buildServices "target" cfg.targets) - ++ (buildServices "timer" cfg.timers) - ++ (buildServices "path" cfg.paths) - ++ (buildServices "mount" cfg.mounts) - ++ (buildServices "automount" cfg.automounts))) - - sessionVariables - ]; - - # Run systemd service reload if user is logged in. If we're - # running this from the NixOS module then XDG_RUNTIME_DIR is not - # set and systemd commands will fail. We'll therefore have to - # set it ourselves in that case. - home.activation.reloadSystemd = hm.dag.entryAfter [ "linkGeneration" ] - (let - cmd = { - suggest = '' - PATH=${dirOf cfg.systemctlPath}:$PATH \ - bash ${./systemd-activate.sh} "''${oldGenPath=}" "$newGenPath" - ''; - legacy = '' - PATH=${dirOf cfg.systemctlPath}:$PATH \ - ${pkgs.ruby}/bin/ruby ${./systemd-activate.rb} \ - "''${oldGenPath=}" "$newGenPath" "${servicesStartTimeoutMs}" - ''; - sd-switch = let - timeoutArg = if cfg.servicesStartTimeoutMs != 0 then - "--timeout " + servicesStartTimeoutMs - else - ""; - in '' - ${pkgs.sd-switch}/bin/sd-switch \ - ''${DRY_RUN:+--dry-run} $VERBOSE_ARG ${timeoutArg} \ - ''${oldGenPath:+--old-units $oldGenPath/home-files/.config/systemd/user} \ - --new-units $newGenPath/home-files/.config/systemd/user - ''; - }; + # If we run under a Linux system we assume that systemd is + # available, in particular we assume that systemctl is in PATH. + # Do not install any user services if username is root. + config = mkIf (pkgs.stdenv.isLinux && config.home.username != "root") { + xdg.configFile = mkMerge [ + (lib.listToAttrs ((buildServices "service" cfg.services) + ++ (buildServices "slice" cfg.slices) + ++ (buildServices "socket" cfg.sockets) + ++ (buildServices "target" cfg.targets) + ++ (buildServices "timer" cfg.timers) + ++ (buildServices "path" cfg.paths) + ++ (buildServices "mount" cfg.mounts) + ++ (buildServices "automount" cfg.automounts))) + + sessionVariables + ]; + + # Run systemd service reload if user is logged in. If we're + # running this from the NixOS module then XDG_RUNTIME_DIR is not + # set and systemd commands will fail. We'll therefore have to + # set it ourselves in that case. + home.activation.reloadSystemd = hm.dag.entryAfter [ "linkGeneration" ] (let + cmd = { + suggest = '' + PATH=${dirOf cfg.systemctlPath}:$PATH \ + bash ${./systemd-activate.sh} "''${oldGenPath=}" "$newGenPath" + ''; + legacy = '' + PATH=${dirOf cfg.systemctlPath}:$PATH \ + ${pkgs.ruby}/bin/ruby ${./systemd-activate.rb} \ + "''${oldGenPath=}" "$newGenPath" "${servicesStartTimeoutMs}" + ''; + sd-switch = let + timeoutArg = if cfg.servicesStartTimeoutMs != 0 then + "--timeout " + servicesStartTimeoutMs + else + ""; + in '' + ${pkgs.sd-switch}/bin/sd-switch \ + ''${DRY_RUN:+--dry-run} $VERBOSE_ARG ${timeoutArg} \ + ''${oldGenPath:+--old-units $oldGenPath/home-files/.config/systemd/user} \ + --new-units $newGenPath/home-files/.config/systemd/user + ''; + }; - ensureRuntimeDir = - "XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"; + ensureRuntimeDir = + "XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"; - systemctl = "${ensureRuntimeDir} ${cfg.systemctlPath}"; - in '' - systemdStatus=$(${systemctl} --user is-system-running 2>&1 || true) + systemctl = "${ensureRuntimeDir} ${cfg.systemctlPath}"; + in '' + systemdStatus=$(${systemctl} --user is-system-running 2>&1 || true) - if [[ $systemdStatus == 'running' || $systemdStatus == 'degraded' ]]; then - if [[ $systemdStatus == 'degraded' ]]; then - warnEcho "The user systemd session is degraded:" - ${systemctl} --user --no-pager --state=failed - warnEcho "Attempting to reload services anyway..." - fi + if [[ $systemdStatus == 'running' || $systemdStatus == 'degraded' ]]; then + if [[ $systemdStatus == 'degraded' ]]; then + warnEcho "The user systemd session is degraded:" + ${systemctl} --user --no-pager --state=failed + warnEcho "Attempting to reload services anyway..." + fi - ${ensureRuntimeDir} \ - ${getAttr cfg.startServices cmd} - else - echo "User systemd daemon not running. Skipping reload." - fi + ${ensureRuntimeDir} \ + ${getAttr cfg.startServices cmd} + else + echo "User systemd daemon not running. Skipping reload." + fi - unset systemdStatus - ''); - }) - ]; + unset systemdStatus + ''); + }; } diff --git a/tests/default.nix b/tests/default.nix index 21ae251d16a5..9bbdaebb16d8 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -102,6 +102,7 @@ import nmt { ./modules/programs/nushell ./modules/programs/oh-my-posh ./modules/programs/pandoc + ./modules/programs/papis ./modules/programs/pet ./modules/programs/pistol ./modules/programs/pls @@ -121,6 +122,7 @@ import nmt { ./modules/programs/tmate ./modules/programs/tmux ./modules/programs/topgrade + ./modules/programs/vim-vint ./modules/programs/vscode ./modules/programs/watson ./modules/programs/wezterm @@ -162,11 +164,13 @@ import nmt { ./modules/programs/terminator ./modules/programs/thunderbird ./modules/programs/waybar + ./modules/programs/wlogout ./modules/programs/xmobar ./modules/programs/yt-dlp ./modules/services/barrier ./modules/services/borgmatic ./modules/services/cachix-agent + ./modules/services/clipman ./modules/services/devilspie2 ./modules/services/dropbox ./modules/services/emacs @@ -185,6 +189,8 @@ import nmt { ./modules/services/mpd ./modules/services/mpdris2 ./modules/services/pantalaimon + ./modules/services/parcellite + ./modules/services/pass-secret-service ./modules/services/pbgopy ./modules/services/picom ./modules/services/playerctld diff --git a/tests/modules/files/default.nix b/tests/modules/files/default.nix index 52e44d22b1c6..2c35b9a2e5ee 100644 --- a/tests/modules/files/default.nix +++ b/tests/modules/files/default.nix @@ -1,4 +1,5 @@ { + files-disabled = ./disabled.nix; files-executable = ./executable.nix; files-hidden-source = ./hidden-source.nix; files-out-of-store-symlink = ./out-of-store-symlink.nix; diff --git a/tests/modules/files/disabled.nix b/tests/modules/files/disabled.nix new file mode 100644 index 000000000000..b9ed858aafb5 --- /dev/null +++ b/tests/modules/files/disabled.nix @@ -0,0 +1,14 @@ +{ ... }: + +{ + home.file."disabled" = { + enable = false; + text = '' + This file should not exist + ''; + }; + + nmt.script = '' + assertPathNotExists home-files/disabled + ''; +} diff --git a/tests/modules/misc/debug/default.nix b/tests/modules/misc/debug/default.nix index 19ff4e2b8185..7eb28666606d 100644 --- a/tests/modules/misc/debug/default.nix +++ b/tests/modules/misc/debug/default.nix @@ -15,7 +15,7 @@ assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \ 'NIX_DEBUG_INFO_DIRS=.*/lib/debug' - # We need to override NIX_DEBUG_INFO_DIRS here as $HOME evalutes to the home + # We need to override NIX_DEBUG_INFO_DIRS here as $HOME evaluates to the home # of the user who executes this testcase :/ { echo quit | PATH="$TESTED/home-path/bin''${PATH:+:}$PATH" NIX_DEBUG_INFO_DIRS=$TESTED/home-path/lib/debug \ gdb curl 2>&1 | \ diff --git a/tests/modules/programs/aerc/extraAccounts.expected b/tests/modules/programs/aerc/extraAccounts.expected index 15749c03826f..9377384fc7f9 100644 --- a/tests/modules/programs/aerc/extraAccounts.expected +++ b/tests/modules/programs/aerc/extraAccounts.expected @@ -59,15 +59,15 @@ source = maildir:///home/hm-user/Maildir/i_maildir-mbsync from = Foo Bar source = maildir:///home/hm-user/Maildir/j_maildir-offlineimap -[l_smpt-auth-none] +[l_smtp-auth-none] from = Foo Bar outgoing = smtps+none://foobar@smtp.host.invalid:42 -[m_smpt-auth-plain] +[m_smtp-auth-plain] from = Foo Bar outgoing = smtps+plain://foobar@smtp.host.invalid:42 -[n_smpt-auth-login] +[n_smtp-auth-login] from = Foo Bar outgoing = smtps+login://foobar@smtp.host.invalid:42 diff --git a/tests/modules/programs/aerc/settings.nix b/tests/modules/programs/aerc/settings.nix index 2fded9cc8416..1f3c25a94fa5 100644 --- a/tests/modules/programs/aerc/settings.nix +++ b/tests/modules/programs/aerc/settings.nix @@ -193,7 +193,7 @@ with lib; i_maildir-mbsync = basics // { mbsync.enable = true; }; j_maildir-offlineimap = basics // { offlineimap.enable = true; }; k_notEnabled = basics // { aerc.enable = false; }; - l_smpt-auth-none = basics // { + l_smtp-auth-none = basics // { smtp = { host = "smtp.host.invalid"; port = 42; @@ -203,7 +203,7 @@ with lib; smtpAuth = "none"; }; }; - m_smpt-auth-plain = basics // { + m_smtp-auth-plain = basics // { smtp = { host = "smtp.host.invalid"; port = 42; @@ -213,7 +213,7 @@ with lib; smtpAuth = "plain"; }; }; - n_smpt-auth-login = basics // { + n_smtp-auth-login = basics // { smtp = { host = "smtp.host.invalid"; port = 42; diff --git a/tests/modules/programs/broot/broot.nix b/tests/modules/programs/broot/broot.nix index 440691cf5d23..b39929e365bc 100644 --- a/tests/modules/programs/broot/broot.nix +++ b/tests/modules/programs/broot/broot.nix @@ -1,26 +1,26 @@ -{ config, lib, pkgs, ... }: - -with lib; +{ ... }: { - config = { - programs.broot = { - enable = true; - settings.modal = true; - }; + programs.broot = { + enable = true; + settings.modal = true; + }; - nmt.script = '' - assertFileExists home-files/.config/broot/conf.toml - assertFileContent home-files/.config/broot/conf.toml ${ - pkgs.writeText "broot.expected" '' - imports = ["verbs.hjson", {file = "dark-blue-skin.hjson", luma = ["dark", "unknown"]}, {file = "white-skin.hjson", luma = "light"}] - modal = true - show_selection_mark = true - verbs = [] + nmt.script = '' + assertFileExists home-files/.config/broot/conf.toml + assertFileContent home-files/.config/broot/conf.toml ${ + builtins.toFile "broot.expected" '' + content_search_max_file_size = "10MB" + imports = ["verbs.hjson", {file = "dark-blue-skin.hjson", luma = ["dark", "unknown"]}, {file = "white-skin.hjson", luma = "light"}] + modal = true + show_selection_mark = true + verbs = [] - [skin] - '' - } - ''; - }; + [skin] + + [special_paths] + "/media" = "no-enter" + '' + } + ''; } diff --git a/tests/modules/programs/direnv/default.nix b/tests/modules/programs/direnv/default.nix index 3efad2b69458..a0e618481f83 100644 --- a/tests/modules/programs/direnv/default.nix +++ b/tests/modules/programs/direnv/default.nix @@ -1,6 +1,7 @@ { direnv-bash = ./bash.nix; direnv-nix-direnv = ./nix-direnv.nix; + direnv-nushell = ./nushell.nix; direnv-stdlib = ./stdlib.nix; direnv-stdlib-and-nix-direnv = ./stdlib-and-nix-direnv.nix; } diff --git a/tests/modules/programs/direnv/nushell.nix b/tests/modules/programs/direnv/nushell.nix new file mode 100644 index 000000000000..3041770c1c9f --- /dev/null +++ b/tests/modules/programs/direnv/nushell.nix @@ -0,0 +1,19 @@ +{ pkgs, ... }: + +{ + programs.nushell.enable = true; + programs.direnv.enable = true; + + test.stubs.nushell = { }; + + nmt.script = let + configFile = if pkgs.stdenv.isDarwin then + "home-files/Library/Application Support/nushell/config.nu" + else + "home-files/.config/nushell/config.nu"; + in '' + assertFileExists "${configFile}" + assertFileRegex "${configFile}" \ + 'let direnv = (/nix/store/.*direnv.*/bin/direnv export json | from json)' + ''; +} diff --git a/tests/modules/programs/firefox/profile-settings-expected-user.js b/tests/modules/programs/firefox/profile-settings-expected-user.js index 0edd47b9101d..d929df2b3d56 100644 --- a/tests/modules/programs/firefox/profile-settings-expected-user.js +++ b/tests/modules/programs/firefox/profile-settings-expected-user.js @@ -1,5 +1,6 @@ // Generated by Home Manager. +user_pref("browser.newtabpage.pinned", "[{\"title\":\"NixOS\",\"url\":\"https://nixos.org\"}]"); user_pref("general.smoothScroll", false); diff --git a/tests/modules/programs/firefox/profile-settings.nix b/tests/modules/programs/firefox/profile-settings.nix index b28e64597e23..278f3dbb9ce0 100644 --- a/tests/modules/programs/firefox/profile-settings.nix +++ b/tests/modules/programs/firefox/profile-settings.nix @@ -9,7 +9,13 @@ lib.mkIf config.test.enableBig { profiles.test = { id = 1; - settings = { "general.smoothScroll" = false; }; + settings = { + "general.smoothScroll" = false; + "browser.newtabpage.pinned" = [{ + title = "NixOS"; + url = "https://nixos.org"; + }]; + }; }; profiles.bookmarks = { diff --git a/tests/modules/programs/himalaya/basic-expected.toml b/tests/modules/programs/himalaya/basic-expected.toml new file mode 100644 index 000000000000..abda4a13a605 --- /dev/null +++ b/tests/modules/programs/himalaya/basic-expected.toml @@ -0,0 +1,24 @@ +["hm@example.com"] +backend = "imap" +default = true +display-name = "H. M. Test" +email = "hm@example.com" +imap-host = "imap.example.com" +imap-login = "home.manager" +imap-passwd-cmd = "password-command" +imap-port = 993 +imap-ssl = true +imap-starttls = false +sender = "smtp" +smtp-host = "smtp.example.com" +smtp-login = "home.manager" +smtp-passwd-cmd = "password-command" +smtp-port = 465 +smtp-ssl = true +smtp-starttls = false + +["hm@example.com".folder-aliases] +drafts = "Drafts" +inbox = "Inbox" +sent = "Sent" +trash = "Trash" diff --git a/tests/modules/programs/himalaya/basic.nix b/tests/modules/programs/himalaya/basic.nix new file mode 100644 index 000000000000..f31a8464c450 --- /dev/null +++ b/tests/modules/programs/himalaya/basic.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + accounts.email.accounts = { + "hm@example.com" = { + imap.port = 993; + smtp.port = 465; + himalaya.enable = true; + }; + }; + + programs.himalaya = { enable = true; }; + + test.stubs.himalaya = { }; + + nmt.script = '' + assertFileExists home-files/.config/himalaya/config.toml + assertFileContent home-files/.config/himalaya/config.toml ${ + ./basic-expected.toml + } + ''; +} diff --git a/tests/modules/programs/himalaya/default.nix b/tests/modules/programs/himalaya/default.nix index 54c3978d8a49..e5473344bc1f 100644 --- a/tests/modules/programs/himalaya/default.nix +++ b/tests/modules/programs/himalaya/default.nix @@ -1 +1,5 @@ -{ himalaya = ./himalaya.nix; } +{ + himalaya-basic = ./basic.nix; + himalaya-imap-smtp = ./imap-smtp.nix; + himalaya-maildir-sendmail = ./maildir-sendmail.nix; +} diff --git a/tests/modules/programs/himalaya/himalaya-expected.toml b/tests/modules/programs/himalaya/imap-smtp-expected.toml similarity index 60% rename from tests/modules/programs/himalaya/himalaya-expected.toml rename to tests/modules/programs/himalaya/imap-smtp-expected.toml index ca7ada66de60..3a653a3cde58 100644 --- a/tests/modules/programs/himalaya/himalaya-expected.toml +++ b/tests/modules/programs/himalaya/imap-smtp-expected.toml @@ -1,6 +1,3 @@ -display-name = "" -downloads-dir = "/data/download" - ["hm@example.com"] backend = "imap" default = true @@ -9,17 +6,20 @@ email = "hm@example.com" email-listing-page-size = 50 imap-host = "imap.example.com" imap-login = "home.manager" -imap-passwd-cmd = "'password-command'" -imap-port = 995 +imap-passwd-cmd = "password-command" +imap-port = 143 +imap-ssl = false imap-starttls = false sender = "smtp" smtp-host = "smtp.example.com" smtp-login = "home.manager" -smtp-passwd-cmd = "'password-command'" +smtp-passwd-cmd = "password-command" smtp-port = 465 -smtp-starttls = false +smtp-ssl = true +smtp-starttls = true -["hm@example.com".mailboxes] -draft = "Drafts" +["hm@example.com".folder-aliases] +drafts = "D" inbox = "In" sent = "Out" +trash = "Trash" diff --git a/tests/modules/programs/himalaya/imap-smtp.nix b/tests/modules/programs/himalaya/imap-smtp.nix new file mode 100644 index 000000000000..d4c19d7369a9 --- /dev/null +++ b/tests/modules/programs/himalaya/imap-smtp.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + # imports = [ ../../accounts/email-test-accounts.nix ]; + + accounts.email.accounts = { + "hm@example.com" = { + primary = true; + address = "hm@example.com"; + userName = "home.manager"; + realName = "H. M. Test"; + passwordCommand = "password-command"; + imap = { + host = "imap.example.com"; + port = 143; + tls = { enable = false; }; + }; + smtp = { + host = "smtp.example.com"; + port = 465; + tls = { + enable = true; + useStartTls = true; + }; + }; + folders = { + inbox = "In"; + sent = "Out"; + drafts = "D"; + }; + himalaya = { + enable = true; + settings = { email-listing-page-size = 50; }; + }; + }; + }; + + programs.himalaya = { enable = true; }; + + test.stubs.himalaya = { }; + + nmt.script = '' + assertFileExists home-files/.config/himalaya/config.toml + assertFileContent home-files/.config/himalaya/config.toml ${ + ./imap-smtp-expected.toml + } + ''; +} diff --git a/tests/modules/programs/himalaya/maildir-sendmail-expected.toml b/tests/modules/programs/himalaya/maildir-sendmail-expected.toml new file mode 100644 index 000000000000..61ae940ded38 --- /dev/null +++ b/tests/modules/programs/himalaya/maildir-sendmail-expected.toml @@ -0,0 +1,16 @@ +email-listing-page-size = 50 + +["hm@example.com"] +backend = "maildir" +default = true +display-name = "H. M. Test" +email = "hm@example.com" +maildir-root-dir = "/home/hm-user/Maildir/hm@example.com" +sender = "sendmail" +sendmail-cmd = "msmtp" + +["hm@example.com".folder-aliases] +drafts = "Drafts" +inbox = "Inbox" +sent = "Sent" +trash = "Deleted" diff --git a/tests/modules/programs/himalaya/himalaya.nix b/tests/modules/programs/himalaya/maildir-sendmail.nix similarity index 50% rename from tests/modules/programs/himalaya/himalaya.nix rename to tests/modules/programs/himalaya/maildir-sendmail.nix index 4d556ff86073..a9d15d224f50 100644 --- a/tests/modules/programs/himalaya/himalaya.nix +++ b/tests/modules/programs/himalaya/maildir-sendmail.nix @@ -3,32 +3,27 @@ with lib; { - imports = [ ../../accounts/email-test-accounts.nix ]; - accounts.email.accounts = { "hm@example.com" = { + primary = true; + address = "hm@example.com"; + userName = "home.manager"; + realName = "H. M. Test"; + passwordCommand = "password-command"; + folders = { trash = "Deleted"; }; himalaya = { enable = true; - - backend = "imap"; - sender = "smtp"; - settings = { email-listing-page-size = 50; }; + settings = { + sender = "sendmail"; + sendmail-cmd = "msmtp"; + }; }; - - folders = { - inbox = "In"; - sent = "Out"; - drafts = "Drafts"; - }; - - imap.port = 995; - smtp.port = 465; }; }; programs.himalaya = { enable = true; - settings = { downloads-dir = "/data/download"; }; + settings = { email-listing-page-size = 50; }; }; test.stubs.himalaya = { }; @@ -36,7 +31,7 @@ with lib; nmt.script = '' assertFileExists home-files/.config/himalaya/config.toml assertFileContent home-files/.config/himalaya/config.toml ${ - ./himalaya-expected.toml + ./maildir-sendmail-expected.toml } ''; } diff --git a/tests/modules/programs/mbsync/mbsync-master-slave-change.nix b/tests/modules/programs/mbsync/mbsync-master-slave-change.nix index 2e8773208792..c6861374b3fa 100644 --- a/tests/modules/programs/mbsync/mbsync-master-slave-change.nix +++ b/tests/modules/programs/mbsync/mbsync-master-slave-change.nix @@ -16,7 +16,7 @@ with lib; # programs.mbsync.groups and # accounts.email.accounts..mbsync.groups should NOT be used at the # same time. - # If they are, then the new version will take precendence. + # If they are, then the new version will take precedence. groups.inboxes = { "hm@example.com" = [ "Inbox1" "Inbox2" ]; hm-account = [ "Inbox" ]; diff --git a/tests/modules/programs/mbsync/mbsync.nix b/tests/modules/programs/mbsync/mbsync.nix index 862e1c0e00d6..ffc1635e2e40 100644 --- a/tests/modules/programs/mbsync/mbsync.nix +++ b/tests/modules/programs/mbsync/mbsync.nix @@ -11,7 +11,7 @@ with lib; # programs.mbsync.groups and # accounts.email.accounts..mbsync.groups should NOT be used at the # same time. - # If they are, then the new version will take precendence. + # If they are, then the new version will take precedence. groups.inboxes = { "hm@example.com" = [ "Inbox1" "Inbox2" ]; hm-account = [ "Inbox" ]; diff --git a/tests/modules/programs/ncmpcpp-linux/default.nix b/tests/modules/programs/ncmpcpp-linux/default.nix index b1185c852491..41933927848a 100644 --- a/tests/modules/programs/ncmpcpp-linux/default.nix +++ b/tests/modules/programs/ncmpcpp-linux/default.nix @@ -1 +1,4 @@ -{ ncmpcpp-use-mpd-config = ./ncmpcpp-use-mpd-config.nix; } +{ + ncmpcpp-use-mpd-config = ./ncmpcpp-use-mpd-config.nix; + ncmpcpp-issue-3560 = ./ncmpcpp-issue-3560.nix; +} diff --git a/tests/modules/programs/ncmpcpp-linux/ncmpcpp-issue-3560-expected-config b/tests/modules/programs/ncmpcpp-linux/ncmpcpp-issue-3560-expected-config new file mode 100644 index 000000000000..24a2f3bc3bf4 --- /dev/null +++ b/tests/modules/programs/ncmpcpp-linux/ncmpcpp-issue-3560-expected-config @@ -0,0 +1 @@ +mpd_music_dir=~/music diff --git a/tests/modules/programs/ncmpcpp-linux/ncmpcpp-issue-3560.nix b/tests/modules/programs/ncmpcpp-linux/ncmpcpp-issue-3560.nix new file mode 100644 index 000000000000..ba1607ab8ca1 --- /dev/null +++ b/tests/modules/programs/ncmpcpp-linux/ncmpcpp-issue-3560.nix @@ -0,0 +1,25 @@ +{ pkgs, ... }: + +{ + config = { + # Minimal config reproducing + # https://github.com/nix-community/home-manager/issues/3560 + programs.ncmpcpp.enable = true; + + services.mpd.enable = true; + services.mpd.musicDirectory = "~/music"; + + test.stubs = { + ncmpcpp = { }; + mpd = { }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/ncmpcpp/config \ + ${./ncmpcpp-issue-3560-expected-config} + + assertPathNotExists home-files/.config/ncmpcpp/bindings + ''; + }; +} diff --git a/tests/modules/programs/neovim/default.nix b/tests/modules/programs/neovim/default.nix index 3950dc8b8623..d3224666b37d 100644 --- a/tests/modules/programs/neovim/default.nix +++ b/tests/modules/programs/neovim/default.nix @@ -5,4 +5,5 @@ # waiting for a nixpkgs patch neovim-no-init = ./no-init.nix; + neovim-extra-lua-init = ./extra-lua-init.nix; } diff --git a/tests/modules/programs/neovim/extra-lua-init.nix b/tests/modules/programs/neovim/extra-lua-init.nix new file mode 100644 index 000000000000..2abaa6e9e7e3 --- /dev/null +++ b/tests/modules/programs/neovim/extra-lua-init.nix @@ -0,0 +1,23 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.neovim = { + enable = true; + + extraLuaConfig = '' + -- extraLuaConfig + ''; + }; + nmt.script = '' + nvimFolder="home-files/.config/nvim" + assertFileContent "$nvimFolder/init.lua" ${ + pkgs.writeText "init.lua-expected" '' + -- extraLuaConfig + '' + } + ''; + }; +} diff --git a/tests/modules/programs/neovim/runtime.nix b/tests/modules/programs/neovim/runtime.nix index 839b2790d6dd..b9d9638a8bf3 100644 --- a/tests/modules/programs/neovim/runtime.nix +++ b/tests/modules/programs/neovim/runtime.nix @@ -4,28 +4,36 @@ with lib; { config = { - programs.neovim = { - enable = true; - plugins = with pkgs.vimPlugins; [ - vim-nix - { - plugin = vim-commentary; - runtime = { - "after/ftplugin/c.vim".text = '' - " plugin-specific config - setlocal commentstring=//\ %s - setlocal comments=:// - ''; - }; - } - ]; + programs.neovim = lib.mkMerge [ + { + enable = true; + plugins = with pkgs.vimPlugins; [ + vim-nix + { + plugin = vim-commentary; + runtime = { + "after/ftplugin/c.vim".text = '' + " plugin-specific config + setlocal commentstring=//\ %s + setlocal comments=:// + ''; + }; + } + ]; + } + { + extraPython3Packages = ps: with ps; [ jedi pynvim ]; + extraLuaPackages = ps: with ps; [ luacheck ]; + } + { + extraPython3Packages = with pkgs.python3Packages; [ jedi pynvim ]; + extraLuaPackages = with pkgs.lua51Packages; [ luacheck ]; + } + ]; - extraPython3Packages = (ps: with ps; [ jedi pynvim ]); - }; nmt.script = '' ftplugin="home-files/.config/nvim/after/ftplugin/c.vim" assertFileExists "$ftplugin" ''; }; } - diff --git a/tests/modules/programs/papis/default.nix b/tests/modules/programs/papis/default.nix new file mode 100644 index 000000000000..a849be85f1d3 --- /dev/null +++ b/tests/modules/programs/papis/default.nix @@ -0,0 +1 @@ +{ papis = ./papis.nix; } diff --git a/tests/modules/programs/papis/papis.nix b/tests/modules/programs/papis/papis.nix new file mode 100644 index 000000000000..507056bed98f --- /dev/null +++ b/tests/modules/programs/papis/papis.nix @@ -0,0 +1,46 @@ +{ ... }: + +{ + programs.papis = { + enable = true; + settings = { + picktool = "fzf"; + file-browser = "ranger"; + add-edit = true; + }; + libraries = { + papers = { + isDefault = true; + settings = { + dir = "~/papers"; + opentool = "okular"; + }; + }; + books.settings = { + dir = "~/books"; + opentool = "firefox"; + }; + }; + }; + + test.stubs.papis = { }; + + nmt.script = '' + assertFileContent home-files/.config/papis/config \ + ${builtins.toFile "papis-expected-settings.ini" '' + [books] + dir=~/books + opentool=firefox + + [papers] + dir=~/papers + opentool=okular + + [settings] + add-edit=true + default-library=papers + file-browser=ranger + picktool=fzf + ''} + ''; +} diff --git a/tests/modules/programs/scmpuff/bash.nix b/tests/modules/programs/scmpuff/bash.nix index ea34373b9c8d..942d472f9d3c 100644 --- a/tests/modules/programs/scmpuff/bash.nix +++ b/tests/modules/programs/scmpuff/bash.nix @@ -1,15 +1,17 @@ -{ pkgs, ... }: { - config = { - programs = { - scmpuff.enable = true; - bash.enable = true; - }; +{ ... }: - nmt.script = '' - assertFileExists home-files/.bashrc - assertFileContains \ - home-files/.bashrc \ - 'eval "$(${pkgs.scmpuff}/bin/scmpuff init -s)"' - ''; +{ + programs = { + scmpuff.enable = true; + bash.enable = true; }; + + test.stubs.scmpuff = { }; + + nmt.script = '' + assertFileExists home-files/.bashrc + assertFileContains \ + home-files/.bashrc \ + 'eval "$(@scmpuff@/bin/scmpuff init -s)"' + ''; } diff --git a/tests/modules/programs/scmpuff/fish.nix b/tests/modules/programs/scmpuff/fish.nix index 5326995f5023..920196b16c1e 100644 --- a/tests/modules/programs/scmpuff/fish.nix +++ b/tests/modules/programs/scmpuff/fish.nix @@ -1,4 +1,6 @@ -{ pkgs, lib, ... }: { +{ lib, ... }: + +{ programs = { scmpuff.enable = true; fish.enable = true; diff --git a/tests/modules/programs/scmpuff/no-bash.nix b/tests/modules/programs/scmpuff/no-bash.nix index e3852b84a0a1..e76295a53327 100644 --- a/tests/modules/programs/scmpuff/no-bash.nix +++ b/tests/modules/programs/scmpuff/no-bash.nix @@ -1,15 +1,17 @@ -{ pkgs, ... }: { - config = { - programs = { - scmpuff = { - enable = true; - enableBashIntegration = false; - }; - bash.enable = true; - }; +{ ... }: - nmt.script = '' - assertFileNotRegex home-files/.bashrc '${pkgs.scmpuff}/bin/scmpuff' - ''; +{ + programs = { + scmpuff = { + enable = true; + enableBashIntegration = false; + }; + bash.enable = true; }; + + test.stubs.scmpuff = { }; + + nmt.script = '' + assertFileNotRegex home-files/.bashrc '@scmpuff@/bin/scmpuff' + ''; } diff --git a/tests/modules/programs/scmpuff/no-fish.nix b/tests/modules/programs/scmpuff/no-fish.nix index 94666a598482..977b8fd3aa63 100644 --- a/tests/modules/programs/scmpuff/no-fish.nix +++ b/tests/modules/programs/scmpuff/no-fish.nix @@ -1,4 +1,6 @@ -{ pkgs, lib, ... }: { +{ lib, ... }: + +{ programs = { scmpuff = { enable = true; diff --git a/tests/modules/programs/scmpuff/no-shell.nix b/tests/modules/programs/scmpuff/no-shell.nix index ddc40773e45a..1f479efdadbe 100644 --- a/tests/modules/programs/scmpuff/no-shell.nix +++ b/tests/modules/programs/scmpuff/no-shell.nix @@ -1,20 +1,23 @@ -{ pkgs, ... }: { - config = { - programs = { - scmpuff = { - enable = true; - enableBashIntegration = false; - enableZshIntegration = false; - }; - bash.enable = true; - zsh.enable = true; - }; +{ ... }: - test.stubs.zsh = { }; +{ + programs = { + scmpuff = { + enable = true; + enableBashIntegration = false; + enableZshIntegration = false; + }; + bash.enable = true; + zsh.enable = true; + }; - nmt.script = '' - assertFileNotRegex home-files/.zshrc '${pkgs.scmpuff} init -s' - assertFileNotRegex home-files/.bashrc '${pkgs.scmpuff} init -s' - ''; + test.stubs = { + zsh = { }; + scmpuff = { }; }; + + nmt.script = '' + assertFileNotRegex home-files/.zshrc '@scmpuff@ init -s' + assertFileNotRegex home-files/.bashrc '@scmpuff@ init -s' + ''; } diff --git a/tests/modules/programs/scmpuff/no-zsh.nix b/tests/modules/programs/scmpuff/no-zsh.nix index 5854fdd6f646..d6ed244900b9 100644 --- a/tests/modules/programs/scmpuff/no-zsh.nix +++ b/tests/modules/programs/scmpuff/no-zsh.nix @@ -1,17 +1,20 @@ -{ pkgs, ... }: { - config = { - programs = { - scmpuff = { - enable = true; - enableZshIntegration = false; - }; - zsh.enable = true; - }; +{ ... }: - test.stubs.zsh = { }; +{ + programs = { + scmpuff = { + enable = true; + enableZshIntegration = false; + }; + zsh.enable = true; + }; - nmt.script = '' - assertFileNotRegex home-files/.zshrc '${pkgs.scmpuff} init -s' - ''; + test.stubs = { + zsh = { }; + scmpuff = { }; }; + + nmt.script = '' + assertFileNotRegex home-files/.zshrc '@scmpuff@ init -s' + ''; } diff --git a/tests/modules/programs/scmpuff/zsh.nix b/tests/modules/programs/scmpuff/zsh.nix index d132945f6039..ce0a0eaeb01b 100644 --- a/tests/modules/programs/scmpuff/zsh.nix +++ b/tests/modules/programs/scmpuff/zsh.nix @@ -1,17 +1,20 @@ -{ pkgs, ... }: { - config = { - programs = { - scmpuff.enable = true; - zsh.enable = true; - }; +{ ... }: - test.stubs.zsh = { }; +{ + programs = { + scmpuff.enable = true; + zsh.enable = true; + }; - nmt.script = '' - assertFileExists home-files/.zshrc - assertFileContains \ - home-files/.zshrc \ - 'eval "$(${pkgs.scmpuff}/bin/scmpuff init -s)"' - ''; + test.stubs = { + zsh = { }; + scmpuff = { }; }; + + nmt.script = '' + assertFileExists home-files/.zshrc + assertFileContains \ + home-files/.zshrc \ + 'eval "$(@scmpuff@/bin/scmpuff init -s)"' + ''; } diff --git a/tests/modules/programs/tmux/default-shell.conf b/tests/modules/programs/tmux/default-shell.conf index a33623630756..8eb4e40fadc5 100644 --- a/tests/modules/programs/tmux/default-shell.conf +++ b/tests/modules/programs/tmux/default-shell.conf @@ -23,6 +23,7 @@ set -g mode-keys emacs +set -g mouse off setw -g aggressive-resize off setw -g clock-mode-style 12 set -s escape-time 500 diff --git a/tests/modules/programs/tmux/default.nix b/tests/modules/programs/tmux/default.nix index be78c2620a4a..979774a717a7 100644 --- a/tests/modules/programs/tmux/default.nix +++ b/tests/modules/programs/tmux/default.nix @@ -7,4 +7,5 @@ tmux-default-shell = ./default-shell.nix; tmux-shortcut-without-prefix = ./shortcut-without-prefix.nix; tmux-prefix = ./prefix.nix; + tmux-mouse-enabled = ./mouse-enabled.nix; } diff --git a/tests/modules/programs/tmux/disable-confirmation-prompt.conf b/tests/modules/programs/tmux/disable-confirmation-prompt.conf index e97a94d192af..b4359316c0a3 100644 --- a/tests/modules/programs/tmux/disable-confirmation-prompt.conf +++ b/tests/modules/programs/tmux/disable-confirmation-prompt.conf @@ -23,6 +23,7 @@ bind-key -N "Kill the current window" & kill-window bind-key -N "Kill the current pane" x kill-pane +set -g mouse off setw -g aggressive-resize off setw -g clock-mode-style 12 set -s escape-time 500 diff --git a/tests/modules/programs/tmux/emacs-with-plugins.conf b/tests/modules/programs/tmux/emacs-with-plugins.conf index d01501925245..54ddce136066 100644 --- a/tests/modules/programs/tmux/emacs-with-plugins.conf +++ b/tests/modules/programs/tmux/emacs-with-plugins.conf @@ -23,6 +23,7 @@ set -g mode-keys emacs +set -g mouse off setw -g aggressive-resize on setw -g clock-mode-style 24 set -s escape-time 500 diff --git a/tests/modules/programs/tmux/mouse-enabled.conf b/tests/modules/programs/tmux/mouse-enabled.conf new file mode 100644 index 000000000000..2069920de24b --- /dev/null +++ b/tests/modules/programs/tmux/mouse-enabled.conf @@ -0,0 +1,29 @@ +# ============================================= # +# Start with defaults from the Sensible plugin # +# --------------------------------------------- # +run-shell @sensible_rtp@ +# ============================================= # + +set -g default-terminal "screen" +set -g base-index 0 +setw -g pane-base-index 0 + + + + + +set -g status-keys emacs +set -g mode-keys emacs + + + + + + + +set -g mouse on +setw -g aggressive-resize off +setw -g clock-mode-style 12 +set -s escape-time 500 +set -g history-limit 2000 + diff --git a/tests/modules/programs/tmux/mouse-enabled.nix b/tests/modules/programs/tmux/mouse-enabled.nix new file mode 100644 index 000000000000..6fc5b526e943 --- /dev/null +++ b/tests/modules/programs/tmux/mouse-enabled.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.tmux = { + enable = true; + mouse = true; + }; + + nixpkgs.overlays = [ + (self: super: { + tmuxPlugins = super.tmuxPlugins // { + sensible = super.tmuxPlugins.sensible // { rtp = "@sensible_rtp@"; }; + }; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/tmux/tmux.conf + assertFileContent home-files/.config/tmux/tmux.conf \ + ${./mouse-enabled.conf} + ''; + }; +} diff --git a/tests/modules/programs/tmux/prefix.conf b/tests/modules/programs/tmux/prefix.conf index 831ec3b0ecdb..00f950e09cae 100644 --- a/tests/modules/programs/tmux/prefix.conf +++ b/tests/modules/programs/tmux/prefix.conf @@ -26,6 +26,7 @@ bind -N "Send the prefix key through to the application" \ +set -g mouse off setw -g aggressive-resize off setw -g clock-mode-style 12 set -s escape-time 500 diff --git a/tests/modules/programs/tmux/secure-socket-enabled.nix b/tests/modules/programs/tmux/secure-socket-enabled.nix index ca2de66310db..60b3f70877bf 100644 --- a/tests/modules/programs/tmux/secure-socket-enabled.nix +++ b/tests/modules/programs/tmux/secure-socket-enabled.nix @@ -12,7 +12,7 @@ with lib; nmt.script = '' assertFileExists home-path/etc/profile.d/hm-session-vars.sh assertFileContains home-path/etc/profile.d/hm-session-vars.sh \ - 'export TMUX_TMPDIR="''${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}"' + 'export TMUX_TMPDIR="''${XDG_RUNTIME_DIR:-"/run/user/$(id -u)"}"' ''; }; } diff --git a/tests/modules/programs/tmux/shortcut-without-prefix.conf b/tests/modules/programs/tmux/shortcut-without-prefix.conf index 4fd89ad242ac..938ecfa823a9 100644 --- a/tests/modules/programs/tmux/shortcut-without-prefix.conf +++ b/tests/modules/programs/tmux/shortcut-without-prefix.conf @@ -27,6 +27,7 @@ bind C-a last-window +set -g mouse off setw -g aggressive-resize off setw -g clock-mode-style 12 set -s escape-time 500 diff --git a/tests/modules/programs/tmux/vi-all-true.conf b/tests/modules/programs/tmux/vi-all-true.conf index 6a6fd611475b..03bf2f5a18a1 100644 --- a/tests/modules/programs/tmux/vi-all-true.conf +++ b/tests/modules/programs/tmux/vi-all-true.conf @@ -23,6 +23,7 @@ set -g mode-keys vi +set -g mouse off setw -g aggressive-resize on setw -g clock-mode-style 24 set -s escape-time 500 diff --git a/tests/modules/programs/vim-vint/basic-configuration.nix b/tests/modules/programs/vim-vint/basic-configuration.nix new file mode 100644 index 000000000000..59bfafa5a718 --- /dev/null +++ b/tests/modules/programs/vim-vint/basic-configuration.nix @@ -0,0 +1,27 @@ +{ config, pkgs, lib, xdg, ... }: + +{ + programs.vim-vint = { + enable = true; + settings = { + cmdargs = { + severity = "error"; + color = true; + env = { neovim = true; }; + }; + policies = { + ProhibitEqualTildeOperator.enabled = false; + ProhibitUsingUndeclaredVariable.enabled = false; + ProhibitAbbreviationOption.enabled = false; + ProhibitImplicitScopeVariable.enabled = false; + ProhibitSetNoCompatible.enabled = false; + }; + }; + }; + + nmt.script = '' + assertFileContent home-files/.config/.vintrc.yaml ${ + ./basic-configuration.yaml + } + ''; +} diff --git a/tests/modules/programs/vim-vint/basic-configuration.yaml b/tests/modules/programs/vim-vint/basic-configuration.yaml new file mode 100644 index 000000000000..1273b14e9400 --- /dev/null +++ b/tests/modules/programs/vim-vint/basic-configuration.yaml @@ -0,0 +1,16 @@ +cmdargs: + color: true + env: + neovim: true + severity: error +policies: + ProhibitAbbreviationOption: + enabled: false + ProhibitEqualTildeOperator: + enabled: false + ProhibitImplicitScopeVariable: + enabled: false + ProhibitSetNoCompatible: + enabled: false + ProhibitUsingUndeclaredVariable: + enabled: false diff --git a/tests/modules/programs/vim-vint/default.nix b/tests/modules/programs/vim-vint/default.nix new file mode 100644 index 000000000000..0066eaf8f1f2 --- /dev/null +++ b/tests/modules/programs/vim-vint/default.nix @@ -0,0 +1 @@ +{ vim-vint-basic-configuration = ./basic-configuration.nix; } diff --git a/tests/modules/programs/wlogout/default.nix b/tests/modules/programs/wlogout/default.nix new file mode 100644 index 000000000000..294772e749a1 --- /dev/null +++ b/tests/modules/programs/wlogout/default.nix @@ -0,0 +1,5 @@ +{ + wlogout-styling = ./styling.nix; + wlogout-layout-single = ./layout-single.nix; + wlogout-layout-multiple = ./layout-multiple.nix; +} diff --git a/tests/modules/programs/wlogout/layout-multiple-expected.json b/tests/modules/programs/wlogout/layout-multiple-expected.json new file mode 100644 index 000000000000..9e69d4e930e3 --- /dev/null +++ b/tests/modules/programs/wlogout/layout-multiple-expected.json @@ -0,0 +1,6 @@ +{"action":"systemctl poweroff","keybind":"s","label":"shutdown","text":"Shutdown"} +{"action":"systemctl hibernate","height":0.5,"keybind":"h","label":"hibernate","text":"Hibernate","width":0.5} +{"action":"systemctl suspend","circular":true,"keybind":"u","label":"suspend","text":"Suspend"} +{"action":"swaymsg exit","keybind":"e","label":"exit","text":"Exit"} +{"action":"systemctl reboot","keybind":"r","label":"reboot","text":"Reboot"} +{"action":"gtklock","keybind":"l","label":"lock","text":"Lock"} diff --git a/tests/modules/programs/wlogout/layout-multiple.nix b/tests/modules/programs/wlogout/layout-multiple.nix new file mode 100644 index 000000000000..108961aaeb36 --- /dev/null +++ b/tests/modules/programs/wlogout/layout-multiple.nix @@ -0,0 +1,62 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + home.stateVersion = "22.11"; + + programs.wlogout = { + package = config.lib.test.mkStubPackage { outPath = "@wlogout@"; }; + enable = true; + layout = [ + { + label = "shutdown"; + action = "systemctl poweroff"; + text = "Shutdown"; + keybind = "s"; + } + { + label = "hibernate"; + action = "systemctl hibernate"; + text = "Hibernate"; + keybind = "h"; + height = 0.5; + width = 0.5; + } + { + label = "suspend"; + action = "systemctl suspend"; + text = "Suspend"; + keybind = "u"; + circular = true; + } + { + label = "exit"; + action = "swaymsg exit"; + text = "Exit"; + keybind = "e"; + } + { + label = "reboot"; + action = "systemctl reboot"; + text = "Reboot"; + keybind = "r"; + } + { + label = "lock"; + action = "gtklock"; + text = "Lock"; + keybind = "l"; + } + ]; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/wlogout/style.css + assertFileContent \ + home-files/.config/wlogout/layout \ + ${./layout-multiple-expected.json} + ''; + }; +} diff --git a/tests/modules/programs/wlogout/layout-single-expected.json b/tests/modules/programs/wlogout/layout-single-expected.json new file mode 100644 index 000000000000..d4d43dde38cc --- /dev/null +++ b/tests/modules/programs/wlogout/layout-single-expected.json @@ -0,0 +1 @@ +{"action":"systemctl poweroff","keybind":"s","label":"shutdown","text":"Shutdown"} diff --git a/tests/modules/programs/wlogout/layout-single.nix b/tests/modules/programs/wlogout/layout-single.nix new file mode 100644 index 000000000000..bbb5d61e6644 --- /dev/null +++ b/tests/modules/programs/wlogout/layout-single.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + home.stateVersion = "22.11"; + + programs.wlogout = { + package = config.lib.test.mkStubPackage { outPath = "@wlogout@"; }; + enable = true; + layout = [{ + label = "shutdown"; + action = "systemctl poweroff"; + text = "Shutdown"; + keybind = "s"; + }]; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/wlogout/style.css + assertFileContent \ + home-files/.config/wlogout/layout \ + ${./layout-single-expected.json} + ''; + }; +} diff --git a/tests/modules/programs/wlogout/styling-expected.css b/tests/modules/programs/wlogout/styling-expected.css new file mode 100644 index 000000000000..49050beb4197 --- /dev/null +++ b/tests/modules/programs/wlogout/styling-expected.css @@ -0,0 +1,16 @@ +* { + border: none; + border-radius: 0; + font-family: Source Code Pro; + font-weight: bold; + color: #abb2bf; + font-size: 18px; + min-height: 0px; +} +window { + background: #16191C; + color: #aab2bf; +} +#window { + padding: 0 0px; +} diff --git a/tests/modules/programs/wlogout/styling.nix b/tests/modules/programs/wlogout/styling.nix new file mode 100644 index 000000000000..6df6290fd650 --- /dev/null +++ b/tests/modules/programs/wlogout/styling.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + home.stateVersion = "22.11"; + + programs.wlogout = { + package = config.lib.test.mkStubPackage { outPath = "@wlogout@"; }; + enable = true; + style = '' + * { + border: none; + border-radius: 0; + font-family: Source Code Pro; + font-weight: bold; + color: #abb2bf; + font-size: 18px; + min-height: 0px; + } + window { + background: #16191C; + color: #aab2bf; + } + #window { + padding: 0 0px; + } + ''; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/wlogout/layout + assertFileContent \ + home-files/.config/wlogout/style.css \ + ${./styling-expected.css} + ''; + }; +} diff --git a/tests/modules/services/borgmatic/basic-configuration.service b/tests/modules/services/borgmatic/basic-configuration.service index 4840f11bc908..80713fd90524 100644 --- a/tests/modules/services/borgmatic/basic-configuration.service +++ b/tests/modules/services/borgmatic/basic-configuration.service @@ -2,6 +2,7 @@ CPUSchedulingPolicy=batch ExecStart=/nix/store/00000000000000000000000000000000-systemd/bin/systemd-inhibit \ --who="borgmatic" \ + --what="sleep:shutdown" \ --why="Prevent interrupting scheduled backup" \ @borgmatic@/bin/borgmatic \ --stats \ diff --git a/tests/modules/services/clipman/clipman-sway-session-target.nix b/tests/modules/services/clipman/clipman-sway-session-target.nix new file mode 100644 index 000000000000..129ab554fbf1 --- /dev/null +++ b/tests/modules/services/clipman/clipman-sway-session-target.nix @@ -0,0 +1,20 @@ +{ ... }: + +{ + home.stateVersion = "21.11"; + + services.clipman = { + enable = true; + systemdTarget = "sway-session.target"; + }; + + test.stubs = { + clipman = { }; + wl-clipboard = { }; + }; + + nmt.script = '' + serviceFile=$(normalizeStorePaths home-files/.config/systemd/user/clipman.service) + assertFileContent "$serviceFile" ${./clipman-sway-session-target.service} + ''; +} diff --git a/tests/modules/services/clipman/clipman-sway-session-target.service b/tests/modules/services/clipman/clipman-sway-session-target.service new file mode 100644 index 000000000000..0d0478cc7c90 --- /dev/null +++ b/tests/modules/services/clipman/clipman-sway-session-target.service @@ -0,0 +1,13 @@ +[Install] +WantedBy=sway-session.target + +[Service] +ExecReload=/nix/store/00000000000000000000000000000000-coreutils/bin/kill -SIGUSR2 $MAINPID +ExecStart=@wl-clipboard@/bin/wl-paste -t text --watch @clipman@/bin/clipman store +KillMode=mixed +Restart=on-failure + +[Unit] +After=graphical-session.target +Description=Clipboard management daemon +PartOf=graphical-session.target diff --git a/tests/modules/services/clipman/default.nix b/tests/modules/services/clipman/default.nix new file mode 100644 index 000000000000..abca59c095ea --- /dev/null +++ b/tests/modules/services/clipman/default.nix @@ -0,0 +1 @@ +{ clipman-sway-session-target = ./clipman-sway-session-target.nix; } diff --git a/tests/modules/services/parcellite/default.nix b/tests/modules/services/parcellite/default.nix new file mode 100644 index 000000000000..5cf326b14006 --- /dev/null +++ b/tests/modules/services/parcellite/default.nix @@ -0,0 +1 @@ +{ parcellite = ./parcellite.nix; } diff --git a/tests/modules/services/parcellite/parcellite-expected.service b/tests/modules/services/parcellite/parcellite-expected.service new file mode 100644 index 000000000000..02d8243a6ebc --- /dev/null +++ b/tests/modules/services/parcellite/parcellite-expected.service @@ -0,0 +1,13 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +ExecStart=@parcellite@/bin/parcellite '--no-icon' +Restart=on-abort + +[Unit] +After=graphical-session-pre.target +After=tray.target +Description=Lightweight GTK+ clipboard manager +PartOf=graphical-session.target +Requires=tray.target diff --git a/tests/modules/services/parcellite/parcellite.nix b/tests/modules/services/parcellite/parcellite.nix new file mode 100644 index 000000000000..25e553bc886e --- /dev/null +++ b/tests/modules/services/parcellite/parcellite.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +{ + services.parcellite = { + enable = true; + package = config.lib.test.mkStubPackage { + name = "parcellite"; + outPath = "@parcellite@"; + }; + extraOptions = [ "--no-icon" ]; + }; + + nmt.script = '' + assertFileContent \ + "home-files/.config/systemd/user/parcellite.service" \ + ${./parcellite-expected.service} + ''; +} diff --git a/tests/modules/services/pass-secret-service/basic-configuration.nix b/tests/modules/services/pass-secret-service/basic-configuration.nix new file mode 100644 index 000000000000..f5568df773b1 --- /dev/null +++ b/tests/modules/services/pass-secret-service/basic-configuration.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + services.pass-secret-service = { + enable = true; + package = config.lib.test.mkStubPackage { }; + storePath = "/mnt/password-store"; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/pass-secret-service.service + + assertFileExists $serviceFile + assertFileRegex $serviceFile 'ExecStart=.*/bin/pass_secret_service' + assertFileRegex $serviceFile '/mnt/password-store' + ''; +} diff --git a/tests/modules/services/pass-secret-service/default-configuration.nix b/tests/modules/services/pass-secret-service/default-configuration.nix new file mode 100644 index 000000000000..d418d823baf1 --- /dev/null +++ b/tests/modules/services/pass-secret-service/default-configuration.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: + +{ + services.pass-secret-service = { + enable = true; + package = config.lib.test.mkStubPackage { }; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/pass-secret-service.service + + assertFileExists $serviceFile + assertFileRegex $serviceFile 'ExecStart=.*/bin/pass_secret_service' + ''; +} diff --git a/tests/modules/services/pass-secret-service/default.nix b/tests/modules/services/pass-secret-service/default.nix new file mode 100644 index 000000000000..d841c97eb0d2 --- /dev/null +++ b/tests/modules/services/pass-secret-service/default.nix @@ -0,0 +1,4 @@ +{ + pass-secret-service-default-configuration = ./default-configuration.nix; + pass-secret-service-basic-configuration = ./basic-configuration.nix; +} diff --git a/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf b/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf index 92f23a921ded..3b8fca8a2e01 100644 --- a/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf +++ b/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf @@ -3,7 +3,7 @@ floating_modifier Mod1 default_border normal 2 default_floating_border normal 2 hide_edge_borders none -force_focus_wrapping no +focus_wrapping yes focus_follows_mouse yes focus_on_window_activation smart mouse_warping output diff --git a/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf b/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf index 27234b96db75..dccf535a3150 100644 --- a/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf +++ b/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf @@ -3,7 +3,7 @@ floating_modifier Mod1 default_border normal 2 default_floating_border normal 2 hide_edge_borders none -force_focus_wrapping no +focus_wrapping yes focus_follows_mouse no focus_on_window_activation smart mouse_warping output diff --git a/tests/modules/services/window-managers/i3/i3-fonts-expected.conf b/tests/modules/services/window-managers/i3/i3-fonts-expected.conf index d85d978e07d4..8e8cb9da3a0c 100644 --- a/tests/modules/services/window-managers/i3/i3-fonts-expected.conf +++ b/tests/modules/services/window-managers/i3/i3-fonts-expected.conf @@ -3,7 +3,7 @@ floating_modifier Mod1 default_border normal 2 default_floating_border normal 2 hide_edge_borders none -force_focus_wrapping no +focus_wrapping yes focus_follows_mouse yes focus_on_window_activation smart mouse_warping output diff --git a/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf b/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf index b3b4c33dea80..2b7251d2f225 100644 --- a/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf +++ b/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf @@ -3,7 +3,7 @@ floating_modifier Mod1 default_border normal 2 default_floating_border normal 2 hide_edge_borders none -force_focus_wrapping no +focus_wrapping yes focus_follows_mouse yes focus_on_window_activation smart mouse_warping output diff --git a/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf b/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf index d7fe4b610431..baca1411537f 100644 --- a/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf +++ b/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf @@ -3,7 +3,7 @@ floating_modifier Mod1 default_border normal 2 default_floating_border normal 2 hide_edge_borders none -force_focus_wrapping no +focus_wrapping yes focus_follows_mouse yes focus_on_window_activation smart mouse_warping output diff --git a/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf b/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf index dedad29e0b16..a51edb9a0c1c 100644 --- a/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf +++ b/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf @@ -3,7 +3,7 @@ floating_modifier Mod1 default_border normal 2 default_floating_border normal 2 hide_edge_borders none -force_focus_wrapping no +focus_wrapping yes focus_follows_mouse yes focus_on_window_activation smart mouse_warping output diff --git a/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf b/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf index 22d00e6ab6a6..a3b9905d6ede 100644 --- a/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf +++ b/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-bindkeys-to-code-and-extra-config.conf b/tests/modules/services/window-managers/sway/sway-bindkeys-to-code-and-extra-config.conf index 9ed389bc4bb8..65780062fcc4 100644 --- a/tests/modules/services/window-managers/sway/sway-bindkeys-to-code-and-extra-config.conf +++ b/tests/modules/services/window-managers/sway/sway-bindkeys-to-code-and-extra-config.conf @@ -29,7 +29,7 @@ bindsym --to-code Mod1+8 workspace number 8 bindsym --to-code Mod1+9 workspace number 9 bindsym --to-code Mod1+Down focus down bindsym --to-code Mod1+Left focus left -bindsym --to-code Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym --to-code Mod1+Return exec @foot@/bin/foot bindsym --to-code Mod1+Right focus right bindsym --to-code Mod1+Shift+1 move container to workspace number 1 bindsym --to-code Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-default.conf b/tests/modules/services/window-managers/sway/sway-default.conf index dc1ff8b8cf78..e1fa6626b53a 100644 --- a/tests/modules/services/window-managers/sway/sway-default.conf +++ b/tests/modules/services/window-managers/sway/sway-default.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf b/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf index c1a627219316..bf99663784f3 100644 --- a/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf +++ b/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf b/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf index 65e9657530f3..d93031c90eec 100644 --- a/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf +++ b/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-modules.conf b/tests/modules/services/window-managers/sway/sway-modules.conf index 551fafd71896..b217f884755a 100644 --- a/tests/modules/services/window-managers/sway/sway-modules.conf +++ b/tests/modules/services/window-managers/sway/sway-modules.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-null-package.conf b/tests/modules/services/window-managers/sway/sway-null-package.conf index dc1ff8b8cf78..e1fa6626b53a 100644 --- a/tests/modules/services/window-managers/sway/sway-null-package.conf +++ b/tests/modules/services/window-managers/sway/sway-null-package.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-stubs.nix b/tests/modules/services/window-managers/sway/sway-stubs.nix index 55a74e1c477d..2ae673c78119 100644 --- a/tests/modules/services/window-managers/sway/sway-stubs.nix +++ b/tests/modules/services/window-managers/sway/sway-stubs.nix @@ -3,7 +3,7 @@ # not containing hashes, version numbers etc. test.stubs = { dmenu = { }; - rxvt-unicode-unwrapped = { }; + foot = { }; i3status = { }; sway = { }; sway-unwrapped = { version = "1"; }; diff --git a/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf b/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf index c5daf6ecc05a..b783d4c20f01 100644 --- a/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf +++ b/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf @@ -26,7 +26,7 @@ bindsym Mod1+7 workspace number 7 bindsym Mod1+8 workspace number 8 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2 diff --git a/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf b/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf index 4c91dc7e5ca9..94ba5e27c024 100644 --- a/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf +++ b/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf @@ -27,7 +27,7 @@ bindsym Mod1+8 workspace number 8 bindsym Mod1+9 workspace number 9 bindsym Mod1+Down focus down bindsym Mod1+Left focus left -bindsym Mod1+Return exec @rxvt-unicode-unwrapped@/bin/urxvt +bindsym Mod1+Return exec @foot@/bin/foot bindsym Mod1+Right focus right bindsym Mod1+Shift+1 move container to workspace number 1 bindsym Mod1+Shift+2 move container to workspace number 2