From a0869759be6764a4eff9bf6428501953a56a1028 Mon Sep 17 00:00:00 2001 From: Default email Date: Sat, 3 Jul 2021 00:36:30 +0200 Subject: [PATCH] Project import generated by Copybara. GitOrigin-RevId: ac319fd3149b23a3ad8ee24cb2def6e67acf194c --- third_party/home-manager/.github/CODEOWNERS | 118 +++- .../home-manager/.github/ISSUE_TEMPLATE.md | 10 +- .../home-manager/.github/dependabot.yml | 17 + third_party/home-manager/.github/stale.yml | 75 +++ .../.github/workflows/github_pages.yml | 4 +- .../home-manager/.github/workflows/test.yml | 7 +- third_party/home-manager/.gitlab-ci.yml | 3 +- third_party/home-manager/.release | 1 + third_party/home-manager/CONTRIBUTING.adoc | 11 +- third_party/home-manager/FAQ.adoc | 6 +- third_party/home-manager/LICENSE | 2 +- third_party/home-manager/README.md | 70 ++- .../home-manager/doc/contributing.adoc | 11 +- third_party/home-manager/doc/default.nix | 63 ++- third_party/home-manager/doc/faq.adoc | 6 +- .../home-manager/doc/installation.adoc | 263 +++++++++ third_party/home-manager/doc/installation.xml | 334 ------------ .../home-manager/doc/man-home-manager.xml | 128 +++-- third_party/home-manager/doc/manual.xml | 14 +- .../doc/release-notes/release-notes.adoc | 4 + .../doc/release-notes/rl-2009.adoc | 5 +- .../doc/release-notes/rl-2105.adoc | 200 +++++++ .../doc/release-notes/rl-2111.adoc | 21 + third_party/home-manager/flake.nix | 53 +- third_party/home-manager/format | 9 - .../home-manager/home-manager/completion.bash | 12 +- .../home-manager/home-manager/completion.zsh | 59 ++ .../home-manager/home-manager/default.nix | 64 +-- .../home-manager/home-manager/home-manager | 152 +++++- .../home-manager/home-manager/install.nix | 2 +- .../home-manager/modules/accounts/email.nix | 5 +- .../home-manager/modules/config/i18n.nix | 46 ++ third_party/home-manager/modules/default.nix | 6 +- third_party/home-manager/modules/files.nix | 75 ++- .../home-manager/modules/home-environment.nix | 66 ++- .../modules/i18n/input-method/default.nix | 102 ++++ .../modules/i18n/input-method/fcitx.nix | 50 ++ .../modules/i18n/input-method/fcitx5.nix | 42 ++ .../modules/i18n/input-method/hime.nix | 23 + .../modules/i18n/input-method/kime.nix | 58 ++ .../modules/i18n/input-method/nabi.nix | 23 + .../modules/i18n/input-method/uim.nix | 45 ++ .../modules/lib-bash/color-echo.sh | 6 +- .../home-manager/modules/lib/file-type.nix | 3 + .../home-manager/modules/lib/maintainers.nix | 84 +++ .../home-manager/modules/lib/types.nix | 13 +- .../home-manager/modules/misc/dconf.nix | 47 +- third_party/home-manager/modules/misc/gtk.nix | 34 +- .../home-manager/modules/misc/news.nix | 398 ++++++++++++++ third_party/home-manager/modules/misc/pam.nix | 3 + third_party/home-manager/modules/misc/qt.nix | 59 +- .../home-manager/modules/misc/version.nix | 11 +- .../modules/misc/xdg-desktop-entries.nix | 178 ++++++ .../modules/misc/xdg-system-dirs.nix | 55 ++ .../modules/misc/xdg-user-dirs.nix | 37 +- third_party/home-manager/modules/misc/xdg.nix | 2 - third_party/home-manager/modules/modules.nix | 40 +- .../home-manager/modules/programs/afew.nix | 4 +- .../modules/programs/alacritty.nix | 10 +- .../home-manager/modules/programs/alot.nix | 5 +- .../modules/programs/astroid-accounts.nix | 2 +- .../home-manager/modules/programs/astroid.nix | 44 +- .../home-manager/modules/programs/bash.nix | 70 +-- .../home-manager/modules/programs/beets.nix | 8 +- .../home-manager/modules/programs/broot.nix | 81 +-- .../modules/programs/chromium.nix | 104 +++- .../command-not-found/command-not-found.nix | 7 +- .../command-not-found/command-not-found.pl | 13 +- .../modules/programs/dircolors.nix | 4 +- .../home-manager/modules/programs/direnv.nix | 47 +- .../home-manager/modules/programs/exa.nix | 36 ++ .../home-manager/modules/programs/firefox.nix | 31 +- .../home-manager/modules/programs/fish.nix | 7 +- .../home-manager/modules/programs/foot.nix | 77 +++ .../home-manager/modules/programs/fzf.nix | 53 +- .../home-manager/modules/programs/getmail.nix | 3 +- .../home-manager/modules/programs/gh.nix | 8 +- .../home-manager/modules/programs/git.nix | 62 ++- .../modules/programs/gnome-terminal.nix | 34 +- .../home-manager/modules/programs/gpg.nix | 84 ++- .../modules/programs/himalaya.nix | 100 ++++ .../modules/programs/home-manager.nix | 2 - .../home-manager/modules/programs/htop.nix | 511 +++++++++++++----- .../modules/programs/i3status-rust.nix | 265 +++++++++ .../home-manager/modules/programs/irssi.nix | 12 + .../home-manager/modules/programs/jq.nix | 19 +- .../home-manager/modules/programs/kakoune.nix | 2 +- .../home-manager/modules/programs/kitty.nix | 6 +- .../home-manager/modules/programs/lazygit.nix | 56 ++ .../home-manager/modules/programs/lsd.nix | 29 +- .../modules/programs/mangohud.nix | 105 ++++ .../modules/programs/matplotlib.nix | 2 +- .../modules/programs/mbsync-accounts.nix | 24 +- .../home-manager/modules/programs/mbsync.nix | 155 ++++-- .../home-manager/modules/programs/mcfly.nix | 10 + .../modules/programs/mercurial.nix | 11 +- .../home-manager/modules/programs/mpv.nix | 72 ++- .../home-manager/modules/programs/msmtp.nix | 20 +- .../home-manager/modules/programs/mu.nix | 2 +- .../home-manager/modules/programs/ncspot.nix | 50 ++ .../home-manager/modules/programs/neomutt.nix | 90 ++- .../home-manager/modules/programs/neovim.nix | 114 ++-- .../modules/programs/newsboat.nix | 64 ++- .../modules/programs/nix-index.nix | 63 +++ .../home-manager/modules/programs/nushell.nix | 18 +- .../modules/programs/obs-studio.nix | 43 +- .../home-manager/modules/programs/octant.nix | 51 ++ .../modules/programs/offlineimap.nix | 13 +- .../modules/programs/password-store.nix | 3 + .../home-manager/modules/programs/pet.nix | 9 + .../modules/programs/piston-cli.nix | 46 ++ .../modules/programs/powerline-go.nix | 35 +- .../modules/programs/qutebrowser.nix | 60 +- .../home-manager/modules/programs/rbw.nix | 116 ++++ .../modules/programs/rofi-pass.nix | 46 ++ .../home-manager/modules/programs/rofi.nix | 239 +++++--- .../home-manager/modules/programs/sbt.nix | 141 +++++ .../home-manager/modules/programs/scmpuff.nix | 47 ++ .../home-manager/modules/programs/senpai.nix | 73 +++ .../home-manager/modules/programs/ssh.nix | 11 +- .../modules/programs/starship.nix | 30 +- .../modules/programs/taskwarrior.nix | 2 +- .../modules/programs/terminator.nix | 70 +++ .../home-manager/modules/programs/termite.nix | 17 +- .../home-manager/modules/programs/texlive.nix | 17 +- .../home-manager/modules/programs/tmux.nix | 51 +- .../modules/programs/topgrade.nix | 60 ++ .../home-manager/modules/programs/urxvt.nix | 2 +- .../home-manager/modules/programs/vscode.nix | 22 +- .../home-manager/modules/programs/waybar.nix | 90 +-- .../home-manager/modules/programs/xmobar.nix | 59 ++ .../home-manager/modules/programs/zathura.nix | 9 +- .../home-manager/modules/programs/zsh.nix | 68 ++- .../modules/programs/zsh/prezto.nix | 8 +- .../home-manager/modules/services/barrier.nix | 71 +++ .../modules/services/blueman-applet.nix | 3 +- .../modules/services/caffeine.nix | 33 ++ .../modules/services/cbatticon.nix | 3 +- .../home-manager/modules/services/dunst.nix | 48 +- .../modules/services/dwm-status.nix | 8 +- .../home-manager/modules/services/emacs.nix | 80 +-- .../modules/services/etesync-dav.nix | 62 +++ .../modules/services/flameshot.nix | 8 +- .../modules/services/gammastep.nix | 166 ------ .../modules/services/gnome-keyring.nix | 2 +- .../modules/services/gpg-agent.nix | 50 +- .../home-manager/modules/services/hound.nix | 8 +- .../modules/services/imapnotify.nix | 38 +- .../home-manager/modules/services/kanshi.nix | 20 + .../home-manager/modules/services/kbfs.nix | 36 +- .../home-manager/modules/services/keybase.nix | 18 +- .../home-manager/modules/services/lieer.nix | 2 + .../home-manager/modules/services/mako.nix | 11 + .../home-manager/modules/services/mpd.nix | 41 +- .../modules/services/mpris-proxy.nix | 32 ++ .../services/network-manager-applet.nix | 3 +- .../modules/services/nextcloud-client.nix | 29 +- .../modules/services/pantalaimon.nix | 79 +++ .../modules/services/parcellite.nix | 20 +- .../modules/services/pass-secret-service.nix | 28 + .../modules/services/pasystray.nix | 3 +- .../home-manager/modules/services/pbgopy.nix | 68 +++ .../modules/services/plan9port.nix | 35 ++ .../modules/services/playerctld.nix | 36 ++ .../home-manager/modules/services/polybar.nix | 93 +++- .../modules/services/poweralertd.nix | 31 ++ .../modules/services/pulseeffects.nix | 16 +- .../services/redshift-gammastep/gammastep.nix | 25 + .../redshift-gammastep/lib/options.nix | 201 +++++++ .../services/redshift-gammastep/redshift.nix | 24 + .../modules/services/redshift.nix | 164 ------ .../modules/services/rsibreak.nix | 1 + .../modules/services/spotifyd.nix | 8 +- .../modules/services/stalonetray.nix | 5 +- .../services/status-notifier-watcher.nix | 14 +- .../home-manager/modules/services/sxhkd.nix | 57 +- .../modules/services/syncthing.nix | 92 +++- .../modules/services/taffybar.nix | 7 +- .../home-manager/modules/services/udiskie.nix | 3 +- .../window-managers/bspwm/default.nix | 104 ++-- .../window-managers/bspwm/options.nix | 13 +- .../services/window-managers/i3-sway/i3.nix | 46 +- .../window-managers/i3-sway/lib/functions.nix | 53 +- .../window-managers/i3-sway/lib/options.nix | 189 +++++-- .../services/window-managers/i3-sway/sway.nix | 143 +++-- .../services/window-managers/xmonad.nix | 98 +++- .../modules/services/wlsunset.nix | 97 ++++ .../modules/services/xidlehook.nix | 149 +++++ .../modules/services/xsuspender.nix | 7 +- third_party/home-manager/modules/systemd.nix | 153 ++++-- .../modules/targets/darwin/default.nix | 51 ++ .../modules/targets/darwin/fonts.nix | 27 + .../modules/targets/darwin/keybindings.nix | 42 ++ .../{darwin.nix => darwin/linkapps.nix} | 0 .../modules/targets/darwin/options.nix | 189 +++++++ .../modules/targets/darwin/search.nix | 33 ++ .../modules/targets/generic-linux.nix | 56 +- third_party/home-manager/modules/xcursor.nix | 9 + .../home-manager/modules/xresources.nix | 18 +- third_party/home-manager/modules/xsession.nix | 37 +- .../home-manager/nix-darwin/default.nix | 34 +- third_party/home-manager/nixos/default.nix | 33 +- third_party/home-manager/tests/asserts.nix | 73 +++ third_party/home-manager/tests/default.nix | 37 +- .../tests/lib/types/dag-merge.nix | 2 +- .../tests/lib/types/dag-submodule.nix | 2 +- .../tests/lib/types/list-or-dag-merge.nix | 2 +- .../home-manager/tests/meta/default.nix | 1 - .../home-manager/tests/meta/formatting.nix | 27 - .../modules/accounts/email-test-accounts.nix | 1 + .../tests/modules/config/i18n/default.nix | 17 + .../tests/modules/files/default.nix | 1 + .../tests/modules/files/target-conflict.nix | 26 + .../modules/home-environment/session-path.nix | 20 +- .../session-variables-expected.txt | 2 +- .../home-environment/session-variables.nix | 40 +- .../modules/i18n/input-method/default.nix | 1 + .../input-method/fcitx5-configuration.nix | 15 + .../i18n/input-method/fcitx5-overlay.nix | 22 + .../tests/modules/misc/gtk/default.nix | 5 + .../misc/gtk/gtk-basic-config-expected.conf | 2 + .../modules/misc/gtk/gtk2-basic-config.nix | 21 + .../misc/gtk/gtk2-config-file-location.nix | 16 + .../tests/modules/misc/qt/default.nix | 4 + .../misc/qt/qt-platform-theme-gnome.nix | 27 + .../modules/misc/qt/qt-platform-theme-gtk.nix | 15 + .../tests/modules/misc/xdg/default.nix | 2 + .../modules/misc/xdg/desktop-entries.nix | 58 ++ .../misc/xdg/desktop-full-expected.desktop | 16 + .../misc/xdg/desktop-min-expected.desktop | 5 + .../tests/modules/misc/xdg/system-dirs.nix | 27 + .../misc/xsession/basic-xsession-expected.txt | 2 +- .../modules/programs/alacritty/default.nix | 1 + .../alacritty/settings-merging-expected.yml | 1 + .../programs/alacritty/settings-merging.nix | 39 ++ .../tests/modules/programs/alot/alot.nix | 1 - .../autorandr/basic-configuration.conf | 10 - .../autorandr/basic-configuration.nix | 17 +- .../modules/programs/autorandr/default.nix | 5 +- .../modules/programs/autorandr/scale.nix | 32 ++ .../modules/programs/bash/logout-expected.txt | 4 - .../tests/modules/programs/bash/logout.nix | 6 +- .../bash/session-variables-expected.txt | 8 - .../programs/bash/session-variables.nix | 11 +- .../programs/dircolors/settings-expected.conf | 4 +- .../modules/programs/direnv/nix-direnv.nix | 2 +- .../programs/direnv/stdlib-and-nix-direnv.nix | 2 +- .../modules/programs/firefox/default.nix | 1 + .../firefox/deprecated-native-messenger.nix | 37 ++ .../programs/firefox/profile-settings.nix | 9 +- .../tests/modules/programs/foot/default.nix | 5 + .../modules/programs/foot/empty-settings.nix | 16 + .../foot/example-settings-expected.ini | 7 + .../programs/foot/example-settings.nix | 29 + .../systemd-user-service-expected.service | 12 + .../programs/foot/systemd-user-service.nix | 21 + .../programs/getmail/getmail-expected.conf | 2 +- .../modules/programs/getmail/getmail.nix | 6 +- .../tests/modules/programs/gh/config-file.nix | 11 +- .../tests/modules/programs/git/default.nix | 3 + .../programs/git/git-with-email-expected.conf | 2 + .../modules/programs/git/git-with-email.nix | 4 +- .../programs/git/git-with-msmtp-expected.conf | 15 + .../modules/programs/git/git-with-msmtp.nix | 45 ++ .../git/git-with-signing-key-id-expected.conf | 10 + .../programs/git/git-with-signing-key-id.nix | 22 + .../git/git-with-str-extra-config.nix | 6 + .../git-without-signing-key-id-expected.conf | 9 + .../git/git-without-signing-key-id.nix | 22 + .../tests/modules/programs/git/git.nix | 6 +- .../programs/gnome-terminal/default.nix | 1 + .../gnome-terminal/gnome-terminal-1.conf | 34 ++ .../gnome-terminal/gnome-terminal-1.nix | 63 +++ .../gpg/override-defaults-expected.conf | 4 +- .../programs/gpg/override-defaults.nix | 10 +- .../modules/programs/himalaya/default.nix | 1 + .../programs/himalaya/himalaya-expected.toml | 18 + .../modules/programs/himalaya/himalaya.nix | 38 ++ .../programs/htop/default-settings.nix | 13 + .../tests/modules/programs/htop/default.nix | 4 + .../programs/htop/example-settings.nix | 43 ++ .../programs/i3status-rust/default.nix | 6 + .../programs/i3status-rust/with-custom.nix | 186 +++++++ .../programs/i3status-rust/with-default.nix | 58 ++ .../i3status-rust/with-extra-settings.nix | 202 +++++++ .../i3status-rust/with-multiple-bars.nix | 106 ++++ .../tests/modules/programs/irsii/default.nix | 1 + .../irsii/example-settings-expected.config | 43 ++ .../programs/irsii/example-settings.nix | 31 ++ .../modules/programs/kakoune/default.nix | 4 +- .../modules/programs/kakoune/no-plugins.nix | 2 +- .../modules/programs/kakoune/use-plugins.nix | 8 +- .../tests/modules/programs/kitty/default.nix | 1 + .../kitty/example-settings-expected.conf | 17 + .../programs/kitty/example-settings.nix | 34 ++ .../tests/modules/programs/lieer/lieer.nix | 6 +- .../mangohud/basic-configuration-mpv.conf | 2 + .../mangohud/basic-configuration.conf | 13 + .../programs/mangohud/basic-configuration.nix | 40 ++ .../modules/programs/mangohud/default.nix | 1 + .../programs/mbsync/mbsync-expected.conf | 32 +- .../mbsync/mbsync-master-slave-change.nix | 93 ++++ .../tests/modules/programs/mbsync/mbsync.nix | 24 +- .../tests/modules/programs/mpv/default.nix | 4 + .../mpv-example-settings-expected-bindings | 3 + .../mpv/mpv-example-settings-expected-config | 13 + .../programs/mpv/mpv-example-settings.nix | 46 ++ .../programs/mpv/mpv-invalid-settings.nix | 37 ++ .../modules/programs/neomutt/default.nix | 7 + .../programs/neomutt/hm-example.com-expected | 3 +- .../neomutt/hm-example.com-gpg-expected.conf | 32 ++ .../hm-example.com-msmtp-expected.conf | 1 + ...example.com-no-folder-change-expected.conf | 30 + .../programs/neomutt/neomutt-expected.conf | 15 +- .../neomutt/neomutt-no-folder-change.nix | 30 + .../neomutt/neomutt-not-primary-expected.conf | 32 ++ .../programs/neomutt/neomutt-not-primary.nix | 26 + .../neomutt/neomutt-with-binds-expected.conf | 34 ++ .../neomutt-with-binds-invalid-settings.nix | 27 + .../neomutt-with-binds-with-warning.nix | 71 +++ .../programs/neomutt/neomutt-with-binds.nix | 67 +++ .../programs/neomutt/neomutt-with-gpg.nix | 33 ++ .../programs/neomutt/neomutt-with-msmtp.nix | 1 - .../modules/programs/neomutt/neomutt.nix | 1 - .../tests/modules/programs/neovim/default.nix | 6 +- .../tests/modules/programs/neovim/no-init.nix | 22 + .../modules/programs/neovim/plugin-config.nix | 13 +- .../modules/programs/neovim/plugin-config.vim | 18 +- .../modules/programs/newsboat/default.nix | 1 + .../newsboat/newsboat-basics-2105.nix | 36 ++ .../nix-index/assert-on-command-not-found.nix | 26 + .../modules/programs/nix-index/default.nix | 4 + .../programs/nix-index/integrations.nix | 38 ++ .../tests/modules/programs/pet/default.nix | 1 + .../tests/modules/programs/pet/snippet.toml | 5 + .../tests/modules/programs/pet/snippets.nix | 29 + .../powerline-go/{standard.nix => bash.nix} | 3 + .../modules/programs/powerline-go/default.nix | 5 +- .../modules/programs/powerline-go/zsh.nix | 35 ++ .../modules/programs/qutebrowser/default.nix | 1 + .../programs/qutebrowser/keybindings.nix | 10 +- .../programs/qutebrowser/quickmarks.nix | 37 ++ .../modules/programs/qutebrowser/settings.nix | 10 +- .../tests/modules/programs/rbw/default.nix | 5 + .../modules/programs/rbw/empty-settings.nix | 19 + .../tests/modules/programs/rbw/overlay.nix | 12 + .../tests/modules/programs/rbw/settings.nix | 39 ++ .../modules/programs/rbw/simple-settings.nix | 33 ++ .../modules/programs/rofi-pass/default.nix | 4 + .../programs/rofi-pass/rofi-pass-config.nix | 35 ++ .../programs/rofi-pass/rofi-pass-root.nix | 30 + ...ert-on-both-theme-and-colors-expected.json | 1 - .../rofi/assert-on-both-theme-and-colors.nix | 11 +- .../programs/rofi/custom-theme-config.rasi | 6 + .../modules/programs/rofi/custom-theme.nix | 44 ++ .../modules/programs/rofi/custom-theme.rasi | 19 + .../tests/modules/programs/rofi/default.nix | 2 + .../programs/rofi/valid-config-expected.rasi | 20 + .../modules/programs/rofi/valid-config.nix | 60 ++ .../modules/programs/sbt/credentials.nix | 39 ++ .../tests/modules/programs/sbt/default.nix | 4 + .../tests/modules/programs/sbt/plugins.nix | 39 ++ .../tests/modules/programs/scmpuff/bash.nix | 15 + .../modules/programs/scmpuff/default.nix | 7 + .../modules/programs/scmpuff/no-bash.nix | 15 + .../modules/programs/scmpuff/no-shell.nix | 18 + .../tests/modules/programs/scmpuff/no-zsh.nix | 15 + .../tests/modules/programs/scmpuff/zsh.nix | 15 + ...ds-dynamic-bind-path-with-port-asserts.nix | 9 +- ...ards-local-bind-path-with-port-asserts.nix | 9 +- ...ards-local-host-path-with-port-asserts.nix | 9 +- .../ssh/forwards-paths-with-ports-error.json | 1 - ...rds-remote-bind-path-with-port-asserts.nix | 9 +- ...rds-remote-host-path-with-port-asserts.nix | 9 +- .../programs/starship/settings-expected.toml | 5 +- .../modules/programs/starship/settings.nix | 12 +- .../programs/terminator/config-file.nix | 25 + .../modules/programs/terminator/default.nix | 1 + .../modules/programs/tmux/default-shell.conf | 30 + .../modules/programs/tmux/default-shell.nix | 27 + .../tests/modules/programs/tmux/default.nix | 3 + .../tmux/disable-confirmation-prompt.nix | 4 +- .../programs/tmux/emacs-with-plugins.nix | 6 +- .../modules/programs/tmux/not-enabled.nix | 2 +- .../tests/modules/programs/tmux/prefix.conf | 32 ++ .../tests/modules/programs/tmux/prefix.nix | 26 + .../tmux/shortcut-without-prefix.conf | 33 ++ .../programs/tmux/shortcut-without-prefix.nix | 27 + .../modules/programs/tmux/vi-all-true.nix | 4 +- .../modules/programs/topgrade/default.nix | 1 + .../programs/topgrade/settings-expected.toml | 8 + .../modules/programs/topgrade/settings.nix | 38 ++ .../modules/programs/vscode/keybindings.nix | 45 +- .../programs/waybar/broken-settings.nix | 80 --- .../tests/modules/programs/waybar/default.nix | 3 +- .../waybar/settings-complex-expected.json | 3 +- .../programs/waybar/settings-complex.nix | 3 +- ...temd-with-graphical-session-target.service | 10 +- .../programs/waybar/warnings-tests.nix | 64 +++ .../xmobar/basic-configuration.expected | 19 + .../programs/xmobar/basic-configuration.nix | 39 ++ .../tests/modules/programs/xmobar/default.nix | 1 + .../tests/modules/programs/zsh/default.nix | 1 + .../programs/zsh/history-ignore-pattern.nix | 21 + .../tests/modules/programs/zsh/prezto.nix | 12 + .../services/barrier/basic-configuration.nix | 20 + .../modules/services/barrier/default.nix | 1 + .../tests/modules/services/emacs/default.nix | 5 +- ...t.desktop => emacs-27-emacsclient.desktop} | 3 +- .../emacs/emacs-28-emacsclient.desktop | 12 + ...emacs-service.nix => emacs-service-27.nix} | 4 +- .../services/emacs/emacs-service-28.nix | 37 ++ .../emacs/emacs-service-emacs.service | 5 +- .../emacs/emacs-socket-26-emacs.service | 9 - .../emacs/emacs-socket-26-emacs.socket | 12 - .../services/emacs/emacs-socket-27.nix | 10 +- ...macs-socket-26.nix => emacs-socket-28.nix} | 14 +- ...acs.service => emacs-socket-emacs.service} | 8 +- ...emacs.socket => emacs-socket-emacs.socket} | 2 +- .../services/gpg-agent/default-homedir.nix | 22 + .../modules/services/gpg-agent/default.nix | 4 + .../services/gpg-agent/override-homedir.nix | 25 + .../lieer/lieer-service-expected.service | 1 + .../modules/services/lieer/lieer-service.nix | 10 +- .../pantalaimon/basic-configuration.nix | 29 + .../modules/services/pantalaimon/default.nix | 1 + .../tests/modules/services/pbgopy/default.nix | 1 + .../tests/modules/services/pbgopy/service.nix | 22 + .../modules/services/playerctld/basic.nix | 31 ++ .../modules/services/playerctld/default.nix | 1 + .../services/polybar/basic-configuration.conf | 11 + .../services/polybar/basic-configuration.nix | 10 + .../services/redshift-gammastep/default.nix | 4 + ...astep-basic-configuration-expected.service | 13 + ...tep-basic-configuration-file-expected.conf | 13 + .../gammastep-basic-configuration.nix | 36 ++ ...shift-basic-configuration-expected.service | 13 + ...ift-basic-configuration-file-expected.conf | 13 + .../redshift-basic-configuration.nix | 36 ++ .../modules/services/sxhkd/configuration.nix | 7 +- .../tests/modules/services/sxhkd/service.nix | 22 +- .../modules/services/syncthing/default.nix | 4 + .../tray-as-bool-triggers-warning.nix | 21 + .../tests/modules/services/syncthing/tray.nix | 21 + .../services/window-managers/bspwm/bspwmrc | 19 + .../window-managers/bspwm/configuration.nix | 40 ++ .../window-managers/bspwm/default.nix | 1 + .../services/window-managers/i3/default.nix | 6 + .../i3/i3-bar-focused-colors-expected.conf | 110 ++++ .../i3/i3-bar-focused-colors.nix | 25 + .../i3/i3-followmouse-expected.conf | 13 +- .../window-managers/i3/i3-followmouse.nix | 4 +- .../i3/i3-fonts-deprecated.nix | 29 + .../window-managers/i3/i3-fonts-expected.conf | 110 ++++ .../services/window-managers/i3/i3-fonts.nix | 33 ++ .../i3/i3-keybindings-expected.conf | 13 +- .../window-managers/i3/i3-keybindings.nix | 10 +- .../window-managers/i3/i3-null-config.nix | 20 + .../window-managers/i3/i3-overlay.nix | 12 + .../i3/i3-workspace-default-expected.conf | 109 ++++ .../i3/i3-workspace-default.nix | 21 + .../i3/i3-workspace-output-expected.conf | 113 ++++ .../i3/i3-workspace-output.nix | 46 ++ .../services/window-managers/sway/default.nix | 6 + .../sway/sway-bar-focused-colors.conf | 114 ++++ .../sway/sway-bar-focused-colors.nix | 32 ++ .../window-managers/sway/sway-default.conf | 15 +- .../window-managers/sway/sway-default.nix | 21 +- .../sway/sway-followmouse-expected.conf | 11 +- .../sway-followmouse-legacy-expected.conf | 11 +- .../sway/sway-followmouse-legacy.nix | 21 +- .../window-managers/sway/sway-followmouse.nix | 21 +- .../window-managers/sway/sway-modules.conf | 126 +++++ .../window-managers/sway/sway-modules.nix | 32 ++ .../window-managers/sway/sway-null-config.nix | 22 + .../sway/sway-null-package.conf | 114 ++++ .../sway/sway-null-package.nix | 35 ++ .../window-managers/sway/sway-overlay.nix | 17 + .../window-managers/sway/sway-post-2003.nix | 21 +- .../sway/sway-workspace-default-expected.conf | 113 ++++ .../sway/sway-workspace-default.nix | 27 + .../sway/sway-workspace-output-expected.conf | 118 ++++ .../sway/sway-workspace-output.nix | 53 ++ .../modules/services/wlsunset/default.nix | 1 + .../wlsunset-service-expected.service | 9 + .../services/wlsunset/wlsunset-service.nix | 25 + .../modules/systemd/services-expected.conf | 5 - .../tests/modules/systemd/services.nix | 12 +- .../systemd/session-variables-expected.conf | 1 + .../modules/systemd/session-variables.nix | 8 +- .../modules/targets-linux/generic-linux.nix | 40 +- 491 files changed, 14231 insertions(+), 2701 deletions(-) create mode 100644 third_party/home-manager/.github/dependabot.yml create mode 100644 third_party/home-manager/.github/stale.yml create mode 100644 third_party/home-manager/.release create mode 100644 third_party/home-manager/doc/installation.adoc delete mode 100644 third_party/home-manager/doc/installation.xml create mode 100644 third_party/home-manager/doc/release-notes/rl-2105.adoc create mode 100644 third_party/home-manager/doc/release-notes/rl-2111.adoc create mode 100644 third_party/home-manager/home-manager/completion.zsh create mode 100644 third_party/home-manager/modules/config/i18n.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/default.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/fcitx.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/fcitx5.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/hime.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/kime.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/nabi.nix create mode 100644 third_party/home-manager/modules/i18n/input-method/uim.nix create mode 100644 third_party/home-manager/modules/misc/xdg-desktop-entries.nix create mode 100644 third_party/home-manager/modules/misc/xdg-system-dirs.nix create mode 100644 third_party/home-manager/modules/programs/exa.nix create mode 100644 third_party/home-manager/modules/programs/foot.nix create mode 100644 third_party/home-manager/modules/programs/himalaya.nix create mode 100644 third_party/home-manager/modules/programs/i3status-rust.nix create mode 100644 third_party/home-manager/modules/programs/lazygit.nix create mode 100644 third_party/home-manager/modules/programs/mangohud.nix create mode 100644 third_party/home-manager/modules/programs/ncspot.nix create mode 100644 third_party/home-manager/modules/programs/nix-index.nix create mode 100644 third_party/home-manager/modules/programs/octant.nix create mode 100644 third_party/home-manager/modules/programs/piston-cli.nix create mode 100644 third_party/home-manager/modules/programs/rbw.nix create mode 100644 third_party/home-manager/modules/programs/rofi-pass.nix create mode 100644 third_party/home-manager/modules/programs/sbt.nix create mode 100644 third_party/home-manager/modules/programs/scmpuff.nix create mode 100644 third_party/home-manager/modules/programs/senpai.nix create mode 100644 third_party/home-manager/modules/programs/terminator.nix create mode 100644 third_party/home-manager/modules/programs/topgrade.nix create mode 100644 third_party/home-manager/modules/programs/xmobar.nix create mode 100644 third_party/home-manager/modules/services/barrier.nix create mode 100644 third_party/home-manager/modules/services/caffeine.nix create mode 100644 third_party/home-manager/modules/services/etesync-dav.nix delete mode 100644 third_party/home-manager/modules/services/gammastep.nix create mode 100644 third_party/home-manager/modules/services/mpris-proxy.nix create mode 100644 third_party/home-manager/modules/services/pantalaimon.nix create mode 100644 third_party/home-manager/modules/services/pass-secret-service.nix create mode 100644 third_party/home-manager/modules/services/pbgopy.nix create mode 100644 third_party/home-manager/modules/services/plan9port.nix create mode 100644 third_party/home-manager/modules/services/playerctld.nix create mode 100644 third_party/home-manager/modules/services/poweralertd.nix create mode 100644 third_party/home-manager/modules/services/redshift-gammastep/gammastep.nix create mode 100644 third_party/home-manager/modules/services/redshift-gammastep/lib/options.nix create mode 100644 third_party/home-manager/modules/services/redshift-gammastep/redshift.nix delete mode 100644 third_party/home-manager/modules/services/redshift.nix create mode 100644 third_party/home-manager/modules/services/wlsunset.nix create mode 100644 third_party/home-manager/modules/services/xidlehook.nix create mode 100644 third_party/home-manager/modules/targets/darwin/default.nix create mode 100644 third_party/home-manager/modules/targets/darwin/fonts.nix create mode 100644 third_party/home-manager/modules/targets/darwin/keybindings.nix rename third_party/home-manager/modules/targets/{darwin.nix => darwin/linkapps.nix} (100%) create mode 100644 third_party/home-manager/modules/targets/darwin/options.nix create mode 100644 third_party/home-manager/modules/targets/darwin/search.nix create mode 100644 third_party/home-manager/tests/asserts.nix delete mode 100644 third_party/home-manager/tests/meta/default.nix delete mode 100644 third_party/home-manager/tests/meta/formatting.nix create mode 100644 third_party/home-manager/tests/modules/config/i18n/default.nix create mode 100644 third_party/home-manager/tests/modules/files/target-conflict.nix create mode 100644 third_party/home-manager/tests/modules/i18n/input-method/default.nix create mode 100644 third_party/home-manager/tests/modules/i18n/input-method/fcitx5-configuration.nix create mode 100644 third_party/home-manager/tests/modules/i18n/input-method/fcitx5-overlay.nix create mode 100644 third_party/home-manager/tests/modules/misc/gtk/default.nix create mode 100644 third_party/home-manager/tests/modules/misc/gtk/gtk-basic-config-expected.conf create mode 100644 third_party/home-manager/tests/modules/misc/gtk/gtk2-basic-config.nix create mode 100644 third_party/home-manager/tests/modules/misc/gtk/gtk2-config-file-location.nix create mode 100644 third_party/home-manager/tests/modules/misc/qt/default.nix create mode 100644 third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gnome.nix create mode 100644 third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gtk.nix create mode 100644 third_party/home-manager/tests/modules/misc/xdg/desktop-entries.nix create mode 100644 third_party/home-manager/tests/modules/misc/xdg/desktop-full-expected.desktop create mode 100644 third_party/home-manager/tests/modules/misc/xdg/desktop-min-expected.desktop create mode 100644 third_party/home-manager/tests/modules/misc/xdg/system-dirs.nix create mode 100644 third_party/home-manager/tests/modules/programs/alacritty/settings-merging-expected.yml create mode 100644 third_party/home-manager/tests/modules/programs/alacritty/settings-merging.nix delete mode 100644 third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.conf create mode 100644 third_party/home-manager/tests/modules/programs/autorandr/scale.nix delete mode 100644 third_party/home-manager/tests/modules/programs/bash/logout-expected.txt delete mode 100644 third_party/home-manager/tests/modules/programs/bash/session-variables-expected.txt create mode 100644 third_party/home-manager/tests/modules/programs/firefox/deprecated-native-messenger.nix create mode 100644 third_party/home-manager/tests/modules/programs/foot/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/foot/empty-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/foot/example-settings-expected.ini create mode 100644 third_party/home-manager/tests/modules/programs/foot/example-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/foot/systemd-user-service-expected.service create mode 100644 third_party/home-manager/tests/modules/programs/foot/systemd-user-service.nix create mode 100644 third_party/home-manager/tests/modules/programs/git/git-with-msmtp-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/git/git-with-msmtp.nix create mode 100644 third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id.nix create mode 100644 third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id.nix create mode 100644 third_party/home-manager/tests/modules/programs/gnome-terminal/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.conf create mode 100644 third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.nix create mode 100644 third_party/home-manager/tests/modules/programs/himalaya/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/himalaya/himalaya-expected.toml create mode 100644 third_party/home-manager/tests/modules/programs/himalaya/himalaya.nix create mode 100644 third_party/home-manager/tests/modules/programs/htop/default-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/htop/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/htop/example-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/i3status-rust/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/i3status-rust/with-custom.nix create mode 100644 third_party/home-manager/tests/modules/programs/i3status-rust/with-default.nix create mode 100644 third_party/home-manager/tests/modules/programs/i3status-rust/with-extra-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/i3status-rust/with-multiple-bars.nix create mode 100644 third_party/home-manager/tests/modules/programs/irsii/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/irsii/example-settings-expected.config create mode 100644 third_party/home-manager/tests/modules/programs/irsii/example-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/kitty/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/kitty/example-settings-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/kitty/example-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/mangohud/basic-configuration-mpv.conf create mode 100644 third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.conf create mode 100644 third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.nix create mode 100644 third_party/home-manager/tests/modules/programs/mangohud/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/mbsync/mbsync-master-slave-change.nix create mode 100644 third_party/home-manager/tests/modules/programs/mpv/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-bindings create mode 100644 third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-config create mode 100644 third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/mpv/mpv-invalid-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-gpg-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-no-folder-change-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-no-folder-change.nix create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary.nix create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-expected.conf create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-invalid-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-with-warning.nix create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds.nix create mode 100644 third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-gpg.nix create mode 100644 third_party/home-manager/tests/modules/programs/neovim/no-init.nix create mode 100644 third_party/home-manager/tests/modules/programs/newsboat/newsboat-basics-2105.nix create mode 100644 third_party/home-manager/tests/modules/programs/nix-index/assert-on-command-not-found.nix create mode 100644 third_party/home-manager/tests/modules/programs/nix-index/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/nix-index/integrations.nix create mode 100644 third_party/home-manager/tests/modules/programs/pet/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/pet/snippet.toml create mode 100644 third_party/home-manager/tests/modules/programs/pet/snippets.nix rename third_party/home-manager/tests/modules/programs/powerline-go/{standard.nix => bash.nix} (86%) create mode 100644 third_party/home-manager/tests/modules/programs/powerline-go/zsh.nix create mode 100644 third_party/home-manager/tests/modules/programs/qutebrowser/quickmarks.nix create mode 100644 third_party/home-manager/tests/modules/programs/rbw/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/rbw/empty-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/rbw/overlay.nix create mode 100644 third_party/home-manager/tests/modules/programs/rbw/settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/rbw/simple-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/rofi-pass/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-config.nix create mode 100644 third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-root.nix delete mode 100644 third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors-expected.json create mode 100644 third_party/home-manager/tests/modules/programs/rofi/custom-theme-config.rasi create mode 100644 third_party/home-manager/tests/modules/programs/rofi/custom-theme.nix create mode 100644 third_party/home-manager/tests/modules/programs/rofi/custom-theme.rasi create mode 100644 third_party/home-manager/tests/modules/programs/rofi/valid-config-expected.rasi create mode 100644 third_party/home-manager/tests/modules/programs/rofi/valid-config.nix create mode 100644 third_party/home-manager/tests/modules/programs/sbt/credentials.nix create mode 100644 third_party/home-manager/tests/modules/programs/sbt/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/sbt/plugins.nix create mode 100644 third_party/home-manager/tests/modules/programs/scmpuff/bash.nix create mode 100644 third_party/home-manager/tests/modules/programs/scmpuff/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/scmpuff/no-bash.nix create mode 100644 third_party/home-manager/tests/modules/programs/scmpuff/no-shell.nix create mode 100644 third_party/home-manager/tests/modules/programs/scmpuff/no-zsh.nix create mode 100644 third_party/home-manager/tests/modules/programs/scmpuff/zsh.nix delete mode 100644 third_party/home-manager/tests/modules/programs/ssh/forwards-paths-with-ports-error.json create mode 100644 third_party/home-manager/tests/modules/programs/terminator/config-file.nix create mode 100644 third_party/home-manager/tests/modules/programs/terminator/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/tmux/default-shell.conf create mode 100644 third_party/home-manager/tests/modules/programs/tmux/default-shell.nix create mode 100644 third_party/home-manager/tests/modules/programs/tmux/prefix.conf create mode 100644 third_party/home-manager/tests/modules/programs/tmux/prefix.nix create mode 100644 third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.conf create mode 100644 third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.nix create mode 100644 third_party/home-manager/tests/modules/programs/topgrade/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/topgrade/settings-expected.toml create mode 100644 third_party/home-manager/tests/modules/programs/topgrade/settings.nix delete mode 100644 third_party/home-manager/tests/modules/programs/waybar/broken-settings.nix create mode 100644 third_party/home-manager/tests/modules/programs/waybar/warnings-tests.nix create mode 100644 third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.expected create mode 100644 third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.nix create mode 100644 third_party/home-manager/tests/modules/programs/xmobar/default.nix create mode 100644 third_party/home-manager/tests/modules/programs/zsh/history-ignore-pattern.nix create mode 100644 third_party/home-manager/tests/modules/services/barrier/basic-configuration.nix create mode 100644 third_party/home-manager/tests/modules/services/barrier/default.nix rename third_party/home-manager/tests/modules/services/emacs/{emacs-emacsclient.desktop => emacs-27-emacsclient.desktop} (87%) create mode 100644 third_party/home-manager/tests/modules/services/emacs/emacs-28-emacsclient.desktop rename third_party/home-manager/tests/modules/services/emacs/{emacs-service.nix => emacs-service-27.nix} (89%) create mode 100644 third_party/home-manager/tests/modules/services/emacs/emacs-service-28.nix delete mode 100644 third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.service delete mode 100644 third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.socket rename third_party/home-manager/tests/modules/services/emacs/{emacs-socket-26.nix => emacs-socket-28.nix} (75%) rename third_party/home-manager/tests/modules/services/emacs/{emacs-socket-27-emacs.service => emacs-socket-emacs.service} (51%) rename third_party/home-manager/tests/modules/services/emacs/{emacs-socket-27-emacs.socket => emacs-socket-emacs.socket} (76%) create mode 100644 third_party/home-manager/tests/modules/services/gpg-agent/default-homedir.nix create mode 100644 third_party/home-manager/tests/modules/services/gpg-agent/default.nix create mode 100644 third_party/home-manager/tests/modules/services/gpg-agent/override-homedir.nix create mode 100644 third_party/home-manager/tests/modules/services/pantalaimon/basic-configuration.nix create mode 100644 third_party/home-manager/tests/modules/services/pantalaimon/default.nix create mode 100644 third_party/home-manager/tests/modules/services/pbgopy/default.nix create mode 100644 third_party/home-manager/tests/modules/services/pbgopy/service.nix create mode 100644 third_party/home-manager/tests/modules/services/playerctld/basic.nix create mode 100644 third_party/home-manager/tests/modules/services/playerctld/default.nix create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/default.nix create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-expected.service create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-file-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration.nix create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-expected.service create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-file-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration.nix create mode 100644 third_party/home-manager/tests/modules/services/syncthing/default.nix create mode 100644 third_party/home-manager/tests/modules/services/syncthing/tray-as-bool-triggers-warning.nix create mode 100644 third_party/home-manager/tests/modules/services/syncthing/tray.nix create mode 100755 third_party/home-manager/tests/modules/services/window-managers/bspwm/bspwmrc create mode 100644 third_party/home-manager/tests/modules/services/window-managers/bspwm/configuration.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/bspwm/default.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-deprecated.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-null-config.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-overlay.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-config.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-overlay.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default.nix create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf create mode 100644 third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output.nix create mode 100644 third_party/home-manager/tests/modules/services/wlsunset/default.nix create mode 100644 third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service-expected.service create mode 100644 third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service.nix delete mode 100644 third_party/home-manager/tests/modules/systemd/services-expected.conf diff --git a/third_party/home-manager/.github/CODEOWNERS b/third_party/home-manager/.github/CODEOWNERS index b922114a06..f7deb577fb 100644 --- a/third_party/home-manager/.github/CODEOWNERS +++ b/third_party/home-manager/.github/CODEOWNERS @@ -4,6 +4,9 @@ /modules/home-environment.nix @rycee +/modules/i18n/input-method @Kranzes +/tests/modules/i18n/input-method @Kranzes + /modules/misc/dconf.nix @gnidorah @rycee /modules/misc/fontconfig.nix @rycee @@ -11,6 +14,9 @@ /modules/misc/gtk.nix @rycee +/modules/config/i18n.nix @midchildan +/tests/modules/config/i18n @midchildan + /modules/misc/news.nix @rycee /modules/misc/numlock.nix @evanjs @@ -31,6 +37,14 @@ /modules/misc/xdg-user-dirs.nix @pacien +/modules/misc/xdg-system-dirs.nix @tadfisher +/tests/modules/misc/xdg/system-dirs.nix @tadfisher + +/modules/misc/xdg-desktop-entries.nix @cwyc +/tests/modules/misc/xdg/desktop-entries.nix @cwyc +/tests/modules/misc/xdg/desktop-full-expected.desktop @cwyc +/tests/modules/misc/xdg/desktop-min-expected.desktop @cwyc + /modules/programs/aria2.nix @JustinLovinger /modules/programs/autojump.nix @evanjs @@ -54,23 +68,37 @@ /modules/programs/emacs.nix @rycee +/modules/programs/exa.nix @kalhauge + /modules/programs/firefox.nix @rycee +/modules/programs/foot.nix @plabadens +/tests/modules/programs/foot @plabadens + /modules/programs/gh.nix @Gerschtli /tests/modules/programs/gh @Gerschtli /modules/programs/git.nix @rycee -/modules/programs/gnome-terminal.nix @rycee +/modules/programs/gnome-terminal.nix @kamadorueda @rycee /modules/programs/go.nix @rvolosatovs +/modules/programs/himalaya.nix @ambroisie +/tests/modules/programs/himalaya @ambroisie + /modules/programs/home-manager.nix @rycee +/modules/programs/htop.nix @bjpbakker + /modules/programs/i3status.nix @JustinLovinger +/modules/programs/i3status-rust.nix @workflow + /modules/programs/keychain.nix @marsam +/modules/programs/lazygit.nix @kalhauge + /modules/programs/lesspipe.nix @rycee /modules/programs/lf.nix @owm111 @@ -82,12 +110,16 @@ /modules/programs/matplotlib.nix @rprospero +/modules/programs/mangohud.nix @ZerataX +/tests/modules/programs/mangohud @ZerataX + /modules/programs/mbsync.nix @KarlJoad /tests/modules/programs/mbsync @KarlJoad /modules/programs/mcfly.nix @marsam -/modules/programs/mpv.nix @tadeokondrak +/modules/programs/mpv.nix @tadeokondrak @thiagokokada +/tests/modules/programs/mpv @thiagokokada /modules/programs/mu.nix @KarlJoad @@ -95,9 +127,17 @@ /tests/modules/programs/ncmpcpp @olmokramer /tests/modules/programs/ncmpcpp-linux @olmokramer +/modules/programs/ncspot.nix @marsam + /modules/programs/ne.nix @cwyc /tests/modules/programs/ne @cwyc +/modules/programs/newsboat.nix @sumnerevans +/tests/modules/programs/newsboat @sumnerevans + +/modules/programs/nix-index.nix @ambroisie +/tests/modules/programs/nix-index @ambroisie + /modules/programs/noti.nix @marsam /modules/programs/nushell.nix @Philipp-M @@ -105,6 +145,8 @@ /modules/programs/obs-studio.nix @adisbladis +/modules/programs/octant.nix @06kellyjac + /modules/programs/opam.nix @marsam /modules/programs/openssh.nix @rycee @@ -115,19 +157,46 @@ /modules/programs/pidgin.nix @rycee +/modules/programs/piston-cli.nix @ethancedwards8 + /modules/programs/powerline-go.nix @DamienCassou +/modules/programs/rbw.nix @ambroisie +/tests/modules/programs/rbw @ambroisie + +/modules/programs/rofi.nix @thiagokokada +/tests/modules/programs/rofi @thiagokokada + +/modules/programs/rofi-pass.nix @seylerius +/tests/modules/programs/rofi-pass @seylerius + /modules/programs/rtorrent.nix @marsam +/modules/programs/sbt.nix @kubukoz +/tests/modules/programs/sbt @kubukoz + +/modules/programs/scmpuff.nix @cpcloud +/tests/modules/programs/scmpuff @cpcloud + +/modules/programs/senpai.nix @malte-v + /modules/programs/ssh.nix @rycee /modules/programs/starship.nix @marsam +/modules/programs/terminator.nix @chisui + /modules/programs/texlive.nix @rycee +/modules/programs/topgrade.nix @msfjarvis +/tests/modules/programs/topgrade @msfjarvis + /modules/programs/waybar.nix @berbiche /tests/modules/programs/waybar @berbiche +/modules/programs/xmobar.nix @t4ccer +/tests/modules/programs/xmobar @t4ccer + /modules/programs/z-lua.nix @marsam /modules/programs/zathura.nix @rprospero @@ -136,6 +205,11 @@ /modules/programs/zsh/prezto.nix @NickHu +/modules/services/barrier.nix @Kritnich +/tests/modules/services/barrier @Kritnich + +/modules/services/caffeine.nix @uvNikita + /modules/services/cbatticon.nix @pmiddend /modules/services/clipmenu.nix @DamienCassou @@ -147,12 +221,12 @@ /modules/services/emacs.nix @tadfisher +/modules/services/etesync-dav.nix @Valodim + /modules/services/flameshot.nix @moredhel /modules/services/fluidsynth.nix @Valodim -/modules/services/gammastep.nix @petabyteboy - /modules/services/gnome-keyring.nix @rycee /modules/services/gpg-agent.nix @rycee @@ -180,21 +254,39 @@ /modules/services/mpdris2.nix @pjones +/modules/services/mpris-proxy.nix @ThibautMarty + /modules/services/muchsync.nix @pacien /modules/services/network-manager-applet.nix @rycee +/modules/services/pantalaimon.nix @jojosch +/tests/modules/services/pantalaimon @jojosch + /modules/services/parcellite.nix @gleber +/modules/services/pass-secret-service.nix @cab404 + /modules/services/password-store-sync.nix @pacien /modules/services/pasystray.nix @pltanton +/modules/services/pbgopy.nix @ivarwithoutbones +/tests/modules/services/pbgopy @ivarwithoutbones + +/modules/services/plan9port.nix @ehmry + +/modules/services/playerctld.nix @fendse +/tests/modules/playerctld @fendse + +/modules/services/poweralertd.nix @ThibautMarty + /modules/services/pulseeffects.nix @jonringer /modules/services/random-background.nix @rycee -/modules/services/redshift.nix @rycee +/modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada +/tests/modules/redshift-gammastep @thiagokokada /modules/services/status-notifier-watcher.nix @pltanton @@ -210,12 +302,26 @@ /modules/services/unison.nix @pacien -/modules/services/window-managers/i3-sway/sway.nix @alexarice +/modules/services/window-managers/bspwm @ncfavier +/tests/modules/services/window-managers/bspwm @ncfavier + +/modules/services/window-managers/i3-sway/i3.nix @sumnerevans +/tests/modules/services/window-managers/i3 @sumnerevans + +/modules/services/window-managers/i3-sway/lib @sumnerevans + +/modules/services/window-managers/i3-sway/sway.nix @alexarice @sumnerevans +/tests/modules/services/window-managers/sway @sumnerevans + +/modules/services/wlsunset.nix @matrss +/tests/modules/services/wlsunset @matrss /modules/services/xcape.nix @nickhu /modules/services/xembed-sni-proxy.nix @rycee +/modules/services/xidlehook.nix @dschrempf + /modules/services/xscreensaver.nix @rycee /modules/services/xsuspender.nix @offlinehacker diff --git a/third_party/home-manager/.github/ISSUE_TEMPLATE.md b/third_party/home-manager/.github/ISSUE_TEMPLATE.md index 75c91499a5..06be7202df 100644 --- a/third_party/home-manager/.github/ISSUE_TEMPLATE.md +++ b/third_party/home-manager/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,16 @@ + + ### Issue description ### Meta diff --git a/third_party/home-manager/.github/dependabot.yml b/third_party/home-manager/.github/dependabot.yml new file mode 100644 index 0000000000..45eab8b749 --- /dev/null +++ b/third_party/home-manager/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + target-branch: "master" + schedule: + interval: "weekly" + commit-message: + prefix: "ci:" + + - package-ecosystem: "github-actions" + directory: "/" + target-branch: "release-20.09" + schedule: + interval: "weekly" + commit-message: + prefix: "ci:" diff --git a/third_party/home-manager/.github/stale.yml b/third_party/home-manager/.github/stale.yml new file mode 100644 index 0000000000..49b9944718 --- /dev/null +++ b/third_party/home-manager/.github/stale.yml @@ -0,0 +1,75 @@ +# Configuration for probot-stale - https://github.com/probot/stale +daysUntilStale: 90 +daysUntilClose: 7 +staleLabel: "status: stale" +closeComment: false +issues: + markComment: | +

+ Thank you for your contribution! + I marked this issue as stale due to inactivity. + If this remains inactive for another 7 days, I will close this issue. + Please read the relevant sections below before commenting. +

+ +
+ If you are the original author of the issue +

+ + * If this is resolved, please consider closing it so that the maintainers know not to focus on this. + * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. + * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue. + +

+
+ +
+ If you are not the original author of the issue +

+ + * If you are also experiencing this issue, please add details of your situation to help with the debugging process. + * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue. + +

+
+ +
+ Memorandum on closing issues +

+ If you have nothing of substance to add, please refrain from commenting and allow the bot close the issue. + Also, don't be afraid to manually close an issue, even if it holds valuable information. +

+

+ Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! + Closing obsolete issues is an important way to help maintainers focus their time and effort. +

+
+pulls: + markComment: | +

+ Thank you for your contribution! + I marked this pull request as stale due to inactivity. + If this remains inactive for another 7 days, I will close this PR. + Please read the relevant sections below before commenting. +

+ +
+ If you are the original author of the PR +

+ + * GitHub sometimes doesn't notify people who commented / reviewed a PR previously, when you (force) push commits. *If you have addressed the reviews* you can [officially ask for a review](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from those who commented to you or anyone else. + * If it is unfinished but you plan to finish it, please mark it as a draft. + * If you don't expect to work on it any time soon, please consider closing it with a short comment encouraging someone else to pick up your work. + * To get things rolling again, rebase the PR against the target branch and address valid comments. + +

+
+ +
+ If you are not the original author of the issue +

+ + * If you want to pick up the work on this PR, please create a new PR and indicate that it supercedes and closes this PR. + +

+
diff --git a/third_party/home-manager/.github/workflows/github_pages.yml b/third_party/home-manager/.github/workflows/github_pages.yml index 5baf396a2f..a3109a9fc7 100644 --- a/third_party/home-manager/.github/workflows/github_pages.yml +++ b/third_party/home-manager/.github/workflows/github_pages.yml @@ -11,10 +11,10 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v10 + - uses: cachix/install-nix-action@v13 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@v6 + - uses: cachix/cachix-action@v10 with: name: nix-community signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' diff --git a/third_party/home-manager/.github/workflows/test.yml b/third_party/home-manager/.github/workflows/test.yml index 52e1badf25..8936bb1a1f 100644 --- a/third_party/home-manager/.github/workflows/test.yml +++ b/third_party/home-manager/.github/workflows/test.yml @@ -11,12 +11,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v10 + - uses: cachix/install-nix-action@v13 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@v6 + - uses: cachix/cachix-action@v10 with: name: nix-community signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' + - run: ./format -c - run: nix-shell . -A install - - run: nix-shell --pure --max-jobs 4 tests -A run.all + - run: nix-shell --pure tests -A run.all diff --git a/third_party/home-manager/.gitlab-ci.yml b/third_party/home-manager/.gitlab-ci.yml index 22eec32283..34085a57e2 100644 --- a/third_party/home-manager/.gitlab-ci.yml +++ b/third_party/home-manager/.gitlab-ci.yml @@ -1,8 +1,7 @@ image: nixos/nix:latest variables: - # Pinned 2020-09-11. - NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/6d4b93323e7f78121f8d6db6c59f3889aa1dd931.tar.gz" + NIX_PATH: "nixpkgs=channel:nixos-unstable" stages: - test diff --git a/third_party/home-manager/.release b/third_party/home-manager/.release new file mode 100644 index 0000000000..a6cf7c3a7f --- /dev/null +++ b/third_party/home-manager/.release @@ -0,0 +1 @@ +21.11 diff --git a/third_party/home-manager/CONTRIBUTING.adoc b/third_party/home-manager/CONTRIBUTING.adoc index dd68f296f7..cffa621392 100644 --- a/third_party/home-manager/CONTRIBUTING.adoc +++ b/third_party/home-manager/CONTRIBUTING.adoc @@ -44,9 +44,10 @@ The first option is good if you only temporarily want to use your clone. [[sec-guidelines]] === Guidelines -:irc-home-manager: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager +:irc-home-manager: https://webchat.oftc.net/?channels=home-manager :valuable-options: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md#valuable-options :rfc-42: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md +:assertions: https://nixos.org/manual/nixos/stable/index.html#sec-assertions If your contribution satisfy the following rules then there is a good chance it will be merged without too much trouble. The rules are enforced by the Home Manager maintainers and to a lesser extent the Home Manager CI system. @@ -55,7 +56,9 @@ If you are uncertain how these rules affect the change you would like to make th [[sec-guidelines-back-compat]] ==== Maintain backward compatibility -Your contribution should never cause another user's existing configuration to break. Home Manager is used in many different environments and you should consider how you change may effect others. For example, +Your contribution should not cause another user's existing configuration to break unless there is a very good reason and the change should be announced to the user through an {assertions}[assertion] or similar. + +Remember that Home Manager is used in many different environments and you should consider how your change may effect others. For example, - Does your change work for people that do not use NixOS? Consider other GNU/Linux distributions and macOS. - Does your change work for people whose configuration is built on one system and deployed on another system? @@ -88,7 +91,7 @@ All contributed code _must_ pass the test suite. ==== Add relevant documentation :docbook: https://tdg.docbook.org/ :asciidoc: https://asciidoc.org/ -:docbook-rocks: https://docbook.rocks/ +:docbook-rocks: https://berbiche.github.io/docbook.rocks/ Many code changes require changing the documentation as well. Module options should be documented with DocBook. See {docbook-rocks}[DocBook rocks!] for a quick introduction and {docbook}[DocBook 5: The Definitive Guide] for in-depth information of DocBook. Home Manager is itself documented using a combination of DocBook and {asciidoc}[AsciiDoc]. All text is hosted in Home Manager's Git repository. @@ -160,7 +163,7 @@ The commit messages should follow the {seven-rules}[seven rules]. We also ask yo {long description} ---- -where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. Note, `{description}` should start with a lower case letter. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <> for a commit message that fulfills these requirements. +where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <> for a commit message that fulfills these requirements. [[ex-commit-message]] .Compliant commit message diff --git a/third_party/home-manager/FAQ.adoc b/third_party/home-manager/FAQ.adoc index b8215254dd..2c9c1f1683 100644 --- a/third_party/home-manager/FAQ.adoc +++ b/third_party/home-manager/FAQ.adoc @@ -40,6 +40,8 @@ error: build of ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment. The solution is typically to uninstall the package from the environment using `nix-env --uninstall` and reattempt the Home Manager generation switch. +You could also opt to unistall _all_ of the packages from your profile with `nix-env --uninstall '*'`. + === Why are the session variables not set? Home Manager is only able to set session variables automatically if it manages your Bash or Z shell configuration. If you don't want to let Home Manager manage your shell then you will have to manually source the `~/.nix-profile/etc/profile.d/hm-session-vars.sh` file in an appropriate way. In Bash and Z shell this can be done by adding @@ -51,7 +53,7 @@ Home Manager is only able to set session variables automatically if it manages y to your `.profile` and `.zshrc` files, respectively. The `hm-session-vars.sh` file should work in most Bourne-like shells. -=== How do set up a configuration for multiple users/machines? +=== How to set up a configuration for multiple users/machines? :post-your-homenix: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/ A typical way to prepare a repository of configurations for multiple logins and machines is to prepare one "top-level" file for each unique combination. @@ -92,7 +94,7 @@ error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt. The solution on NixOS is to add [source,nix] -services.dbus.packages = with pkgs; [ gnome3.dconf ]; +services.dbus.packages = with pkgs; [ gnome.dconf ]; to your system configuration. diff --git a/third_party/home-manager/LICENSE b/third_party/home-manager/LICENSE index 122b9b4a56..2db3938bbe 100644 --- a/third_party/home-manager/LICENSE +++ b/third_party/home-manager/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017-2020 Robert Helgesson and Home Manager contributors +Copyright (c) 2017-2020 Home Manager contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/third_party/home-manager/README.md b/third_party/home-manager/README.md index 4cdc1542bd..45327ba7be 100644 --- a/third_party/home-manager/README.md +++ b/third_party/home-manager/README.md @@ -3,8 +3,10 @@ Home Manager using Nix This project provides a basic system for managing a user environment using the [Nix][] package manager together with the Nix libraries -found in [Nixpkgs][]. Before attempting to use Home Manager please -read the warning below. +found in [Nixpkgs][]. It allows declarative configuration of user +specific (non global) packages and dotfiles. + +Before attempting to use Home Manager please read the warning below. For a more systematic overview of Home Manager and its available options, please see the [Home Manager manual][manual]. @@ -12,22 +14,25 @@ options, please see the [Home Manager manual][manual]. Words of warning ---------------- -This project is under development. I personally use it to manage -several user configurations but it may fail catastrophically for you. -So beware! +Unfortunately, it is quite possible to get difficult to understand +errors when working with Home Manager, such as infinite loops with no +clear source reference. You should therefore be comfortable using the +Nix language and the various tools in the Nix ecosystem. Reading +through the [Nix Pills][] document is a good way to familiarize +yourself with them. -Before using Home Manager you should be comfortable using the Nix -language and the various tools in the Nix ecosystem. Reading through -the [Nix Pills][] document is a good way to familiarize yourself with -them. +If you are not very familiar with Nix but still want to use Home +Manager then you are strongly encouraged to start with a small and +very simple configuration and gradually make it more elaborate as you +learn. In some cases Home Manager cannot detect whether it will overwrite a previous manual configuration. For example, the Gnome Terminal module will write to your dconf store and cannot tell whether a configuration -that it is about to be overwrite was from a previous Home Manager +that it is about to be overwritten was from a previous Home Manager generation or from manual configuration. -Home Manager targets [NixOS][] unstable and NixOS version 20.03 (the +Home Manager targets [NixOS][] unstable and NixOS version 21.05 (the current stable version), it may or may not work on other Linux distributions and NixOS versions. @@ -43,8 +48,7 @@ Contact ------- You can chat with us on IRC in the channel [#home-manager][] on -[freenode][]. The [channel logs][] are hosted courtesy of -[samueldr][]. +[OFTC][]. Installation ------------ @@ -61,22 +65,23 @@ Currently the easiest way to install Home Manager is as follows: control this option using the [`nix.allowedUsers`][nixosAllowedUsers] system option. -2. Add the appropriate Home Manager channel. Typically this is + Note that Nix 2.4 (`nixUnstable`) is not yet supported. + +2. Add the appropriate Home Manager channel. If you are following + Nixpkgs master or an unstable channel you can run ```console $ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager $ nix-channel --update ``` - if you are following Nixpkgs master or an unstable channel and + and if you follow a Nixpkgs version 21.05 channel you can run ```console - $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager + $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager $ nix-channel --update ``` - if you follow a Nixpkgs version 20.03 channel. - On NixOS you may need to log out and back in for the channel to become available. On non-NixOS you may have to add @@ -112,6 +117,13 @@ Currently the easiest way to install Home Manager is as follows: . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" ``` + or this when managing home configuration together with system + configuration + + ```bash + . "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh" + ``` + to your `~/.profile` file. If instead of using channels you want to run Home Manager from a Git @@ -129,8 +141,8 @@ configuration generations. As an example, let us expand the initial configuration file from the installation above to install the htop and fortune packages, install -Emacs with a few extra packages enabled, install Firefox with the -IcedTea plugin enabled, and enable the user gpg-agent service. +Emacs with a few extra packages enabled, install Firefox with +smooth scrolling disabled, and enable the user gpg-agent service. To satisfy the above setup we should elaborate the `~/.config/nixpkgs/home.nix` file as follows: @@ -267,7 +279,7 @@ then result in $ home-manager switch … Activating checkLinkTargets -Existing file '/home/jdoe/.gitconfig' is in the way +Existing file '/home/jdoe/.config/git/config' is in the way Please move the above files and try again ``` @@ -331,7 +343,7 @@ as follows: { home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; - home-manager.users.user = import ./home.nix; + home-manager.users.jdoe = import ./home.nix; } ]; }; @@ -340,6 +352,13 @@ as follows: } ``` +Note, the Home Manager library is exported by the flake under +`lib.hm`. + +When using flakes, switch to new configurations as you do for the +whole system (e. g. `nixos-rebuild switch --flake `) instead of +using the `home-manager` command line tool. + Releases -------- @@ -347,7 +366,7 @@ Home Manager is developed against `nixpkgs-unstable` branch, which often causes it to contain tweaks for changes/packages not yet released in stable NixOS. To avoid breaking users' configurations, Home Manager is released in branches corresponding to NixOS releases -(e.g. `release-20.03`). These branches get fixes, but usually not new +(e.g. `release-21.05`). These branches get fixes, but usually not new modules. If you need a module to be backported, then feel free to open an issue. @@ -360,9 +379,8 @@ an issue. [Z shell]: http://zsh.sourceforge.net/ [manual]: https://nix-community.github.io/home-manager/ [configuration options]: https://nix-community.github.io/home-manager/options.html -[#home-manager]: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager -[freenode]: https://freenode.net/ -[channel logs]: https://logs.nix.samueldr.com/home-manager/ +[#home-manager]: https://webchat.oftc.net/?channels=home-manager +[OFTC]: https://oftc.net/ [samueldr]: https://github.com/samueldr/ [Nix Pills]: https://nixos.org/nixos/nix-pills/ [Nix Flakes]: https://nixos.wiki/wiki/Flakes diff --git a/third_party/home-manager/doc/contributing.adoc b/third_party/home-manager/doc/contributing.adoc index dd68f296f7..cffa621392 100644 --- a/third_party/home-manager/doc/contributing.adoc +++ b/third_party/home-manager/doc/contributing.adoc @@ -44,9 +44,10 @@ The first option is good if you only temporarily want to use your clone. [[sec-guidelines]] === Guidelines -:irc-home-manager: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager +:irc-home-manager: https://webchat.oftc.net/?channels=home-manager :valuable-options: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md#valuable-options :rfc-42: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md +:assertions: https://nixos.org/manual/nixos/stable/index.html#sec-assertions If your contribution satisfy the following rules then there is a good chance it will be merged without too much trouble. The rules are enforced by the Home Manager maintainers and to a lesser extent the Home Manager CI system. @@ -55,7 +56,9 @@ If you are uncertain how these rules affect the change you would like to make th [[sec-guidelines-back-compat]] ==== Maintain backward compatibility -Your contribution should never cause another user's existing configuration to break. Home Manager is used in many different environments and you should consider how you change may effect others. For example, +Your contribution should not cause another user's existing configuration to break unless there is a very good reason and the change should be announced to the user through an {assertions}[assertion] or similar. + +Remember that Home Manager is used in many different environments and you should consider how your change may effect others. For example, - Does your change work for people that do not use NixOS? Consider other GNU/Linux distributions and macOS. - Does your change work for people whose configuration is built on one system and deployed on another system? @@ -88,7 +91,7 @@ All contributed code _must_ pass the test suite. ==== Add relevant documentation :docbook: https://tdg.docbook.org/ :asciidoc: https://asciidoc.org/ -:docbook-rocks: https://docbook.rocks/ +:docbook-rocks: https://berbiche.github.io/docbook.rocks/ Many code changes require changing the documentation as well. Module options should be documented with DocBook. See {docbook-rocks}[DocBook rocks!] for a quick introduction and {docbook}[DocBook 5: The Definitive Guide] for in-depth information of DocBook. Home Manager is itself documented using a combination of DocBook and {asciidoc}[AsciiDoc]. All text is hosted in Home Manager's Git repository. @@ -160,7 +163,7 @@ The commit messages should follow the {seven-rules}[seven rules]. We also ask yo {long description} ---- -where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. Note, `{description}` should start with a lower case letter. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <> for a commit message that fulfills these requirements. +where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <> for a commit message that fulfills these requirements. [[ex-commit-message]] .Compliant commit message diff --git a/third_party/home-manager/doc/default.nix b/third_party/home-manager/doc/default.nix index 6b8e229aae..8015f1b59d 100644 --- a/third_party/home-manager/doc/default.nix +++ b/third_party/home-manager/doc/default.nix @@ -26,27 +26,78 @@ let }]; }; - hmModulesDocs = nmd.buildModulesDocs { + buildModulesDocs = args: + nmd.buildModulesDocs ({ + moduleRootPaths = [ ./.. ]; + mkModuleUrl = path: + "https://github.com/nix-community/home-manager/blob/master/${path}#blob-path"; + channelName = "home-manager"; + } // args); + + hmModulesDocs = buildModulesDocs { modules = import ../modules/modules.nix { inherit lib pkgs; check = false; } ++ [ scrubbedPkgsModule ]; - moduleRootPaths = [ ./.. ]; - mkModuleUrl = path: - "https://github.com/nix-community/home-manager/blob/master/${path}#blob-path"; - channelName = "home-manager"; docBook.id = "home-manager-options"; }; + nixosModuleDocs = buildModulesDocs { + modules = let + nixosModule = module: pkgs.path + "/nixos/modules" + module; + mockedNixos = with lib; { + options = { + environment.pathsToLink = mkSinkUndeclaredOptions { }; + systemd.services = mkSinkUndeclaredOptions { }; + users.users = mkSinkUndeclaredOptions { }; + }; + }; + in [ + ../nixos/default.nix + mockedNixos + (nixosModule "/misc/assertions.nix") + scrubbedPkgsModule + ]; + docBook = { + id = "nixos-options"; + optionIdPrefix = "nixos-opt"; + }; + }; + + nixDarwinModuleDocs = buildModulesDocs { + modules = let + nixosModule = module: pkgs.path + "/nixos/modules" + module; + mockedNixDarwin = with lib; { + options = { + environment.pathsToLink = mkSinkUndeclaredOptions { }; + system.activationScripts.postActivation.text = + mkSinkUndeclaredOptions { }; + users.users = mkSinkUndeclaredOptions { }; + }; + }; + in [ + ../nix-darwin/default.nix + mockedNixDarwin + (nixosModule "/misc/assertions.nix") + scrubbedPkgsModule + ]; + docBook = { + id = "nix-darwin-options"; + optionIdPrefix = "nix-darwin-opt"; + }; + }; + docs = nmd.buildDocBookDocs { pathName = "home-manager"; - modulesDocs = [ hmModulesDocs ]; + modulesDocs = [ hmModulesDocs nixDarwinModuleDocs nixosModuleDocs ]; documentsDirectory = ./.; documentType = "book"; chunkToc = '' + + diff --git a/third_party/home-manager/doc/faq.adoc b/third_party/home-manager/doc/faq.adoc index b8215254dd..2c9c1f1683 100644 --- a/third_party/home-manager/doc/faq.adoc +++ b/third_party/home-manager/doc/faq.adoc @@ -40,6 +40,8 @@ error: build of ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment. The solution is typically to uninstall the package from the environment using `nix-env --uninstall` and reattempt the Home Manager generation switch. +You could also opt to unistall _all_ of the packages from your profile with `nix-env --uninstall '*'`. + === Why are the session variables not set? Home Manager is only able to set session variables automatically if it manages your Bash or Z shell configuration. If you don't want to let Home Manager manage your shell then you will have to manually source the `~/.nix-profile/etc/profile.d/hm-session-vars.sh` file in an appropriate way. In Bash and Z shell this can be done by adding @@ -51,7 +53,7 @@ Home Manager is only able to set session variables automatically if it manages y to your `.profile` and `.zshrc` files, respectively. The `hm-session-vars.sh` file should work in most Bourne-like shells. -=== How do set up a configuration for multiple users/machines? +=== How to set up a configuration for multiple users/machines? :post-your-homenix: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/ A typical way to prepare a repository of configurations for multiple logins and machines is to prepare one "top-level" file for each unique combination. @@ -92,7 +94,7 @@ error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt. The solution on NixOS is to add [source,nix] -services.dbus.packages = with pkgs; [ gnome3.dconf ]; +services.dbus.packages = with pkgs; [ gnome.dconf ]; to your system configuration. diff --git a/third_party/home-manager/doc/installation.adoc b/third_party/home-manager/doc/installation.adoc new file mode 100644 index 0000000000..123ca7146c --- /dev/null +++ b/third_party/home-manager/doc/installation.adoc @@ -0,0 +1,263 @@ +[[ch-installation]] +== Installing Home Manager + +:nix-darwin: https://github.com/LnL7/nix-darwin/ + +Home Manager can be used in three primary ways: + +1. Using the standalone `home-manager` tool. For platforms other than +NixOS and Darwin, this is the only available choice. It is also +recommended for people on NixOS or Darwin that want to manage their +home directory independent of the system as a whole. See +<> for instructions on how to perform this +installation. + +2. As a module within a NixOS system configuration. This allows the +user profiles to be built together with the system when running +`nixos-rebuild`. See <> for a description of +this setup. + +3. As a module within a {nix-darwin}[nix-darwin] system configuration. +This allows the user profiles to be built together with the system +when running `darwin-rebuild`. See <> +for a description of this setup. + +[[sec-install-standalone]] +=== Standalone installation + +:nix-allowed-users: https://nixos.org/nix/manual/#conf-allowed-users +:nixos-allowed-users: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers + +1. Make sure you have a working Nix installation. Specifically, make +sure that your user is able to build and install Nix packages. For +example, you should be able to successfully run a command like +`nix-instantiate '' -A hello` without having to switch to the +root user. For a multi-user install of Nix this means that your user +must be covered by the {nix-allowed-users}[`allowed-users`] Nix +option. On NixOS you can control this option using the +{nixos-allowed-users}[`nix.allowedUsers`] system option. + +2. Add the Home Manager channel that you wish to follow. If you are +following Nixpkgs master or an unstable channel then this is done by +running ++ +[source,console] +---- +$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager +$ nix-channel --update +---- ++ +and if you follow a Nixpkgs version 21.05 channel, you can run ++ +[source,console] +---- +$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager +$ nix-channel --update +---- ++ +On NixOS you may need to log out and back in for the channel to become +available. On non-NixOS you may have to add ++ +[source,bash] +export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH ++ +to your shell (see +https://github.com/NixOS/nix/issues/2033[nix#2033]). + +3. Run the Home Manager installation command and create the first Home +Manager generation: ++ +[source,console] +$ nix-shell '' -A install ++ +Once finished, Home Manager should be active and available in your +user environment. + +4. If you do not plan on having Home Manager manage your shell +configuration then you must source the ++ +[source,bash] +$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh ++ +file in your shell configuration. Alternatively source ++ +[source,bash] +/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh ++ +when managing home configuration together with system configuration. ++ +Unfortunately, we currently only support POSIX.2-like shells such as +https://www.gnu.org/software/bash/[Bash] or +http://zsh.sourceforge.net/[Z shell]. ++ +For example, if you use Bash then add ++ +[source,bash] +---- +. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" +---- ++ +to your `~/.profile` file. + +If instead of using channels you want to run Home Manager from a Git +checkout of the repository then you can use the +<> option to specify the absolute path +to the repository. + +[[sec-install-nixos-module]] +=== NixOS module + +Home Manager provides a NixOS module that allows you to prepare user +environments directly from the system configuration file, which often +is more convenient than using the `home-manager` tool. It also opens +up additional possibilities, for example, to automatically configure +user environments in NixOS declarative containers or on systems +deployed through NixOps. + +To make the NixOS module available for use you must `import` it into +your system configuration. This is most conveniently done by adding a +Home Manager channel. For example, if you are following Nixpkgs master +or an unstable channel, you can run + +[source,console] +---- +# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager +# nix-channel --update +---- + +and if you follow a Nixpkgs version 21.05 channel, you can run + +[source,console] +---- +# nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager +# nix-channel --update +---- + +It is then possible to add + +[source,nix] +imports = [ ]; + +to your system `configuration.nix` file, which will introduce a new +NixOS option called `home-manager.users` whose type is an attribute +set that maps user names to Home Manager configurations. + +For example, a NixOS configuration may include the lines + +[source,nix] +---- +users.users.eve.isNormalUser = true; +home-manager.users.eve = { pkgs, ... }: { + home.packages = [ pkgs.atool pkgs.httpie ]; + programs.bash.enable = true; +}; +---- + +and after a `nixos-rebuild switch` the user eve's environment should +include a basic Bash configuration and the packages atool and httpie. + +[NOTE] +==== +By default packages will be installed to `$HOME/.nix-profile` but they +can be installed to `/etc/profiles` if + +[source,nix] +home-manager.useUserPackages = true; + +is added to the system configuration. This is necessary if, for +example, you wish to use `nixos-rebuild build-vm`. This option may +become the default value in the future. +==== + +[NOTE] +==== +By default, Home Manager uses a private `pkgs` instance that is +configured via the `home-manager.users..nixpkgs` options. To +instead use the global `pkgs` that is configured via the system level +`nixpkgs` options, set + +[source,nix] +home-manager.useGlobalPkgs = true; + +This saves an extra Nixpkgs evaluation, adds consistency, and removes +the dependency on `NIX_PATH`, which is otherwise used for importing +Nixpkgs. +==== + +[[sec-install-nix-darwin-module]] +=== nix-darwin module + +Home Manager provides a module that allows you to prepare user +environments directly from the {nix-darwin}[nix-darwin] configuration +file, which often is more convenient than using the `home-manager` +tool. + +To make the NixOS module available for use you must `import` it into +your system configuration. This is most conveniently done by adding a +Home Manager channel. For example, if you are following Nixpkgs master +or an unstable channel, you can run + +[source,console] +---- +# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager +# nix-channel --update +---- + +and if you follow a Nixpkgs version 21.05 channel, you can run + +[source,console] +---- +# nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager +# nix-channel --update +---- + +It is then possible to add + +[source,nix] +imports = [ ]; + +to your nix-darwin `configuration.nix` file, which will introduce a +new NixOS option called `home-manager` whose type is an attribute set +that maps user names to Home Manager configurations. + +For example, a nix-darwin configuration may include the lines + +[source,nix] +---- +home-manager.users.eve = { pkgs, ... }: { + home.packages = [ pkgs.atool pkgs.httpie ]; + programs.bash.enable = true; +}; +---- + +and after a `darwin-rebuild switch` the user eve's environment +should include a basic Bash configuration and the packages atool and +httpie. + +[NOTE] +==== +By default user packages will not be ignored in favor of +`environment.systemPackages`, but they will be intalled to +`/etc/profiles/per-user/$USERNAME` if + +[source,nix] +home-manager.useUserPackages = true; + +is added to the nix-darwin configuration. This option may become the +default value in the future. +==== + +[NOTE] +==== +By default, Home Manager uses a private `pkgs` instance that is +configured via the `home-manager.users..nixpkgs` options. To +instead use the global `pkgs` that is configured via the system level +`nixpkgs` options, set + +[source,nix] +home-manager.useGlobalPkgs = true; + +This saves an extra Nixpkgs evaluation, adds consistency, and removes +the dependency on `NIX_PATH`, which is otherwise used for importing +Nixpkgs. +==== diff --git a/third_party/home-manager/doc/installation.xml b/third_party/home-manager/doc/installation.xml deleted file mode 100644 index bd8d0185c1..0000000000 --- a/third_party/home-manager/doc/installation.xml +++ /dev/null @@ -1,334 +0,0 @@ - - Installing Home Manager - - Home Manager can be used in three primary ways: - - - - Using the standalone home-manager tool. For platforms - other than NixOS and Darwin, this is the only available choice. It is also - recommended for people on NixOS or Darwin that want to manage their home - directory independent of the system as a whole. See - for instructions on how to - perform this installation. - - - - - As a module within a NixOS system configuration. This allows the user - profiles to be built together with the system when running - nixos-rebuild. See - for a description of this - setup. - - - - - As a module within a - nix-darwin - system configuration. This allows the user profiles to be built together - with the system when running darwin-rebuild. See - for a description of this - setup. - - - - -
- Standalone installation - - - - - Make sure you have a working Nix installation. Specifically, make - sure that your user is able to build and install Nix packages. - For example, you should be able to successfully run a command - like nix-instantiate '<nixpkgs>' -A hello - without having to switch to the root user. For a multi-user - install of Nix this means that your user must be covered by the - allowed-users - Nix option. On NixOS you can control this option using the - nix.allowedUsers - system option. - - - - - Add the Home Manager channel that you wish to follow. This is done by - running - - -$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager -$ nix-channel --update - - - if you are following Nixpkgs master or an unstable channel and - - -$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager -$ nix-channel --update - - - if you follow a Nixpkgs version 20.03 channel. - - - On NixOS you may need to log out and back in for the channel to become - available. On non-NixOS you may have to add - -export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH - - to your shell (see - nix#2033). - - - - - Run the Home Manager installation command and create the first Home - Manager generation: - - -$ nix-shell '<home-manager>' -A install - - - Once finished, Home Manager should be active and available in your user - environment. - - - - - If you do not plan on having Home Manager manage your shell configuration - then you must source the - - -$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh - - - file in your shell configuration. Unfortunately, we currently only support - POSIX.2-like shells such as - Bash or - Z shell. - - - For example, if you use Bash then add - - -. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" - - - to your ~/.profile file. - - - - - - If instead of using channels you want to run Home Manager from a Git - checkout of the repository then you can use the - programs.home-manager.path option to specify the absolute - path to the repository. - -
-
- NixOS module - - - Home Manager provides a NixOS module that allows you to prepare user - environments directly from the system configuration file, which often is - more convenient than using the home-manager tool. It also - opens up additional possibilities, for example, to automatically configure - user environments in NixOS declarative containers or on systems deployed - through NixOps. - - - - To make the NixOS module available for use you must - it into your system configuration. This is most conveniently done by adding - a Home Manager channel, for example - - - -# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager -# nix-channel --update - - - - if you are following Nixpkgs master or an unstable channel and - - - -# nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager -# nix-channel --update - - - - if you follow a Nixpkgs version 20.03 channel. - - - - It is then possible to add - - - -imports = [ <home-manager/nixos> ]; - - - - to your system configuration.nix file, which will - introduce a new NixOS option called - whose type is an attribute set that maps user names to Home Manager - configurations. - - - - For example, a NixOS configuration may include the lines - - - -users.users.eve.isNormalUser = true; -home-manager.users.eve = { pkgs, ... }: { - home.packages = [ pkgs.atool pkgs.httpie ]; - programs.bash.enable = true; -}; - - - - and after a nixos-rebuild switch the user eve's - environment should include a basic Bash configuration and the packages atool - and httpie. - - - - - By default packages will be installed to - $HOME/.nix-profile but they can be installed to - /etc/profiles if - - -home-manager.useUserPackages = true; - - - is added to the system configuration. This is necessary if, for example, - you wish to use nixos-rebuild build-vm. This option may - become the default value in the future. - - - - - - By default, Home Manager uses a private pkgs instance - that is configured via the options. - To instead use the global pkgs that is configured via - the system level options, set - - -home-manager.useGlobalPkgs = true; - - - This saves an extra Nixpkgs evaluation, adds consistency, and removes the - dependency on NIX_PATH, which is otherwise used for - importing Nixpkgs. - - -
-
- nix-darwin module - - - Home Manager provides a module that allows you to prepare user - environments directly from the nix-darwin configuration file, which often is - more convenient than using the home-manager tool. - - - - To make the NixOS module available for use you must - it into your system configuration. This is most conveniently done by adding - a Home Manager channel, for example - - - -# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager -# nix-channel --update - - - - if you are following Nixpkgs master or an unstable channel and - - - -# nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager -# nix-channel --update - - - - if you follow a Nixpkgs version 20.03 channel. - - - - It is then possible to add - - - -imports = [ <home-manager/nix-darwin> ]; - - - - to your nix-darwin configuration.nix file, which will - introduce a new NixOS option called whose type - is an attribute set that maps user names to Home Manager configurations. - - - - For example, a nix-darwin configuration may include the lines - - - -home-manager.users.eve = { pkgs, ... }: { - home.packages = [ pkgs.atool pkgs.httpie ]; - programs.bash.enable = true; -}; - - - - and after a darwin-rebuild --switch the user eve's - environment should include a basic Bash configuration and the packages atool - and httpie. - - - - - By default user packages will not be ignored in favor of - , but they will be intalled to - if - - - -home-manager.useUserPackages = true; - - - - is added to the nix-darwin configuration. This option may become the default - value in the future. - - - - - - By default, Home Manager uses a private pkgs instance - that is configured via the options. - To instead use the global pkgs that is configured via - the system level options, set - - -home-manager.useGlobalPkgs = true; - - - This saves an extra Nixpkgs evaluation, adds consistency, and removes the - dependency on NIX_PATH, which is otherwise used for - importing Nixpkgs. - - -
-
diff --git a/third_party/home-manager/doc/man-home-manager.xml b/third_party/home-manager/doc/man-home-manager.xml index 2f141d9704..357f4d5e8f 100644 --- a/third_party/home-manager/doc/man-home-manager.xml +++ b/third_party/home-manager/doc/man-home-manager.xml @@ -12,47 +12,51 @@ - home-manager + home-manager build - + instantiate - + edit - + expire-generations timestamp - + generations - + help - + news - + + + option option.name + + packages - + remove-generations ID … - + switch - + uninstall @@ -61,85 +65,102 @@ -A attrPath - + -I path - + + + --flake flake-uri + + -b ext - + - + -f - + --file path - + - + -h - + --help - + - + -n - + --dry-run - + --option name value - + --cores number - + - --max-jobs number + + + -j + + + + --max-jobs + + + number - + + + --debug + + --keep-failed - + --keep-going - + --show-trace - + --(no-)substitute - + - + -v - + --verbose @@ -151,7 +172,7 @@ Description This command updates the user environment so that it corresponds to the - configuration specified in ~/.config/nixpkgs/home.nix. + configuration specified in ~/.config/nixpkgs/home.nix or ~/.config/nixpkgs/flake.nix. All operations using this tool expects a sub-command that indicates the @@ -233,6 +254,18 @@ + + + + + + + Inspect the given option name in the home configuration, like + nixos-option + 8 . + + + @@ -334,6 +367,18 @@ + + + + + + + Build Home Manager configuration from the flake, which must contain the + output homeConfigurations.name. If no name is specified it will first try + username@hostname and then username. + + + @@ -417,6 +462,9 @@ + + + @@ -428,6 +476,18 @@ + + + + + + + Passed on to + nix-build + 1 . + + + diff --git a/third_party/home-manager/doc/manual.xml b/third_party/home-manager/doc/manual.xml index 314d7c10a9..3f21649fc6 100644 --- a/third_party/home-manager/doc/manual.xml +++ b/third_party/home-manager/doc/manual.xml @@ -14,10 +14,8 @@ If you encounter problems then please reach out on the IRC channel - #home-manager - hosted by freenode. - The channel logs - are hosted courtesy of samueldr. + #home-manager + hosted by OFTC. If your problem is caused by a bug in Home Manager then it should be reported on the Home Manager issue tracker. @@ -38,6 +36,14 @@ Configuration Options + + NixOS Module Options + + + + nix-darwin Module Options + + Tools diff --git a/third_party/home-manager/doc/release-notes/release-notes.adoc b/third_party/home-manager/doc/release-notes/release-notes.adoc index 9a98e3850c..826b991d56 100644 --- a/third_party/home-manager/doc/release-notes/release-notes.adoc +++ b/third_party/home-manager/doc/release-notes/release-notes.adoc @@ -6,6 +6,10 @@ This section lists the release notes for stable versions of Home Manager and the :leveloffset: 1 +include::rl-2111.adoc[] + +include::rl-2105.adoc[] + include::rl-2009.adoc[] include::rl-2003.adoc[] diff --git a/third_party/home-manager/doc/release-notes/rl-2009.adoc b/third_party/home-manager/doc/release-notes/rl-2009.adoc index c1939ab5af..a3de0260c7 100644 --- a/third_party/home-manager/doc/release-notes/rl-2009.adoc +++ b/third_party/home-manager/doc/release-notes/rl-2009.adoc @@ -1,8 +1,7 @@ [[sec-release-20.09]] -== Release 20.09 (unreleased) +== Release 20.09 -This is the current unstable branch and the information in this -section is therefore not final. +The 20.09 release branch became the stable branch in late September, 2020. [[sec-release-20.09-highlights]] === Highlights diff --git a/third_party/home-manager/doc/release-notes/rl-2105.adoc b/third_party/home-manager/doc/release-notes/rl-2105.adoc new file mode 100644 index 0000000000..7fcfb268d3 --- /dev/null +++ b/third_party/home-manager/doc/release-notes/rl-2105.adoc @@ -0,0 +1,200 @@ +[[sec-release-21.05]] +== Release 21.05 + +The 21.05 release branch became the stable branch in May, 2021. + +[[sec-release-21.05-highlights]] +=== Highlights + +This release has the following notable changes: + +* The <> option is now a list rather than an +attribute set. To migrate, move the keys of the attrset into the list +items' `invocation` keys. For example, ++ +[source,nix] +---- +programs.broot.verbs = { + "p" = { execution = ":parent"; }; +}; +---- ++ +becomes ++ +[source,nix] +---- +programs.broot.verbs = [ + { + invocation = "p"; + execution = ":parent"; + } +]; +---- + +* The <> option has been changed to allow custom +derivations. The following configuration is now possible: ++ +[source,nix] +---- +programs.mpv.package = (pkgs.wrapMpv (pkgs.mpv-unwrapped.override { + vapoursynthSupport = true; +}) { + extraMakeWrapperArgs = [ + "--prefix" "LD_LIBRARY_PATH" ":" "${pkgs.vapoursynth-mvtools}/lib/vapoursynth" + ]; +}); +---- ++ +As a result of this change, <> is no longer the +resulting derivation. Use the newly introduced `programs.mpv.finalPackage` +instead. + +* The <> option is now an attribute set rather +than a string. To migrate, move each line into the attribute set, +removing the `rofi.` prefix from the keys. For example, ++ +[source,nix] +---- +programs.rofi.extraConfig = '' + rofi.show-icons: true + rofi.modi: drun,emoji,ssh +''; +---- ++ +becomes ++ +[source,nix] +---- +programs.rofi.extraConfig = { + show-icons = true; + modi = "drun,emoji,ssh"; +}; +---- ++ +* The <> option now supports defining a theme +using an attribute set, the following configuration is now possible: ++ +[source,nix] +---- +programs.rofi.theme = let + # Necessary to avoid quoting non-string values + inherit (config.lib.formats.rasi) mkLiteral; +in { + "@import" = "~/.config/rofi/theme.rasi"; + + "*" = { + background-color = mkLiteral "#000000"; + foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )"; + border-color = mkLiteral "#FFFFFF"; + width = 512; + }; + + "#textbox-prompt-colon" = { + expand = false; + str = ":"; + margin = mkLiteral "0px 0.3em 0em 0em"; + text-color = mkLiteral "@foreground-color"; + }; +}; +---- + + +* The `services.redshift.extraOptions` and `services.gammastep.extraOptions` +options were removed in favor of <> and +`services.gammastep.settings`, that are now an attribute set rather +than a string. They also support new features not available before, for +example: ++ +[source,nix] +---- +services.redshift = { + dawnTime = "6:00-7:45"; + duskTime = "18:35-20:15"; + settings = { + redshift = { + gamma = 0.8; + adjustment-method = "randr"; + }; + + randr = { + screen = 0; + }; + }; +}; +---- ++ +It is recommended to check either +https://github.com/jonls/redshift/blob/master/redshift.conf.sample[redshift.conf.sample] or +https://gitlab.com/chinstrap/gammastep/-/blob/master/gammastep.conf.sample[gammastep.conf.sample] +for the available additional options in each program. + +* Specifying `programs.neomutt.binds.map` or `programs.neomutt.macros.map` as a + single string is now deprecated in favor of specfiying it as a list of + strings. + +* The `programs.neovim.configure` is deprecated in favor of other `programs.neovim` options; +please use the other options at your disposal: ++ +[source,nix] +---- +configure.packages.*.opt -> programs.neovim.plugins = [ { plugin = ...; optional = true; }] +configure.packages.*.start -> programs.neovim.plugins = [ { plugin = ...; }] +configure.customRC -> programs.neovim.extraConfig +---- + +* Home Manager now respects the `NO_COLOR` environment variable as per +https://no-color.org/[]. + +* Qt module now supports <> to specify a theme name and +<> to specify a theme package. If you have set +<> to `gnome`, a <> compatible +with both Qt and Gtk is now required to be set. For instance: ++ +[source,nix] +---- +qt = { + platformTheme = "gnome"; + style = { + name = "adwaita-dark"; + package = pkgs.adwaita-qt; + }; +}; +---- + +* The library type `fontType` now has a `size` attribute in addition to `name`. For example: ++ +[source,nix] +---- +font = { + name = "DejaVu Sans"; + size = 8; +}; +---- + +* The <> option is introduced to replace individual +options in `programs.htop`. To migrate, set the htop options directly in +<>. For example: ++ +[source,nix] +---- +programs.htop = { + enabled = true; + settings = { + color_scheme = 5; + delay = 15; + highlight_base_name = 1; + highlight_megabytes = 1; + highlight_threads = 1; + }; +}; +---- + +[[sec-release-21.05-state-version-changes]] +=== State Version Changes + +The state version in this release includes the changes below. These +changes are only active if the `home.stateVersion` option is set to +"21.05" or later. + +* The `newsboat` module now stores generated configuration in + `$XDG_CONFIG_HOME/newsboat`. diff --git a/third_party/home-manager/doc/release-notes/rl-2111.adoc b/third_party/home-manager/doc/release-notes/rl-2111.adoc new file mode 100644 index 0000000000..63986f953d --- /dev/null +++ b/third_party/home-manager/doc/release-notes/rl-2111.adoc @@ -0,0 +1,21 @@ +[[sec-release-21.11]] +== Release 21.11 + +This is the current unstable branch and the information in this +section is therefore not final. + +[[sec-release-21.11-highlights]] +=== Highlights + +This release has the following notable changes: + +* Nothing has happened. + +[[sec-release-21.11-state-version-changes]] +=== State Version Changes + +The state version in this release includes the changes below. These +changes are only active if the `home.stateVersion` option is set to +"21.11" or later. + +* Nothing has happened. diff --git a/third_party/home-manager/flake.nix b/third_party/home-manager/flake.nix index 2d53d603a6..486562b4dc 100644 --- a/third_party/home-manager/flake.nix +++ b/third_party/home-manager/flake.nix @@ -1,23 +1,46 @@ { description = "Home Manager for Nix"; - outputs = { self, nixpkgs }: rec { - nixosModules.home-manager = import ./nixos; + outputs = { self, nixpkgs }: + let + # List of systems supported by home-manager binary + supportedSystems = nixpkgs.lib.platforms.unix; - darwinModules.home-manager = import ./nix-darwin; + # Function to generate a set based on supported systems + forAllSystems = f: + nixpkgs.lib.genAttrs supportedSystems (system: f system); - lib = { - homeManagerConfiguration = { configuration, system, homeDirectory - , username - , pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages - , check ? true }@args: - import ./modules { - inherit pkgs check; - configuration = { ... }: { - imports = [ configuration ]; - home = { inherit homeDirectory username; }; + nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); + in rec { + nixosModules.home-manager = import ./nixos; + nixosModule = self.nixosModules.home-manager; + + darwinModules.home-manager = import ./nix-darwin; + darwinModule = self.darwinModules.home-manager; + + packages = forAllSystems (system: { + home-manager = nixpkgsFor.${system}.callPackage ./home-manager { }; + }); + + defaultPackage = + forAllSystems (system: self.packages.${system}.home-manager); + + lib = { + hm = import ./modules/lib { lib = nixpkgs.lib; }; + homeManagerConfiguration = { configuration, system, homeDirectory + , username, extraModules ? [ ], extraSpecialArgs ? { } + , pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages + , check ? true, stateVersion ? "20.09" }@args: + assert nixpkgs.lib.versionAtLeast stateVersion "20.09"; + + import ./modules { + inherit pkgs check extraSpecialArgs; + configuration = { ... }: { + imports = [ configuration ] ++ extraModules; + home = { inherit homeDirectory stateVersion username; }; + nixpkgs = { inherit (pkgs) config overlays; }; + }; }; - }; + }; }; - }; } diff --git a/third_party/home-manager/format b/third_party/home-manager/format index 7d48cb8a11..5682a1f293 100755 --- a/third_party/home-manager/format +++ b/third_party/home-manager/format @@ -18,7 +18,6 @@ esac find . -name '*.nix' \ ! -path ./modules/programs/irssi.nix \ \ - ! -path ./home-manager/default.nix \ ! -path ./home-manager/home-manager.nix \ ! -path ./modules/default.nix \ ! -path ./modules/files.nix \ @@ -26,32 +25,24 @@ find . -name '*.nix' \ ! -path ./modules/lib/default.nix \ ! -path ./modules/lib/file-type.nix \ ! -path ./modules/manual.nix \ - ! -path ./modules/misc/dconf.nix \ ! -path ./modules/misc/news.nix \ ! -path ./modules/misc/nixpkgs.nix \ ! -path ./modules/misc/xdg.nix \ ! -path ./modules/modules.nix \ - ! -path ./modules/programs/afew.nix \ ! -path ./modules/programs/bash.nix \ ! -path ./modules/programs/firefox.nix \ ! -path ./modules/programs/gpg.nix \ - ! -path ./modules/programs/lesspipe.nix \ ! -path ./modules/programs/ssh.nix \ ! -path ./modules/programs/tmux.nix \ ! -path ./modules/programs/zsh.nix \ ! -path ./modules/services/gpg-agent.nix \ - ! -path ./modules/services/kbfs.nix \ - ! -path ./modules/services/keybase.nix \ ! -path ./modules/services/mpd.nix \ ! -path ./modules/services/sxhkd.nix \ - ! -path ./modules/services/window-managers/i3.nix \ ! -path ./modules/systemd.nix \ ! -path ./nix-darwin/default.nix \ ! -path ./tests/default.nix \ - ! -path ./tests/modules/home-environment/default.nix \ ! -path ./tests/modules/home-environment/session-variables.nix \ ! -path ./tests/modules/programs/gpg/override-defaults.nix \ - ! -path ./tests/modules/programs/tmux/default.nix \ ! -path ./tests/modules/programs/zsh/session-variables.nix \ ! -path ./tests/modules/services/sxhkd/service.nix \ ! -path ./tests/modules/systemd/services.nix \ diff --git a/third_party/home-manager/home-manager/completion.bash b/third_party/home-manager/home-manager/completion.bash index e9f0457891..9a470cc2cc 100644 --- a/third_party/home-manager/home-manager/completion.bash +++ b/third_party/home-manager/home-manager/completion.bash @@ -62,6 +62,7 @@ # generations # help # news +# option # packages # remove-generations # switch @@ -86,6 +87,7 @@ # # help # edit +# option # build # switch # generations @@ -131,6 +133,9 @@ # # edit Open the home configuration in $EDITOR # +# option OPTION.NAME +# Inspect configuration option named OPTION.NAME. +# # build Build configuration into result directory # # switch Build and activate configuration @@ -278,14 +283,15 @@ _home-manager_completions () #--------------------------# local Subcommands - Subcommands=( "help" "edit" "build" "instantiate" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" ) + Subcommands=( "help" "edit" "option" "build" "instantiate" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" ) # ^ « home-manager »'s subcommands. #--------------------------# local Options - Options=( "-f" "--file" "-b" "-A" "-I" "-h" "--help" "-n" "--dry-run" "-v" "--verbose" "--show-trace" ) + Options=( "-f" "--file" "-b" "-A" "-I" "-h" "--help" "-n" "--dry-run" "-v" "--verbose" \ + "--cores" "--debug" "--keep-failed" "--keep-going" "-j" "--max-jobs" "--no-substitute" "--show-trace" "--substitute") # ^ « home-manager »'s options. @@ -353,4 +359,4 @@ _home-manager_completions () complete -F _home-manager_completions -o default home-manager -#complete -W "help edit build switch generations remove-generations expire-generations packages news" home-manager +#complete -W "help edit option build switch generations remove-generations expire-generations packages news" home-manager diff --git a/third_party/home-manager/home-manager/completion.zsh b/third_party/home-manager/home-manager/completion.zsh new file mode 100644 index 0000000000..9d346851b4 --- /dev/null +++ b/third_party/home-manager/home-manager/completion.zsh @@ -0,0 +1,59 @@ +#compdef home-manager + +local state ret=1 + +_arguments \ + '-A[attribute]:ATTRIBUTE:()' \ + '-I[search path]:PATH:_files -/' \ + '-b[backup files]:EXT:()' \ + '--cores[cores]:NUM:()' \ + '--debug[debug]' \ + '--keep-failed[keep failed]' \ + '--keep-going[keep going]' \ + '(-h --help)'{--help,-h}'[help]' \ + '(-v --verbose)'{--verbose,-v}'[verbose]' \ + '(-n --dry-run)'{--dry-run,-n}'[dry run]' \ + '(-f --file)'{--file,-f}'[configuration file]:FILE:_files' \ + '(-j --max-jobs)'{--max-jobs,-j}'[max jobs]:NUM:()' \ + '--option[option]:NAME VALUE:()' \ + '--show-trace[show trace]' \ + '1: :->cmds' \ + '*:: :->args' && ret=0 + +case "$state" in + cmds) + _values 'command' \ + 'help[help]' \ + 'edit[edit]' \ + 'option[inspect option]' \ + 'build[build]' \ + 'switch[switch]' \ + 'generations[list generations]' \ + 'remove-generations[remove generations]' \ + 'expire-generations[expire generations]' \ + 'packages[managed packages]' \ + 'news[read the news]' \ + 'uninstall[uninstall]' && ret=0 + ;; + args) + case $line[1] in + remove-generations) + _values 'generations' \ + $(home-manager generations | cut -d ' ' -f 5) && ret=0 + ;; + build|switch) + _arguments \ + '--cores[cores]:NUM:()' \ + '--debug[debug]' \ + '--keep-failed[keep failed]' \ + '--keep-going[keep going]' \ + '--max-jobs[max jobs]:NUM:()' \ + '--no-substitute[no substitute]' \ + '--option[option]:NAME VALUE:()' \ + '--show-trace[show trace]' \ + '--substitute[substitute]' + ;; + esac +esac + +return ret diff --git a/third_party/home-manager/home-manager/default.nix b/third_party/home-manager/home-manager/default.nix index 8b5ae75e0f..ecdea9e7bd 100644 --- a/third_party/home-manager/home-manager/default.nix +++ b/third_party/home-manager/home-manager/default.nix @@ -1,40 +1,42 @@ -{ runCommand, lib, bash, coreutils, findutils, gnused, less +{ runCommand, lib, bash, callPackage, coreutils, findutils, gnused, less +# used for pkgs.path for nixos-option +, pkgs - # Extra path to Home Manager. If set then this path will be tried - # before `$HOME/.config/nixpkgs/home-manager` and - # `$HOME/.nixpkgs/home-manager`. -, path ? null -}: +# Extra path to Home Manager. If set then this path will be tried +# before `$HOME/.config/nixpkgs/home-manager` and +# `$HOME/.nixpkgs/home-manager`. +, path ? null }: let pathStr = if path == null then "" else path; -in + nixos-option = + callPackage (pkgs.path + "/nixos/modules/installer/tools/nixos-option") { }; -runCommand - "home-manager" - { - preferLocalBuild = true; - allowSubstitutes = false; - meta = with lib; { - description = "A user environment configurator"; - maintainers = [ maintainers.rycee ]; - platforms = platforms.unix; - license = licenses.mit; - }; - } - '' - install -v -D -m755 ${./home-manager} $out/bin/home-manager +in runCommand "home-manager" { + preferLocalBuild = true; + allowSubstitutes = false; + meta = with lib; { + description = "A user environment configurator"; + maintainers = [ maintainers.rycee ]; + platforms = platforms.unix; + license = licenses.mit; + }; +} '' + install -v -D -m755 ${./home-manager} $out/bin/home-manager - substituteInPlace $out/bin/home-manager \ - --subst-var-by bash "${bash}" \ - --subst-var-by coreutils "${coreutils}" \ - --subst-var-by findutils "${findutils}" \ - --subst-var-by gnused "${gnused}" \ - --subst-var-by less "${less}" \ - --subst-var-by HOME_MANAGER_PATH '${pathStr}' + substituteInPlace $out/bin/home-manager \ + --subst-var-by bash "${bash}" \ + --subst-var-by coreutils "${coreutils}" \ + --subst-var-by findutils "${findutils}" \ + --subst-var-by gnused "${gnused}" \ + --subst-var-by less "${less}" \ + --subst-var-by nixos-option "${nixos-option}" \ + --subst-var-by HOME_MANAGER_PATH '${pathStr}' - install -D -m755 ${./completion.bash} \ - $out/share/bash-completion/completions/home-manager - '' + install -D -m755 ${./completion.bash} \ + $out/share/bash-completion/completions/home-manager + install -D -m755 ${./completion.zsh} \ + $out/share/zsh/site-functions/_home-manager +'' diff --git a/third_party/home-manager/home-manager/home-manager b/third_party/home-manager/home-manager/home-manager index 96de69148f..de521242ee 100644 --- a/third_party/home-manager/home-manager/home-manager +++ b/third_party/home-manager/home-manager/home-manager @@ -1,7 +1,7 @@ #!@bash@/bin/bash # Prepare to use tools from Nixpkgs. -PATH=@coreutils@/bin:@findutils@/bin:@gnused@/bin:@less@/bin${PATH:+:}$PATH +PATH=@coreutils@/bin:@findutils@/bin:@gnused@/bin:@less@/bin:@nixos-option@/bin${PATH:+:}$PATH set -euo pipefail @@ -74,7 +74,75 @@ function setHomeManagerNixPath() { done } +function setFlakeAttribute() { + local configFlake="${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/flake.nix" + if [[ -z $FLAKE_ARG && ! -v HOME_MANAGER_CONFIG && -e "$configFlake" ]]; then + FLAKE_ARG="$(dirname "$(readlink -f "$configFlake")")" + fi + + if [[ -n "$FLAKE_ARG" ]]; then + local flake="${FLAKE_ARG%#*}" + case $FLAKE_ARG in + *#*) + local name="${FLAKE_ARG#*#}" + ;; + *) + local name="$USER@$(hostname)" + if [ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$name\"")" = "false" ]; then + name="$USER" + fi + ;; + esac + export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$name\"" + fi +} + +function doInspectOption() { + setFlakeAttribute + if [[ -v FLAKE_CONFIG_URI ]]; then + errorEcho "Can't inspect options of a flake configuration" + exit 1 + fi + setConfigFile + setHomeManagerNixPath + + local extraArgs=("$@") + + for p in "${EXTRA_NIX_PATH[@]}"; do + extraArgs=("${extraArgs[@]}" "-I" "$p") + done + + if [[ -v VERBOSE ]]; then + extraArgs=("${extraArgs[@]}" "--show-trace") + fi + + local HOME_MANAGER_CONFIG_NIX HOME_MANAGER_CONFIG_ATTRIBUTE_NIX + HOME_MANAGER_CONFIG_NIX=${HOME_MANAGER_CONFIG//'\'/'\\'} + HOME_MANAGER_CONFIG_NIX=${HOME_MANAGER_CONFIG_NIX//'"'/'\"'} + HOME_MANAGER_CONFIG_NIX=${HOME_MANAGER_CONFIG_NIX//$'\n'/$'\\n'} + HOME_MANAGER_CONFIG_ATTRIBUTE_NIX=${HOME_MANAGER_CONFIG_ATTRIBUTE//'\'/'\\'} + HOME_MANAGER_CONFIG_ATTRIBUTE_NIX=${HOME_MANAGER_CONFIG_ATTRIBUTE_NIX//'"'/'\"'} + HOME_MANAGER_CONFIG_ATTRIBUTE_NIX=${HOME_MANAGER_CONFIG_ATTRIBUTE_NIX//$'\n'/$'\\n'} + local modulesExpr + modulesExpr="let confPath = \"${HOME_MANAGER_CONFIG_NIX}\"; " + modulesExpr+="confAttr = \"${HOME_MANAGER_CONFIG_ATTRIBUTE_NIX}\"; in " + modulesExpr+="(import {" + modulesExpr+=" configuration = if confAttr == \"\" then confPath else (import confPath).\${confAttr};" + modulesExpr+=" pkgs = import {}; check = true; })" + + nixos-option \ + --options_expr "$modulesExpr.options" \ + --config_expr "$modulesExpr.config" \ + "${extraArgs[@]}" \ + "${PASSTHROUGH_OPTS[@]}" +} + function doInstantiate() { + setFlakeAttribute + if [[ -v FLAKE_CONFIG_URI ]]; then + errorEcho "Can't instantiate a flake configuration" + exit 1 + fi setConfigFile setHomeManagerNixPath @@ -178,6 +246,17 @@ function doBuild() { return 1 fi + setFlakeAttribute + if [[ -v FLAKE_CONFIG_URI ]]; then + local exitCode=0 + nix build \ + "${PASSTHROUGH_OPTS[@]}" \ + ${DRY_RUN+--dry-run} \ + "$FLAKE_CONFIG_URI.activationPackage" \ + || exitCode=1 + return $exitCode + fi + setWorkDir local newsInfo @@ -194,6 +273,16 @@ function doBuild() { } function doSwitch() { + setFlakeAttribute + if [[ -v FLAKE_CONFIG_URI ]]; then + local exitCode=0 + nix run \ + "${PASSTHROUGH_OPTS[@]}" \ + "$FLAKE_CONFIG_URI.activationPackage" \ + || exitCode=1 + return $exitCode + fi + setWorkDir local newsInfo @@ -221,7 +310,7 @@ function doSwitch() { function doListGens() { # Whether to colorize the generations output. local color="never" - if [[ -t 1 ]]; then + if [[ ! -v NO_COLOR && -t 1 ]]; then color="always" fi @@ -409,22 +498,25 @@ function doHelp() { echo echo "Options" echo - echo " -f FILE The home configuration file." - echo " Default is '~/.config/nixpkgs/home.nix'." - echo " -A ATTRIBUTE Optional attribute that selects a configuration" - echo " expression in the configuration file." - echo " -I PATH Add a path to the Nix expression search path." - echo " -b EXT Move existing files to new path rather than fail." - echo " -v Verbose output" - echo " -n Do a dry run, only prints what actions would be taken" - echo " -h Print this help" + echo " -f FILE The home configuration file." + echo " Default is '~/.config/nixpkgs/home.nix'." + echo " -A ATTRIBUTE Optional attribute that selects a configuration" + echo " expression in the configuration file." + echo " -I PATH Add a path to the Nix expression search path." + echo " --flake flake-uri Use home-manager configuration at flake-uri" + echo " -b EXT Move existing files to new path rather than fail." + echo " -v Verbose output" + echo " -n Do a dry run, only prints what actions would be taken" + echo " -h Print this help" echo echo "Options passed on to nix-build(1)" echo + echo " --arg(str) NAME VALUE Override inputs passed to home-manager.nix" echo " --cores NUM" + echo " --debug" echo " --keep-failed" echo " --keep-going" - echo " --max-jobs NUM" + echo " -j, --max-jobs NUM" echo " --option NAME VALUE" echo " --show-trace" echo " --(no-)substitute" @@ -435,6 +527,9 @@ function doHelp() { echo echo " edit Open the home configuration in \$EDITOR" echo + echo " option OPTION.NAME" + echo " Inspect configuration option named OPTION.NAME." + echo echo " build Build configuration into result directory" echo echo " instantiate Instantiate the configuration and print the resulting derivation" @@ -466,12 +561,13 @@ HOME_MANAGER_CONFIG_ATTRIBUTE="" PASSTHROUGH_OPTS=() COMMAND="" COMMAND_ARGS=() +FLAKE_ARG="" while [[ $# -gt 0 ]]; do opt="$1" shift case $opt in - build|instantiate|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall) + build|instantiate|option|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall) COMMAND="$opt" ;; -A) @@ -490,6 +586,21 @@ while [[ $# -gt 0 ]]; do HOME_MANAGER_CONFIG="$1" shift ;; + --flake) + FLAKE_ARG="$1" + shift + ;; + --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file) + PASSTHROUGH_OPTS+=("$opt") + ;; + --update-input) + PASSTHROUGH_OPTS+=("$opt" "$1") + shift + ;; + --override-input) + PASSTHROUGH_OPTS+=("$opt" "$1" "$2") + shift 2 + ;; -h|--help) doHelp exit 0 @@ -497,24 +608,28 @@ while [[ $# -gt 0 ]]; do -n|--dry-run) export DRY_RUN=1 ;; - --option) + --option|--arg|--argstr) PASSTHROUGH_OPTS+=("$opt" "$1" "$2") shift 2 ;; - --max-jobs|--cores) + -j|--max-jobs|--cores) PASSTHROUGH_OPTS+=("$opt" "$1") shift ;; - --keep-failed|--keep-going|--show-trace\ + --debug|--keep-failed|--keep-going|--show-trace\ |--substitute|--no-substitute) PASSTHROUGH_OPTS+=("$opt") ;; -v|--verbose) export VERBOSE=1 ;; + --version) + echo 21.11 + exit 0 + ;; *) case $COMMAND in - expire-generations|remove-generations) + expire-generations|remove-generations|option) COMMAND_ARGS+=("$opt") ;; *) @@ -559,6 +674,9 @@ case $COMMAND in doExpireGenerations "${COMMAND_ARGS[@]}" fi ;; + option) + doInspectOption "${COMMAND_ARGS[@]}" + ;; packages) doListPackages ;; diff --git a/third_party/home-manager/home-manager/install.nix b/third_party/home-manager/home-manager/install.nix index 50b5ea16a4..2c1685389a 100644 --- a/third_party/home-manager/home-manager/install.nix +++ b/third_party/home-manager/home-manager/install.nix @@ -45,7 +45,7 @@ runCommand "home-manager-install" { # You can update Home Manager without changing this value. See # the Home Manager release notes for a list of state version # changes in each release. - home.stateVersion = "20.09"; + home.stateVersion = "21.11"; } EOF fi diff --git a/third_party/home-manager/modules/accounts/email.nix b/third_party/home-manager/modules/accounts/email.nix index 1e7aff9461..f922014958 100644 --- a/third_party/home-manager/modules/accounts/email.nix +++ b/third_party/home-manager/modules/accounts/email.nix @@ -332,7 +332,10 @@ let (mkIf (config.flavor == "gmail.com") { userName = mkDefault config.address; - imap = { host = "imap.gmail.com"; }; + imap = { + host = "imap.gmail.com"; + port = 993; + }; smtp = { host = "smtp.gmail.com"; diff --git a/third_party/home-manager/modules/config/i18n.nix b/third_party/home-manager/modules/config/i18n.nix new file mode 100644 index 0000000000..9fca360da1 --- /dev/null +++ b/third_party/home-manager/modules/config/i18n.nix @@ -0,0 +1,46 @@ +# The glibc package in Nixpkgs is patched to make it possible to specify +# an alternative path for the locale archive through a special environment +# variable. This would allow different versions of glibc to coexist on the +# same system because each version of glibc could look up different paths +# for its locale archive should the archive format ever change in +# incompatible ways. +# +# See also: +# - localedef(1) +# - https://nixos.org/manual/nixpkgs/stable/#locales +# - https://github.com/NixOS/nixpkgs/issues/38991 +# +# Note, the name of the said environment variable gets updated with each +# breaking release of the glibcLocales package. Periodically check the link +# below for changes: +# https://github.com/NixOS/nixpkgs/blob/nixpkgs-unstable/pkgs/development/libraries/glibc/nix-locale-archive.patch + +{ lib, pkgs, ... }: + +with lib; + +let + + inherit (pkgs.glibcLocales) version; + + archivePath = "${pkgs.glibcLocales}/lib/locale/locale-archive"; + + # lookup the version of glibcLocales and set the appropriate environment vars + localeVars = if versionAtLeast version "2.27" then { + LOCALE_ARCHIVE_2_27 = archivePath; + } else if versionAtLeast version "2.11" then { + LOCALE_ARCHIVE_2_11 = archivePath; + } else + { }; + +in { + meta.maintainers = with maintainers; [ midchildan ]; + + config = { + # For shell sessions. + home.sessionVariables = localeVars; + + # For desktop apps. + systemd.user.sessionVariables = localeVars; + }; +} diff --git a/third_party/home-manager/modules/default.nix b/third_party/home-manager/modules/default.nix index 7f3494e4de..a138dc2c94 100644 --- a/third_party/home-manager/modules/default.nix +++ b/third_party/home-manager/modules/default.nix @@ -1,9 +1,11 @@ { configuration , pkgs -, lib ? pkgs.stdenv.lib +, lib ? pkgs.lib # Whether to check that each option has a matching declaration. , check ? true + # Extra arguments passed to specialArgs. +, extraSpecialArgs ? { } }: with lib; @@ -31,7 +33,7 @@ let modules = [ configuration ] ++ hmModules; specialArgs = { modulesPath = builtins.toString ./.; - }; + } // extraSpecialArgs; }; module = showWarnings ( diff --git a/third_party/home-manager/modules/files.nix b/third_party/home-manager/modules/files.nix index 09ecf71549..1ecc182177 100644 --- a/third_party/home-manager/modules/files.nix +++ b/third_party/home-manager/modules/files.nix @@ -39,6 +39,28 @@ in }; config = { + assertions = [( + let + dups = + attrNames + (filterAttrs (n: v: v > 1) + (foldAttrs (acc: v: acc + v) 0 + (mapAttrsToList (n: v: { ${v.target} = 1; }) cfg))); + dupsStr = concatStringsSep ", " dups; + in { + assertion = dups == []; + message = '' + Conflicting managed target files: ${dupsStr} + + This may happen, for example, if you have a configuration similar to + + home.file = { + conflict1 = { source = ./foo.nix; target = "baz"; }; + conflict2 = { source = ./bar.nix; target = "baz"; }; + }''; + }) + ]; + lib.file.mkOutOfStoreSymlink = path: let pathStr = toString path; @@ -53,7 +75,7 @@ in # Paths that should be forcibly overwritten by Home Manager. # Caveat emptor! forcedPaths = - concatMapStringsSep " " (p: ''"$HOME/${p}"'') + concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'') (mapAttrsToList (n: v: v.target) (filterAttrs (n: v: v.force) cfg)); @@ -62,7 +84,7 @@ in # A symbolic link whose target path matches this pattern will be # considered part of a Home Manager generation. - homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*" + homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*" forcedPaths=(${forcedPaths}) @@ -140,7 +162,7 @@ in # source and target generation. home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] ( let - link = pkgs.writeText "link" '' + link = pkgs.writeShellScript "link" '' newGenFiles="$1" shift for sourcePath in "$@" ; do @@ -155,12 +177,12 @@ in done ''; - cleanup = pkgs.writeText "cleanup" '' + cleanup = pkgs.writeShellScript "cleanup" '' . ${./lib-bash/color-echo.sh} # A symbolic link whose target path matches this pattern will be # considered part of a Home Manager generation. - homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*" + homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*" newGenFiles="$1" shift 1 @@ -235,18 +257,34 @@ in ); home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] ( - '' + let + homeDirArg = escapeShellArg homeDirectory; + in '' + function _cmp() { + if [[ -d $1 && -d $2 ]]; then + diff -rq "$1" "$2" &> /dev/null + else + cmp --quiet "$1" "$2" + fi + } declare -A changedFiles - '' + concatMapStrings (v: '' - cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \ - && changedFiles["${v.target}"]=0 \ - || changedFiles["${v.target}"]=1 - '') (filter (v: v.onChange != "") (attrValues cfg)) + '' + concatMapStrings (v: + let + sourceArg = escapeShellArg (sourceStorePath v); + targetArg = escapeShellArg v.target; + in '' + _cmp ${sourceArg} ${homeDirArg}/${targetArg} \ + && changedFiles[${targetArg}]=0 \ + || changedFiles[${targetArg}]=1 + '') (filter (v: v.onChange != "") (attrValues cfg)) + + '' + unset -f _cmp + '' ); home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] ( concatMapStrings (v: '' - if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then + if [[ ''${changedFiles[${escapeShellArg v.target}]} -eq 1 ]]; then ${v.onChange} fi '') (filter (v: v.onChange != "") (attrValues cfg)) @@ -254,12 +292,10 @@ in # Symlink directories and files that have the right execute bit. # Copy files that need their execute bit changed. - home-files = pkgs.runCommand + home-files = pkgs.runCommandLocal "home-manager-files" { nativeBuildInputs = [ pkgs.xorg.lndir ]; - preferLocalBuild = true; - allowSubstitutes = false; } ('' mkdir -p $out @@ -273,6 +309,15 @@ in local executable="$3" local recursive="$4" + # If the target already exists then we have a collision. Note, this + # should not happen due to the assertion found in the 'files' module. + # We therefore simply log the conflict and otherwise ignore it, mainly + # to make the `files-target-config` test work as expected. + if [[ -e "$realOut/$relTarget" ]]; then + echo "File conflict for file '$relTarget'" >&2 + return + fi + # Figure out the real absolute path to the target. local target target="$(realpath -m "$realOut/$relTarget")" diff --git a/third_party/home-manager/modules/home-environment.nix b/third_party/home-manager/modules/home-environment.nix index e5b6cc3a6e..872fcd8ff5 100644 --- a/third_party/home-manager/modules/home-environment.nix +++ b/third_party/home-manager/modules/home-environment.nix @@ -390,6 +390,21 @@ in Extra commands to run in the Home Manager profile builder. ''; }; + + home.enableNixpkgsReleaseCheck = mkOption { + type = types.bool; + default = true; + description = '' + Determines whether to check for release version mismatch between Home + Manager and Nixpkgs. Using mismatched versions is likely to cause errors + and unexpected behavior. It is therefore highly recommended to use a + release of Home Manager than corresponds with your chosen release of + Nixpkgs. + + When this option is enabled and a mismatch is detected then a warning + will be printed when the user configuration is being built. + ''; + }; }; config = { @@ -404,6 +419,31 @@ in } ]; + warnings = + let + hmRelease = fileContents ../.release; + nixpkgsRelease = pkgs.lib.trivial.release; + releaseMismatch = + config.home.enableNixpkgsReleaseCheck + && hmRelease != nixpkgsRelease; + in + optional releaseMismatch '' + You are using + + Home Manager version ${hmRelease} and + Nixpkgs version ${nixpkgsRelease}. + + Using mismatched versions is likely to cause errors and unexpected + behavior. It is therefore highly recommended to use a release of Home + Manager than corresponds with your chosen release of Nixpkgs. + + If you insist then you can disable this warning by adding + + home.enableNixpkgsReleaseCheck = false; + + to your configuration. + ''; + home.username = mkIf (versionOlder config.home.stateVersion "20.09") (mkDefault (builtins.getEnv "USER")); @@ -493,7 +533,24 @@ in '' else '' - $DRY_RUN_CMD nix-env -i ${cfg.path} + if ! $DRY_RUN_CMD nix-env -i ${cfg.path} ; then + cat < $out/etc/gtk-2.0/immodules.cache + ''; + + gtk3Cache = pkgs.runCommandLocal "gtk3-immodule.cache" { + buildInputs = [ pkgs.gtk3 cfg.package ]; + } '' + mkdir -p $out/etc/gtk-3.0/ + GTK_PATH=${cfg.package}/lib/gtk-3.0/ \ + gtk-query-immodules-3.0 > $out/etc/gtk-3.0/immodules.cache + ''; + +in { + imports = + [ ./fcitx.nix ./fcitx5.nix ./hime.nix ./kime.nix ./nabi.nix ./uim.nix ]; + + options.i18n = { + inputMethod = { + enabled = mkOption { + type = types.nullOr + (types.enum [ "fcitx" "fcitx5" "nabi" "uim" "hime" "kime" ]); + default = null; + example = "fcitx"; + description = '' + Select the enabled input method. Input methods is a software to input + symbols that are not available on standard input devices. + + Input methods are specially used to input Chinese, Japanese and Korean + characters. + + Currently the following input methods are available in Home Manager: + + + + fcitx + + A customizable lightweight input method + extra input engines can be added using + i18n.inputMethod.fcitx.engines. + + + + fcitx5 + + The next generation of fcitx, + addons (including engines, dictionaries, skins) can be added using + i18n.inputMethod.fcitx5.addons. + + + + nabi + + A Korean input method based on XIM. Nabi doesn't support Qt 5. + + + + uim + + The universal input method, is a library with a XIM bridge. + uim mainly support Chinese, Japanese and Korean. + + + + hime + An extremely easy-to-use input method framework. + + + kime + A Korean IME. + + + ''; + }; + + package = mkOption { + internal = true; + type = types.nullOr types.path; + default = null; + description = '' + The input method method package. + ''; + }; + }; + }; + + config = mkIf (cfg.enabled != null) { + home.packages = [ cfg.package gtk2Cache gtk3Cache ]; + }; + + meta.maintainers = with lib; [ hm.maintainers.kranzes ]; +} diff --git a/third_party/home-manager/modules/i18n/input-method/fcitx.nix b/third_party/home-manager/modules/i18n/input-method/fcitx.nix new file mode 100644 index 0000000000..b04382a787 --- /dev/null +++ b/third_party/home-manager/modules/i18n/input-method/fcitx.nix @@ -0,0 +1,50 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.i18n.inputMethod.fcitx; + fcitxPackage = pkgs.fcitx.override { plugins = cfg.engines; }; + fcitxEngine = types.package // { + name = "fcitx-engine"; + check = x: + types.package.check x && attrByPath [ "meta" "isFcitxEngine" ] false x; + }; +in { + options = { + + i18n.inputMethod.fcitx = { + engines = mkOption { + type = with types; listOf fcitxEngine; + default = [ ]; + example = literalExample "with pkgs.fcitx-engines; [ mozc hangul ]"; + description = let + enginesDrv = filterAttrs (const isDerivation) pkgs.fcitx-engines; + engines = concatStringsSep ", " + (map (name: "${name}") (attrNames enginesDrv)); + in "Enabled Fcitx engines. Available engines are: ${engines}."; + }; + }; + + }; + + config = mkIf (config.i18n.inputMethod.enabled == "fcitx") { + i18n.inputMethod.package = fcitxPackage; + + home.sessionVariables = { + GTK_IM_MODULE = "fcitx"; + QT_IM_MODULE = "fcitx"; + XMODIFIERS = "@im=fcitx"; + }; + + systemd.user.services.fcitx-daemon = { + Unit = { + Description = "Fcitx input method editor"; + PartOf = [ "graphical-session.desktop" ]; + }; + Service.ExecStart = "${fcitxPackage}/bin/fcitx"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/third_party/home-manager/modules/i18n/input-method/fcitx5.nix b/third_party/home-manager/modules/i18n/input-method/fcitx5.nix new file mode 100644 index 0000000000..29b0ed5580 --- /dev/null +++ b/third_party/home-manager/modules/i18n/input-method/fcitx5.nix @@ -0,0 +1,42 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + im = config.i18n.inputMethod; + cfg = im.fcitx5; + fcitx5Package = pkgs.fcitx5-with-addons.override { inherit (cfg) addons; }; +in { + options = { + i18n.inputMethod.fcitx5 = { + addons = mkOption { + type = with types; listOf package; + default = [ ]; + example = literalExample "with pkgs; [ fcitx5-rime ]"; + description = '' + Enabled Fcitx5 addons. + ''; + }; + }; + }; + + config = mkIf (im.enabled == "fcitx5") { + i18n.inputMethod.package = fcitx5Package; + + home.sessionVariables = { + GTK_IM_MODULE = "fcitx"; + QT_IM_MODULE = "fcitx"; + XMODIFIERS = "@im=fcitx"; + }; + + systemd.user.services.fcitx5-daemon = { + Unit = { + Description = "Fcitx5 input method editor"; + PartOf = [ "graphical-session.target" ]; + }; + Service.ExecStart = "${fcitx5Package}/bin/fcitx5"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/third_party/home-manager/modules/i18n/input-method/hime.nix b/third_party/home-manager/modules/i18n/input-method/hime.nix new file mode 100644 index 0000000000..7b5700a9db --- /dev/null +++ b/third_party/home-manager/modules/i18n/input-method/hime.nix @@ -0,0 +1,23 @@ +{ config, pkgs, lib, ... }: + +with lib; { + config = mkIf (config.i18n.inputMethod.enabled == "hime") { + i18n.inputMethod.package = pkgs.hime; + + home.sessionVariables = { + GTK_IM_MODULE = "hime"; + QT_IM_MODULE = "hime"; + XMODIFIERS = "@im=hime"; + }; + + systemd.user.services.hime-daemon = { + Unit = { + Description = "Hime input method editor"; + PartOf = [ "graphical-session.desktop" ]; + }; + Service.ExecStart = "${pkgs.hime}/bin/hime"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/third_party/home-manager/modules/i18n/input-method/kime.nix b/third_party/home-manager/modules/i18n/input-method/kime.nix new file mode 100644 index 0000000000..b948a99d41 --- /dev/null +++ b/third_party/home-manager/modules/i18n/input-method/kime.nix @@ -0,0 +1,58 @@ +{ config, pkgs, lib, generators, ... }: +with lib; +let + cfg = config.i18n.inputMethod.kime; + yamlFormat = pkgs.formats.yaml { }; +in { + options = { + i18n.inputMethod.kime = { + config = mkOption { + type = yamlFormat.type; + default = { }; + example = literalExample '' + { + daemon = { + modules = ["Xim" "Indicator"]; + }; + + indicator = { + icon_color = "White"; + }; + + engine = { + hangul = { + layout = "dubeolsik"; + }; + }; + } + ''; + description = '' + kime configuration. Refer to + + for details on supported values. + ''; + }; + }; + }; + + config = mkIf (config.i18n.inputMethod.enabled == "kime") { + i18n.inputMethod.package = pkgs.kime; + + home.sessionVariables = { + GTK_IM_MODULE = "kime"; + QT_IM_MODULE = "kime"; + XMODIFIERS = "@im=kime"; + }; + + xdg.configFile."kime/config.yaml".text = + replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.config); + + systemd.user.services.kime-daemon = { + Unit = { Description = "Kime input method editor"; }; + PartOf = [ "graphical-session.target" ]; + Service.ExecStart = "${pkgs.kime}/bin/kime"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/third_party/home-manager/modules/i18n/input-method/nabi.nix b/third_party/home-manager/modules/i18n/input-method/nabi.nix new file mode 100644 index 0000000000..01f9f7911e --- /dev/null +++ b/third_party/home-manager/modules/i18n/input-method/nabi.nix @@ -0,0 +1,23 @@ +{ config, pkgs, lib, ... }: + +with lib; { + config = mkIf (config.i18n.inputMethod.enabled == "nabi") { + i18n.inputMethod.package = pkgs.nabi; + + home.sessionVariables = { + GTK_IM_MODULE = "nabi"; + QT_IM_MODULE = "nabi"; + XMODIFIERS = "@im=nabi"; + }; + + systemd.user.services.nabi-daemon = { + Unit = { + Description = "Nabi input method editor"; + PartOf = [ "graphical-session.desktop" ]; + }; + Service.ExecStart = "${pkgs.nabi}/bin/nabi"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/third_party/home-manager/modules/i18n/input-method/uim.nix b/third_party/home-manager/modules/i18n/input-method/uim.nix new file mode 100644 index 0000000000..e7890352c9 --- /dev/null +++ b/third_party/home-manager/modules/i18n/input-method/uim.nix @@ -0,0 +1,45 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let cfg = config.i18n.inputMethod.uim; +in { + options = { + + i18n.inputMethod.uim = { + toolbar = mkOption { + type = types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt4" ]; + default = "gtk"; + example = "gtk-systray"; + description = '' + Selected UIM toolbar. + ''; + }; + }; + + }; + + config = mkIf (config.i18n.inputMethod.enabled == "uim") { + i18n.inputMethod.package = pkgs.uim; + + home.sessionVariables = { + GTK_IM_MODULE = "uim"; + QT_IM_MODULE = "uim"; + XMODIFIERS = "@im=uim"; + }; + + systemd.user.services.uim-daemon = { + Unit = { + Description = "Uim input method editor"; + PartOf = [ "graphical-session.desktop" ]; + }; + Service.ExecStart = toString + (pkgs.writeShellScript "start-uim-xim-and-uim-toolbar" '' + ${pkgs.uim}/bin/uim-xim & + ${pkgs.uim}/bin/uim-toolbar-${cfg.toolbar} + ''); + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/third_party/home-manager/modules/lib-bash/color-echo.sh b/third_party/home-manager/modules/lib-bash/color-echo.sh index ef708b29c4..ac36cedc6e 100644 --- a/third_party/home-manager/modules/lib-bash/color-echo.sh +++ b/third_party/home-manager/modules/lib-bash/color-echo.sh @@ -1,5 +1,7 @@ # The check for terminal output and color support is heavily inspired # by https://unix.stackexchange.com/a/10065. +# +# Allow opt out by respecting the `NO_COLOR` environment variable. function setupColors() { normalColor="" @@ -7,8 +9,8 @@ function setupColors() { warnColor="" noteColor="" - # Check if stdout is a terminal. - if [[ -t 1 ]]; then + # Enable colors for terminals, and allow opting out. + if [[ ! -v NO_COLOR && -t 1 ]]; then # See if it supports colors. local ncolors ncolors=$(tput colors) diff --git a/third_party/home-manager/modules/lib/file-type.nix b/third_party/home-manager/modules/lib/file-type.nix index 56a3a1286a..71babc79aa 100644 --- a/third_party/home-manager/modules/lib/file-type.nix +++ b/third_party/home-manager/modules/lib/file-type.nix @@ -82,6 +82,9 @@ with lib; generations. The script will be run after the new files have been linked into place. + + Note, this code is always run when recursive is + enabled. ''; }; diff --git a/third_party/home-manager/modules/lib/maintainers.nix b/third_party/home-manager/modules/lib/maintainers.nix index f70913bcb4..d091b28a46 100644 --- a/third_party/home-manager/modules/lib/maintainers.nix +++ b/third_party/home-manager/modules/lib/maintainers.nix @@ -25,10 +25,94 @@ github = "cwyc"; githubId = 16950437; }; + chisui = { + name = "Philipp Dargel"; + email = "chisui@users.noreply.github.com"; + github = "chisui"; + githubId = 4526429; + }; olmokramer = { name = "Olmo Kramer"; email = "olmokramer@users.noreply.github.com"; github = "olmokramer"; githubId = 3612514; }; + kalhauge = { + name = "Christian Gram Kalhauge"; + email = "kalhauge@users.noreply.github.com"; + github = "kalhauge"; + githubId = 1182166; + }; + kamadorueda = { + name = "Kevin Amado"; + email = "kamadorueda@gmail.com"; + github = "kamadorueda"; + githubId = 47480384; + keys = [{ + longkeyid = "rsa4096/0x04D0CEAF916A9A40"; + fingerprint = "2BE3 BAFD 793E A349 ED1F F00F 04D0 CEAF 916A 9A40"; + }]; + }; + kubukoz = { + name = "Jakub Kozłowski"; + email = "kubukoz@users.noreply.github.com"; + github = "kubukoz"; + githubId = 894884; + }; + matrss = { + name = "Matthias Riße"; + email = "matrss@users.noreply.github.com"; + github = "matrss"; + githubId = 9308656; + }; + seylerius = { + email = "sable@seyleri.us"; + name = "Sable Seyler"; + github = "seylerius"; + githubId = 1145981; + keys = [{ + logkeyid = "rsa4096/0x68BF2EAE6D91CAFF"; + fingerprint = "F0E0 0311 126A CD72 4392 25E6 68BF 2EAE 6D91 CAFF"; + }]; + }; + thiagokokada = { + email = "thiagokokada@gmail.com"; + name = "Thiago Kenji Okada"; + github = "thiagokokada"; + githubId = 844343; + }; + fendse = { + email = "46252070+Fendse@users.noreply.github.com"; + github = "Fendse"; + githubId = 46252070; + name = "Sara Johnsson"; + }; + msfjarvis = { + email = "me@msfjarvis.dev"; + github = "msfjarvis"; + githubId = "13348378"; + name = "Harsh Shandilya"; + keys = [{ + longkeyid = "rsa4096/0xB7843F823355E9B9"; + fingerprint = "8F87 050B 0F9C B841 1515 7399 B784 3F82 3355 E9B9"; + }]; + }; + ambroisie = { + email = "bruno.home-manager@belanyi.fr"; + github = "ambroisie"; + githubId = 12465195; + name = "Bruno BELANYI"; + }; + malvo = { + email = "malte@malvo.org"; + github = "malte-v"; + githubId = 34393802; + name = "Malte Voos"; + }; + kranzes = { + email = "personal@ilanjoselevich.com"; + github = "Kranzes"; + githubId = 56614642; + name = "Ilan Joselevich"; + }; } diff --git a/third_party/home-manager/modules/lib/types.nix b/third_party/home-manager/modules/lib/types.nix index 64a6b4a34f..a7d1dd2154 100644 --- a/third_party/home-manager/modules/lib/types.nix +++ b/third_party/home-manager/modules/lib/types.nix @@ -47,9 +47,18 @@ in rec { name = mkOption { type = types.str; - example = "DejaVu Sans 8"; + example = "DejaVu Sans"; description = '' - The family name and size of the font within the package. + The family name of the font within the package. + ''; + }; + + size = mkOption { + type = types.nullOr types.int; + default = null; + example = "8"; + description = '' + The size of the font. ''; }; }; diff --git a/third_party/home-manager/modules/misc/dconf.nix b/third_party/home-manager/modules/misc/dconf.nix index 5fc7748a76..e8a04de0a3 100644 --- a/third_party/home-manager/modules/misc/dconf.nix +++ b/third_party/home-manager/modules/misc/dconf.nix @@ -8,12 +8,9 @@ let toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; }; - mkIniKeyValue = key: value: - "${key}=${toString (hm.gvariant.mkValue value)}"; + mkIniKeyValue = key: value: "${key}=${toString (hm.gvariant.mkValue value)}"; -in - -{ +in { meta.maintainers = [ maintainers.gnidorah maintainers.rycee ]; options = { @@ -29,7 +26,7 @@ in settings = mkOption { type = with types; attrsOf (attrsOf hm.types.gvariant); - default = {}; + default = { }; example = literalExample '' { "org/gnome/calculator" = { @@ -48,26 +45,26 @@ in }; }; - config = mkIf (cfg.enable && cfg.settings != {}) { - home.activation.dconfSettings = hm.dag.entryAfter ["installPackages"] ( - let - iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings); - in - '' - if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then - DCONF_DBUS_RUN_SESSION="" - else - DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session" - fi + config = mkIf (cfg.enable && cfg.settings != { }) { + # Make sure the dconf directory exists. + xdg.configFile."dconf/.keep".source = builtins.toFile "keep" ""; - if [[ -v DRY_RUN ]]; then - echo $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / "<" ${iniFile} - else - $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile} - fi + home.activation.dconfSettings = hm.dag.entryAfter [ "installPackages" ] + (let iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings); + in '' + if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then + DCONF_DBUS_RUN_SESSION="" + else + DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session" + fi - unset DCONF_DBUS_RUN_SESSION - '' - ); + if [[ -v DRY_RUN ]]; then + echo $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / "<" ${iniFile} + else + $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile} + fi + + unset DCONF_DBUS_RUN_SESSION + ''); }; } diff --git a/third_party/home-manager/modules/misc/gtk.nix b/third_party/home-manager/modules/misc/gtk.nix index bf25aaaf66..db0a8e7a36 100644 --- a/third_party/home-manager/modules/misc/gtk.nix +++ b/third_party/home-manager/modules/misc/gtk.nix @@ -33,7 +33,7 @@ let package = mkOption { type = types.nullOr types.package; default = null; - example = literalExample "pkgs.gnome3.gnome_themes_standard"; + example = literalExample "pkgs.gnome.gnome_themes_standard"; description = '' Package providing the theme. This package will be installed to your profile. If null then the theme @@ -92,6 +92,18 @@ in { ~/.gtkrc-2.0. ''; }; + + configLocation = mkOption { + type = types.path; + default = "${config.home.homeDirectory}/.gtkrc-2.0"; + defaultText = + literalExample ''"''${config.home.homeDirectory}/.gtkrc-2.0"''; + example = + literalExample ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"''; + description = '' + The location to put the GTK configuration file. + ''; + }; }; gtk3 = { @@ -128,14 +140,22 @@ in { }; config = mkIf cfg.enable (let - ini = optionalAttrs (cfg.font != null) { gtk-font-name = cfg.font.name; } - // optionalAttrs (cfg.theme != null) { gtk-theme-name = cfg.theme.name; } + ini = optionalAttrs (cfg.font != null) { + gtk-font-name = let + fontSize = + optionalString (cfg.font.size != null) " ${toString cfg.font.size}"; + in "${cfg.font.name}" + fontSize; + } // optionalAttrs (cfg.theme != null) { gtk-theme-name = cfg.theme.name; } // optionalAttrs (cfg.iconTheme != null) { gtk-icon-theme-name = cfg.iconTheme.name; }; - dconfIni = optionalAttrs (cfg.font != null) { font-name = cfg.font.name; } - // optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; } + dconfIni = optionalAttrs (cfg.font != null) { + font-name = let + fontSize = + optionalString (cfg.font.size != null) " ${toString cfg.font.size}"; + in "${cfg.font.name}" + fontSize; + } // optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; } // optionalAttrs (cfg.iconTheme != null) { icon-theme = cfg.iconTheme.name; }; @@ -146,10 +166,12 @@ in { home.packages = optionalPackage cfg.font ++ optionalPackage cfg.theme ++ optionalPackage cfg.iconTheme; - home.file.".gtkrc-2.0".text = + home.file.${cfg2.configLocation}.text = concatStringsSep "\n" (mapAttrsToList formatGtk2Option ini) + "\n" + cfg2.extraConfig; + home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation; + xdg.configFile."gtk-3.0/settings.ini".text = toGtk3Ini { Settings = ini // cfg3.extraConfig; }; diff --git a/third_party/home-manager/modules/misc/news.nix b/third_party/home-manager/modules/misc/news.nix index 3e5d8d5299..6e88b62466 100644 --- a/third_party/home-manager/modules/misc/news.nix +++ b/third_party/home-manager/modules/misc/news.nix @@ -116,6 +116,9 @@ in # # date --iso-8601=second --universal # + # On darwin (or BSD like systems) use + # + # date -u +'%Y-%m-%dT%H:%M:%S+00:00' news.entries = [ { time = "2017-09-01T10:56:28+00:00"; @@ -1720,6 +1723,401 @@ in A new module is available: 'programs.gh'. ''; } + + { + time = "2020-11-01T11:17:02+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.caffeine'. + ''; + } + + { + time = "2020-11-05T22:59:21+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.i3status-rust'. + ''; + } + + { + time = "2020-11-14T13:02:40+00:00"; + condition = config.programs.broot.enable; + message = '' + The 'programs.broot.verbs' option is now a list rather than an + attribute set. To migrate, move the keys of the attrset into the + list items' 'invocation' keys. For example, + + programs.broot.verbs = { + "p" = { execution = ":parent"; }; + }; + + becomes + + programs.broot.verbs = [ + { + invocation = "p"; + execution = ":parent"; + } + ]; + ''; + } + + { + time = "2020-12-01T20:46:14+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.wlsunset'. + ''; + } + + { + time = "2020-12-09T22:34:33+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.pbgopy'. + ''; + } + + { + time = "2020-12-18T22:22:25+00:00"; + message = '' + A new module is available: 'programs.rofi.pass'. + ''; + } + + { + time = "2020-12-31T14:16:47+00:00"; + message = '' + A new module is available: 'programs.octant'. + ''; + } + + { + time = "2021-01-01T08:51:11+00:00"; + condition = config.pam.sessionVariables != {}; + message = '' + The option 'pam.sessionVariables' will be deprecated in the future. + This is due to PAM 1.5.0 deprecating reading of the user environment. + The deprecation will not take place immediately but you may wish to + consider alternatives to PAM environment variables. + + See + + https://github.com/nix-community/home-manager/issues/1691 + + for discussion. + ''; + } + + { + time = "2021-01-02T07:49:15+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.plan9port'. + ''; + } + + { + time = "2021-01-31T11:23:30+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.playerctld'. + ''; + } + + { + time = "2021-01-28T15:07:34+00:00"; + condition = hostPlatform.isDarwin; + message = '' + New options are available for 'targets.darwin': + + - targets.darwin.defaults + + This adds options for configuring macOS through the defaults(1) + system. + + - targets.darwin.keybindings + + This adds options for configuring the default keybindings for macOS + text fields. + + - targets.darwin.search + + This adds options for configuring the default search engine for + macOS. + ''; + } + + { + time = "2021-02-04T22:28:26+00:00"; + message = '' + A new module is available: 'programs.sbt'. + ''; + } + + { + time = "2021-02-20T00:00:00+00:00"; + condition = config.services.polybar.enable; + message = '' + The polybar configuration can now be written in a more nix-friendly format. + The new 'services.polybar.settings' option is an alternative to + 'services.polybar.config' that supports nested keys and converts nix + lists to polybar-style 'foo-0, foo-1, ...' lists. + ''; + } + + { + time = "2021-02-25T22:36:43+00:00"; + condition = config.programs.git.enable && any (msmtp: msmtp.enable) + (mapAttrsToList (name: account: account.msmtp) + config.accounts.email.accounts); + message = '' + Git will now defer to msmtp for sending emails if + 'accounts.email.accounts..msmtp.enable' is true. + ''; + } + + { + time = "2021-03-03T22:16:05+00:00"; + message = '' + Home Manager now respects the 'NO_COLOR' environment variable as per + https://no-color.org/. + ''; + } + + { + time = "2021-03-29T21:05:50+00:00"; + message = '' + Configuration specified by 'programs.dircolors.extraConfig' is now + applied after 'programs.dircolors.settings'. + ''; + } + + { + time = "2021-04-11T20:44:54+00:00"; + message = '' + A new module is available: 'programs.exa'. + ''; + } + + { + time = "2021-04-23T10:00:00+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.pass-secret-service'. + ''; + } + + { + time = "2021-04-26T07:00:00+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new service is available: 'services.poweralertd'. + ''; + } + + { + time = "2021-04-28T10:00:00+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new service is available: 'services.mpris-proxy'. + ''; + } + + { + time = "2021-04-28T12:00:00+00:00"; + message = '' + A new module is available: 'programs.topgrade'. + ''; + } + + { + time = "2021-04-30T22:05:01+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new service is available: 'services.barrier'. + ''; + } + + { + time = "2021-05-01T15:16:08+00:00"; + message = '' + A new module is available: 'programs.lazygit'. + ''; + } + + { + time = "2021-04-27T00:00:00+00:00"; + message = '' + A new module is available: 'programs.ncspot'. + ''; + } + + { + time = "2021-05-02T11:22:42+00:00"; + condition = hostPlatform.isLinux && config.services.sxhkd.enable; + message = '' + The sxhkd service now is started using 'xsession.initExtra', + therefore this module loses systemd service management capabilities + and works only if Home Manager starts the user X session. + + The option 'services.sxhkd.extraPath' has been deprecated. + ''; + } + + { + time = "2021-05-06T20:47:37+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.etesync-dav' + ''; + } + + { + time = "2021-05-06T11:01:41+00:00"; + message = '' + A new module is available: 'programs.nix-index'. + ''; + } + + { + time = "2021-05-10T18:50:07+00:00"; + message = '' + A new module is available: 'xdg.systemDirs'. Options are: + + - xdg.systemDirs.config + + Extra directory names to add to $XDG_CONFIG_DIRS in the user + session. + + - xdg.systemDirs.data + + Extra directory names to add to $XDG_DATA_DIRS in the user + session. + + These variables are visible in both systemd user services and + login shells. + ''; + } + + { + time = "2021-05-18T12:22:42+00:00"; + condition = config.services.syncthing != {}; + message = '' + Setting 'services.syncthing.tray' as a boolean will be deprecated in + the future. + + This is to make the syncthing tray package configurable, with + `services.syncthing.tray.package`, following QSyncthingTray becoming + no longer actively maintained. The default syncthing tray package has + also changed to https://github.com/Martchus/syncthingtray. To + continue as before, set `services.syncthing.tray.enable`. + + See + + https://github.com/nix-community/home-manager/pull/1257 + + for discussion. + ''; + } + + { + time = "2021-05-18T20:28:50+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.foot'. + ''; + } + + { + time = "2021-05-23T18:31:38+00:00"; + condition = config.programs.mbsync.enable; + message = '' + mbsync channels no longer accepts the masterPattern or slavePattern + attribute keys. This is due to an upstream change. + They have been renamed: masterPattern -> farPattern, and + slavePattern -> nearPattern. + This is a stateful change, where the database file(s) used to keep track + of mail are silently upgraded once you upgrade both your configuration file + and the mbsync program. + + Note that this change is non-reversible, meaning once you choose to switch to + near/farPattern, you can no longer use your previous slave/masterPattern + configuration file. + ''; + } + + { + time = "2021-05-10T20:41:44+00:00"; + message = '' + A new module is available: 'programs.rbw'. + ''; + } + + { + time = "2021-05-30T15:22:10+00:00"; + message = '' + A new module is available: 'programs.piston-cli'. + ''; + } + + { + time = "2021-06-02T04:24:10+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.xidlehook'. + ''; + } + + { + time = "2021-06-07T20:44:00+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.pantalaimon'. + ''; + } + + { + time = "2021-06-12T05:00:22+00:00"; + message = '' + A new module is available: 'programs.mangohud'. + ''; + } + + { + time = "2021-06-16T01:26:16+00:00"; + condition = hostPlatform.isLinux; + message = '' + The xmonad module now compiles the configuration before + linking the binary to the place xmonad expects to find + the compiled configuration (the binary). + + This breaks recompilation of xmonad (i.e. the 'q' binding or + 'xmonad --recompile'). + + If this behavior is undesirable, do not use the + 'xsession.windowManager.xmonad.config' option. Instead, set the + contents of the configuration file with + 'home.file.".xmonad/config.hs".text = "content of the file"' + or 'home.file.".xmonad/config.hs".source = ./path-to-config'. + ''; + } + + { + time = "2021-06-24T22:36:11+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'i18n.inputMethod'. + ''; + } + + { + time = "2021-06-22T14:43:53+00:00"; + message = '' + A new module is available: 'programs.himalaya'. + ''; + } ]; }; } diff --git a/third_party/home-manager/modules/misc/pam.nix b/third_party/home-manager/modules/misc/pam.nix index f54f4b9508..c94efb5067 100644 --- a/third_party/home-manager/modules/misc/pam.nix +++ b/third_party/home-manager/modules/misc/pam.nix @@ -21,6 +21,9 @@ in { pam_env.conf 5 . + + Note, this option will become deprecated in the future and its use is + therefore discouraged. ''; }; }; diff --git a/third_party/home-manager/modules/misc/qt.nix b/third_party/home-manager/modules/misc/qt.nix index ff38f842c8..1fdaf9f9b9 100644 --- a/third_party/home-manager/modules/misc/qt.nix +++ b/third_party/home-manager/modules/misc/qt.nix @@ -44,19 +44,72 @@ in { ''; }; + + style = { + name = mkOption { + type = types.nullOr types.str; + default = null; + example = "adwaita-dark"; + relatedPackages = [ "adwaita-qt" [ "libsForQt5" "qtstyleplugins" ] ]; + description = '' + Selects the style to use for Qt5 applications. + The options are + + + adwaita + adwaita-dark + Use Adwaita Qt style with + adwaita + + + + cleanlooks + gtk2 + motif + plastique + Use styles from + qtstyleplugins + + + + ''; + }; + + package = mkOption { + type = types.nullOr types.package; + default = null; + example = literalExample "pkgs.adwaita-qt"; + description = "Theme package to be used in Qt5 applications."; + }; + }; }; }; config = mkIf (cfg.enable && cfg.platformTheme != null) { - home.sessionVariables.QT_QPA_PLATFORMTHEME = - if cfg.platformTheme == "gnome" then "gnome" else "gtk2"; + assertions = [{ + assertion = (cfg.platformTheme == "gnome") + -> ((cfg.style.name != null) && (cfg.style.package != null)); + message = '' + `qt.platformTheme` "gnome" must have `qt.style` set to a theme that + supports both Qt and Gtk, for example "adwaita" or "adwaita-dark". + ''; + }]; + + # Necessary because home.sessionVariables is of types.attrs + home.sessionVariables = (filterAttrs (n: v: v != null) { + QT_QPA_PLATFORMTHEME = + if cfg.platformTheme == "gnome" then "gnome" else "gtk2"; + QT_STYLE_OVERRIDE = cfg.style.name; + }); home.packages = if cfg.platformTheme == "gnome" then [ pkgs.qgnomeplatform ] + ++ lib.optionals (cfg.style.package != null) [ cfg.style.package ] else [ pkgs.libsForQt5.qtstyleplugins ]; - xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ]; + xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ] + ++ lib.optionals (cfg.style != null) [ "QT_STYLE_OVERRIDE" ]; # Enable GTK+ style for Qt4 in either case. # It doesn’t support the platform theme packages. diff --git a/third_party/home-manager/modules/misc/version.nix b/third_party/home-manager/modules/misc/version.nix index fbeb3ec539..270d3bc3db 100644 --- a/third_party/home-manager/modules/misc/version.nix +++ b/third_party/home-manager/modules/misc/version.nix @@ -5,7 +5,16 @@ with lib; { options = { home.stateVersion = mkOption { - type = types.enum [ "18.09" "19.03" "19.09" "20.03" "20.09" ]; + type = types.enum [ + "18.09" + "19.03" + "19.09" + "20.03" + "20.09" + "21.03" + "21.05" + "21.11" + ]; default = "18.09"; description = '' It is occasionally necessary for Home Manager to change diff --git a/third_party/home-manager/modules/misc/xdg-desktop-entries.nix b/third_party/home-manager/modules/misc/xdg-desktop-entries.nix new file mode 100644 index 0000000000..382d6c2b56 --- /dev/null +++ b/third_party/home-manager/modules/misc/xdg-desktop-entries.nix @@ -0,0 +1,178 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + desktopEntry = { + options = { + # Since this module uses the nixpkgs/pkgs/build-support/make-desktopitem function, + # our options and defaults follow its parameters, with the following exceptions: + + # `desktopName` on makeDesktopItem is controlled by `name`. + # This is what we'd commonly consider the name of the application. + # `name` on makeDesktopItem is controlled by this module's key in the attrset. + # This is the file's filename excluding ".desktop". + + # `extraEntries` on makeDesktopItem is controlled by `extraConfig`, + # and `extraDesktopEntries` by `settings`, + # to match what's commonly used by other home manager modules. + + # `startupNotify` on makeDesktopItem asks for "true" or "false" strings, + # for usability's sake we ask for a boolean. + + # `mimeType` and `categories` on makeDesktopItem ask for a string in the format "one;two;three;", + # for the same reason we ask for a list of strings. + + # Descriptions are taken from the desktop entry spec: + # https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys + + type = mkOption { + description = "The type of the desktop entry."; + default = "Application"; + type = types.enum [ "Application" "Link" "Directory" ]; + }; + + exec = mkOption { + description = "Program to execute, possibly with arguments."; + type = types.str; + }; + + icon = mkOption { + description = "Icon to display in file manager, menus, etc."; + type = types.nullOr types.str; + default = null; + }; + + comment = mkOption { + description = "Tooltip for the entry."; + type = types.nullOr types.str; + default = null; + }; + + terminal = mkOption { + description = "Whether the program runs in a terminal window."; + type = types.bool; + default = false; + }; + + name = mkOption { + description = "Specific name of the application."; + type = types.str; + }; + + genericName = mkOption { + description = "Generic name of the application."; + type = types.nullOr types.str; + default = null; + }; + + mimeType = mkOption { + description = "The MIME type(s) supported by this application."; + type = types.nullOr (types.listOf types.str); + default = null; + }; + + categories = mkOption { + description = + "Categories in which the entry should be shown in a menu."; + type = types.nullOr (types.listOf types.str); + default = null; + }; + + startupNotify = mkOption { + description = '' + If true, it is KNOWN that the application will send a "remove" + message when started with the DESKTOP_STARTUP_ID + environment variable set. If false, it is KNOWN that the application + does not work with startup notification at all.''; + type = types.nullOr types.bool; + default = null; + }; + + extraConfig = mkOption { + description = '' + Extra configuration. Will be appended to the end of the file and + may thus contain extra sections. + ''; + type = types.lines; + default = ""; + }; + + settings = mkOption { + type = types.attrsOf types.string; + description = '' + Extra key-value pairs to add to the [Desktop Entry] section. + This may override other values. + ''; + default = { }; + example = literalExample '' + { + Keywords = "calc;math"; + DBusActivatable = "false"; + } + ''; + }; + + fileValidation = mkOption { + type = types.bool; + description = "Whether to validate the generated desktop file."; + default = true; + }; + }; + }; + + #formatting helpers + ifNotNull = a: a': if a == null then null else a'; + stringBool = bool: if bool then "true" else "false"; + semicolonList = list: + (concatStringsSep ";" list) + ";"; # requires trailing semicolon + + #passes config options to makeDesktopItem in expected format + makeFile = name: config: + pkgs.makeDesktopItem { + name = name; + type = config.type; + exec = config.exec; + icon = config.icon; + comment = config.comment; + terminal = config.terminal; + desktopName = config.name; + genericName = config.genericName; + mimeType = ifNotNull config.mimeType (semicolonList config.mimeType); + categories = + ifNotNull config.categories (semicolonList config.categories); + startupNotify = + ifNotNull config.startupNotify (stringBool config.startupNotify); + extraEntries = config.extraConfig; + extraDesktopEntries = config.settings; + }; +in { + meta.maintainers = with maintainers; [ cwyc ]; + + options.xdg.desktopEntries = mkOption { + description = '' + Desktop Entries allow applications to be shown in your desktop environment's app launcher. + You can define entries for programs without entries or override existing entries. + See for more information on options. + ''; + default = { }; + type = types.attrsOf (types.submodule desktopEntry); + example = literalExample '' + { + firefox = { + name = "Firefox"; + genericName = "Web Browser"; + exec = "firefox %U"; + terminal = false; + categories = [ "Application" "Network" "WebBrowser" ]; + mimeType = [ "text/html" "text/xml" ]; + }; + } + ''; + }; + + config.home.packages = mkIf (config.xdg.desktopEntries != { }) + (map hiPrio # we need hiPrio to override existing entries + (attrsets.mapAttrsToList makeFile config.xdg.desktopEntries)); + +} diff --git a/third_party/home-manager/modules/misc/xdg-system-dirs.nix b/third_party/home-manager/modules/misc/xdg-system-dirs.nix new file mode 100644 index 0000000000..f79ebc55bc --- /dev/null +++ b/third_party/home-manager/modules/misc/xdg-system-dirs.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.xdg.systemDirs; + + configDirs = concatStringsSep ":" cfg.config; + + dataDirs = concatStringsSep ":" cfg.data; + +in { + meta.maintainers = with maintainers; [ tadfisher ]; + + options.xdg.systemDirs = { + config = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExample ''[ "/etc/xdg" ]''; + description = '' + Directory names to add to XDG_CONFIG_DIRS + in the user session. + ''; + }; + + data = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExample ''[ "/usr/share" "/usr/local/share" ]''; + description = '' + Directory names to add to XDG_DATA_DIRS + in the user session. + ''; + }; + }; + + config = mkMerge [ + (mkIf (cfg.config != [ ]) { + home.sessionVariables.XDG_CONFIG_DIRS = + "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}"; + + systemd.user.sessionVariables.XDG_CONFIG_DIRS = + "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}"; + }) + + (mkIf (cfg.data != [ ]) { + home.sessionVariables.XDG_DATA_DIRS = + "${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"; + + systemd.user.sessionVariables.XDG_DATA_DIRS = + "${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"; + }) + ]; +} diff --git a/third_party/home-manager/modules/misc/xdg-user-dirs.nix b/third_party/home-manager/modules/misc/xdg-user-dirs.nix index a1db6b115a..6694b52d76 100644 --- a/third_party/home-manager/modules/misc/xdg-user-dirs.nix +++ b/third_party/home-manager/modules/misc/xdg-user-dirs.nix @@ -86,25 +86,36 @@ in { example = { XDG_MISC_DIR = "$HOME/Misc"; }; description = "Other user directories."; }; + + createDirectories = + mkEnableOption "automatic creation of the XDG user directories"; }; - config = mkIf cfg.enable { + config = let + directories = { + XDG_DESKTOP_DIR = cfg.desktop; + XDG_DOCUMENTS_DIR = cfg.documents; + XDG_DOWNLOAD_DIR = cfg.download; + XDG_MUSIC_DIR = cfg.music; + XDG_PICTURES_DIR = cfg.pictures; + XDG_PUBLICSHARE_DIR = cfg.publicShare; + XDG_TEMPLATES_DIR = cfg.templates; + XDG_VIDEOS_DIR = cfg.videos; + } // cfg.extraConfig; + in mkIf cfg.enable { xdg.configFile."user-dirs.dirs".text = let - options = { - XDG_DESKTOP_DIR = cfg.desktop; - XDG_DOCUMENTS_DIR = cfg.documents; - XDG_DOWNLOAD_DIR = cfg.download; - XDG_MUSIC_DIR = cfg.music; - XDG_PICTURES_DIR = cfg.pictures; - XDG_PUBLICSHARE_DIR = cfg.publicShare; - XDG_TEMPLATES_DIR = cfg.templates; - XDG_VIDEOS_DIR = cfg.videos; - } // cfg.extraConfig; - # For some reason, these need to be wrapped with quotes to be valid. - wrapped = mapAttrs (_: value: ''"${value}"'') options; + wrapped = mapAttrs (_: value: ''"${value}"'') directories; in generators.toKeyValue { } wrapped; xdg.configFile."user-dirs.conf".text = "enabled=False"; + + home.activation = mkIf cfg.createDirectories { + createXdgUserDirectories = let + directoriesList = attrValues directories; + mkdir = (dir: ''$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "${dir}"''); + in lib.hm.dag.entryAfter [ "writeBoundary" ] + (strings.concatMapStringsSep "\n" mkdir directoriesList); + }; }; } diff --git a/third_party/home-manager/modules/misc/xdg.nix b/third_party/home-manager/modules/misc/xdg.nix index f207d7d353..6b2917d448 100644 --- a/third_party/home-manager/modules/misc/xdg.nix +++ b/third_party/home-manager/modules/misc/xdg.nix @@ -6,8 +6,6 @@ let cfg = config.xdg; - dag = config.lib.dag; - fileType = (import ../lib/file-type.nix { inherit (config.home) homeDirectory; inherit lib pkgs; diff --git a/third_party/home-manager/modules/modules.nix b/third_party/home-manager/modules/modules.nix index 26e6d14b2e..6d6cff5dbb 100644 --- a/third_party/home-manager/modules/modules.nix +++ b/third_party/home-manager/modules/modules.nix @@ -22,8 +22,10 @@ let allModules = [ (loadModule ./accounts/email.nix { }) + (loadModule ./config/i18n.nix { condition = hostPlatform.isLinux; }) (loadModule ./files.nix { }) (loadModule ./home-environment.nix { }) + (loadModule ./i18n/input-method/default.nix { condition = hostPlatform.isLinux; }) (loadModule ./manual.nix { }) (loadModule ./misc/dconf.nix { }) (loadModule ./misc/debug.nix { }) @@ -39,6 +41,8 @@ let (loadModule ./misc/tmpfiles.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/version.nix { }) (loadModule ./misc/vte.nix { }) + (loadModule ./misc/xdg-system-dirs.nix { condition = hostPlatform.isLinux; }) + (loadModule ./misc/xdg-desktop-entries.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; }) (loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; }) @@ -62,9 +66,11 @@ let (loadModule ./programs/direnv.nix { }) (loadModule ./programs/eclipse.nix { }) (loadModule ./programs/emacs.nix { }) + (loadModule ./programs/exa.nix { }) (loadModule ./programs/feh.nix { }) (loadModule ./programs/firefox.nix { }) (loadModule ./programs/fish.nix { }) + (loadModule ./programs/foot.nix { condition = hostPlatform.isLinux; }) (loadModule ./programs/fzf.nix { }) (loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; }) (loadModule ./programs/gh.nix { }) @@ -72,9 +78,11 @@ let (loadModule ./programs/gnome-terminal.nix { }) (loadModule ./programs/go.nix { }) (loadModule ./programs/gpg.nix { }) + (loadModule ./programs/himalaya.nix { }) (loadModule ./programs/home-manager.nix { }) (loadModule ./programs/htop.nix { }) (loadModule ./programs/i3status.nix { }) + (loadModule ./programs/i3status-rust.nix { condition = hostPlatform.isLinux; }) (loadModule ./programs/info.nix { }) (loadModule ./programs/irssi.nix { }) (loadModule ./programs/lieer.nix { }) @@ -82,10 +90,12 @@ let (loadModule ./programs/kakoune.nix { }) (loadModule ./programs/keychain.nix { }) (loadModule ./programs/kitty.nix { }) + (loadModule ./programs/lazygit.nix { }) (loadModule ./programs/lesspipe.nix { }) (loadModule ./programs/lf.nix { }) (loadModule ./programs/lsd.nix { }) (loadModule ./programs/man.nix { }) + (loadModule ./programs/mangohud.nix { condition = hostPlatform.isLinux; }) (loadModule ./programs/matplotlib.nix { }) (loadModule ./programs/mbsync.nix { }) (loadModule ./programs/mcfly.nix { }) @@ -94,44 +104,58 @@ let (loadModule ./programs/msmtp.nix { }) (loadModule ./programs/mu.nix { }) (loadModule ./programs/ncmpcpp.nix { }) + (loadModule ./programs/ncspot.nix { }) (loadModule ./programs/ne.nix { }) (loadModule ./programs/neomutt.nix { }) (loadModule ./programs/neovim.nix { }) (loadModule ./programs/newsboat.nix { }) + (loadModule ./programs/nix-index.nix { }) (loadModule ./programs/noti.nix { }) (loadModule ./programs/notmuch.nix { }) (loadModule ./programs/nushell.nix { }) (loadModule ./programs/obs-studio.nix { }) + (loadModule ./programs/octant.nix { }) (loadModule ./programs/offlineimap.nix { }) (loadModule ./programs/opam.nix { }) (loadModule ./programs/password-store.nix { }) (loadModule ./programs/pazi.nix { }) (loadModule ./programs/pet.nix { }) (loadModule ./programs/pidgin.nix { }) + (loadModule ./programs/piston-cli.nix { }) (loadModule ./programs/powerline-go.nix { }) (loadModule ./programs/qutebrowser.nix { }) + (loadModule ./programs/rbw.nix { }) (loadModule ./programs/readline.nix { }) (loadModule ./programs/rofi.nix { }) + (loadModule ./programs/rofi-pass.nix { }) (loadModule ./programs/rtorrent.nix { }) + (loadModule ./programs/scmpuff.nix { }) + (loadModule ./programs/senpai.nix { }) (loadModule ./programs/skim.nix { }) (loadModule ./programs/starship.nix { }) + (loadModule ./programs/sbt.nix { }) (loadModule ./programs/ssh.nix { }) (loadModule ./programs/taskwarrior.nix { }) (loadModule ./programs/termite.nix { }) (loadModule ./programs/texlive.nix { }) (loadModule ./programs/tmux.nix { }) + (loadModule ./programs/terminator.nix { condition = hostPlatform.isLinux; }) + (loadModule ./programs/topgrade.nix { }) (loadModule ./programs/urxvt.nix { }) (loadModule ./programs/vim.nix { }) (loadModule ./programs/vscode.nix { }) (loadModule ./programs/vscode/haskell.nix { }) (loadModule ./programs/waybar.nix { condition = hostPlatform.isLinux; }) + (loadModule ./programs/xmobar.nix { }) (loadModule ./programs/z-lua.nix { }) (loadModule ./programs/zathura.nix { }) (loadModule ./programs/zoxide.nix { }) (loadModule ./programs/zplug.nix { }) (loadModule ./programs/zsh.nix { }) (loadModule ./programs/zsh/prezto.nix { }) + (loadModule ./services/barrier.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/blueman-applet.nix { }) + (loadModule ./services/caffeine.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/cbatticon.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/clipmenu.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/compton.nix { }) @@ -139,9 +163,10 @@ let (loadModule ./services/dunst.nix { }) (loadModule ./services/dwm-status.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/emacs.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/etesync-dav.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/flameshot.nix { }) (loadModule ./services/fluidsynth.nix { condition = hostPlatform.isLinux; }) - (loadModule ./services/gammastep.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/redshift-gammastep/gammastep.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/getmail.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/gnome-keyring.nix { }) (loadModule ./services/gpg-agent.nix { }) @@ -160,18 +185,25 @@ let (loadModule ./services/mbsync.nix { }) (loadModule ./services/mpd.nix { }) (loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/mpris-proxy.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/muchsync.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/network-manager-applet.nix { }) (loadModule ./services/nextcloud-client.nix { }) (loadModule ./services/owncloud-client.nix { }) + (loadModule ./services/pantalaimon.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/parcellite.nix { }) + (loadModule ./services/pass-secret-service.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/pasystray.nix { }) + (loadModule ./services/pbgopy.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/picom.nix { }) + (loadModule ./services/plan9port.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/playerctld.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/polybar.nix { }) + (loadModule ./services/poweralertd.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/pulseeffects.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/random-background.nix { }) - (loadModule ./services/redshift.nix { }) + (loadModule ./services/redshift-gammastep/redshift.nix { }) (loadModule ./services/rsibreak.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/screen-locker.nix { }) (loadModule ./services/stalonetray.nix { }) @@ -190,12 +222,14 @@ let (loadModule ./services/window-managers/i3-sway/i3.nix { }) (loadModule ./services/window-managers/i3-sway/sway.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/window-managers/xmonad.nix { }) + (loadModule ./services/wlsunset.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/xcape.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/xembed-sni-proxy.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/xidlehook.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/xscreensaver.nix { }) (loadModule ./services/xsuspender.nix { condition = hostPlatform.isLinux; }) (loadModule ./systemd.nix { }) - (loadModule ./targets/darwin.nix { condition = hostPlatform.isDarwin; }) + (loadModule ./targets/darwin { condition = hostPlatform.isDarwin; }) (loadModule ./targets/generic-linux.nix { condition = hostPlatform.isLinux; }) (loadModule ./xcursor.nix { }) (loadModule ./xresources.nix { }) diff --git a/third_party/home-manager/modules/programs/afew.nix b/third_party/home-manager/modules/programs/afew.nix index 99bae88c0e..6c480f03be 100644 --- a/third_party/home-manager/modules/programs/afew.nix +++ b/third_party/home-manager/modules/programs/afew.nix @@ -6,9 +6,7 @@ let cfg = config.programs.afew; -in - -{ +in { options.programs.afew = { enable = mkEnableOption "the afew initial tagging script for Notmuch"; diff --git a/third_party/home-manager/modules/programs/alacritty.nix b/third_party/home-manager/modules/programs/alacritty.nix index ea908f2b05..9c3e8e75dc 100644 --- a/third_party/home-manager/modules/programs/alacritty.nix +++ b/third_party/home-manager/modules/programs/alacritty.nix @@ -3,9 +3,8 @@ with lib; let - cfg = config.programs.alacritty; - + yamlFormat = pkgs.formats.yaml { }; in { options = { programs.alacritty = { @@ -19,7 +18,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = yamlFormat.type; default = { }; example = literalExample '' { @@ -51,6 +50,11 @@ in { home.packages = [ cfg.package ]; xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) { + # TODO: Replace by the generate function but need to figure out how to + # handle the escaping first. + # + # source = yamlFormat.generate "alacritty.yml" cfg.settings; + text = replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings); }; diff --git a/third_party/home-manager/modules/programs/alot.nix b/third_party/home-manager/modules/programs/alot.nix index e907cd3e0a..b3abf1f7da 100644 --- a/third_party/home-manager/modules/programs/alot.nix +++ b/third_party/home-manager/modules/programs/alot.nix @@ -7,9 +7,12 @@ let cfg = config.programs.alot; - alotAccounts = + enabledAccounts = filter (a: a.notmuch.enable) (attrValues config.accounts.email.accounts); + # sorted: primary first + alotAccounts = sort (a: b: !(a.primary -> b.primary)) enabledAccounts; + boolStr = v: if v then "True" else "False"; mkKeyValue = key: value: diff --git a/third_party/home-manager/modules/programs/astroid-accounts.nix b/third_party/home-manager/modules/programs/astroid-accounts.nix index 17544ff789..fb803867ef 100644 --- a/third_party/home-manager/modules/programs/astroid-accounts.nix +++ b/third_party/home-manager/modules/programs/astroid-accounts.nix @@ -16,7 +16,7 @@ with lib; }; extraConfig = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; example = { select_query = ""; }; description = '' diff --git a/third_party/home-manager/modules/programs/astroid.nix b/third_party/home-manager/modules/programs/astroid.nix index af12b10edb..8af18f16c1 100644 --- a/third_party/home-manager/modules/programs/astroid.nix +++ b/third_party/home-manager/modules/programs/astroid.nix @@ -7,6 +7,8 @@ let cfg = config.programs.astroid; + jsonFormat = pkgs.formats.json { }; + astroidAccounts = filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts; @@ -36,19 +38,18 @@ let } // astroid.extraConfig; # See https://github.com/astroidmail/astroid/wiki/Configuration-Reference - configFile = mailAccounts: - let - template = fromJSON (readFile ./astroid-config-template.json); - astroidConfig = foldl' recursiveUpdate template [ - { - astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc"; - accounts = mapAttrs (n: accountAttr) astroidAccounts; - crypto.gpg.path = "${pkgs.gnupg}/bin/gpg"; - } - cfg.extraConfig - cfg.externalEditor - ]; - in builtins.toJSON astroidConfig; + finalConfig = let + template = fromJSON (readFile ./astroid-config-template.json); + astroidConfig = foldl' recursiveUpdate template [ + { + astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc"; + accounts = mapAttrs (n: accountAttr) astroidAccounts; + crypto.gpg.path = "${pkgs.gnupg}/bin/gpg"; + } + cfg.extraConfig + cfg.externalEditor + ]; + in astroidConfig; in { options = { @@ -90,9 +91,13 @@ in { }; extraConfig = mkOption { - type = types.attrs; + type = jsonFormat.type; default = { }; - example = { poll.interval = 0; }; + example = literalExample '' + { + poll.interval = 0; + } + ''; description = '' JSON config that will override the default Astroid configuration. ''; @@ -107,13 +112,8 @@ in { config = mkIf cfg.enable { home.packages = [ pkgs.astroid ]; - xdg.configFile."astroid/config".source = pkgs.runCommand "out.json" { - json = configFile astroidAccounts; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - echo -n "$json" | ${pkgs.jq}/bin/jq . > $out - ''; + xdg.configFile."astroid/config".source = + jsonFormat.generate "astroid-config" finalConfig; xdg.configFile."astroid/poll.sh" = { executable = true; diff --git a/third_party/home-manager/modules/programs/bash.nix b/third_party/home-manager/modules/programs/bash.nix index 6338f5e4a5..5140e1aada 100644 --- a/third_party/home-manager/modules/programs/bash.nix +++ b/third_party/home-manager/modules/programs/bash.nix @@ -30,8 +30,8 @@ in }; historyFile = mkOption { - type = types.str; - default = "$HOME/.bash_history"; + type = types.nullOr types.str; + default = null; description = "Location of the bash history file."; }; @@ -111,17 +111,6 @@ in ''; }; - bashrcExtra = mkOption { - # Hide for now, may want to rename in the future. - visible = false; - default = ""; - type = types.lines; - description = '' - Extra commands that should be added to - ~/.bashrc. - ''; - }; - initExtra = mkOption { default = ""; type = types.lines; @@ -131,6 +120,15 @@ in ''; }; + bashrcExtra = mkOption { + default = ""; + type = types.lines; + description = '' + Extra commands that should be placed in ~/.bashrc. + Note that these commands will be run even in non-interactive shells. + ''; + }; + logoutExtra = mkOption { default = ""; type = types.lines; @@ -157,10 +155,12 @@ in historyControlStr = concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") ( { - HISTFILE = "\"${cfg.historyFile}\""; HISTFILESIZE = toString cfg.historyFileSize; HISTSIZE = toString cfg.historySize; } + // optionalAttrs (cfg.historyFile != null) { + HISTFILE = "\"${cfg.historyFile}\""; + } // optionalAttrs (cfg.historyControl != []) { HISTCONTROL = concatStringsSep ":" cfg.historyControl; } @@ -169,22 +169,7 @@ in } )); in mkIf cfg.enable { - programs.bash.bashrcExtra = '' - # Commands that should be applied only for interactive shells. - if [[ $- == *i* ]]; then - ${historyControlStr} - - ${shoptsStr} - - ${aliasesStr} - - ${cfg.initExtra} - fi - ''; - - home.file.".bash_profile".text = '' - # -*- mode: sh -*- - + home.file.".bash_profile".source = pkgs.writeShellScript "bash_profile" '' # include .profile if it exists [[ -f ~/.profile ]] && . ~/.profile @@ -192,9 +177,7 @@ in [[ -f ~/.bashrc ]] && . ~/.bashrc ''; - home.file.".profile".text = '' - # -*- mode: sh -*- - + home.file.".profile".source = pkgs.writeShellScript "profile" '' . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" ${sessionVarsStr} @@ -202,18 +185,23 @@ in ${cfg.profileExtra} ''; - home.file.".bashrc".text = '' - # -*- mode: sh -*- - + home.file.".bashrc".source = pkgs.writeShellScript "bashrc" '' ${cfg.bashrcExtra} + + # Commands that should be applied only for interactive shells. + [[ $- == *i* ]] || return + + ${historyControlStr} + + ${shoptsStr} + + ${aliasesStr} + + ${cfg.initExtra} ''; home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") { - text = '' - # -*- mode: sh -*- - - ${cfg.logoutExtra} - ''; + source = pkgs.writeShellScript "bash_logout" cfg.logoutExtra; }; } ); diff --git a/third_party/home-manager/modules/programs/beets.nix b/third_party/home-manager/modules/programs/beets.nix index 1a45bbea1c..6eb183dd1e 100644 --- a/third_party/home-manager/modules/programs/beets.nix +++ b/third_party/home-manager/modules/programs/beets.nix @@ -6,6 +6,8 @@ let cfg = config.programs.beets; + yamlFormat = pkgs.formats.yaml { }; + in { meta.maintainers = [ maintainers.rycee ]; @@ -39,7 +41,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = yamlFormat.type; default = { }; description = '' Configuration written to @@ -52,7 +54,7 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; - xdg.configFile."beets/config.yaml".text = - builtins.toJSON config.programs.beets.settings; + xdg.configFile."beets/config.yaml".source = + yamlFormat.generate "beets-config" cfg.settings; }; } diff --git a/third_party/home-manager/modules/programs/broot.nix b/third_party/home-manager/modules/programs/broot.nix index 6951e035d3..72b2c6ea13 100644 --- a/third_party/home-manager/modules/programs/broot.nix +++ b/third_party/home-manager/modules/programs/broot.nix @@ -6,20 +6,10 @@ let cfg = config.programs.broot; - configFile = config: - pkgs.runCommand "conf.toml" { - buildInputs = [ pkgs.remarshal ]; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - remarshal -if json -of toml \ - < ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \ - > $out - ''; + tomlFormat = pkgs.formats.toml { }; brootConf = { - verbs = - mapAttrsToList (name: value: value // { invocation = name; }) cfg.verbs; + verbs = cfg.verbs; skin = cfg.skin; }; @@ -54,41 +44,60 @@ in { }; verbs = mkOption { - type = with types; attrsOf (attrsOf (either bool str)); - default = { - "p" = { execution = ":parent"; }; - "edit" = { + type = with types; listOf (attrsOf (either bool str)); + default = [ + { + invocation = "p"; + execution = ":parent"; + } + { + invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}"; - }; - "create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; }; - "view" = { execution = "less {file}"; }; - }; - example = literalExample '' + } { - "p" = { execution = ":parent"; }; - "edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; }; - "create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; }; - "view" = { execution = "less {file}"; }; - "blop {name}\\.{type}" = { + invocation = "create {subpath}"; + execution = "$EDITOR {directory}/{subpath}"; + } + { + invocation = "view"; + execution = "less {file}"; + } + ]; + example = literalExample '' + [ + { invocation = "p"; execution = ":parent"; } + { invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}" ; } + { invocation = "create {subpath}"; execution = "$EDITOR {directory}/{subpath}"; } + { invocation = "view"; execution = "less {file}"; } + { + invocation = "blop {name}\\.{type}"; execution = "/bin/mkdir {parent}/{type} && /usr/bin/nvim {parent}/{type}/{name}.{type}"; from_shell = true; - }; - } + } + ] ''; description = '' - Define new verbs. The attribute name indicates how the verb is - called by the user, with placeholders for arguments. + Define new verbs. For more information, see + . The possible attributes are: + + invocation (optional) + how the verb is called by the user, with placeholders for arguments + execution (mandatory) how the verb is executed + + key (optional) + a keyboard key triggering execution + shortcut (optional) an alternate way to call the verb (without @@ -109,6 +118,13 @@ in { ''; }; + package = mkOption { + type = types.package; + default = pkgs.broot; + defaultText = literalExample "pkgs.broot"; + description = "Package providing broot"; + }; + skin = mkOption { type = types.attrsOf types.str; default = { }; @@ -167,9 +183,10 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.broot ]; + home.packages = [ cfg.package ]; - xdg.configFile."broot/conf.toml".source = configFile brootConf; + xdg.configFile."broot/conf.toml".source = + tomlFormat.generate "broot-config" brootConf; # Dummy file to prevent broot from trying to reinstall itself xdg.configFile."broot/launcher/installed-v1".text = ""; diff --git a/third_party/home-manager/modules/programs/chromium.nix b/third_party/home-manager/modules/programs/chromium.nix index 4e35c07b90..c866c09992 100644 --- a/third_party/home-manager/modules/programs/chromium.nix +++ b/third_party/home-manager/modules/programs/chromium.nix @@ -5,7 +5,9 @@ with lib; let browserModule = defaultPkg: name: visible: - let browser = (builtins.parseDrvName defaultPkg.name).name; + let + browser = (builtins.parseDrvName defaultPkg.name).name; + isProprietaryChrome = hasPrefix "Google Chrome" name; in { enable = mkOption { inherit visible; @@ -22,23 +24,78 @@ let defaultText = literalExample "pkgs.${browser}"; description = "The ${name} package to use."; }; - + } // optionalAttrs (!isProprietaryChrome) { + # Extensions do not work with Google Chrome + # see https://github.com/nix-community/home-manager/issues/1383 extensions = mkOption { inherit visible; - type = types.listOf types.str; + type = with types; + let + extensionType = submodule { + options = { + id = mkOption { + type = strMatching "[a-zA-Z]{32}"; + description = '' + The extension's ID from the Chome Web Store url or the unpacked crx. + ''; + default = ""; + }; + + updateUrl = mkOption { + type = str; + description = '' + URL of the extension's update manifest XML file. Linux only. + ''; + default = "https://clients2.google.com/service/update2/crx"; + visible = pkgs.stdenv.isLinux; + readOnly = pkgs.stdenv.isDarwin; + }; + + crxPath = mkOption { + type = nullOr path; + description = '' + Path to the extension's crx file. Linux only. + ''; + default = null; + visible = pkgs.stdenv.isLinux; + }; + + version = mkOption { + type = nullOr str; + description = '' + The extension's version, required for local installation. Linux only. + ''; + default = null; + visible = pkgs.stdenv.isLinux; + }; + }; + }; + in listOf (coercedTo str (v: { id = v; }) extensionType); default = [ ]; example = literalExample '' [ - "chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet - "mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot - "gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere - "cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin + { id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # ublock origin + { + id = "dcpihecpambacapedldabdbpakmachpb"; + updateUrl = "https://raw.githubusercontent.com/iamadamdev/bypass-paywalls-chrome/master/updates.xml"; + } + { + id = "aaaaaaaaaabbbbbbbbbbcccccccccc"; + crxPath = "/home/share/extension.crx"; + version = "1.0"; + } ] ''; description = '' List of ${name} extensions to install. To find the extension ID, check its URL on the Chrome Web Store. + + To install extensions outside of the Chrome Web Store set + updateUrl or crxPath and + version as explained in the + Chrome + documentation. ''; }; }; @@ -46,13 +103,15 @@ let browserConfig = cfg: let - browser = (builtins.parseDrvName cfg.package.name).name; + drvName = (builtins.parseDrvName cfg.package.name).name; + browser = if drvName == "ungoogled-chromium" then "chromium" else drvName; darwinDirs = { chromium = "Chromium"; google-chrome = "Google/Chrome"; google-chrome-beta = "Google/Chrome Beta"; google-chrome-dev = "Google/Chrome Dev"; + brave = "BraveSoftware/Brave-Browser"; }; configDir = if pkgs.stdenv.isDarwin then @@ -60,20 +119,33 @@ let else "${config.xdg.configHome}/${browser}"; - extensionJson = ext: { - name = "${configDir}/External Extensions/${ext}.json"; - value.text = builtins.toJSON { - external_update_url = - "https://clients2.google.com/service/update2/crx"; + extensionJson = ext: + assert ext.crxPath != null -> ext.version != null; + with builtins; { + name = "${configDir}/External Extensions/${ext.id}.json"; + value.text = toJSON (if ext.crxPath != null then { + external_crx = ext.crxPath; + external_version = ext.version; + } else { + external_update_url = ext.updateUrl; + }); }; - }; in mkIf cfg.enable { home.packages = [ cfg.package ]; - home.file = listToAttrs (map extensionJson cfg.extensions); + home.file = listToAttrs (map extensionJson (cfg.extensions or [ ])); }; in { + # Extensions do not work with the proprietary Google Chrome version + # see https://github.com/nix-community/home-manager/issues/1383 + imports = map (flip mkRemovedOptionModule + "The `extensions` option does not work on Google Chrome anymore.") [ + [ "programs" "google-chrome" "extensions" ] + [ "programs" "google-chrome-beta" "extensions" ] + [ "programs" "google-chrome-dev" "extensions" ] + ]; + options.programs = { chromium = browserModule pkgs.chromium "Chromium" true; google-chrome = browserModule pkgs.google-chrome "Google Chrome" false; @@ -81,6 +153,7 @@ in { browserModule pkgs.google-chrome-beta "Google Chrome Beta" false; google-chrome-dev = browserModule pkgs.google-chrome-dev "Google Chrome Dev" false; + brave = browserModule pkgs.brave "Brave Browser" false; }; config = mkMerge [ @@ -88,5 +161,6 @@ in { (browserConfig config.programs.google-chrome) (browserConfig config.programs.google-chrome-beta) (browserConfig config.programs.google-chrome-dev) + (browserConfig config.programs.brave) ]; } diff --git a/third_party/home-manager/modules/programs/command-not-found/command-not-found.nix b/third_party/home-manager/modules/programs/command-not-found/command-not-found.nix index b79fde0f61..a4917bbf18 100644 --- a/third_party/home-manager/modules/programs/command-not-found/command-not-found.nix +++ b/third_party/home-manager/modules/programs/command-not-found/command-not-found.nix @@ -11,13 +11,8 @@ let dir = "bin"; src = ./command-not-found.pl; isExecutable = true; - inherit (pkgs) perl; inherit (cfg) dbPath; - perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [ - pkgs.perlPackages.DBI - pkgs.perlPackages.DBDSQLite - pkgs.perlPackages.StringShellQuote - ]); + perl = pkgs.perl.withPackages (p: [ p.DBDSQLite p.StringShellQuote ]); }; shInit = commandNotFoundHandlerName: '' diff --git a/third_party/home-manager/modules/programs/command-not-found/command-not-found.pl b/third_party/home-manager/modules/programs/command-not-found/command-not-found.pl index 997dfec649..220d057b7f 100644 --- a/third_party/home-manager/modules/programs/command-not-found/command-not-found.pl +++ b/third_party/home-manager/modules/programs/command-not-found/command-not-found.pl @@ -1,4 +1,4 @@ -#! @perl@/bin/perl -w @perlFlags@ +#! @perl@/bin/perl -w use strict; use DBI; @@ -29,16 +29,17 @@ if (!defined $res || scalar @$res == 0) { exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV)); } else { print STDERR <{package}\n" foreach @$res; + print STDERR " nix-shell -p $_->{package}\n" foreach @$res; } exit 127; diff --git a/third_party/home-manager/modules/programs/dircolors.nix b/third_party/home-manager/modules/programs/dircolors.nix index 026de72d71..6ac16da50b 100644 --- a/third_party/home-manager/modules/programs/dircolors.nix +++ b/third_party/home-manager/modules/programs/dircolors.nix @@ -204,8 +204,8 @@ in { }; home.file.".dir_colors".text = concatStringsSep "\n" ([ ] - ++ optional (cfg.extraConfig != "") cfg.extraConfig - ++ mapAttrsToList formatLine cfg.settings) + "\n"; + ++ mapAttrsToList formatLine cfg.settings ++ [ "" ] + ++ optional (cfg.extraConfig != "") cfg.extraConfig); programs.bash.initExtra = mkIf cfg.enableBashIntegration '' eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors) diff --git a/third_party/home-manager/modules/programs/direnv.nix b/third_party/home-manager/modules/programs/direnv.nix index 1d1374b8e2..383cff3af8 100644 --- a/third_party/home-manager/modules/programs/direnv.nix +++ b/third_party/home-manager/modules/programs/direnv.nix @@ -5,25 +5,25 @@ with lib; let cfg = config.programs.direnv; - configFile = config: - pkgs.runCommand "config.toml" { - buildInputs = [ pkgs.remarshal ]; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - remarshal -if json -of toml \ - < ${pkgs.writeText "config.json" (builtins.toJSON config)} \ - > $out - ''; + + tomlFormat = pkgs.formats.toml { }; in { + imports = [ + (mkRenamedOptionModule [ + "programs" + "direnv" + "enableNixDirenvIntegration" + ] [ "programs" "direnv" "nix-direnv" "enable" ]) + ]; + meta.maintainers = [ maintainers.rycee ]; options.programs.direnv = { enable = mkEnableOption "direnv, the environment switcher"; config = mkOption { - type = types.attrs; + type = tomlFormat.type; default = { }; description = '' Configuration written to @@ -71,22 +71,29 @@ in { ''; }; - enableNixDirenvIntegration = mkEnableOption '' - nix-direnv, - a fast, persistent use_nix implementation for direnv''; + nix-direnv = { + enable = mkEnableOption '' + nix-direnv, + a fast, persistent use_nix implementation for direnv''; + enableFlakes = mkEnableOption "Flake support in nix-direnv"; + }; + }; config = mkIf cfg.enable { home.packages = [ pkgs.direnv ]; - xdg.configFile."direnv/config.toml" = - mkIf (cfg.config != { }) { source = configFile cfg.config; }; + xdg.configFile."direnv/config.toml" = mkIf (cfg.config != { }) { + source = tomlFormat.generate "direnv-config" cfg.config; + }; xdg.configFile."direnv/direnvrc" = let + package = + pkgs.nix-direnv.override { inherit (cfg.nix-direnv) enableFlakes; }; text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib - ++ optional cfg.enableNixDirenvIntegration - "source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc"); + ++ optional cfg.nix-direnv.enable + "source ${package}/share/nix-direnv/direnvrc"); in mkIf (text != "") { inherit text; }; programs.bash.initExtra = mkIf cfg.enableBashIntegration ( @@ -101,7 +108,7 @@ in { ''; programs.fish.shellInit = mkIf cfg.enableFishIntegration '' - eval (${pkgs.direnv}/bin/direnv hook fish) + ${pkgs.direnv}/bin/direnv hook fish | source ''; }; } diff --git a/third_party/home-manager/modules/programs/exa.nix b/third_party/home-manager/modules/programs/exa.nix new file mode 100644 index 0000000000..771e4e65ce --- /dev/null +++ b/third_party/home-manager/modules/programs/exa.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.exa; + + aliases = { + ls = "${pkgs.exa}/bin/exa"; + ll = "${pkgs.exa}/bin/exa -l"; + la = "${pkgs.exa}/bin/exa -a"; + lt = "${pkgs.exa}/bin/exa --tree"; + lla = "${pkgs.exa}/bin/exa -la"; + }; + +in { + meta.maintainers = [ maintainers.kalhauge ]; + + options.programs.exa = { + enable = + mkEnableOption "exa, a modern replacement for ls"; + enableAliases = mkEnableOption "recommended exa aliases"; + }; + + config = mkIf cfg.enable { + home.packages = [ pkgs.exa ]; + + programs.bash.shellAliases = mkIf cfg.enableAliases aliases; + + programs.zsh.shellAliases = mkIf cfg.enableAliases aliases; + + programs.fish.shellAliases = mkIf cfg.enableAliases aliases; + + }; +} diff --git a/third_party/home-manager/modules/programs/firefox.nix b/third_party/home-manager/modules/programs/firefox.nix index eafeef47f3..d474f5b808 100644 --- a/third_party/home-manager/modules/programs/firefox.nix +++ b/third_party/home-manager/modules/programs/firefox.nix @@ -67,6 +67,8 @@ in meta.maintainers = [ maintainers.rycee ]; imports = [ + (mkRemovedOptionModule ["programs" "firefox" "enableAdobeFlash"] + "Support for this option has been removed.") (mkRemovedOptionModule ["programs" "firefox" "enableGoogleTalk"] "Support for this option has been removed.") (mkRemovedOptionModule ["programs" "firefox" "enableIcedTea"] @@ -84,6 +86,17 @@ in then pkgs.firefox else pkgs.firefox-unwrapped; defaultText = literalExample "pkgs.firefox"; + example = literalExample '' + pkgs.firefox.override { + # See nixpkgs' firefox/wrapper.nix to check which options you can use + cfg = { + # Gnome shell native connector + enableGnomeExtensions = true; + # Tridactyl native connector + enableTridactylNative = true; + }; + } + ''; description = '' The Firefox package to use. If state version ≥ 19.09 then this should be a wrapped Firefox package. For earlier state @@ -215,12 +228,6 @@ in description = "Attribute set of Firefox profiles."; }; - enableAdobeFlash = mkOption { - type = types.bool; - default = false; - description = "Whether to enable the unfree Adobe Flash plugin."; - }; - enableGnomeExtensions = mkOption { type = types.bool; default = false; @@ -268,11 +275,17 @@ in ) ]; + warnings = optional (cfg.enableGnomeExtensions or false) '' + Using 'programs.firefox.enableGnomeExtensions' has been deprecated and + will be removed in the future. Please change to overriding the package + configuration using 'programs.firefox.package' instead. You can refer to + its example for how to do this. + ''; + home.packages = let # The configuration expected by the Firefox wrapper. fcfg = { - enableAdobeFlash = cfg.enableAdobeFlash; enableGnomeExtensions = cfg.enableGnomeExtensions; }; @@ -287,7 +300,7 @@ in if isDarwin then cfg.package else if versionAtLeast config.home.stateVersion "19.09" then - cfg.package.override { cfg = fcfg; } + cfg.package.override (old: { cfg = old.cfg or {} // fcfg; }) else (pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { }; in @@ -305,6 +318,8 @@ in }; }] ++ flip mapAttrsToList cfg.profiles (_: profile: { + "${profilesPath}/${profile.path}/.keep".text = ""; + "${profilesPath}/${profile.path}/chrome/userChrome.css" = mkIf (profile.userChrome != "") { text = profile.userChrome; diff --git a/third_party/home-manager/modules/programs/fish.nix b/third_party/home-manager/modules/programs/fish.nix index 730afa7926..f381960f6e 100644 --- a/third_party/home-manager/modules/programs/fish.nix +++ b/third_party/home-manager/modules/programs/fish.nix @@ -343,7 +343,12 @@ in { # if we haven't sourced the general config, do it if not set -q __fish_general_config_sourced - set -p fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions + set --prepend fish_function_path ${ + if pkgs ? fishPlugins && pkgs.fishPlugins ? foreign-env then + "${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d" + else + "${pkgs.fish-foreign-env}/share/fish-foreign-env/functions" + } fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null set -e fish_function_path[1] diff --git a/third_party/home-manager/modules/programs/foot.nix b/third_party/home-manager/modules/programs/foot.nix new file mode 100644 index 0000000000..8df201fd9f --- /dev/null +++ b/third_party/home-manager/modules/programs/foot.nix @@ -0,0 +1,77 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.foot; + iniFormat = pkgs.formats.ini { }; + +in { + meta.maintainers = with lib.maintainers; [ plabadens ]; + + options.programs.foot = { + enable = mkEnableOption "Foot terminal"; + + package = mkOption { + type = types.package; + default = pkgs.foot; + defaultText = literalExample "pkgs.foot"; + description = "The foot package to install"; + }; + + server.enable = mkEnableOption "Foot terminal server"; + + settings = mkOption { + type = iniFormat.type; + default = { }; + description = '' + Configuration written to + $XDG_CONFIG_HOME/foot/foot.ini. See + for a list of available options. + ''; + example = literalExample '' + { + main = { + term = "xterm-256color"; + + font = "Fira Code:size=11"; + dpi-aware = "yes"; + }; + + mouse = { + hide-when-typing = "yes"; + }; + } + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."foot/foot.ini" = mkIf (cfg.settings != { }) { + source = iniFormat.generate "foot.ini" cfg.settings; + }; + + systemd.user.services = mkIf cfg.server.enable { + foot = { + Unit = { + Description = + "Fast, lightweight and minimalistic Wayland terminal emulator."; + Documentation = "man:foot(1)"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = "${cfg.package}/bin/foot --server"; + Restart = "on-failure"; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/programs/fzf.nix b/third_party/home-manager/modules/programs/fzf.nix index 3aee57768e..6cdd894d2a 100644 --- a/third_party/home-manager/modules/programs/fzf.nix +++ b/third_party/home-manager/modules/programs/fzf.nix @@ -7,9 +7,21 @@ let cfg = config.programs.fzf; in { + imports = [ + (mkRemovedOptionModule [ "programs" "fzf" "historyWidgetCommand" ] + "This option is no longer supported by fzf.") + ]; + options.programs.fzf = { enable = mkEnableOption "fzf - a command-line fuzzy finder"; + package = mkOption { + type = types.package; + default = pkgs.fzf; + defaultText = literalExample "pkgs.fzf"; + description = "Package providing the fzf tool."; + }; + defaultCommand = mkOption { type = types.nullOr types.str; default = null; @@ -67,15 +79,6 @@ in { ''; }; - historyWidgetCommand = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The command that gets executed as the source for fzf for the - CTRL-R keybinding. - ''; - }; - historyWidgetOptions = mkOption { type = types.listOf types.str; default = [ ]; @@ -85,6 +88,23 @@ in { ''; }; + tmux = { + enableShellIntegration = mkEnableOption '' + setting FZF_TMUX=1 which causes shell integration to use fzf-tmux + ''; + + shellIntegrationOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExample ''[ "-d 40%" ]''; + description = '' + If is set to true, + shell integration will use these options for fzf-tmux. + See fzf-tmux --help for available options. + ''; + }; + }; + enableBashIntegration = mkOption { default = true; type = types.bool; @@ -111,36 +131,37 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.fzf ]; + home.packages = [ cfg.package ]; home.sessionVariables = mapAttrs (n: v: toString v) (filterAttrs (n: v: v != [ ] && v != null) { FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand; FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions; - FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand; FZF_CTRL_R_OPTS = cfg.historyWidgetOptions; FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand; FZF_CTRL_T_OPTS = cfg.fileWidgetOptions; FZF_DEFAULT_COMMAND = cfg.defaultCommand; FZF_DEFAULT_OPTS = cfg.defaultOptions; + FZF_TMUX = if cfg.tmux.enableShellIntegration then "1" else null; + FZF_TMUX_OPTS = cfg.tmux.shellIntegrationOptions; }); programs.bash.initExtra = mkIf cfg.enableBashIntegration '' if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then - . ${pkgs.fzf}/share/fzf/completion.bash - . ${pkgs.fzf}/share/fzf/key-bindings.bash + . ${cfg.package}/share/fzf/completion.bash + . ${cfg.package}/share/fzf/key-bindings.bash fi ''; programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' if [[ $options[zle] = on ]]; then - . ${pkgs.fzf}/share/fzf/completion.zsh - . ${pkgs.fzf}/share/fzf/key-bindings.zsh + . ${cfg.package}/share/fzf/completion.zsh + . ${cfg.package}/share/fzf/key-bindings.zsh fi ''; programs.fish.shellInit = mkIf cfg.enableFishIntegration '' - source ${pkgs.fzf}/share/fzf/key-bindings.fish && fzf_key_bindings + source ${cfg.package}/share/fzf/key-bindings.fish && fzf_key_bindings ''; }; } diff --git a/third_party/home-manager/modules/programs/getmail.nix b/third_party/home-manager/modules/programs/getmail.nix index f83c469ff2..eaf297cf2a 100644 --- a/third_party/home-manager/modules/programs/getmail.nix +++ b/third_party/home-manager/modules/programs/getmail.nix @@ -11,8 +11,7 @@ let with account; let passCmd = concatMapStringsSep ", " (x: "'${x}'") passwordCommand; - renderedMailboxes = - concatMapStringsSep ", " (x: "'${x}'") getmail.mailboxes; + renderedMailboxes = concatMapStrings (x: "'${x}', ") getmail.mailboxes; retrieverType = if imap.tls.enable then "SimpleIMAPSSLRetriever" else diff --git a/third_party/home-manager/modules/programs/gh.nix b/third_party/home-manager/modules/programs/gh.nix index 41d6aa1dec..4cda4eab34 100644 --- a/third_party/home-manager/modules/programs/gh.nix +++ b/third_party/home-manager/modules/programs/gh.nix @@ -45,9 +45,11 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.gitAndTools.gh ]; + home.packages = [ pkgs.gh ]; - xdg.configFile."gh/config.yml".text = - builtins.toJSON { inherit (cfg) aliases editor gitProtocol; }; + xdg.configFile."gh/config.yml".text = builtins.toJSON { + inherit (cfg) aliases editor; + git_protocol = cfg.gitProtocol; + }; }; } diff --git a/third_party/home-manager/modules/programs/git.nix b/third_party/home-manager/modules/programs/git.nix index 312269de31..097fbf4b42 100644 --- a/third_party/home-manager/modules/programs/git.nix +++ b/third_party/home-manager/modules/programs/git.nix @@ -61,8 +61,13 @@ let signModule = types.submodule { options = { key = mkOption { - type = types.str; - description = "The default GPG signing key fingerprint."; + type = types.nullOr types.str; + description = '' + The default GPG signing key fingerprint. + + Set to null to let GnuPG decide what signing key + to use depending on commit’s author. + ''; }; signByDefault = mkOption { @@ -101,7 +106,7 @@ let }; contents = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; description = '' Configuration to include. If empty then a path must be given. @@ -276,28 +281,34 @@ in { genIdentity = name: account: with account; - nameValuePair "sendemail.${name}" ({ - smtpEncryption = if smtp.tls.enable then - (if smtp.tls.useStartTls - || versionOlder config.home.stateVersion "20.09" then - "tls" - else - "ssl") - else - ""; - smtpServer = smtp.host; - smtpUser = userName; + nameValuePair "sendemail.${name}" (if account.msmtp.enable then { + smtpServer = "${pkgs.msmtp}/bin/msmtp"; + envelopeSender = "auto"; from = address; - } // optionalAttrs (smtp.port != null) { - smtpServerPort = smtp.port; - }); + } else + { + smtpEncryption = if smtp.tls.enable then + (if smtp.tls.useStartTls + || versionOlder config.home.stateVersion "20.09" then + "tls" + else + "ssl") + else + ""; + smtpSslCertPath = mkIf smtp.tls.enable smtp.tls.certificatesFile; + smtpServer = smtp.host; + smtpUser = userName; + from = address; + } // optionalAttrs (smtp.port != null) { + smtpServerPort = smtp.port; + }); in mapAttrs' genIdentity (filterAttrs hasSmtp config.accounts.email.accounts); } (mkIf (cfg.signing != null) { programs.git.iniContent = { - user.signingKey = cfg.signing.key; + user.signingKey = mkIf (cfg.signing.key != null) cfg.signing.key; commit.gpgSign = cfg.signing.signByDefault; gpg.program = cfg.signing.gpgPath; }; @@ -348,13 +359,14 @@ in { }) (mkIf cfg.delta.enable { - programs.git.iniContent = - let deltaCommand = "${pkgs.gitAndTools.delta}/bin/delta"; - in { - core.pager = deltaCommand; - interactive.diffFilter = "${deltaCommand} --color-only"; - delta = cfg.delta.options; - }; + home.packages = [ pkgs.delta ]; + + programs.git.iniContent = let deltaCommand = "${pkgs.delta}/bin/delta"; + in { + core.pager = deltaCommand; + interactive.diffFilter = "${deltaCommand} --color-only"; + delta = cfg.delta.options; + }; }) ]); } diff --git a/third_party/home-manager/modules/programs/gnome-terminal.nix b/third_party/home-manager/modules/programs/gnome-terminal.nix index dec2a10c59..a9e3b5a758 100644 --- a/third_party/home-manager/modules/programs/gnome-terminal.nix +++ b/third_party/home-manager/modules/programs/gnome-terminal.nix @@ -187,6 +187,12 @@ let ''; }; + boldIsBright = mkOption { + default = null; + type = types.nullOr types.bool; + description = "Whether bold text is shown in bright colors."; + }; + deleteBinding = mkOption { default = "delete-sequence"; type = eraseBinding; @@ -228,12 +234,26 @@ let ''; }; + + audibleBell = mkOption { + default = true; + type = types.bool; + description = "Turn on/off the terminal's bell."; + }; + + transparencyPercent = mkOption { + default = null; + type = types.nullOr (types.ints.between 0 100); + description = "Background transparency in percent."; + }; }; }); buildProfileSet = pcfg: { + audible-bell = pcfg.audibleBell; visible-name = pcfg.visibleName; + scroll-on-output = pcfg.scrollOnOutput; scrollbar-policy = if pcfg.showScrollbar then "always" else "never"; scrollback-lines = pcfg.scrollbackLines; cursor-shape = pcfg.cursorShape; @@ -266,7 +286,9 @@ let } else { bold-color-same-as-fg = false; bold-color = pcfg.colors.boldColor; - }) // (if (pcfg.colors.cursor != null) then { + }) // optionalAttrs (pcfg.boldIsBright != null) { + bold-is-bright = pcfg.boldIsBright; + } // (if (pcfg.colors.cursor != null) then { cursor-colors-set = true; cursor-foreground-color = pcfg.colors.cursor.foreground; cursor-background-color = pcfg.colors.cursor.background; @@ -278,10 +300,14 @@ let highlight-background-color = pcfg.colors.highlight.background; } else { highlight-colors-set = false; - }))); + }) // optionalAttrs (pcfg.transparencyPercent != null) { + background-transparency-percent = pcfg.transparencyPercent; + use-theme-transparency = false; + use-transparent-background = true; + })); in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = with maintainers; [ kamadorueda rycee ]; options = { programs.gnome-terminal = { @@ -308,7 +334,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.gnome3.gnome-terminal ]; + home.packages = [ pkgs.gnome.gnome-terminal ]; dconf.settings = let dconfPath = "org/gnome/terminal/legacy"; in { diff --git a/third_party/home-manager/modules/programs/gpg.nix b/third_party/home-manager/modules/programs/gpg.nix index 4588c59c88..b1717adeb2 100644 --- a/third_party/home-manager/modules/programs/gpg.nix +++ b/third_party/home-manager/modules/programs/gpg.nix @@ -5,31 +5,74 @@ with lib; let cfg = config.programs.gpg; - cfgText = - concatStringsSep "\n" - (attrValues - (mapAttrs (key: value: - if isString value - then "${key} ${value}" - else optionalString value key) - cfg.settings)); + mkKeyValue = key: value: + if isString value + then "${key} ${value}" + else optionalString value key; -in { + cfgText = generators.toKeyValue { + inherit mkKeyValue; + listsAsDuplicateKeys = true; + } cfg.settings; + + scdaemonCfgText = generators.toKeyValue { + inherit mkKeyValue; + listsAsDuplicateKeys = true; + } cfg.scdaemonSettings; + + primitiveType = types.oneOf [ types.str types.bool ]; +in +{ options.programs.gpg = { enable = mkEnableOption "GnuPG"; + package = mkOption { + type = types.package; + default = pkgs.gnupg; + defaultText = literalExample "pkgs.gnupg"; + example = literalExample "pkgs.gnupg23"; + description = "The Gnupg package to use (also used the gpg-agent service)."; + }; + settings = mkOption { - type = types.attrsOf (types.either types.str types.bool); - example = { - no-comments = false; - s2k-cipher-algo = "AES128"; - }; + type = types.attrsOf (types.either primitiveType (types.listOf types.str)); + example = literalExample '' + { + no-comments = false; + s2k-cipher-algo = "AES128"; + } + ''; description = '' GnuPG configuration options. Available options are described in the gpg manpage: . + + + Note that lists are converted to duplicate keys. ''; }; + + scdaemonSettings = mkOption { + type = types.attrsOf (types.either primitiveType (types.listOf types.str)); + example = literalExample '' + { + disable-ccid = true; + } + ''; + description = '' + SCdaemon configuration options. Available options are described + in the gpg scdaemon manpage: + . + ''; + }; + + homedir = mkOption { + type = types.path; + example = literalExample "\"\${config.xdg.dataHome}/gnupg\""; + default = "${config.home.homeDirectory}/.gnupg"; + defaultText = literalExample "\"\${config.home.homeDirectory}/.gnupg\""; + description = "Directory to store keychains and configuration."; + }; }; config = mkIf cfg.enable { @@ -54,8 +97,17 @@ in { use-agent = mkDefault true; }; - home.packages = [ pkgs.gnupg ]; + programs.gpg.scdaemonSettings = { + # no defaults for scdaemon + }; - home.file.".gnupg/gpg.conf".text = cfgText; + home.packages = [ cfg.package ]; + home.sessionVariables = { + GNUPGHOME = cfg.homedir; + }; + + home.file."${cfg.homedir}/gpg.conf".text = cfgText; + + home.file."${cfg.homedir}/scdaemon.conf".text = scdaemonCfgText; }; } diff --git a/third_party/home-manager/modules/programs/himalaya.nix b/third_party/home-manager/modules/programs/himalaya.nix new file mode 100644 index 0000000000..d7b6d31ccd --- /dev/null +++ b/third_party/home-manager/modules/programs/himalaya.nix @@ -0,0 +1,100 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.programs.himalaya; + + enabledAccounts = + lib.filterAttrs (_: a: a.himalaya.enable) (config.accounts.email.accounts); + + tomlFormat = pkgs.formats.toml { }; + + himalayaConfig = let + toHimalayaConfig = account: + { + email = account.address; + name = account.realName; + default = account.primary; + + # FIXME: does not support disabling TLS altogether + # NOTE: does not accept sequence of strings for password commands + imap-login = account.userName; + imap-passwd-cmd = lib.escapeShellArgs account.passwordCommand; + imap-host = account.imap.host; + imap-port = account.imap.port; + imap-starttls = account.imap.tls.useStartTls; + + smtp-login = account.userName; + smtp-passwd-cmd = lib.escapeShellArgs account.passwordCommand; + smtp-host = account.smtp.host; + smtp-port = account.smtp.port; + smtp-starttls = account.imap.tls.useStartTls; + } // (lib.optionalAttrs (account.signature.showSignature == "append") { + # FIXME: signature cannot be attached + signature = account.signature.text; + }) // account.himalaya.settings; + in { + # NOTE: will not start without this configured, but each account overrides it + name = ""; + } // cfg.settings // (lib.mapAttrs (_: toHimalayaConfig) enabledAccounts); +in { + meta.maintainers = with lib.hm.maintainers; [ ambroisie ]; + + options = with lib; { + programs.himalaya = { + enable = mkEnableOption "himalaya mail client"; + + package = mkOption { + type = types.package; + default = pkgs.himalaya; + defaultText = literalExample "pkgs.himalaya"; + description = '' + Package providing the himalaya mail client. + ''; + }; + + settings = mkOption { + type = tomlFormat.type; + default = { }; + example = lib.literalExample '' + { + default-page-size = 50; + } + ''; + description = '' + Global himalaya configuration values. + ''; + }; + }; + + accounts.email.accounts = mkOption { + type = with types; + attrsOf (submodule { + options.himalaya = { + enable = mkEnableOption '' + the himalaya mail client for this account + ''; + + settings = mkOption { + type = tomlFormat.type; + default = { }; + example = lib.literalExample '' + { + default-page-size = 50; + } + ''; + description = '' + Extra settings to add to this himalaya + account configuration. + ''; + }; + }; + }); + }; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."himalaya/config.toml".source = + tomlFormat.generate "himalaya-config.toml" himalayaConfig; + }; +} diff --git a/third_party/home-manager/modules/programs/home-manager.nix b/third_party/home-manager/modules/programs/home-manager.nix index 9039a59d7c..cc760baf4d 100644 --- a/third_party/home-manager/modules/programs/home-manager.nix +++ b/third_party/home-manager/modules/programs/home-manager.nix @@ -6,8 +6,6 @@ let cfg = config.programs.home-manager; - dag = config.lib.dag; - in { meta.maintainers = [ maintainers.rycee ]; diff --git a/third_party/home-manager/modules/programs/htop.nix b/third_party/home-manager/modules/programs/htop.nix index 1fb397cdc3..1edd0f7ab6 100644 --- a/third_party/home-manager/modules/programs/htop.nix +++ b/third_party/home-manager/modules/programs/htop.nix @@ -6,9 +6,20 @@ let cfg = config.programs.htop; - list = xs: concatMapStrings (x: "${toString x} ") xs; + formatOption = n: v: + let v' = if isBool v then (if v then "1" else "0") else toString v; + in "${n}=${v'}"; - bool = b: if b then "1" else "0"; + formatMeters = side: meters: + let + warn' = warn "htop: meters should be passed as a list"; + meters' = if isList meters then meters else warn' [ meters ]; + in { + "${side}_meters" = concatMap (mapAttrsToList (x: _: x)) meters'; + "${side}_meter_modes" = concatMap (mapAttrsToList (_: y: y)) meters'; + }; + leftMeters = formatMeters "left"; + rightMeters = formatMeters "right"; fields = { PID = 0; @@ -66,13 +77,32 @@ let M_PSSWP = 120; }; + modes = { + Bar = 1; + Text = 2; + Graph = 3; + LED = 4; + }; + + # Utilities for constructing meters + meter = mode: name: { ${name} = mode; }; + bar = meter modes.Bar; + text = meter modes.Text; + graph = meter modes.Graph; + led = meter modes.LED; + blank = text "Blank"; + # Mapping from names to defaults meters = { Clock = 2; + Date = 2; + DateTime = 2; LoadAverage = 2; Load = 2; Memory = 1; Swap = 1; + Zram = 2; + HugePages = 2; Tasks = 2; Uptime = 2; Battery = 2; @@ -80,6 +110,7 @@ let AllCPUs = 1; AllCPUs2 = 1; AllCPUs4 = 1; + AllCPUs8 = 1; LeftCPUs = 1; RightCPUs = 1; Right = 1; @@ -88,6 +119,8 @@ let RightCPUs2 = 1; LeftCPUs4 = 1; RightCPUs4 = 1; + LeftCPUs8 = 1; + RightCPUs8 = 1; Blank = 2; PressureStallCPUSome = 2; PressureStallIOSome = 2; @@ -105,6 +138,10 @@ let "CPU(6)" = 1; "CPU(7)" = 1; "CPU(8)" = 1; + SELinux = 2; + Systemd = 2; + DiskIO = 2; + NetworkIO = 2; }; singleMeterType = let @@ -166,22 +203,102 @@ in { options.programs.htop = { enable = mkEnableOption "htop"; + settings = mkOption { + type = types.attrs; + default = { + account_guest_in_cpu_meter = false; + color_scheme = 0; + cpu_count_from_zero = false; + delay = 15; + detailed_cpu_time = false; + enable_mouse = true; + fields = with fields; [ + PID + USER + PRIORITY + NICE + M_SIZE + M_RESIDENT + M_SHARE + STATE + PERCENT_CPU + PERCENT_MEM + TIME + COMM + ]; + header_margin = true; + hide_kernel_threads = true; + hide_threads = false; + hide_userland_threads = false; + highlight_base_name = false; + highlight_megabytes = true; + highlight_threads = true; + shadow_other_users = false; + show_cpu_frequency = false; + show_cpu_usage = false; + show_program_path = true; + show_thread_names = false; + sort_direction = 1; + sort_key = fields.PERCENT_CPU; + tree_view = false; + update_process_names = false; + vim_mode = false; + } // (leftMeters [ + (bar "AllCPUs2") + (bar "Memory") + (bar "Swap") + (text "Zram") + ]) // (rightMeters [ + (text "Tasks") + (text "LoadAverage") + (text "Uptime") + (text "Systemd") + ]); + example = literalExample '' + { + color_scheme = 6; + cpu_count_from_one = 0; + delay = 15; + fields = with config.lib.htop.fields; [ + PID + USER + PRIORITY + NICE + M_SIZE + M_RESIDENT + M_SHARE + STATE + PERCENT_CPU + PERCENT_MEM + TIME + COMM + ]; + highlight_base_name = 1; + highlight_megabytes = 1; + highlight_threads = 1; + } // (with config.lib.htop; leftMeters [ + (bar "AllCPUs2") + (bar "Memory") + (bar "Swap") + (text "Zram") + ]) // (with config.lib.htop; rightMeters [ + (text "Tasks") + (text "LoadAverage") + (text "Uptime") + (text "Systemd") + ]); + ''; + description = '' + Configuration options to add to + ~/.config/htop/htoprc. + + This superseedes any other (deprecated) settings in this module. + ''; + }; + fields = mkOption { - type = types.listOf (types.enum (attrNames fields)); - default = [ - "PID" - "USER" - "PRIORITY" - "NICE" - "M_SIZE" - "M_RESIDENT" - "M_SHARE" - "STATE" - "PERCENT_CPU" - "PERCENT_MEM" - "TIME" - "COMM" - ]; + type = types.nullOr (types.listOf (types.enum (attrNames fields))); + default = null; example = [ "PID" "USER" @@ -192,151 +309,247 @@ in { "TIME" "COMM" ]; - description = "Active fields shown in the table."; + description = '' + Deprecated. Please use programs.htop.settings.fields instead. + + Active fields shown in the table. + ''; }; sortKey = mkOption { - type = types.enum (attrNames fields); - default = "PERCENT_CPU"; + type = types.nullOr (types.enum (attrNames fields)); + default = null; example = "TIME"; - description = "Which field to use for sorting."; + description = '' + Deprecated. Please use programs.htop.settings.sort_key instead. + + Which field to use for sorting. + ''; }; sortDescending = mkOption { - type = types.bool; - default = true; - description = "Whether to sort descending or not."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.sort_direction instead. + + Whether to sort descending or not. + ''; }; hideThreads = mkOption { - type = types.bool; - default = false; - description = "Hide threads."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.hide_threads instead. + + Hide threads. + ''; }; hideKernelThreads = mkOption { - type = types.bool; - default = true; - description = "Hide kernel threads."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.hide_kernel_threads instead. + + Hide kernel threads. + ''; }; hideUserlandThreads = mkOption { - type = types.bool; - default = false; - description = "Hide userland process threads."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.hide_userland_threads instead. + + Hide userland process threads. + ''; }; shadowOtherUsers = mkOption { - type = types.bool; - default = false; - description = "Shadow other users' processes."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.shadow_other_users instead. + + Shadow other users' processes. + ''; }; showThreadNames = mkOption { - type = types.bool; - default = false; - description = "Show custom thread names."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.show_thread_names instead. + + Show custom thread names. + ''; }; showProgramPath = mkOption { - type = types.bool; - default = true; - description = "Show program path."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.show_program_path instead. + + Show program path. + ''; }; highlightBaseName = mkOption { - type = types.bool; - default = false; - description = "Highlight program basename."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.highlight_base_name instead. + + Highlight program basename. + ''; }; highlightMegabytes = mkOption { - type = types.bool; - default = true; - description = "Highlight large numbers in memory counters."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.highlight_megabytes instead. + + Highlight large numbers in memory counters. + ''; }; highlightThreads = mkOption { - type = types.bool; - default = true; - description = "Display threads in a different color."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.highlight_threads instead. + + Display threads in a different color. + ''; }; treeView = mkOption { - type = types.bool; - default = false; - description = "Tree view."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.tree_view instead. + + Tree view. + ''; }; headerMargin = mkOption { - type = types.bool; - default = true; - description = "Leave a margin around header."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.header_margin instead. + + Leave a margin around header. + ''; }; detailedCpuTime = mkOption { - type = types.bool; - default = false; - description = - "Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest)."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.detailed_cpu_time instead. + + Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest). + ''; }; cpuCountFromZero = mkOption { - type = types.bool; - default = false; - description = "Count CPUs from 0 instead of 1."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.cpu_count_from_zero instead. + + Count CPUs from 0 instead of 1. + ''; }; showCpuUsage = mkOption { - type = types.bool; - default = false; - description = "Show CPU usage frequency."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.show_cpu_usage instead. + + Show CPU usage frequency. + ''; }; showCpuFrequency = mkOption { - type = types.bool; - default = false; - description = "Show CPU frequency."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.show_cpu_frequency instead. + + Show CPU frequency. + ''; }; updateProcessNames = mkOption { - type = types.bool; - default = false; - description = "Update process names on every refresh."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.update_process_names instead. + + Update process names on every refresh. + ''; }; accountGuestInCpuMeter = mkOption { - type = types.bool; - default = false; - description = "Add guest time in CPU meter percentage."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.account_guest_in_cpu_meter instead. + + Add guest time in CPU meter percentage. + ''; }; colorScheme = mkOption { - type = types.enum [ 0 1 2 3 4 5 6 ]; - default = 0; + type = types.nullOr (types.enum [ 0 1 2 3 4 5 6 ]); + default = null; example = 6; - description = "Which color scheme to use."; + description = '' + Deprecated. Please use programs.htop.settings.color_scheme instead. + + Which color scheme to use. + ''; }; enableMouse = mkOption { - type = types.bool; - default = true; - description = "Enable mouse support."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.enable_mouse instead. + + Enable mouse support. + ''; }; delay = mkOption { - type = types.int; - default = 15; + type = types.nullOr types.int; + default = null; example = 2; - description = "Set the delay between updates, in tenths of seconds."; + description = '' + Deprecated. Please use programs.htop.settings.delay instead. + + Set the delay between updates, in tenths of seconds. + ''; }; meters = mkOption { - description = "Meters shown in the header."; - default = { - left = [ "AllCPUs" "Memory" "Swap" ]; - right = [ "Tasks" "LoadAverage" "Uptime" ]; - }; + description = '' + Deprecated. Please use programs.htop.settings.left_meters, + programs.htop.settings.left_meter_modes, + programs.htop.settings.right_meters and + programs.htop.settings.right_meter_modes instead. Or consider using + lib.htop.leftMeters and lib.htop.rightMeters. + + Meters shown in the header. + ''; + default = null; example = { left = [ "Memory" @@ -362,55 +575,93 @@ in { } ]; }; - type = meterType; + type = types.nullOr meterType; }; vimMode = mkOption { - type = types.bool; - default = false; - description = "Vim key bindings."; + type = types.nullOr types.bool; + default = null; + description = '' + Deprecated. Please use programs.htop.settings.vim_mode instead. + + Vim key bindings. + ''; }; }; config = mkIf cfg.enable { + lib.htop = { + inherit fields modes leftMeters rightMeters bar text graph led blank; + }; + home.packages = [ pkgs.htop ]; xdg.configFile."htop/htoprc".text = let - leftMeters = map (m: m.kind) cfg.meters.left; - leftModes = map (m: m.mode) cfg.meters.left; - rightMeters = map (m: m.kind) cfg.meters.right; - rightModes = map (m: m.mode) cfg.meters.right; - in '' - # This file is regenerated by home-manager - # when options are changed in the config - fields=${list (map (n: fields.${n}) cfg.fields)} - sort_key=${toString (fields.${cfg.sortKey})} - sort_direction=${bool cfg.sortDescending} - hide_threads=${bool cfg.hideThreads} - hide_kernel_threads=${bool cfg.hideKernelThreads} - hide_userland_threads=${bool cfg.hideUserlandThreads} - shadow_other_users=${bool cfg.shadowOtherUsers} - show_thread_names=${bool cfg.showThreadNames} - show_program_path=${bool cfg.showProgramPath} - highlight_base_name=${bool cfg.highlightBaseName} - highlight_megabytes=${bool cfg.highlightMegabytes} - highlight_threads=${bool cfg.highlightThreads} - tree_view=${bool cfg.treeView} - header_margin=${bool cfg.headerMargin} - detailed_cpu_time=${bool cfg.detailedCpuTime} - cpu_count_from_zero=${bool cfg.cpuCountFromZero} - show_cpu_usage=${bool cfg.showCpuUsage} - show_cpu_frequency=${bool cfg.showCpuFrequency} - update_process_names=${bool cfg.updateProcessNames} - account_guest_in_cpu_meter=${bool cfg.accountGuestInCpuMeter} - color_scheme=${toString cfg.colorScheme} - enable_mouse=${bool cfg.enableMouse} - delay=${toString cfg.delay} - left_meters=${list leftMeters} - left_meter_modes=${list leftModes} - right_meters=${list rightMeters} - right_meter_modes=${list rightModes} - vim_mode=${bool cfg.vimMode} - ''; + + deprecate = settingsKey: optionKey: optionValue: + let + warn' = warn + "htop: programs.htop.${optionKey} is deprecated; please is programs.htop.settings.${settingsKey} instead"; + in if !isNull optionValue then + warn' optionValue + else if hasAttr settingsKey cfg.settings then + cfg.settings.${settingsKey} + else + null; + + deprecate' = settingsKey: optionKey: + deprecate settingsKey optionKey cfg.${optionKey}; + + ifNonNull = x: y: if isNull x then null else y; + + leftMeters = deprecate "left_meters" "meters.left" + (ifNonNull cfg.meters (map (m: m.kind) cfg.meters.left)); + leftModes = deprecate "left_meter_modes" "meters.left" + (ifNonNull cfg.meters (map (m: m.mode) cfg.meters.left)); + rightMeters = deprecate "right_meters" "meters.right" + (ifNonNull cfg.meters (map (m: m.kind) cfg.meters.right)); + rightModes = deprecate "right_meter_modes" "meters.right" + (ifNonNull cfg.meters (map (m: m.mode) cfg.meters.right)); + + settings' = cfg.settings // (filterAttrs (_: v: !isNull v) { + fields = deprecate "fields" "fields" + (ifNonNull cfg.fields (map (n: fields.${n}) cfg.fields)); + sort_key = deprecate "sort_key" "sortKey" + (ifNonNull cfg.sortKey fields.${cfg.sortKey}); + sort_direction = deprecate' "sort_direction" "sortDescending"; + hide_threads = deprecate' "hide_threads" "hideThreads"; + hide_kernel_threads = + deprecate' "hide_kernel_threads" "hideKernelThreads"; + hide_userland_threads = + deprecate' "hide_userland_threads" "hideUserlandThreads"; + shadow_other_users = deprecate' "shadow_other_users" "shadowOtherUsers"; + show_thread_names = deprecate' "show_thread_names" "showThreadNames"; + show_program_path = deprecate' "show_program_path" "showProgramPath"; + highlight_base_name = + deprecate' "highlight_base_name" "highlightBaseName"; + highlight_megabytes = + deprecate' "highlight_megabytes" "highlightMegabytes"; + highlight_threads = deprecate' "highlight_threads" "highlightThreads"; + tree_view = deprecate' "tree_view" "treeView"; + header_margin = deprecate' "header_margin" "headerMargin"; + detailed_cpu_time = deprecate' "detailed_cpu_time" "detailedCpuTime"; + cpu_count_from_zero = + deprecate' "cpu_count_from_zero" "cpuCountFromZero"; + show_cpu_usage = deprecate' "show_cpu_usage" "showCpuUsage"; + show_cpu_frequency = deprecate' "show_cpu_frequency" "showCpuFrequency"; + update_process_names = + deprecate' "update_process_names" "updateProcessNames"; + account_guest_in_cpu_meter = + deprecate' "account_guest_in_cpu_meter" "accountGuestInCpuMeter"; + color_scheme = deprecate' "color_scheme" "colorScheme"; + enable_mouse = deprecate' "enable_mouse" "enableMouse"; + delay = deprecate' "delay" "delay"; + left_meters = leftMeters; + left_meter_modes = leftModes; + right_meters = rightMeters; + right_meter_modes = rightModes; + vim_mode = deprecate' "vim_mode" "vimMode"; + }); + in concatStringsSep "\n" (mapAttrsToList formatOption settings'); }; } diff --git a/third_party/home-manager/modules/programs/i3status-rust.nix b/third_party/home-manager/modules/programs/i3status-rust.nix new file mode 100644 index 0000000000..5d721cc509 --- /dev/null +++ b/third_party/home-manager/modules/programs/i3status-rust.nix @@ -0,0 +1,265 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.i3status-rust; + + restartI3 = '' + i3Socket=''${XDG_RUNTIME_DIR:-/run/user/$UID}/i3/ipc-socket.* + if [ -S $i3Socket ]; then + echo "Reloading i3" + $DRY_RUN_CMD ${config.xsession.windowManager.i3.package}/bin/i3-msg -s $i3Socket restart 1>/dev/null + fi + ''; + + settingsFormat = pkgs.formats.toml { }; + +in { + meta.maintainers = [ maintainers.farlion ]; + + options.programs.i3status-rust = { + enable = mkEnableOption "a replacement for i3-status written in Rust"; + + bars = mkOption { + type = types.attrsOf (types.submodule { + options = { + + blocks = mkOption { + type = settingsFormat.type; + default = [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "memory"; + display_type = "memory"; + format_mem = "{mem_used_percents}"; + format_swap = "{swap_used_percents}"; + } + { + block = "cpu"; + interval = 1; + } + { + block = "load"; + interval = 1; + format = "{1m}"; + } + { block = "sound"; } + { + block = "time"; + interval = 60; + format = "%a %d/%m %R"; + } + ]; + description = '' + Configuration blocks to add to i3status-rust + config. See + + for block options. + ''; + example = literalExample '' + [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "sound"; + format = "{output_name} {volume}%"; + on_click = "pavucontrol --tab=3"; + mappings = { + "alsa_output.pci-0000_00_1f.3.analog-stereo" = ""; + "bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = ""; + }; + } + ]; + ''; + }; + + settings = mkOption { + type = settingsFormat.type; + default = { }; + description = '' + Any extra options to add to i3status-rust + config. + ''; + example = literalExample '' + { + theme = { + name = "solarized-dark"; + overrides = { + idle_bg = "#123456"; + idle_fg = "#abcdef"; + }; + }; + } + ''; + }; + + icons = mkOption { + type = types.str; + default = "none"; + description = '' + The icons set to use. See + + for a list of available icon sets. + ''; + example = "awesome5"; + }; + + theme = mkOption { + type = types.str; + default = "plain"; + description = '' + The theme to use. See + + for a list of available themes. + ''; + example = "gruvbox-dark"; + }; + }; + }); + + default = { + default = { + blocks = [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "memory"; + display_type = "memory"; + format_mem = "{Mup}%"; + format_swap = "{SUp}%"; + } + { + block = "cpu"; + interval = 1; + } + { + block = "load"; + interval = 1; + format = "{1m}"; + } + { block = "sound"; } + { + block = "time"; + interval = 60; + format = "%a %d/%m %R"; + } + ]; + }; + }; + description = '' + Attribute set of i3status-rust bars, each with their own configuration. + Each bar name generates a config file suffixed with + the bar's name from the attribute set, like so: + config-name.toml. + + This way, multiple config files can be generated, such as for having a + top and a bottom bar. + + See + + i3status-rust + 1 + + for options. + ''; + example = literalExample '' + bottom = { + blocks = [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "memory"; + display_type = "memory"; + format_mem = "{mem_used_percents}"; + format_swap = "{swap_used_percents}"; + } + { + block = "cpu"; + interval = 1; + } + { + block = "load"; + interval = 1; + format = "{1m}"; + } + { block = "sound"; } + { + block = "time"; + interval = 60; + format = "%a %d/%m %R"; + } + ]; + settings = { + theme = { + name = "solarized-dark"; + overrides = { + idle_bg = "#123456"; + idle_fg = "#abcdef"; + }; + }; + }; + icons = "awesome5"; + theme = "gruvbox-dark"; + }; + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.i3status-rust; + defaultText = literalExample "pkgs.i3status-rust"; + description = "Package providing i3status-rust"; + }; + + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile = mapAttrs' (cfgFileSuffix: cfg: + nameValuePair ("i3status-rust/config-${cfgFileSuffix}.toml") ({ + onChange = mkIf config.xsession.windowManager.i3.enable restartI3; + + source = settingsFormat.generate ("config-${cfgFileSuffix}.toml") ({ + theme = cfg.theme; + icons = cfg.icons; + block = cfg.blocks; + } // cfg.settings); + })) cfg.bars; + }; +} diff --git a/third_party/home-manager/modules/programs/irssi.nix b/third_party/home-manager/modules/programs/irssi.nix index fc8fa8e613..af9e16fc72 100644 --- a/third_party/home-manager/modules/programs/irssi.nix +++ b/third_party/home-manager/modules/programs/irssi.nix @@ -35,6 +35,9 @@ let use_ssl = "${boolStr v.server.ssl.enable}"; ssl_verify = "${boolStr v.server.ssl.verify}"; autoconnect = "${boolStr v.server.autoConnect}"; + ${lib.optionalString (v.server.ssl.certificateFile != null) '' + ssl_cert = "${v.server.ssl.certificateFile}"; + ''} } '')); @@ -118,6 +121,15 @@ let default = true; description = "Whether the SSL certificate should be verified."; }; + + certificateFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path to a file containing the certificate used for + client authentication to the server. + ''; + }; }; autoConnect = mkOption { diff --git a/third_party/home-manager/modules/programs/jq.nix b/third_party/home-manager/modules/programs/jq.nix index 6c89df0df9..764629918a 100644 --- a/third_party/home-manager/modules/programs/jq.nix +++ b/third_party/home-manager/modules/programs/jq.nix @@ -30,6 +30,13 @@ in { programs.jq = { enable = mkEnableOption "the jq command-line JSON processor"; + package = mkOption { + type = types.package; + default = pkgs.jq; + defaultText = literalExample "pkgs.jq"; + description = "jq package to use."; + }; + colors = mkOption { description = '' The colors used in colored JSON output. @@ -51,12 +58,12 @@ in { default = { null = "1;30"; - false = "0;39"; - true = "0;39"; - numbers = "0;39"; + false = "0;37"; + true = "0;37"; + numbers = "0;37"; strings = "0;32"; - arrays = "1;39"; - objects = "1;39"; + arrays = "1;37"; + objects = "1;37"; }; type = colorsType; @@ -65,7 +72,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.jq ]; + home.packages = [ cfg.package ]; home.sessionVariables = let c = cfg.colors; in { diff --git a/third_party/home-manager/modules/programs/kakoune.nix b/third_party/home-manager/modules/programs/kakoune.nix index 6db311a137..01b30167da 100644 --- a/third_party/home-manager/modules/programs/kakoune.nix +++ b/third_party/home-manager/modules/programs/kakoune.nix @@ -574,7 +574,7 @@ let hookString = h: concatStringsSep " " [ "hook" - "${optionalString (h.group != null) "-group ${group}"}" + "${optionalString (h.group != null) "-group ${h.group}"}" "${optionalString (h.once) "-once"}" "global" "${h.name}" diff --git a/third_party/home-manager/modules/programs/kitty.nix b/third_party/home-manager/modules/programs/kitty.nix index 313a0bfadd..3fa4452e64 100644 --- a/third_party/home-manager/modules/programs/kitty.nix +++ b/third_party/home-manager/modules/programs/kitty.nix @@ -79,7 +79,11 @@ in { # Generated by Home Manager. # See https://sw.kovidgoyal.net/kitty/conf.html - ${optionalString (cfg.font != null) "font_family ${cfg.font.name}"} + ${optionalString (cfg.font != null) '' + font_family ${cfg.font.name} + ${optionalString (cfg.font.size != null) + "font_size ${toString cfg.font.size}"} + ''} ${toKittyConfig cfg.settings} diff --git a/third_party/home-manager/modules/programs/lazygit.nix b/third_party/home-manager/modules/programs/lazygit.nix new file mode 100644 index 0000000000..6d4a2bd403 --- /dev/null +++ b/third_party/home-manager/modules/programs/lazygit.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.lazygit; + + yamlFormat = pkgs.formats.yaml { }; + + inherit (pkgs.stdenv.hostPlatform) isDarwin; + +in { + meta.maintainers = [ maintainers.kalhauge ]; + + options.programs.lazygit = { + enable = mkEnableOption "lazygit, a simple terminal UI for git commands"; + + settings = mkOption { + type = yamlFormat.type; + default = { }; + defaultText = literalExample "{ }"; + example = literalExample '' + { + gui.theme = { + lightTheme = true; + activeBorderColor = [ "blue" "bold" ]; + inactiveBorderColor = [ "black" ]; + selectedLineBgColor = [ "default" ]; + }; + } + ''; + description = '' + Configuration written to + ~/.config/lazygit/config.yml on Linux + or ~/Library/Application Support/lazygit/config.yml on Darwin. See + + for supported values. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ pkgs.lazygit ]; + + home.file."Library/Application Support/lazygit/config.yml" = + mkIf (cfg.settings != { } && isDarwin) { + source = yamlFormat.generate "lazygit-config" cfg.settings; + }; + + xdg.configFile."lazygit/config.yml" = + mkIf (cfg.settings != { } && !isDarwin) { + source = yamlFormat.generate "lazygit-config" cfg.settings; + }; + }; +} diff --git a/third_party/home-manager/modules/programs/lsd.nix b/third_party/home-manager/modules/programs/lsd.nix index ab1880ff82..b5dd260e02 100644 --- a/third_party/home-manager/modules/programs/lsd.nix +++ b/third_party/home-manager/modules/programs/lsd.nix @@ -6,12 +6,14 @@ let cfg = config.programs.lsd; + yamlFormat = pkgs.formats.yaml { }; + aliases = { ls = "${pkgs.lsd}/bin/lsd"; - ll = "ls -l"; - la = "ls -a"; - lt = "ls --tree"; - lla = "ls -la"; + ll = "${pkgs.lsd}/bin/lsd -l"; + la = "${pkgs.lsd}/bin/lsd -a"; + lt = "${pkgs.lsd}/bin/lsd --tree"; + lla = "${pkgs.lsd}/bin/lsd -la"; }; in { @@ -27,6 +29,21 @@ in { Whether to enable recommended lsd aliases. ''; }; + + settings = mkOption { + type = yamlFormat.type; + default = { }; + example = { + date = "relative"; + ignore-globs = [ ".git" ".hg" ]; + }; + description = '' + Configuration written to + ~/.config/lsd/config.yaml. See + + for supported values. + ''; + }; }; config = mkIf cfg.enable { @@ -37,5 +54,9 @@ in { programs.zsh.shellAliases = mkIf cfg.enableAliases aliases; programs.fish.shellAliases = mkIf cfg.enableAliases aliases; + + xdg.configFile."lsd/config.yaml" = mkIf (cfg.settings != { }) { + source = yamlFormat.generate "lsd-config" cfg.settings; + }; }; } diff --git a/third_party/home-manager/modules/programs/mangohud.nix b/third_party/home-manager/modules/programs/mangohud.nix new file mode 100644 index 0000000000..3a2158e3d6 --- /dev/null +++ b/third_party/home-manager/modules/programs/mangohud.nix @@ -0,0 +1,105 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.mangohud; + + settingsType = with types; + (oneOf [ bool int float str path (listOf (oneOf [ int str ])) ]); + + renderOption = option: + rec { + int = toString option; + float = int; + path = int; + bool = "false"; + string = option; + list = concatStringsSep "," (lists.forEach option (x: toString x)); + }.${builtins.typeOf option}; + + renderLine = k: v: (if isBool v && v then k else "${k}=${renderOption v}"); + renderSettings = attrs: + strings.concatStringsSep "\n" (attrsets.mapAttrsToList renderLine attrs) + + "\n"; + +in { + options = { + programs.mangohud = { + enable = mkEnableOption "Mangohud"; + + package = mkOption { + type = types.package; + default = pkgs.mangohud; + defaultText = literalExample "pkgs.mangohud"; + description = "The Mangohud package to install."; + }; + + enableSessionWide = mkOption { + type = types.bool; + default = false; + description = '' + Sets environment variables so that + MangoHud is started on any application that supports it. + ''; + }; + + settings = mkOption { + type = with types; attrsOf settingsType; + default = { }; + example = literalExample '' + { + output_folder = ~/Documents/mangohud/; + full = true; + } + ''; + description = '' + Configuration written to + ~/.config/MangoHud/MangoHud.conf. See + + for the default configuration. + ''; + }; + + settingsPerApplication = mkOption { + type = with types; attrsOf (attrsOf settingsType); + default = { }; + example = literalExample '' + { + mpv = { + no_display = true; + } + } + ''; + description = '' + Sets MangoHud settings per application. + Configuration written to + ~/.config/MangoHud/{application_name}.conf. See + + for the default configuration. + ''; + }; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + { + home.packages = [ cfg.package ]; + + home.sessionVariables = mkIf cfg.enableSessionWide { + MANGOHUD = 1; + MANGOHUD_DLSYM = 1; + }; + + xdg.configFile."MangoHud/MangoHud.conf" = + mkIf (cfg.settings != { }) { text = renderSettings cfg.settings; }; + } + { + xdg.configFile = mapAttrs' + (n: v: nameValuePair "MangoHud/${n}.conf" { text = renderSettings v; }) + cfg.settingsPerApplication; + } + ]); + + meta.maintainers = with maintainers; [ zeratax ]; +} diff --git a/third_party/home-manager/modules/programs/matplotlib.nix b/third_party/home-manager/modules/programs/matplotlib.nix index da80c11677..0d4e48c953 100644 --- a/third_party/home-manager/modules/programs/matplotlib.nix +++ b/third_party/home-manager/modules/programs/matplotlib.nix @@ -23,7 +23,7 @@ in { config = mkOption { default = { }; - type = types.attrs; + type = types.attrsOf types.anything; description = '' Add terms to the matplotlibrc file to control the default matplotlib behavior. diff --git a/third_party/home-manager/modules/programs/mbsync-accounts.nix b/third_party/home-manager/modules/programs/mbsync-accounts.nix index c1bd551fa0..3f3f2d14d4 100644 --- a/third_party/home-manager/modules/programs/mbsync-accounts.nix +++ b/third_party/home-manager/modules/programs/mbsync-accounts.nix @@ -50,13 +50,13 @@ let ''; }; - masterPattern = mkOption { + farPattern = mkOption { type = types.str; default = ""; example = "[Gmail]/Sent Mail"; description = '' IMAP4 patterns for which mailboxes on the remote mail server to sync. - If Patterns are specified, masterPattern + If Patterns are specified, farPattern is interpreted as a prefix which is not matched against the patterns, and is not affected by mailbox list overrides. @@ -65,14 +65,14 @@ let ''; }; - slavePattern = mkOption { + nearPattern = mkOption { type = types.str; default = ""; example = "Sent"; description = '' - Name for where mail coming from the master mail server will end up - locally. The mailbox specified by the master's pattern will be placed - in this directory. + Name for where mail coming from the remote (far) mail server will end up + locally. The mailbox specified by the far pattern will be placed in + this directory. If this is left as the default, then mbsync will default to the pattern INBOX. @@ -85,7 +85,7 @@ let example = [ "INBOX" ]; description = '' Instead of synchronizing just the mailboxes that - match the masterPattern, use it as a prefix which is + match the farPattern, use it as a prefix which is not matched against the patterns, and is not affected by mailbox list overrides. ''; @@ -125,6 +125,16 @@ in { ''; }; + subFolders = mkOption { + type = types.enum [ "Verbatim" "Maildir++" "Legacy" ]; + default = "Verbatim"; + example = "Maildir++"; + description = '' + The on-disk folder naming style. This option has no + effect when is used. + ''; + }; + create = mkOption { type = types.enum [ "none" "maildir" "imap" "both" ]; default = "none"; diff --git a/third_party/home-manager/modules/programs/mbsync.nix b/third_party/home-manager/modules/programs/mbsync.nix index f9713da3ae..91e7d0f77e 100644 --- a/third_party/home-manager/modules/programs/mbsync.nix +++ b/third_party/home-manager/modules/programs/mbsync.nix @@ -10,6 +10,24 @@ let mbsyncAccounts = filter (a: a.mbsync.enable) (attrValues config.accounts.email.accounts); + # Given a SINGLE group's channels attribute set, return true if ANY of the channel's + # patterns use the invalidOption attribute set value name. + channelInvalidOption = channels: invalidOption: + any (c: c) (mapAttrsToList (c: hasAttr invalidOption) channels); + + # Given a SINGLE account's groups attribute set, return true if ANY of the account's group's channel's patterns use the invalidOption attribute set value name. + groupInvalidOption = groups: invalidOption: + any (g: g) (mapAttrsToList (groupName: groupVals: + channelInvalidOption groupVals.channels invalidOption) groups); + + # Given all accounts (ensure that accounts passed in here ARE mbsync-using accounts) + # return true if ANY of the account's groups' channels' patterns use the + # invalidOption attribute set value name. + accountInvalidOption = accounts: invalidOption: + any (a: a) + (map (account: groupInvalidOption account.mbsync.groups invalidOption) + mbsyncAccounts); + genTlsConfig = tls: { SSLType = if !tls.enable then @@ -22,10 +40,18 @@ let CertificateFile = toString tls.certificatesFile; }; - masterSlaveMapping = { + imports = [ + (mkRenamedOptionModule [ "programs" "mbsync" "masterSlaveMapping" ] [ + "programs" + "mbsync" + "nearFarMapping" + ]) + ]; + + nearFarMapping = { none = "None"; - imap = "Master"; - maildir = "Slave"; + imap = "Far"; + maildir = "Near"; both = "Both"; }; @@ -65,10 +91,13 @@ let + genSection "IMAPStore ${name}-remote" ({ Account = name; } // mbsync.extraConfig.remote) + "\n" + genSection "MaildirStore ${name}-local" ({ - Path = "${maildir.absPath}/"; Inbox = "${maildir.absPath}/${folders.inbox}"; - SubFolders = "Verbatim"; - } // optionalAttrs (mbsync.flatten != null) { Flatten = mbsync.flatten; } + } // optionalAttrs + (mbsync.subFolders != "Maildir++" || mbsync.flatten != null) { + Path = "${maildir.absPath}/"; + } // optionalAttrs (mbsync.flatten == null) { + SubFolders = mbsync.subFolders; + } // optionalAttrs (mbsync.flatten != null) { Flatten = mbsync.flatten; } // mbsync.extraConfig.local) + "\n" + genChannels account; genChannels = account: @@ -85,18 +114,18 @@ let genAccountWideChannel = account: with account; genSection "Channel ${name}" ({ - Master = ":${name}-remote:"; - Slave = ":${name}-local:"; + Far = ":${name}-remote:"; + Near = ":${name}-local:"; Patterns = mbsync.patterns; - Create = masterSlaveMapping.${mbsync.create}; - Remove = masterSlaveMapping.${mbsync.remove}; - Expunge = masterSlaveMapping.${mbsync.expunge}; + Create = nearFarMapping.${mbsync.create}; + Remove = nearFarMapping.${mbsync.remove}; + Expunge = nearFarMapping.${mbsync.expunge}; SyncState = "*"; } // mbsync.extraConfig.channel) + "\n"; # Given the attr set of groups, return a string of channels that will direct # mail to the proper directories, according to the pattern used in channel's - # master pattern definition. + # "far" pattern definition. genGroupChannelConfig = storeName: groups: let # Given the name of the group this channel is part of and the channel @@ -115,8 +144,8 @@ let else ""; in genSection "Channel ${groupName}-${channel.name}" ({ - Master = ":${storeName}-remote:${channel.masterPattern}"; - Slave = ":${storeName}-local:${channel.slavePattern}"; + Far = ":${storeName}-remote:${channel.farPattern}"; + Near = ":${storeName}-local:${channel.nearPattern}"; } // channel.extraConfig) + genChannelPatterns channel.patterns; # Given the group name, and a attr set of channels within that group, # Generate a list of strings for each channels' configuration. @@ -203,50 +232,66 @@ in { }; }; - config = mkIf cfg.enable { - assertions = let - checkAccounts = pred: msg: - let badAccounts = filter pred mbsyncAccounts; - in { - assertion = badAccounts == [ ]; - message = "mbsync: ${msg} for accounts: " - + concatMapStringsSep ", " (a: a.name) badAccounts; - }; - in [ - (checkAccounts (a: a.maildir == null) "Missing maildir configuration") - (checkAccounts (a: a.imap == null) "Missing IMAP configuration") - (checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand") - (checkAccounts (a: a.userName == null) "Missing username") - ]; + config = mkIf cfg.enable (mkMerge [ + { + assertions = let + checkAccounts = pred: msg: + let badAccounts = filter pred mbsyncAccounts; + in { + assertion = badAccounts == [ ]; + message = "mbsync: ${msg} for accounts: " + + concatMapStringsSep ", " (a: a.name) badAccounts; + }; + in [ + (checkAccounts (a: a.maildir == null) "Missing maildir configuration") + (checkAccounts (a: a.imap == null) "Missing IMAP configuration") + (checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand") + (checkAccounts (a: a.userName == null) "Missing username") + ]; + } - home.packages = [ cfg.package ]; + (mkIf (accountInvalidOption mbsyncAccounts "masterPattern") { + warnings = [ + "mbsync channels no longer use masterPattern. Use farPattern in its place." + ]; + }) - programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ]; + (mkIf (accountInvalidOption mbsyncAccounts "slavePattern") { + warnings = [ + "mbsync channels no longer use slavePattern. Use nearPattern in its place." + ]; + }) - home.file.".mbsyncrc".text = let - accountsConfig = map genAccountConfig mbsyncAccounts; - # Only generate this kind of Group configuration if there are ANY accounts - # that do NOT have a per-account groups/channels option(s) specified. - groupsConfig = - if any (account: account.mbsync.groups == { }) mbsyncAccounts then - mapAttrsToList genGroupConfig cfg.groups - else - [ ]; - in '' - # Generated by Home Manager. + { + home.packages = [ cfg.package ]; - '' - + concatStringsSep "\n" (optional (cfg.extraConfig != "") cfg.extraConfig) - + concatStringsSep "\n\n" accountsConfig - + concatStringsSep "\n" groupsConfig; + programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ]; - home.activation = mkIf (mbsyncAccounts != [ ]) { - createMaildir = - hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] '' - $DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${ - concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts - } - ''; - }; - }; + home.file.".mbsyncrc".text = let + accountsConfig = map genAccountConfig mbsyncAccounts; + # Only generate this kind of Group configuration if there are ANY accounts + # that do NOT have a per-account groups/channels option(s) specified. + groupsConfig = + if any (account: account.mbsync.groups == { }) mbsyncAccounts then + mapAttrsToList genGroupConfig cfg.groups + else + [ ]; + in '' + # Generated by Home Manager. + + '' + + concatStringsSep "\n" (optional (cfg.extraConfig != "") cfg.extraConfig) + + concatStringsSep "\n\n" accountsConfig + + concatStringsSep "\n" groupsConfig; + + home.activation = mkIf (mbsyncAccounts != [ ]) { + createMaildir = + hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] '' + $DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${ + concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts + } + ''; + }; + } + ]); } diff --git a/third_party/home-manager/modules/programs/mcfly.nix b/third_party/home-manager/modules/programs/mcfly.nix index 1206f9da56..7f73039163 100644 --- a/third_party/home-manager/modules/programs/mcfly.nix +++ b/third_party/home-manager/modules/programs/mcfly.nix @@ -27,6 +27,14 @@ in { ''; }; + enableFuzzySearch = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable fuzzy searching. + ''; + }; + enableBashIntegration = mkOption { default = true; type = types.bool; @@ -75,5 +83,7 @@ in { } (mkIf cfg.enableLightTheme { home.sessionVariables.MCFLY_LIGHT = "TRUE"; }) + + (mkIf cfg.enableFuzzySearch { home.sessionVariables.MCFLY_FUZZY = "TRUE"; }) ]); } diff --git a/third_party/home-manager/modules/programs/mercurial.nix b/third_party/home-manager/modules/programs/mercurial.nix index 8e9a3befba..2fc6e0076a 100644 --- a/third_party/home-manager/modules/programs/mercurial.nix +++ b/third_party/home-manager/modules/programs/mercurial.nix @@ -6,6 +6,8 @@ let cfg = config.programs.mercurial; + iniFormat = pkgs.formats.ini { }; + in { options = { @@ -30,19 +32,19 @@ in { }; aliases = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; description = "Mercurial aliases to define."; }; extraConfig = mkOption { - type = types.either types.attrs types.lines; + type = types.either (types.attrsOf types.anything) types.lines; default = { }; description = "Additional configuration to add."; }; iniContent = mkOption { - type = types.attrsOf types.attrs; + type = iniFormat.type; internal = true; }; @@ -71,7 +73,8 @@ in { username = cfg.userName + " <" + cfg.userEmail + ">"; }; - xdg.configFile."hg/hgrc".text = generators.toINI { } cfg.iniContent; + xdg.configFile."hg/hgrc".source = + iniFormat.generate "hgrc" cfg.iniContent; } (mkIf (cfg.ignores != [ ] || cfg.ignoresRegexp != [ ]) { diff --git a/third_party/home-manager/modules/programs/mpv.nix b/third_party/home-manager/modules/programs/mpv.nix index 7c15bd9e1b..ab82251112 100644 --- a/third_party/home-manager/modules/programs/mpv.nix +++ b/third_party/home-manager/modules/programs/mpv.nix @@ -8,9 +8,11 @@ let cfg = config.programs.mpv; mpvOption = with types; either str (either int (either bool float)); - mpvOptions = with types; attrsOf mpvOption; + mpvOptionDup = with types; either mpvOption (listOf mpvOption); + mpvOptions = with types; attrsOf mpvOptionDup; mpvProfiles = with types; attrsOf mpvOptions; mpvBindings = with types; attrsOf str; + mpvDefaultProfiles = with types; listOf str; renderOption = option: rec { @@ -22,25 +24,33 @@ let string = option; }.${typeOf option}; - renderOptions = options: - concatStringsSep "\n" (mapAttrsToList (name: value: - let - rendered = renderOption value; - length = toString (stringLength rendered); - in "${name}=%${length}%${rendered}") options); + renderOptionValue = value: + let + rendered = renderOption value; + length = toString (stringLength rendered); + in "%${length}%${rendered}"; - renderProfiles = profiles: - concatStringsSep "\n" (mapAttrsToList (name: value: '' - [${name}] - ${renderOptions value} - '') profiles); + renderOptions = generators.toKeyValue { + mkKeyValue = + generators.mkKeyValueDefault { mkValueString = renderOptionValue; } "="; + listsAsDuplicateKeys = true; + }; + + renderProfiles = generators.toINI { + mkKeyValue = + generators.mkKeyValueDefault { mkValueString = renderOptionValue; } "="; + listsAsDuplicateKeys = true; + }; renderBindings = bindings: concatStringsSep "\n" (mapAttrsToList (name: value: "${name} ${value}") bindings); + renderDefaultProfiles = profiles: + renderOptions { profile = concatStringsSep "," profiles; }; + mpvPackage = if cfg.scripts == [ ] then - pkgs.mpv + cfg.package else pkgs.wrapMpv pkgs.mpv-unwrapped { scripts = cfg.scripts; }; @@ -50,8 +60,19 @@ in { enable = mkEnableOption "mpv"; package = mkOption { + type = types.package; + default = pkgs.mpv; + example = literalExample + "pkgs.wrapMpv (pkgs.mpv-unwrapped.override { vapoursynthSupport = true; }) { youtubeSupport = true; }"; + description = '' + Package providing mpv. + ''; + }; + + finalPackage = mkOption { type = types.package; readOnly = true; + visible = false; description = '' Resulting mpv package. ''; @@ -81,7 +102,7 @@ in { example = literalExample '' { profile = "gpu-hq"; - force-window = "yes"; + force-window = true; ytdl-format = "bestvideo+bestaudio"; cache-default = 4000000; } @@ -109,6 +130,16 @@ in { ''; }; + defaultProfiles = mkOption { + description = '' + Profiles to be applied by default. Options set by them are overridden + by options set in . + ''; + type = mpvDefaultProfiles; + default = [ ]; + example = [ "gpu-hq" ]; + }; + bindings = mkOption { description = '' Input configuration written to @@ -133,12 +164,21 @@ in { }; config = mkIf cfg.enable (mkMerge [ + { + assertions = [{ + assertion = (cfg.scripts == [ ]) || (cfg.package == pkgs.mpv); + message = '' + The programs.mpv "package" option is mutually exclusive with "scripts" option.''; + }]; + } { home.packages = [ mpvPackage ]; - programs.mpv.package = mpvPackage; + programs.mpv.finalPackage = mpvPackage; } (mkIf (cfg.config != { } || cfg.profiles != { }) { xdg.configFile."mpv/mpv.conf".text = '' + ${optionalString (cfg.defaultProfiles != [ ]) + (renderDefaultProfiles cfg.defaultProfiles)} ${optionalString (cfg.config != { }) (renderOptions cfg.config)} ${optionalString (cfg.profiles != { }) (renderProfiles cfg.profiles)} ''; @@ -148,5 +188,5 @@ in { }) ]); - meta.maintainers = with maintainers; [ tadeokondrak ]; + meta.maintainers = with maintainers; [ tadeokondrak thiagokokada ]; } diff --git a/third_party/home-manager/modules/programs/msmtp.nix b/third_party/home-manager/modules/programs/msmtp.nix index 7b6704860e..f8ba6a6f72 100644 --- a/third_party/home-manager/modules/programs/msmtp.nix +++ b/third_party/home-manager/modules/programs/msmtp.nix @@ -26,9 +26,7 @@ let tls_fingerprint = msmtp.tls.fingerprint; } // optionalAttrs (smtp.port != null) { port = toString smtp.port; } // optionalAttrs (passwordCommand != null) { - # msmtp requires the password to finish with a newline. - passwordeval = - ''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"''; + passwordeval = toString passwordCommand; } // msmtp.extraConfig) ++ optional primary '' account default : ${name}''); @@ -39,6 +37,8 @@ let ${cfg.extraConfig} ${concatStringsSep "\n\n" (map accountStr mailAccounts)} + + ${cfg.extraAccounts} ''; in { @@ -53,6 +53,20 @@ in { description = '' Extra configuration lines to add to ~/.msmtprc. See for examples. + + Note, if running msmtp fails with the error message "account default + was already defined" then you probably have an account command here. + Account commands should be placed in + . + ''; + }; + + extraAccounts = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration lines to add to the end of ~/.msmtprc. + See for examples. ''; }; }; diff --git a/third_party/home-manager/modules/programs/mu.nix b/third_party/home-manager/modules/programs/mu.nix index 18c3993a15..233624d14c 100644 --- a/third_party/home-manager/modules/programs/mu.nix +++ b/third_party/home-manager/modules/programs/mu.nix @@ -50,7 +50,7 @@ in { # In theory, mu is the only thing that creates that directory, and it is # only created during the initial index. if [[ ! -d "${dbLocation}" ]]; then - $DRY_RUN_CMD mu init ${maildirOption} $VERBOSE_ARG; + $DRY_RUN_CMD mu init ${maildirOption} ${myAddresses} $VERBOSE_ARG; fi ''; }; diff --git a/third_party/home-manager/modules/programs/ncspot.nix b/third_party/home-manager/modules/programs/ncspot.nix new file mode 100644 index 0000000000..ea46c9fc29 --- /dev/null +++ b/third_party/home-manager/modules/programs/ncspot.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.ncspot; + + tomlFormat = pkgs.formats.toml { }; + +in { + meta.maintainers = [ maintainers.marsam ]; + + options.programs.ncspot = { + enable = mkEnableOption "ncspot"; + + package = mkOption { + type = types.package; + default = pkgs.ncspot; + defaultText = literalExample "pkgs.ncspot"; + description = "The package to use for ncspot."; + }; + + settings = mkOption { + type = tomlFormat.type; + default = { }; + example = literalExample '' + { + shuffle = true; + gapless = true; + } + ''; + description = '' + Configuration written to + ~/.config/ncspot/config.toml. + + See + for the full list of options. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."ncspot/config.toml" = mkIf (cfg.settings != { }) { + source = tomlFormat.generate "ncspot-config" cfg.settings; + }; + }; +} diff --git a/third_party/home-manager/modules/programs/neomutt.nix b/third_party/home-manager/modules/programs/neomutt.nix index d990f02eac..dbfe889901 100644 --- a/third_party/home-manager/modules/programs/neomutt.nix +++ b/third_party/home-manager/modules/programs/neomutt.nix @@ -54,21 +54,23 @@ let bindModule = types.submodule { options = { map = mkOption { - type = types.enum [ - "alias" - "attach" - "browser" - "compose" - "editor" - "generic" - "index" - "mix" - "pager" - "pgp" - "postpone" - "query" - "smime" - ]; + type = let + menus = [ + "alias" + "attach" + "browser" + "compose" + "editor" + "generic" + "index" + "mix" + "pager" + "pgp" + "postpone" + "query" + "smime" + ]; + in with types; either (enum menus) (listOf (enum menus)); default = "index"; description = "Select the menu to bind the command to."; }; @@ -116,15 +118,16 @@ let "${smtpProto}://${escape userName}@${smtp.host}${smtpPort}"; in { smtp_url = "'${smtpBaseUrl}'"; - smtp_pass = "'`${passCmd}`'"; + smtp_pass = ''"`${passCmd}`"''; }; genMaildirAccountConfig = account: with account; let - folderHook = mapAttrsToList setOption (genCommonFolderHooks account // { - folder = "'${account.maildir.absPath}'"; - }); + folderHook = mapAttrsToList setOption (genCommonFolderHooks account + // optionalAttrs cfg.changeFolderWhenSourcingAccount { + folder = "'${account.maildir.absPath}'"; + }); in '' ${concatStringsSep "\n" folderHook} ''; @@ -154,11 +157,16 @@ let set sidebar_format = '${cfg.sidebar.format}' ''; - bindSection = concatMapStringsSep "\n" - (bind: ''bind ${bind.map} ${bind.key} "${bind.action}"'') cfg.binds; + genBindMapper = bindType: + concatMapStringsSep "\n" (bind: + '' + ${bindType} ${ + concatStringsSep "," (toList bind.map) + } ${bind.key} "${bind.action}"''); - macroSection = concatMapStringsSep "\n" - (bind: ''macro ${bind.map} ${bind.key} "${bind.action}"'') cfg.macros; + bindSection = (genBindMapper "bind") cfg.binds; + + macroSection = (genBindMapper "macro") cfg.macros; mailCheckSection = '' set mail_check_stats @@ -182,6 +190,7 @@ let # GPG section set crypt_use_gpgme = yes set crypt_autosign = ${yesno (gpg.signByDefault or false)} + set crypt_opportunistic_encrypt = ${yesno (gpg.encryptByDefault or false)} set pgp_use_gpg_agent = yes set mbox_type = ${if maildir != null then "Maildir" else "mbox"} set sort = "${cfg.sort}" @@ -258,6 +267,11 @@ in { description = "Extra configuration appended to the end."; }; + changeFolderWhenSourcingAccount = + mkEnableOption "changing the folder when sourcing an account" // { + default = true; + }; + extraConfig = mkOption { type = types.lines; default = ""; @@ -279,7 +293,11 @@ in { in foldl' (a: b: a // b) { } (map rcFile neomuttAccounts); xdg.configFile."neomutt/neomuttrc" = mkIf (neomuttAccounts != [ ]) { - text = let primary = filter (a: a.primary) neomuttAccounts; + text = let + # Find the primary account, if it has neomutt enabled; + # otherwise use the first neomutt account as primary. + primary = + head (filter (a: a.primary) neomuttAccounts ++ neomuttAccounts); in '' # Generated by Home Manager. set header_cache = "${config.xdg.cacheHome}/neomutt/headers/" @@ -300,13 +318,31 @@ in { ${optionalString cfg.vimKeys "source ${pkgs.neomutt}/share/doc/neomutt/vim-keys/vim-keys.rc"} + # Register accounts + ${concatMapStringsSep "\n" registerAccount neomuttAccounts} + + # Source primary account + source ${accountFilename primary} + # Extra configuration ${optionsStr cfg.settings} ${cfg.extraConfig} - '' + concatMapStringsSep "\n" registerAccount neomuttAccounts + - # source primary account - "source ${accountFilename (builtins.head primary)}"; + ''; }; + + assertions = [{ + assertion = + ((filter (b: (length (toList b.map)) == 0) (cfg.binds ++ cfg.macros)) + == [ ]); + message = + "The 'programs.neomutt.(binds|macros).map' list must contain at least one element."; + }]; + + warnings = + let hasOldBinds = binds: (filter (b: !(isList b.map)) binds) != [ ]; + in mkIf (hasOldBinds (cfg.binds ++ cfg.macros)) [ + "Specifying 'programs.neomutt.(binds|macros).map' as a string is deprecated, use a list of strings instead. See https://github.com/nix-community/home-manager/pull/1885." + ]; }; } diff --git a/third_party/home-manager/modules/programs/neovim.nix b/third_party/home-manager/modules/programs/neovim.nix index ea58e3f341..8cb93bf365 100644 --- a/third_party/home-manager/modules/programs/neovim.nix +++ b/third_party/home-manager/modules/programs/neovim.nix @@ -6,14 +6,6 @@ let cfg = config.programs.neovim; - extraPythonPackageType = mkOptionType { - name = "extra-python-packages"; - description = "python packages in python.withPackages format"; - check = with types; - (x: if isFunction x then isList (x pkgs.pythonPackages) else false); - merge = mergeOneOption; - }; - extraPython3PackageType = mkOptionType { name = "extra-python3-packages"; description = "python3 packages in python.withPackages format"; @@ -24,38 +16,55 @@ let pluginWithConfigType = types.submodule { options = { - plugin = mkOption { - type = types.package; - description = "vim plugin"; - }; config = mkOption { type = types.lines; description = "vimscript for this plugin to be placed in init.vim"; default = ""; }; + + optional = mkEnableOption "optional" // { + description = "Don't load by default (load with :packadd)"; + }; + + plugin = mkOption { + type = types.package; + description = "vim plugin"; + }; }; }; # A function to get the configuration string (if any) from an element of 'plugins' pluginConfig = p: - if builtins.hasAttr "plugin" p && builtins.hasAttr "config" p then '' - " ${p.plugin.pname} {{{ + if p ? plugin && (p.config or "") != "" then '' + " ${p.plugin.pname or p.plugin.name} {{{ ${p.config} " }}} '' else ""; - moduleConfigure = optionalAttrs (cfg.extraConfig != "" - || (lib.filter (hasAttr "config") cfg.plugins) != [ ]) { - customRC = cfg.extraConfig - + pkgs.lib.concatMapStrings pluginConfig cfg.plugins; - } // optionalAttrs (cfg.plugins != [ ]) { - packages.home-manager.start = map (x: x.plugin or x) cfg.plugins; + moduleConfigure = { + packages.home-manager = { + start = filter (f: f != null) (map + (x: if x ? plugin && x.optional == true then null else (x.plugin or x)) + cfg.plugins); + opt = filter (f: f != null) + (map (x: if x ? plugin && x.optional == true then x.plugin else null) + cfg.plugins); }; + beforePlugins = ""; + }; + extraMakeWrapperArgs = lib.optionalString (cfg.extraPackages != [ ]) - ''--prefix PATH : "${lib.makeBinPath cfg.extraPackages}"''; + ''--suffix PATH : "${lib.makeBinPath cfg.extraPackages}"''; in { + imports = [ + (mkRemovedOptionModule [ "programs" "neovim" "withPython" ] + "Python2 support has been removed from neovim.") + (mkRemovedOptionModule [ "programs" "neovim" "extraPythonPackages" ] + "Python2 support has been removed from neovim.") + ]; + options = { programs.neovim = { enable = mkEnableOption "Neovim"; @@ -93,26 +102,6 @@ in { ''; }; - withPython = mkOption { - type = types.bool; - default = true; - description = '' - Enable Python 2 provider. Set to true to - use Python 2 plugins. - ''; - }; - - extraPythonPackages = mkOption { - type = with types; either extraPythonPackageType (listOf package); - default = (_: [ ]); - defaultText = "ps: []"; - example = literalExample "(ps: with ps; [ pandas jedi ])"; - description = '' - A function in python.withPackages format, which returns a - list of Python 2 packages required for your plugins to work. - ''; - }; - withRuby = mkOption { type = types.nullOr types.bool; default = true; @@ -156,7 +145,7 @@ in { }; configure = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; example = literalExample '' configure = { @@ -172,6 +161,8 @@ in { }; ''; description = '' + Deprecated. Please use the other options. + Generate your init file from your list of plugins and custom commands, and loads it from the store via nvim -u /nix/store/hash-vimrc @@ -229,23 +220,36 @@ in { }; }; - config = mkIf cfg.enable { - assertions = [{ - assertion = cfg.configure == { } || moduleConfigure == { }; - message = "The programs.neovim option configure is mutually exclusive" - + " with extraConfig and plugins."; - }]; + config = let + neovimConfig = pkgs.neovimUtils.makeNeovimConfig { + inherit (cfg) + extraPython3Packages withPython3 withNodeJs withRuby viAlias vimAlias; + configure = cfg.configure // moduleConfigure; + plugins = cfg.plugins; + customRC = cfg.extraConfig; + }; + + in mkIf cfg.enable { + warnings = optional (cfg.configure != { }) '' + programs.neovim.configure is deprecated. + Other programs.neovim options can override its settings or ignore them. + Please use the other options at your disposal: + configure.packages.*.opt -> programs.neovim.plugins = [ { plugin = ...; optional = true; }] + configure.packages.*.start -> programs.neovim.plugins = [ { plugin = ...; }] + configure.customRC -> programs.neovim.extraConfig + ''; home.packages = [ cfg.finalPackage ]; - programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package { - inherit (cfg) - extraPython3Packages withPython3 extraPythonPackages withPython - withNodeJs withRuby viAlias vimAlias; - - extraMakeWrapperArgs = extraMakeWrapperArgs; - configure = cfg.configure // moduleConfigure; + xdg.configFile = mkIf (neovimConfig.neovimRcContent != "") { + "nvim/init.vim".text = neovimConfig.neovimRcContent; }; + programs.neovim.finalPackage = pkgs.wrapNeovimUnstable cfg.package + (neovimConfig // { + wrapperArgs = (lib.escapeShellArgs neovimConfig.wrapperArgs) + " " + + extraMakeWrapperArgs; + wrapRc = false; + }); programs.bash.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; }; programs.fish.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; }; diff --git a/third_party/home-manager/modules/programs/newsboat.nix b/third_party/home-manager/modules/programs/newsboat.nix index 793b30680b..eac4cce8c0 100644 --- a/third_party/home-manager/modules/programs/newsboat.nix +++ b/third_party/home-manager/modules/programs/newsboat.nix @@ -6,7 +6,35 @@ let cfg = config.programs.newsboat; wrapQuote = x: ''"${x}"''; + urlsFileContents = let + mkUrlEntry = u: + concatStringsSep " " ([ u.url ] ++ map wrapQuote u.tags + ++ optional (u.title != null) (wrapQuote "~${u.title}")); + urls = map mkUrlEntry cfg.urls; + + mkQueryEntry = n: v: ''"query:${n}:${escape [ ''"'' ] v}"''; + queries = mapAttrsToList mkQueryEntry cfg.queries; + in concatStringsSep "\n" + (if versionAtLeast config.home.stateVersion "20.03" then + queries ++ urls + else + urls ++ queries) + "\n"; + + configFileContents = '' + max-items ${toString cfg.maxItems} + browser ${cfg.browser} + reload-threads ${toString cfg.reloadThreads} + auto-reload ${if cfg.autoReload then "yes" else "no"} + ${optionalString (cfg.reloadTime != null) + (toString "reload-time ${toString cfg.reloadTime}")} + prepopulate-query-feeds yes + + ${cfg.extraConfig} + ''; + in { + meta.maintainers = [ maintainers.sumnerevans ]; + options = { programs.newsboat = { enable = mkEnableOption "the Newsboat feed reader"; @@ -71,7 +99,7 @@ in { browser = mkOption { type = types.str; - default = "${pkgs.xdg_utils}/bin/xdg-open"; + default = "${pkgs.xdg-utils}/bin/xdg-open"; description = "External browser to use."; }; @@ -94,30 +122,16 @@ in { config = mkIf cfg.enable { home.packages = [ pkgs.newsboat ]; - home.file.".newsboat/urls".text = let - mkUrlEntry = u: - concatStringsSep " " ([ u.url ] ++ map wrapQuote u.tags - ++ optional (u.title != null) (wrapQuote "~${u.title}")); - urls = map mkUrlEntry cfg.urls; - mkQueryEntry = n: v: ''"query:${n}:${escape [ ''"'' ] v}"''; - queries = mapAttrsToList mkQueryEntry cfg.queries; - in concatStringsSep "\n" - (if versionAtLeast config.home.stateVersion "20.03" then - queries ++ urls - else - urls ++ queries) + "\n"; - - home.file.".newsboat/config".text = '' - max-items ${toString cfg.maxItems} - browser ${cfg.browser} - reload-threads ${toString cfg.reloadThreads} - auto-reload ${if cfg.autoReload then "yes" else "no"} - ${optionalString (cfg.reloadTime != null) - (toString "reload-time ${toString cfg.reloadTime}")} - prepopulate-query-feeds yes - - ${cfg.extraConfig} - ''; + # Use ~/.newsboat on stateVersion < 21.05 and use ~/.config/newsboat for + # stateVersion >= 21.05. + home.file = mkIf (versionOlder config.home.stateVersion "21.05") { + ".newsboat/urls".text = urlsFileContents; + ".newsboat/config".text = configFileContents; + }; + xdg.configFile = mkIf (versionAtLeast config.home.stateVersion "21.05") { + "newsboat/urls".text = urlsFileContents; + "newsboat/config".text = configFileContents; + }; }; } diff --git a/third_party/home-manager/modules/programs/nix-index.nix b/third_party/home-manager/modules/programs/nix-index.nix new file mode 100644 index 0000000000..38115d4c50 --- /dev/null +++ b/third_party/home-manager/modules/programs/nix-index.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: +let cfg = config.programs.nix-index; +in { + meta.maintainers = with lib.hm.maintainers; [ ambroisie ]; + + options.programs.nix-index = with lib; { + enable = mkEnableOption "nix-index, a file database for nixpkgs"; + + package = mkOption { + type = types.package; + default = pkgs.nix-index; + defaultText = literalExample "pkgs.nix-index"; + description = "Package providing the nix-index tool."; + }; + + enableBashIntegration = mkEnableOption "Bash integration" // { + default = true; + }; + + enableZshIntegration = mkEnableOption "Zsh integration" // { + default = true; + }; + + enableFishIntegration = mkEnableOption "Fish integration" // { + default = true; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = let + checkOpt = name: { + assertion = cfg.${name} -> !config.programs.command-not-found.enable; + message = '' + The 'programs.command-not-found.enable' option is mutually exclusive + with the 'programs.nix-index.${name}' option. + ''; + }; + in [ (checkOpt "enableBashIntegration") (checkOpt "enableZshIntegration") ]; + + home.packages = [ cfg.package ]; + + programs.bash.initExtra = lib.mkIf cfg.enableBashIntegration '' + source ${cfg.package}/etc/profile.d/command-not-found.sh + ''; + + programs.zsh.initExtra = lib.mkIf cfg.enableZshIntegration '' + source ${cfg.package}/etc/profile.d/command-not-found.sh + ''; + + # See https://github.com/bennofs/nix-index/issues/126 + programs.fish.shellInit = let + wrapper = pkgs.writeScript "command-not-found" '' + #!${pkgs.bash}/bin/bash + source ${cfg.package}/etc/profile.d/command-not-found.sh + command_not_found_handle "$@" + ''; + in lib.mkIf cfg.enableFishIntegration '' + function __fish_command_not_found_handler --on-event fish_command_not_found + ${wrapper} $argv + end + ''; + }; +} diff --git a/third_party/home-manager/modules/programs/nushell.nix b/third_party/home-manager/modules/programs/nushell.nix index 1eb42f9515..1a53a71f4d 100644 --- a/third_party/home-manager/modules/programs/nushell.nix +++ b/third_party/home-manager/modules/programs/nushell.nix @@ -6,16 +6,7 @@ let cfg = config.programs.nushell; - configFile = config: - pkgs.runCommand "config.toml" { - buildInputs = [ pkgs.remarshal ]; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - remarshal -if json -of toml \ - < ${pkgs.writeText "config.json" (builtins.toJSON config)} \ - > $out - ''; + tomlFormat = pkgs.formats.toml { }; in { meta.maintainers = [ maintainers.Philipp-M ]; @@ -53,7 +44,7 @@ in { Configuration written to ~/.config/nushell/config.toml. - See for the full list + See for the full list of options. ''; }; @@ -62,7 +53,8 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; - xdg.configFile."nu/config.toml" = - mkIf (cfg.settings != { }) { source = configFile cfg.settings; }; + xdg.configFile."nu/config.toml" = mkIf (cfg.settings != { }) { + source = tomlFormat.generate "nushell-config" cfg.settings; + }; }; } diff --git a/third_party/home-manager/modules/programs/obs-studio.nix b/third_party/home-manager/modules/programs/obs-studio.nix index 6df5978384..1ebde7f4bd 100644 --- a/third_party/home-manager/modules/programs/obs-studio.nix +++ b/third_party/home-manager/modules/programs/obs-studio.nix @@ -5,22 +5,6 @@ with lib; let cfg = config.programs.obs-studio; - package = pkgs.obs-studio; - - mkPluginEnv = packages: - let - pluginDirs = map (pkg: "${pkg}/share/obs/obs-plugins") packages; - plugins = concatMapStringsSep " " (p: "${p}/*") pluginDirs; - in pkgs.runCommand "obs-studio-plugins" { - preferLocalBuild = true; - allowSubstitutes = false; - } '' - mkdir $out - [[ '${plugins}' ]] || exit 0 - for plugin in ${plugins}; do - ln -s "$plugin" $out/ - done - ''; in { meta.maintainers = [ maintainers.adisbladis ]; @@ -29,9 +13,25 @@ in { programs.obs-studio = { enable = mkEnableOption "obs-studio"; + package = mkOption { + type = types.package; + default = pkgs.obs-studio; + defaultText = literalExample "pkgs.obs-studio"; + description = '' + OBS Studio package to install. + ''; + }; + + finalPackage = mkOption { + type = types.package; + visible = false; + readOnly = true; + description = "Resulting customized OBS Studio package."; + }; + plugins = mkOption { default = [ ]; - example = literalExample "[ pkgs.obs-linuxbrowser ]"; + example = literalExample "[ pkgs.obs-studio-plugins.wlrobs ]"; description = "Optional OBS plugins."; type = types.listOf types.package; }; @@ -39,9 +39,10 @@ in { }; config = mkIf cfg.enable { - home.packages = [ package ]; - - xdg.configFile."obs-studio/plugins" = - mkIf (cfg.plugins != [ ]) { source = mkPluginEnv cfg.plugins; }; + home.packages = [ cfg.finalPackage ]; + programs.obs-studio.finalPackage = + pkgs.wrapOBS.override { obs-studio = cfg.package; } { + plugins = cfg.plugins; + }; }; } diff --git a/third_party/home-manager/modules/programs/octant.nix b/third_party/home-manager/modules/programs/octant.nix new file mode 100644 index 0000000000..347d0d4685 --- /dev/null +++ b/third_party/home-manager/modules/programs/octant.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.octant; + + mkPluginEnv = packages: + let + pluginDirs = map (pkg: "${pkg}/bin") packages; + plugins = concatMapStringsSep " " (p: "${p}/*") pluginDirs; + in pkgs.runCommandLocal "octant-plugins" { } '' + mkdir $out + [[ '${plugins}' ]] || exit 0 + for plugin in ${plugins}; do + ln -s "$plugin" $out/ + done + ''; + +in { + meta.maintainers = with maintainers; [ jk ]; + + options = { + programs.octant = { + enable = mkEnableOption "octant"; + + package = mkOption { + type = types.package; + default = pkgs.octant; + defaultText = literalExample "pkgs.octant"; + example = literalExample "pkgs.octant-other"; + description = "The Octant package to use."; + }; + + plugins = mkOption { + default = [ ]; + example = literalExample "[ pkgs.starboard-octant-plugin ]"; + description = "Optional Octant plugins."; + type = types.listOf types.package; + }; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."octant/plugins" = + mkIf (cfg.plugins != [ ]) { source = mkPluginEnv cfg.plugins; }; + }; +} diff --git a/third_party/home-manager/modules/programs/offlineimap.nix b/third_party/home-manager/modules/programs/offlineimap.nix index b6ba847e9b..edb6e73604 100644 --- a/third_party/home-manager/modules/programs/offlineimap.nix +++ b/third_party/home-manager/modules/programs/offlineimap.nix @@ -65,7 +65,7 @@ let remotePassEval = let arglist = concatMapStringsSep "," (x: "'${x}'") passwordCommand; in optionalAttrs (passwordCommand != null) { - remotepasseval = ''get_pass("${name}", [${arglist}])''; + remotepasseval = ''get_pass("${name}", [${arglist}]).strip("\n")''; }; in toIni { "Account ${name}" = { @@ -158,6 +158,17 @@ in { home.packages = [ pkgs.offlineimap ]; xdg.configFile."offlineimap/get_settings.py".text = cfg.pythonFile; + xdg.configFile."offlineimap/get_settings.pyc".source = "${ + pkgs.runCommandLocal "get_settings-compile" { + nativeBuildInputs = [ pkgs.python2 ]; + pythonFile = cfg.pythonFile; + passAsFile = [ "pythonFile" ]; + } '' + mkdir -p $out/bin + cp $pythonFilePath $out/bin/get_settings.py + python2 -m py_compile $out/bin/get_settings.py + '' + }/bin/get_settings.pyc"; xdg.configFile."offlineimap/config".text = '' # Generated by Home Manager. diff --git a/third_party/home-manager/modules/programs/password-store.nix b/third_party/home-manager/modules/programs/password-store.nix index db31146a1b..658750b8ef 100644 --- a/third_party/home-manager/modules/programs/password-store.nix +++ b/third_party/home-manager/modules/programs/password-store.nix @@ -58,5 +58,8 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; home.sessionVariables = cfg.settings; + + xsession.importedVariables = mkIf config.xsession.enable + (mapAttrsToList (name: value: name) cfg.settings); }; } diff --git a/third_party/home-manager/modules/programs/pet.nix b/third_party/home-manager/modules/programs/pet.nix index 0da205dab9..1de4f7e6f0 100644 --- a/third_party/home-manager/modules/programs/pet.nix +++ b/third_party/home-manager/modules/programs/pet.nix @@ -36,6 +36,15 @@ let Example output of the command. ''; }; + + tag = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExample ''["git" "nixpkgs"]''; + description = '' + List of tags attached to the command. + ''; + }; }; }; diff --git a/third_party/home-manager/modules/programs/piston-cli.nix b/third_party/home-manager/modules/programs/piston-cli.nix new file mode 100644 index 0000000000..d2e1373caa --- /dev/null +++ b/third_party/home-manager/modules/programs/piston-cli.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.piston-cli; + yamlFormat = pkgs.formats.yaml { }; +in { + meta.maintainers = with maintainers; [ ethancedwards8 ]; + + options.programs.piston-cli = { + enable = mkEnableOption "piston-cli, code runner"; + + package = mkOption { + type = types.package; + default = pkgs.piston-cli; + defaultText = literalExample "pkgs.piston-cli"; + description = "The piston-cli package to use."; + }; + + settings = mkOption { + type = yamlFormat.type; + default = { }; + example = literalExample '' + { + theme = "emacs"; + box_style = "MINIMAL_DOUBLE_HEAD"; + prompt_continuation = "..."; + prompt_start = ">>>"; + } + ''; + description = '' + Configuration written to + $XDG_CONFIG_HOME/piston-cli/config.yml. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."piston-cli/config.yml" = mkIf (cfg.settings != { }) { + source = yamlFormat.generate "config.yml" cfg.settings; + }; + }; +} diff --git a/third_party/home-manager/modules/programs/powerline-go.nix b/third_party/home-manager/modules/programs/powerline-go.nix index a4cd233cf7..8f5db8f260 100644 --- a/third_party/home-manager/modules/programs/powerline-go.nix +++ b/third_party/home-manager/modules/programs/powerline-go.nix @@ -106,17 +106,38 @@ in { }; }; - config = mkIf (cfg.enable && config.programs.bash.enable) { - programs.bash.initExtra = '' - function _update_ps1() { - local old_exit_status=$? - PS1="$(${pkgs.powerline-go}/bin/powerline-go -error $old_exit_status ${commandLineArguments})" + config = { + programs.bash.initExtra = + mkIf (cfg.enable && config.programs.bash.enable) '' + function _update_ps1() { + local old_exit_status=$? + PS1="$(${pkgs.powerline-go}/bin/powerline-go -error $old_exit_status ${commandLineArguments})" + ${cfg.extraUpdatePS1} + return $old_exit_status + } + + if [ "$TERM" != "linux" ]; then + PROMPT_COMMAND="_update_ps1;$PROMPT_COMMAND" + fi + ''; + + programs.zsh.initExtra = mkIf (cfg.enable && config.programs.zsh.enable) '' + function powerline_precmd() { + PS1="$(${pkgs.powerline-go}/bin/powerline-go -error $? -shell zsh ${commandLineArguments})" ${cfg.extraUpdatePS1} - return $old_exit_status + } + + function install_powerline_precmd() { + for s in "$\{precmd_functions[@]}"; do + if [ "$s" = "powerline_precmd" ]; then + return + fi + done + precmd_functions+=(powerline_precmd) } if [ "$TERM" != "linux" ]; then - PROMPT_COMMAND="_update_ps1;$PROMPT_COMMAND" + install_powerline_precmd fi ''; }; diff --git a/third_party/home-manager/modules/programs/qutebrowser.nix b/third_party/home-manager/modules/programs/qutebrowser.nix index 798363fb18..8d4868fbb5 100644 --- a/third_party/home-manager/modules/programs/qutebrowser.nix +++ b/third_party/home-manager/modules/programs/qutebrowser.nix @@ -32,6 +32,8 @@ let ''config.bind("${k}", "${escape [ ''"'' ] c}", mode="${m}")''; in concatStringsSep "\n" (mapAttrsToList (formatKeyBinding m) b); + formatQuickmarks = n: s: "${n} ${s}"; + in { options.programs.qutebrowser = { enable = mkEnableOption "qutebrowser"; @@ -51,6 +53,14 @@ in { ''; }; + loadAutoconfig = mkOption { + type = types.bool; + default = false; + description = '' + Load settings configured via the GUI. + ''; + }; + searchEngines = mkOption { type = types.attrsOf types.str; default = { }; @@ -78,7 +88,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; description = '' Options to add to qutebrowser config.py file. @@ -243,6 +253,21 @@ in { ''; }; + quickmarks = mkOption { + type = types.attrsOf types.str; + default = { }; + description = '' + Quickmarks to add to qutebrowser's quickmarks file. + Note that when Home Manager manages your quickmarks, you cannot edit them at runtime. + ''; + example = literalExample '' + { + nixpkgs = "https://github.com/NixOS/nixpkgs"; + home-manager = "https://github.com/nix-community/home-manager"; + } + ''; + }; + extraConfig = mkOption { type = types.lines; default = ""; @@ -252,11 +277,13 @@ in { }; }; - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; - - xdg.configFile."qutebrowser/config.py".text = concatStringsSep "\n" ([ ] - ++ mapAttrsToList (formatLine "c.") cfg.settings + config = let + qutebrowserConfig = concatStringsSep "\n" ([ + (if cfg.loadAutoconfig then + "config.load_autoconfig()" + else + "config.load_autoconfig(False)") + ] ++ mapAttrsToList (formatLine "c.") cfg.settings ++ mapAttrsToList (formatDictLine "c.aliases") cfg.aliases ++ mapAttrsToList (formatDictLine "c.url.searchengines") cfg.searchEngines ++ mapAttrsToList (formatDictLine "c.bindings.key_mappings") @@ -264,5 +291,26 @@ in { ++ optional (!cfg.enableDefaultBindings) "c.bindings.default = {}" ++ mapAttrsToList formatKeyBindings cfg.keyBindings ++ optional (cfg.extraConfig != "") cfg.extraConfig); + + quickmarksFile = optionals (cfg.quickmarks != { }) concatStringsSep "\n" + ((mapAttrsToList formatQuickmarks cfg.quickmarks)); + in mkIf cfg.enable { + home.packages = [ cfg.package ]; + + home.file.".qutebrowser/config.py" = + mkIf pkgs.stdenv.hostPlatform.isDarwin { text = qutebrowserConfig; }; + + home.file.".qutebrowser/quickmarks" = + mkIf (cfg.quickmarks != { } && pkgs.stdenv.hostPlatform.isDarwin) { + text = quickmarksFile; + }; + + xdg.configFile."qutebrowser/config.py" = + mkIf pkgs.stdenv.hostPlatform.isLinux { text = qutebrowserConfig; }; + + xdg.configFile."qutebrowser/quickmarks" = + mkIf (cfg.quickmarks != { } && pkgs.stdenv.hostPlatform.isLinux) { + text = quickmarksFile; + }; }; } diff --git a/third_party/home-manager/modules/programs/rbw.nix b/third_party/home-manager/modules/programs/rbw.nix new file mode 100644 index 0000000000..8c074aeaa3 --- /dev/null +++ b/third_party/home-manager/modules/programs/rbw.nix @@ -0,0 +1,116 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.programs.rbw; + + jsonFormat = pkgs.formats.json { }; + + inherit (pkgs.stdenv.hostPlatform) isDarwin; + + settingsModule = with lib; + types.submodule { + freeformType = jsonFormat.type; + options = { + email = mkOption { + type = types.str; + example = "name@example.com"; + description = "The email address for your bitwarden account."; + }; + + base_url = mkOption { + type = with types; nullOr str; + default = null; + example = "bitwarden.example.com"; + description = + "The base-url for a self-hosted bitwarden installation."; + }; + + identity_url = mkOption { + type = with types; nullOr str; + default = null; + example = "identity.example.com"; + description = "The identity url for your bitwarden installation."; + }; + + lock_timeout = mkOption { + type = types.ints.unsigned; + default = 3600; + example = 300; + description = '' + The amount of time that your login information should be cached. + ''; + }; + + pinentry = mkOption { + type = with types; either package (enum pkgs.pinentry.flavors); + example = "gnome3"; + default = "gtk2"; + description = '' + Which pinentry interface to use. Beware that + pinentry-gnome3 may not work on non-Gnome + systems. You can fix it by adding the following to your + system configuration: + + services.dbus.packages = [ pkgs.gcr ]; + + For this reason, the default is gtk2 for + now. + ''; + # we want the program in the config + apply = val: + if builtins.isString val then + "${pkgs.pinentry.${val}}/bin/pinentry" + else + "${val}/${val.binaryPath or "bin/pinentry"}"; + }; + }; + }; +in { + meta.maintainers = with lib.hm.maintainers; [ ambroisie ]; + + options.programs.rbw = with lib; { + enable = mkEnableOption "rwb, a CLI Bitwarden client"; + + package = mkOption { + type = types.package; + default = pkgs.rbw; + defaultText = literalExample "pkgs.rbw"; + description = '' + Package providing the rbw tool and its + rbw-agent daemon. + ''; + }; + + settings = mkOption { + type = types.nullOr settingsModule; + default = null; + example = literalExample '' + { + email = "name@example.com"; + lock_timeout = 300; + pinentry = "gnome3"; + } + ''; + description = '' + rbw configuration, if not defined the configuration will not be + managed by Home Manager. + ''; + }; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + { + home.packages = [ cfg.package ]; + } + + # Only manage configuration if not empty + (lib.mkIf (cfg.settings != null && !isDarwin) { + xdg.configFile."rbw/config.json".source = + jsonFormat.generate "rbw-config.json" cfg.settings; + }) + + (lib.mkIf (cfg.settings != null && isDarwin) { + home.file."Library/Application Support/rbw/config.json".source = + jsonFormat.generate "rbw-config.json" cfg.settings; + }) + ]); +} diff --git a/third_party/home-manager/modules/programs/rofi-pass.nix b/third_party/home-manager/modules/programs/rofi-pass.nix new file mode 100644 index 0000000000..da75299e67 --- /dev/null +++ b/third_party/home-manager/modules/programs/rofi-pass.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.rofi.pass; + +in { + meta.maintainers = [ maintainers.seylerius ]; + + options.programs.rofi.pass = { + enable = mkEnableOption "rofi integration with password-store"; + + stores = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + Directory roots of your password-stores. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + URL_field='url' + USERNAME_field='user' + AUTOTYPE_field='autotype' + ''; + description = '' + Extra configuration to be added at to the rofi-pass config file. + Additional examples can be found at + . + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ pkgs.rofi-pass ]; + + xdg.configFile."rofi-pass/config".text = optionalString (cfg.stores != [ ]) + ("root=" + (concatStringsSep ":" cfg.stores) + "\n") + cfg.extraConfig + + optionalString (cfg.extraConfig != "") "\n"; + }; +} diff --git a/third_party/home-manager/modules/programs/rofi.nix b/third_party/home-manager/modules/programs/rofi.nix index 734bcc423e..f4f7594e13 100644 --- a/third_party/home-manager/modules/programs/rofi.nix +++ b/third_party/home-manager/modules/programs/rofi.nix @@ -1,7 +1,6 @@ { config, lib, pkgs, ... }: with lib; -with builtins; let @@ -71,21 +70,9 @@ let }; }; - valueToString = value: - if isBool value then (if value then "true" else "else") else toString value; - windowColorsToString = window: concatStringsSep ", " (with window; [ background border separator ]); - rowsColorsToString = rows: '' - ${optionalString (rows.normal != null) - (setOption "color-normal" (rowColorsToString rows.normal))} - ${optionalString (rows.active != null) - (setOption "color-active" (rowColorsToString rows.active))} - ${optionalString (rows.urgent != null) - (setOption "color-urgent" (rowColorsToString rows.urgent))} - ''; - rowColorsToString = row: concatStringsSep ", " (with row; [ background @@ -95,15 +82,62 @@ let highlight.foreground ]); - setOption = name: value: - optionalString (value != null) "rofi.${name}: ${valueToString value}"; + mkColorScheme = colors: + if colors != null then + with colors; { + color-window = + if (window != null) then (windowColorsToString window) else null; + color-normal = if (rows != null && rows.normal != null) then + (rowColorsToString rows.normal) + else + null; + color-active = if (rows != null && rows.active != null) then + (rowColorsToString rows.active) + else + null; + color-urgent = if (rows != null && rows.active != null) then + (rowColorsToString rows.urgent) + else + null; + } + else + { }; - setColorScheme = colors: - optionalString (colors != null) '' - ${optionalString (colors.window != null) setOption "color-window" - (windowColorsToString colors.window)} - ${optionalString (colors.rows != null) (rowsColorsToString colors.rows)} - ''; + mkValueString = value: + if isBool value then + if value then "true" else "false" + else if isInt value then + toString value + else if value._type or "" == "literal" then + value.value + else if isString value then + ''"${value}"'' + else if isList value then + "[ ${strings.concatStringsSep "," (map mkValueString value)} ]" + else + abort "Unhandled value type ${builtins.typeOf value}"; + + mkKeyValue = { sep ? ": ", end ? ";" }: + name: value: + "${name}${sep}${mkValueString value}${end}"; + + mkRasiSection = name: value: + if isAttrs value then + let + toRasiKeyValue = generators.toKeyValue { mkKeyValue = mkKeyValue { }; }; + # Remove null values so the resulting config does not have empty lines + configStr = toRasiKeyValue (filterAttrs (_: v: v != null) value); + in '' + ${name} { + ${configStr}} + '' + else + mkKeyValue { + sep = " "; + end = ""; + } name value; + + toRasi = attrs: concatStringsSep "\n" (mapAttrsToList mkRasiSection attrs); locationsMap = { center = 0; @@ -117,14 +151,45 @@ let left = 8; }; + primitive = with types; (oneOf [ str int bool rasiLiteral ]); + + # Either a `section { foo: "bar"; }` or a `@import/@theme "some-text"` + configType = with types; + (either (attrsOf (either primitive (listOf primitive))) str); + + rasiLiteral = types.submodule { + options = { + _type = mkOption { + type = types.enum [ "literal" ]; + internal = true; + }; + + value = mkOption { + type = types.str; + internal = true; + }; + }; + } // { + description = "Rasi literal string"; + }; + + themeType = with types; attrsOf configType; + themeName = if (cfg.theme == null) then null - else if (lib.isString cfg.theme) then + else if (isString cfg.theme) then cfg.theme + else if (isAttrs cfg.theme) then + "custom" else - lib.removeSuffix ".rasi" (baseNameOf cfg.theme); + removeSuffix ".rasi" (baseNameOf cfg.theme); - themePath = if (lib.isString cfg.theme) then null else cfg.theme; + themePath = if (isString cfg.theme) then + null + else if (isAttrs cfg.theme) then + "custom" + else + cfg.theme; in { options.programs.rofi = { @@ -142,6 +207,15 @@ in { ''; }; + plugins = mkOption { + default = [ ]; + type = types.listOf types.package; + description = '' + List of rofi plugins to be installed. + ''; + example = literalExample "[ pkgs.rofi-calc ]"; + }; + width = mkOption { default = null; type = types.nullOr types.int; @@ -196,7 +270,7 @@ in { description = '' Path to the terminal which will be used to run console applications ''; - example = "\${pkgs.gnome3.gnome_terminal}/bin/gnome-terminal"; + example = "\${pkgs.gnome.gnome_terminal}/bin/gnome-terminal"; }; separator = mkOption { @@ -220,7 +294,7 @@ in { location = mkOption { default = "center"; - type = types.enum (builtins.attrNames locationsMap); + type = types.enum (attrNames locationsMap); description = "The location rofi appears on the screen."; }; @@ -274,25 +348,54 @@ in { theme = mkOption { default = null; - type = with types; nullOr (either str path); - example = "Arc"; + type = with types; nullOr (oneOf [ str path themeType ]); + example = literalExample '' + let + inherit (config.lib.formats.rasi) mkLiteral; + in { + "*" = { + background-color = mkLiteral "#000000"; + foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )"; + border-color = mkLiteral "#FFFFFF"; + width = 512; + }; + + "#inputbar" = { + children = map mkLiteral [ "prompt" "entry" ]; + }; + + "#textbox-prompt-colon" = { + expand = false; + str = ":"; + margin = mkLiteral "0px 0.3em 0em 0em"; + text-color = mkLiteral "@foreground-color"; + }; + } + ''; description = '' - Name of theme or path to theme file in rasi format. Available - named themes can be viewed using the + Name of theme or path to theme file in rasi format or attribute set with + theme configuration. Available named themes can be viewed using the rofi-theme-selector tool. ''; }; configPath = mkOption { - default = "${config.xdg.configHome}/rofi/config"; - defaultText = "$XDG_CONFIG_HOME/rofi/config"; + default = "${config.xdg.configHome}/rofi/config.rasi"; + defaultText = "$XDG_CONFIG_HOME/rofi/config.rasi"; type = types.str; description = "Path where to put generated configuration file."; }; extraConfig = mkOption { - default = ""; - type = types.lines; + default = { }; + example = literalExample '' + { + modi = "drun,emoji,ssh"; + kb-primary-paste = "Control+V,Shift+Insert"; + kb-secondary-paste = "Control+v,Insert"; + } + ''; + type = configType; description = "Additional configuration to add."; }; @@ -306,33 +409,47 @@ in { ''; }]; - home.packages = [ cfg.package ]; - - home.file."${cfg.configPath}".text = '' - ${setOption "width" cfg.width} - ${setOption "lines" cfg.lines} - ${setOption "font" cfg.font} - ${setOption "bw" cfg.borderWidth} - ${setOption "eh" cfg.rowHeight} - ${setOption "padding" cfg.padding} - ${setOption "separator-style" cfg.separator} - ${setOption "hide-scrollbar" - (if (cfg.scrollbar != null) then (!cfg.scrollbar) else cfg.scrollbar)} - ${setOption "terminal" cfg.terminal} - ${setOption "cycle" cfg.cycle} - ${setOption "fullscreen" cfg.fullscreen} - ${setOption "location" (builtins.getAttr cfg.location locationsMap)} - ${setOption "xoffset" cfg.xoffset} - ${setOption "yoffset" cfg.yoffset} - - ${setColorScheme cfg.colors} - ${setOption "theme" themeName} - - ${cfg.extraConfig} - ''; - - xdg.dataFile = mkIf (themePath != null) { - "rofi/themes/${themeName}.rasi".source = themePath; + lib.formats.rasi.mkLiteral = value: { + _type = "literal"; + inherit value; }; + + home.packages = let + rofiWithPlugins = cfg.package.override + (old: rec { plugins = (old.plugins or [ ]) ++ cfg.plugins; }); + rofiPackage = if builtins.hasAttr "override" cfg.package then + rofiWithPlugins + else + cfg.package; + in [ rofiPackage ]; + + home.file."${cfg.configPath}".text = toRasi { + configuration = ({ + width = cfg.width; + lines = cfg.lines; + font = cfg.font; + bw = cfg.borderWidth; + eh = cfg.rowHeight; + padding = cfg.padding; + separator-style = cfg.separator; + hide-scrollbar = + if (cfg.scrollbar != null) then (!cfg.scrollbar) else null; + terminal = cfg.terminal; + cycle = cfg.cycle; + fullscreen = cfg.fullscreen; + location = (getAttr cfg.location locationsMap); + xoffset = cfg.xoffset; + yoffset = cfg.yoffset; + theme = themeName; + } // (mkColorScheme cfg.colors) // cfg.extraConfig); + }; + + xdg.dataFile = mkIf (themePath != null) (if themePath == "custom" then { + "rofi/themes/${themeName}.rasi".text = toRasi cfg.theme; + } else { + "rofi/themes/${themeName}.rasi".source = themePath; + }); }; + + meta.maintainers = with maintainers; [ thiagokokada ]; } diff --git a/third_party/home-manager/modules/programs/sbt.nix b/third_party/home-manager/modules/programs/sbt.nix new file mode 100644 index 0000000000..d3ba31e193 --- /dev/null +++ b/third_party/home-manager/modules/programs/sbt.nix @@ -0,0 +1,141 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + renderPlugin = plugin: '' + addSbtPlugin("${plugin.org}" % "${plugin.artifact}" % "${plugin.version}") + ''; + + renderCredential = cred: '' + credentials += Credentials("${cred.realm}", "${cred.host}", "${cred.user}", "${cred.passwordCommand}".!!) + ''; + + renderCredentials = creds: '' + import scala.sys.process._ + ${concatStrings (map renderCredential creds)}''; + + sbtTypes = { + plugin = types.submodule { + options = { + org = mkOption { + type = types.str; + description = "The organization the artifact is published under."; + }; + + artifact = mkOption { + type = types.str; + description = "The name of the artifact."; + }; + + version = mkOption { + type = types.str; + description = "The version of the plugin."; + }; + }; + }; + + credential = types.submodule { + options = { + realm = mkOption { + type = types.str; + description = "The realm of the repository you're authenticating to."; + }; + + host = mkOption { + type = types.str; + description = + "The hostname of the repository you're authenticating to."; + }; + + user = mkOption { + type = types.str; + description = "The user you're using to authenticate."; + }; + + passwordCommand = mkOption { + type = types.str; + description = '' + The command that provides the password or authentication token for + the repository. + ''; + }; + }; + }; + }; + + cfg = config.programs.sbt; + +in { + meta.maintainers = [ maintainers.kubukoz ]; + + options.programs.sbt = { + enable = mkEnableOption "sbt"; + + package = mkOption { + type = types.package; + default = pkgs.sbt; + defaultText = literalExample "pkgs.sbt"; + description = "The package with sbt to be installed."; + }; + + baseConfigPath = mkOption { + type = types.str; + default = ".sbt/1.0"; + description = "Where the plugins and credentials should be located."; + }; + + plugins = mkOption { + type = types.listOf (sbtTypes.plugin); + default = [ ]; + example = literalExample '' + [ + { + org = "net.virtual-void"; + artifact = "sbt-dependency-graph"; + version = "0.10.0-RC1"; + } + { + org = "com.dwijnand"; + artifact = "sbt-project-graph"; + version = "0.4.0"; + } + ] + ''; + description = '' + A list of plugins to place in the sbt configuration directory. + ''; + }; + + credentials = mkOption { + type = types.listOf (sbtTypes.credential); + default = [ ]; + example = literalExample '' + [{ + realm = "Sonatype Nexus Repository Manager"; + host = "example.com"; + user = "user"; + passwordCommand = "pass show sbt/user@example.com"; + }] + ''; + description = '' + A list of credentials to define in the sbt configuration directory. + ''; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + { home.packages = [ cfg.package ]; } + + (mkIf (cfg.plugins != [ ]) { + home.file."${cfg.baseConfigPath}/plugins/plugins.sbt".text = + concatStrings (map renderPlugin cfg.plugins); + }) + + (mkIf (cfg.credentials != [ ]) { + home.file."${cfg.baseConfigPath}/credentials.sbt".text = + renderCredentials cfg.credentials; + }) + ]); +} diff --git a/third_party/home-manager/modules/programs/scmpuff.nix b/third_party/home-manager/modules/programs/scmpuff.nix new file mode 100644 index 0000000000..d2e6651e1e --- /dev/null +++ b/third_party/home-manager/modules/programs/scmpuff.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, ... }: +with lib; +let cfg = config.programs.scmpuff; +in { + meta.maintainers = [ maintainers.cpcloud ]; + + options.programs.scmpuff = { + enable = mkEnableOption '' + scmpuff, a command line tool that allows you to work quicker with Git by + substituting numeric shortcuts for files''; + + package = mkOption { + type = types.package; + default = pkgs.scmpuff; + defaultText = literalExample "pkgs.scmpuff"; + description = "Package providing the scmpuff tool."; + }; + + enableBashIntegration = mkOption { + default = true; + type = types.bool; + description = '' + Whether to enable Bash integration. + ''; + }; + + enableZshIntegration = mkOption { + default = true; + type = types.bool; + description = '' + Whether to enable Zsh integration. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + programs.bash.initExtra = mkIf cfg.enableBashIntegration '' + eval "$(${cfg.package}/bin/scmpuff init -s)" + ''; + + programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' + eval "$(${cfg.package}/bin/scmpuff init -s)" + ''; + }; +} diff --git a/third_party/home-manager/modules/programs/senpai.nix b/third_party/home-manager/modules/programs/senpai.nix new file mode 100644 index 0000000000..6e5a4a0ae2 --- /dev/null +++ b/third_party/home-manager/modules/programs/senpai.nix @@ -0,0 +1,73 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.senpai; + cfgFmt = pkgs.formats.yaml { }; +in { + options.programs.senpai = { + enable = mkEnableOption "senpai"; + package = mkOption { + type = types.package; + default = pkgs.senpai; + defaultText = literalExample "pkgs.senpai"; + description = "The senpai package to use."; + }; + config = mkOption { + type = types.submodule { + freeformType = cfgFmt.type; + options = { + addr = mkOption { + type = types.str; + description = '' + The address (host[:port]) of the IRC server. senpai uses TLS + connections by default unless you specify no-tls option. TLS + connections default to port 6697, plain-text use port 6667. + ''; + }; + nick = mkOption { + type = types.str; + description = '' + Your nickname, sent with a NICK IRC message. It mustn't contain + spaces or colons (:). + ''; + }; + password = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Your password, used for SASL authentication. Note that it will + reside world-readable in the Nix store. + ''; + }; + no-tls = mkOption { + type = types.bool; + default = false; + description = "Disables TLS encryption."; + }; + }; + }; + example = literalExample '' + { + addr = "libera.chat:6697"; + nick = "nicholas"; + password = "verysecurepassword"; + } + ''; + description = '' + Configuration for senpai. For a complete list of options, see + senpai + 5. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + xdg.configFile."senpai/senpai.yaml".source = + cfgFmt.generate "senpai.yaml" cfg.config; + }; + + meta.maintainers = [ hm.maintainers.malvo ]; +} diff --git a/third_party/home-manager/modules/programs/ssh.nix b/third_party/home-manager/modules/programs/ssh.nix index ae1f221803..b4940cbfab 100644 --- a/third_party/home-manager/modules/programs/ssh.nix +++ b/third_party/home-manager/modules/programs/ssh.nix @@ -26,7 +26,8 @@ let }; port = mkOption { - type = types.port; + type = types.nullOr types.port; + default = null; example = 8080; description = "Specifies port number to bind on bind address."; }; @@ -42,13 +43,15 @@ let host = { address = mkOption { - type = types.str; + type = types.nullOr types.str; + default = null; example = "example.org"; description = "The address where to forward the traffic to."; }; port = mkOption { - type = types.port; + type = types.nullOr types.port; + default = null; example = 80; description = "Specifies port number to forward the traffic to."; }; @@ -450,7 +453,7 @@ in any' = pred: items: if items == [] then true else any pred items; # Check that if `entry.address` is defined, and is a path, that `entry.port` has not # been defined. - noPathWithPort = entry: entry ? address && isPath entry.address -> !(entry ? port); + noPathWithPort = entry: entry.address != null && isPath entry.address -> entry.port == null; checkDynamic = block: any' noPathWithPort block.dynamicForwards; checkBindAndHost = fwd: noPathWithPort fwd.bind && noPathWithPort fwd.host; checkLocal = block: any' checkBindAndHost block.localForwards; diff --git a/third_party/home-manager/modules/programs/starship.nix b/third_party/home-manager/modules/programs/starship.nix index 8462d33150..33db8e6d6c 100644 --- a/third_party/home-manager/modules/programs/starship.nix +++ b/third_party/home-manager/modules/programs/starship.nix @@ -6,16 +6,7 @@ let cfg = config.programs.starship; - configFile = config: - pkgs.runCommand "config.toml" { - buildInputs = [ pkgs.remarshal ]; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - remarshal -if json -of toml \ - < ${pkgs.writeText "config.json" (builtins.toJSON config)} \ - > $out - ''; + tomlFormat = pkgs.formats.toml { }; in { meta.maintainers = [ maintainers.marsam ]; @@ -43,9 +34,17 @@ in { example = literalExample '' { add_newline = false; - prompt_order = [ "line_break" "package" "line_break" "character" ]; + format = lib.concatStrings [ + "$line_break" + "$package" + "$line_break" + "$character" + ]; scan_timeout = 10; - character.symbol = "➜"; + character = { + success_symbol = "➜"; + error_symbol = "➜"; + }; } ''; description = '' @@ -85,8 +84,9 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; - xdg.configFile."starship.toml" = - mkIf (cfg.settings != { }) { source = configFile cfg.settings; }; + xdg.configFile."starship.toml" = mkIf (cfg.settings != { }) { + source = tomlFormat.generate "starship-config" cfg.settings; + }; programs.bash.initExtra = mkIf cfg.enableBashIntegration '' if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then @@ -95,7 +95,7 @@ in { ''; programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' - if [ -z "$INSIDE_EMACS" ]; then + if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then eval "$(${cfg.package}/bin/starship init zsh)" fi ''; diff --git a/third_party/home-manager/modules/programs/taskwarrior.nix b/third_party/home-manager/modules/programs/taskwarrior.nix index cf95511f8e..6a887e0f5b 100644 --- a/third_party/home-manager/modules/programs/taskwarrior.nix +++ b/third_party/home-manager/modules/programs/taskwarrior.nix @@ -40,7 +40,7 @@ in { enable = mkEnableOption "Task Warrior"; config = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; example = literalExample '' { diff --git a/third_party/home-manager/modules/programs/terminator.nix b/third_party/home-manager/modules/programs/terminator.nix new file mode 100644 index 0000000000..d100a9cd98 --- /dev/null +++ b/third_party/home-manager/modules/programs/terminator.nix @@ -0,0 +1,70 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.terminator; + + toValue = val: + if val == null then + "None" + else if val == true then + "True" + else if val == false then + "False" + else + ''"${toString val}"''; + + toConfigObject = let + toKey = depth: key: + if depth == 0 then key else toKey (depth - 1) "[${key}]"; + toConfigObjectLevel = depth: obj: + flatten (mapAttrsToList (key: val: + if isAttrs val then + [ (toKey depth key) ] ++ toConfigObjectLevel (depth + 1) val + else + [ "${key} = ${toValue val}" ]) obj); + in obj: concatStringsSep "\n" (toConfigObjectLevel 1 obj); + +in { + meta.maintainers = [ maintainers.chisui ]; + + options.programs.terminator = { + enable = mkEnableOption "terminator, a tiling terminal emulator"; + + package = mkOption { + type = types.package; + default = pkgs.terminator; + example = literalExample "pkgs.terminator"; + description = "terminator package to install."; + }; + + config = mkOption { + default = { }; + description = '' + configuration for terminator. + + For a list of all possible options refer to the + + terminator_config + 5 + + man page. + ''; + type = types.attrsOf types.anything; + example = literalExample '' + { + global_config.borderless = true; + profiles.default.background_color = "#002b36"; + } + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + xdg.configFile."terminator/config" = + mkIf (cfg.config != { }) { text = toConfigObject cfg.config; }; + }; +} diff --git a/third_party/home-manager/modules/programs/termite.nix b/third_party/home-manager/modules/programs/termite.nix index e3d704424e..ccf3cabb3f 100644 --- a/third_party/home-manager/modules/programs/termite.nix +++ b/third_party/home-manager/modules/programs/termite.nix @@ -6,13 +6,6 @@ let cfg = config.programs.termite; - vteInitStr = '' - # See https://github.com/thestinger/termite#id1 - if [[ $TERM == xterm-termite ]]; then - . ${pkgs.termite.vte-ng}/etc/profile.d/vte.sh - fi - ''; - in { options = { programs.termite = { @@ -50,6 +43,10 @@ in { ''; }; + enableVteIntegration = mkEnableOption "Shell VTE integration" // { + default = true; + }; + fullscreen = mkOption { default = null; type = types.nullOr types.bool; @@ -123,7 +120,7 @@ in { browser = mkOption { default = null; type = types.nullOr types.str; - example = "${pkgs.xdg_utils}/xdg-open"; + example = "${pkgs.xdg-utils}/xdg-open"; description = '' Set the default browser for opening links. If its not set, $BROWSER is read. If that's not set, url hints will be disabled. @@ -381,7 +378,7 @@ in { ${cfg.hintsExtra} ''; - programs.bash.initExtra = vteInitStr; - programs.zsh.initExtra = vteInitStr; + programs.bash.enableVteIntegration = lib.mkDefault cfg.enableVteIntegration; + programs.zsh.enableVteIntegration = lib.mkDefault cfg.enableVteIntegration; }); } diff --git a/third_party/home-manager/modules/programs/texlive.nix b/third_party/home-manager/modules/programs/texlive.nix index 08a376d654..0921417ba2 100644 --- a/third_party/home-manager/modules/programs/texlive.nix +++ b/third_party/home-manager/modules/programs/texlive.nix @@ -6,14 +6,21 @@ let cfg = config.programs.texlive; - texlivePkgs = cfg.extraPackages pkgs.texlive; + texlive = cfg.packageSet; + texlivePkgs = cfg.extraPackages texlive; in { meta.maintainers = [ maintainers.rycee ]; options = { programs.texlive = { - enable = mkEnableOption "Texlive"; + enable = mkEnableOption "TeX Live"; + + packageSet = mkOption { + default = pkgs.texlive; + defaultText = literalExample "pkgs.texlive"; + description = "TeX Live package set to use."; + }; extraPackages = mkOption { default = tpkgs: { inherit (tpkgs) collection-basic; }; @@ -21,12 +28,12 @@ in { example = literalExample '' tpkgs: { inherit (tpkgs) collection-fontsrecommended algorithms; } ''; - description = "Extra packages available to Texlive."; + description = "Extra packages available to TeX Live."; }; package = mkOption { type = types.package; - description = "Resulting customized Texlive package."; + description = "Resulting customized TeX Live package."; readOnly = true; }; }; @@ -41,6 +48,6 @@ in { home.packages = [ cfg.package ]; - programs.texlive.package = pkgs.texlive.combine texlivePkgs; + programs.texlive.package = texlive.combine texlivePkgs; }; } diff --git a/third_party/home-manager/modules/programs/tmux.nix b/third_party/home-manager/modules/programs/tmux.nix index a71c302ac6..8628155b88 100644 --- a/third_party/home-manager/modules/programs/tmux.nix +++ b/third_party/home-manager/modules/programs/tmux.nix @@ -27,6 +27,7 @@ let defaultResize = 5; defaultShortcut = "b"; defaultTerminal = "screen"; + defaultShell = null; boolToStr = value: if value then "on" else "off"; @@ -41,7 +42,10 @@ let set -g default-terminal "${cfg.terminal}" set -g base-index ${toString cfg.baseIndex} setw -g pane-base-index ${toString cfg.baseIndex} - + ${optionalString (cfg.shell != null) '' + # We need to set default-shell before calling new-session + set -g default-shell "${cfg.shell}" + ''} ${optionalString cfg.newSession "new-session"} ${optionalString cfg.reverseSplit '' @@ -64,13 +68,21 @@ let bind -r L resize-pane -R ${toString cfg.resizeAmount} ''} - ${optionalString (cfg.shortcut != defaultShortcut) '' - # rebind main key: C-${cfg.shortcut} - unbind C-${defaultShortcut} - set -g prefix C-${cfg.shortcut} - bind ${cfg.shortcut} send-prefix - bind C-${cfg.shortcut} last-window - ''} + ${if cfg.prefix != null + then '' + # rebind main key: ${cfg.prefix} + unbind C-${defaultShortcut} + set -g prefix ${cfg.prefix} + bind ${cfg.prefix} send-prefix + '' + else optionalString (cfg.shortcut != defaultShortcut) '' + # rebind main key: C-${cfg.shortcut} + unbind C-${defaultShortcut} + set -g prefix C-${cfg.shortcut} + bind ${cfg.shortcut} send-prefix + bind C-${cfg.shortcut} last-window + '' + } ${optionalString cfg.disableConfirmationPrompt '' bind-key & kill-window @@ -97,7 +109,7 @@ let } )]; - home.file.".tmux.conf".text = '' + xdg.configFile."tmux/tmux.conf".text = '' # ============================================= # # Load plugins with Home Manager # # --------------------------------------------- # @@ -234,6 +246,15 @@ in ''; }; + prefix = mkOption { + default = null; + example = "C-a"; + type = types.nullOr types.str; + description = '' + Set the prefix key. Overrules the "shortcut" option when set. + ''; + }; + shortcut = mkOption { default = defaultShortcut; example = "a"; @@ -250,6 +271,13 @@ in description = "Set the $TERM variable."; }; + shell = mkOption { + default = defaultShell; + example = "\${pkgs.zsh}/bin/zsh"; + type = with types; nullOr str; + description = "Set the default-shell tmux variable."; + }; + secureSocket = mkOption { default = pkgs.stdenv.isLinux; type = types.bool; @@ -307,10 +335,9 @@ in }; }) - # config file ~/.tmux.conf - { home.file.".tmux.conf".text = mkBefore tmuxConf; } + { xdg.configFile."tmux/tmux.conf".text = mkBefore tmuxConf; } (mkIf (cfg.plugins != []) configPlugins) - { home.file.".tmux.conf".text = mkAfter cfg.extraConfig; } + { xdg.configFile."tmux/tmux.conf".text = mkAfter cfg.extraConfig; } ]) ); } diff --git a/third_party/home-manager/modules/programs/topgrade.nix b/third_party/home-manager/modules/programs/topgrade.nix new file mode 100644 index 0000000000..878fdbb088 --- /dev/null +++ b/third_party/home-manager/modules/programs/topgrade.nix @@ -0,0 +1,60 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.topgrade; + + tomlFormat = pkgs.formats.toml { }; + +in { + + meta.maintainers = [ hm.maintainers.msfjarvis ]; + + options.programs.topgrade = { + enable = mkEnableOption "topgrade"; + + package = mkOption { + type = types.package; + default = pkgs.topgrade; + defaultText = literalExample "pkgs.topgrade"; + description = "The package to use for the topgrade binary."; + }; + + settings = mkOption { + type = tomlFormat.type; + default = { }; + defaultText = literalExample "{ }"; + example = literalExample '' + { + assume_yes = true; + disable = [ + "flutter" + "node" + ]; + set_title = false; + cleanup = true; + commands = { + "Run garbage collection on Nix store" = "nix-collect-garbage"; + }; + } + ''; + description = '' + Configuration written to + ~/.config/topgrade.toml. + + See for the full list + of options. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."topgrade.toml" = mkIf (cfg.settings != { }) { + source = tomlFormat.generate "topgrade-config" cfg.settings; + }; + }; +} diff --git a/third_party/home-manager/modules/programs/urxvt.nix b/third_party/home-manager/modules/programs/urxvt.nix index e4c72bfe27..5eb3d90d79 100644 --- a/third_party/home-manager/modules/programs/urxvt.nix +++ b/third_party/home-manager/modules/programs/urxvt.nix @@ -124,7 +124,7 @@ in { extraConfig = mkOption { default = { }; - type = types.attrs; + type = types.attrsOf types.anything; description = "Additional configuration to add."; example = { "shading" = 15; }; }; diff --git a/third_party/home-manager/modules/programs/vscode.nix b/third_party/home-manager/modules/programs/vscode.nix index f5710ae905..473cd1705e 100644 --- a/third_party/home-manager/modules/programs/vscode.nix +++ b/third_party/home-manager/modules/programs/vscode.nix @@ -8,6 +8,8 @@ let vscodePname = cfg.package.pname; + jsonFormat = pkgs.formats.json { }; + configDir = { "vscode" = "Code"; "vscode-insiders" = "Code - Insiders"; @@ -46,7 +48,7 @@ in { }; userSettings = mkOption { - type = types.attrs; + type = jsonFormat.type; default = { }; example = literalExample '' { @@ -76,11 +78,19 @@ in { }; when = mkOption { - type = types.str; - default = ""; + type = types.nullOr (types.str); + default = null; example = "textInputFocus"; description = "Optional context filter."; }; + + # https://code.visualstudio.com/docs/getstarted/keybindings#_command-arguments + args = mkOption { + type = types.nullOr (types.attrs); + default = null; + example = { direction = "up"; }; + description = "Optional arguments for a command."; + }; }; }); default = [ ]; @@ -123,12 +133,14 @@ in { (k: _: { "${extensionPath}/${k}".source = "${path}/${subDir}/${k}"; }) (builtins.readDir (path + "/${subDir}")); toSymlink = concatMap toPaths cfg.extensions; + dropNullFields = filterAttrs (_: v: v != null); in foldr (a: b: a // b) { "${configFilePath}" = mkIf (cfg.userSettings != { }) { - text = builtins.toJSON cfg.userSettings; + source = jsonFormat.generate "vscode-user-settings" cfg.userSettings; }; "${keybindingsFilePath}" = mkIf (cfg.keybindings != [ ]) { - text = builtins.toJSON cfg.keybindings; + source = jsonFormat.generate "vscode-keybindings" + (map dropNullFields cfg.keybindings); }; } toSymlink; }; diff --git a/third_party/home-manager/modules/programs/waybar.nix b/third_party/home-manager/modules/programs/waybar.nix index 64df4e797f..3cf919cc77 100644 --- a/third_party/home-manager/modules/programs/waybar.nix +++ b/third_party/home-manager/modules/programs/waybar.nix @@ -1,18 +1,30 @@ { config, lib, pkgs, ... }: -with lib; let + inherit (lib) + any attrByPath attrNames concatMap concatMapStringsSep elem elemAt filter + filterAttrs flip foldl' hasPrefix head length mergeAttrs optionalAttrs + stringLength subtractLists types unique; + inherit (lib.options) literalExample mkEnableOption mkOption; + inherit (lib.modules) mkIf mkMerge; + cfg = config.programs.waybar; # Used when generating warnings modulesPath = "programs.waybar.settings.[].modules"; - # Taken from + jsonFormat = pkgs.formats.json { }; + + # Taken from (2020/10/10) + # Order is preserved from the file for easier matching defaultModuleNames = [ + "battery" "sway/mode" "sway/workspaces" "sway/window" + "sway/language" "wlr/taskbar" + "river/tags" "idle_inhibitor" "memory" "cpu" @@ -23,13 +35,24 @@ let "backlight" "pulseaudio" "mpd" + "sndio" "temperature" "bluetooth" - "battery" ]; - isValidCustomModuleName = x: - elem x defaultModuleNames || (hasPrefix "custom/" x && stringLength x > 7); + # Allow specifying a CSS id after the default module name + isValidDefaultModuleName = x: + any (name: + let + res = builtins.split name x; + # if exact match of default module name + in if res == [ "" [ ] ] || res == [ "" [ ] "" ] then + true + else + head res == "" && length res >= 3 && hasPrefix "#" (elemAt res 2)) + defaultModuleNames; + + isValidCustomModuleName = x: hasPrefix "custom/" x && stringLength x > 7; margins = let mkMargin = name: { @@ -92,8 +115,8 @@ let }; modules-left = mkOption { - type = nullOr (listOf str); - default = null; + type = listOf str; + default = [ ]; description = "Modules that will be displayed on the left."; example = literalExample '' [ "sway/workspaces" "sway/mode" "wlr/taskbar" ] @@ -101,8 +124,8 @@ let }; modules-center = mkOption { - type = nullOr (listOf str); - default = null; + type = listOf str; + default = [ ]; description = "Modules that will be displayed in the center."; example = literalExample '' [ "sway/window" ] @@ -110,8 +133,8 @@ let }; modules-right = mkOption { - type = nullOr (listOf str); - default = null; + type = listOf str; + default = [ ]; description = "Modules that will be displayed on the right."; example = literalExample '' [ "mpd" "custom/mymodule#with-css-id" "temperature" ] @@ -119,7 +142,7 @@ let }; modules = mkOption { - type = attrsOf unspecified; + type = jsonFormat.type; default = { }; description = "Modules configuration."; example = literalExample '' @@ -169,7 +192,7 @@ in { package = mkOption { type = package; default = pkgs.waybar; - defaultText = literalExample "${pkgs.waybar}"; + defaultText = "pkgs.waybar"; description = '' Waybar package to use. Set to null to use the default module. ''; @@ -243,11 +266,7 @@ in { }; config = let - # Inspired by https://github.com/NixOS/nixpkgs/pull/89781 - writePrettyJSON = name: x: - pkgs.runCommandLocal name { } '' - ${pkgs.jq}/bin/jq . > $out <<<${escapeShellArg (builtins.toJSON x)} - ''; + writePrettyJSON = jsonFormat.generate; configSource = let # Removes nulls because Waybar ignores them for most values @@ -259,8 +278,7 @@ in { let # The "modules" option is not valid in the JSON # as its descendants have to live at the top-level - settingsWithoutModules = - filterAttrs (n: _: n != "modules") configuration; + settingsWithoutModules = removeAttrs configuration [ "modules" ]; settingsModules = optionalAttrs (configuration.modules != { }) configuration.modules; in removeNulls (settingsWithoutModules // settingsModules); @@ -268,6 +286,15 @@ in { finalConfiguration = map makeConfiguration cfg.settings; in writePrettyJSON "waybar-config.json" finalConfiguration; + # + # Warnings are generated based on the following things: + # 1. A `module` is referenced in any of `modules-{left,center,right}` that is neither + # a default module name nor defined in `modules`. + # 2. A `module` is defined in `modules` but is not referenced in either of + # `modules-{left,center,right}`. + # 3. A custom `module` configuration is defined in `modules` but has an invalid name + # for a custom module (i.e. not "custom/my-module-name"). + # warnings = let mkUnreferencedModuleWarning = name: "The module '${name}' defined in '${modulesPath}' is not referenced " @@ -288,9 +315,6 @@ in { + "module name. A custom module's name must start with 'custom/' " + "like 'custom/mymodule' for instance"; - # Find all modules in `modules-{left,center,right}` and `modules` not declared/referenced. - # `cfg.settings` is a list of Waybar configurations - # and we need to preserve the index for appropriate warnings allFaultyModules = flip map cfg.settings (settings: let allModules = unique @@ -303,15 +327,17 @@ in { # Modules declared in `modules` but not referenced in `modules-{left,center,right}` unreferencedModules = subtractLists allModules declaredModules; # Modules listed in modules-{left,center,right} that are not default modules - nonDefaultModules = subtractLists defaultModuleNames allModules; + nonDefaultModules = + filter (x: !isValidDefaultModuleName x) allModules; # Modules referenced in `modules-{left,center,right}` but not declared in `modules` undefinedModules = subtractLists declaredModules nonDefaultModules; # Check for invalid module names - invalidModuleNames = - filter (m: !isValidCustomModuleName m) (attrNames settings.modules); + invalidModuleNames = filter + (m: !isValidCustomModuleName m && !isValidDefaultModuleName m) + declaredModules; in { # The Waybar bar configuration (since config.settings is a list) - settings = settings; + inherit settings; undef = undefinedModules; unref = unreferencedModules; invalidName = invalidModuleNames; @@ -344,16 +370,14 @@ in { "Highly customizable Wayland bar for Sway and Wlroots based compositors."; Documentation = "https://github.com/Alexays/Waybar/wiki"; PartOf = [ "graphical-session.target" ]; - Requisite = [ "dbus.service" ]; - After = [ "dbus.service" ]; + After = [ "graphical-session.target" ]; }; Service = { - Type = "dbus"; - BusName = "fr.arouillard.waybar"; ExecStart = "${cfg.package}/bin/waybar"; - Restart = "always"; - RestartSec = "1sec"; + ExecReload = "kill -SIGUSR2 $MAINPID"; + Restart = "on-failure"; + KillMode = "mixed"; }; Install = { WantedBy = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/programs/xmobar.nix b/third_party/home-manager/modules/programs/xmobar.nix new file mode 100644 index 0000000000..0ad5d7c190 --- /dev/null +++ b/third_party/home-manager/modules/programs/xmobar.nix @@ -0,0 +1,59 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.programs.xmobar; +in { + options.programs.xmobar = { + enable = mkEnableOption "Xmobar, a minimalistic status bar"; + + package = mkOption { + default = pkgs.haskellPackages.xmobar; + defaultText = literalExample "pkgs.haskellPackages.xmobar"; + type = types.package; + description = '' + Package providing the xmobar binary. + ''; + }; + + extraConfig = mkOption { + default = ""; + example = literalExample '' + Config + { font = "Fira Code" + , borderColor = "#d0d0d0" + , border = FullB + , borderWidth = 3 + , bgColor = "#222" + , fgColor = "grey" + , position = TopSize C 99 30 + , commands = + [ Run Cpu ["-t", "cpu: %"] 10 + , Run Network "enp3s0" ["-S", "True", "-t", "eth: /"] 10 + , Run Memory ["-t","mem: %"] 10 + , Run Date "date: %a %d %b %Y %H:%M:%S " "date" 10 + , Run StdinReader + ] + , sepChar = "%" + , alignSep = "}{" + , template = " %StdinReader% | %cpu% | %memory% | %enp3s0% }{%date% " + } + ''; + type = types.lines; + description = '' + Extra configuration lines to add to + $XDG_CONFIG_HOME/xmobar/.xmobarrc. + See + + for options. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + xdg.configFile."xmobar/.xmobarrc".text = cfg.extraConfig; + }; + + meta.maintainers = with maintainers; [ t4ccer ]; +} diff --git a/third_party/home-manager/modules/programs/zathura.nix b/third_party/home-manager/modules/programs/zathura.nix index d9f3c1af1f..64a77cb3be 100644 --- a/third_party/home-manager/modules/programs/zathura.nix +++ b/third_party/home-manager/modules/programs/zathura.nix @@ -20,6 +20,13 @@ in { Zathura, a highly customizable and functional document viewer focused on keyboard interaction''; + package = mkOption { + type = types.package; + default = pkgs.zathura; + defaultText = "pkgs.zathura"; + description = "The Zathura package to use"; + }; + options = mkOption { default = { }; type = with types; attrsOf (either str (either bool int)); @@ -49,7 +56,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.zathura ]; + home.packages = [ cfg.package ]; xdg.configFile."zathura/zathurarc".text = concatStringsSep "\n" ([ ] ++ optional (cfg.extraConfig != "") cfg.extraConfig diff --git a/third_party/home-manager/modules/programs/zsh.nix b/third_party/home-manager/modules/programs/zsh.nix index 362daa3c01..5f6f7b89f4 100644 --- a/third_party/home-manager/modules/programs/zsh.nix +++ b/third_party/home-manager/modules/programs/zsh.nix @@ -22,6 +22,10 @@ let mapAttrsToList (k: v: "alias -g ${k}=${lib.escapeShellArg v}") cfg.shellGlobalAliases ); + dirHashesStr = concatStringsSep "\n" ( + mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes + ); + zdotdir = "$HOME/" + cfg.dotDir; bindkeyCommands = { @@ -52,10 +56,24 @@ let default = if versionAtLeast stateVersion "20.03" then "$HOME/.zsh_history" else relToDotDir ".zsh_history"; + defaultText = literalExample '' + "$HOME/.zsh_history" if state version ≥ 20.03, + "$ZDOTDIR/.zsh_history" otherwise + ''; example = literalExample ''"''${config.xdg.dataHome}/zsh/zsh_history"''; description = "History file location"; }; + ignorePatterns = mkOption { + type = types.listOf types.str; + default = []; + example = literalExample ''[ "rm *" "pkill *" ]''; + description = '' + Do not enter command lines into the history list + if they match any one of the given shell patterns. + ''; + }; + ignoreDups = mkOption { type = types.bool; default = true; @@ -234,6 +252,21 @@ in type = types.attrsOf types.str; }; + dirHashes = mkOption { + default = {}; + example = literalExample '' + { + docs = "$HOME/Documents"; + vids = "$HOME/Videos"; + dl = "$HOME/Downloads"; + } + ''; + description = '' + An attribute set that adds to named directory hash table. + ''; + type = types.attrsOf types.str; + }; + enableCompletion = mkOption { default = true; description = '' @@ -246,11 +279,22 @@ in type = types.bool; }; + completionInit = mkOption { + default = "autoload -U compinit && compinit"; + description = "Initialization commands to run when completion is enabled."; + type = types.lines; + }; + enableAutosuggestions = mkOption { default = false; description = "Enable zsh autosuggestions"; }; + enableSyntaxHighlighting = mkOption { + default = false; + description = "Enable zsh syntax highlighting"; + }; + history = mkOption { type = historyModule; default = {}; @@ -283,6 +327,12 @@ in description = "Extra commands that should be added to .zshrc."; }; + initExtraFirst = mkOption { + default = ""; + type = types.lines; + description = "Commands that should be added to top of .zshrc."; + }; + envExtra = mkOption { default = ""; type = types.lines; @@ -398,6 +448,8 @@ in ++ optional cfg.oh-my-zsh.enable oh-my-zsh; home.file."${relToDotDir ".zshrc"}".text = '' + ${cfg.initExtraFirst} + typeset -U path cdpath fpath manpath ${optionalString (cfg.cdpath != []) '' @@ -425,16 +477,20 @@ in '') cfg.plugins)} # Oh-My-Zsh/Prezto calls compinit during initialization, - # calling it twice causes sight start up slowdown + # calling it twice causes slight start up slowdown # as all $fpath entries will be traversed again. ${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable) - "autoload -U compinit && compinit" + cfg.completionInit } ${optionalString cfg.enableAutosuggestions "source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh" } + ${optionalString cfg.enableSyntaxHighlighting + "source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" + } + # Environment variables . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" ${envVarsStr} @@ -456,10 +512,10 @@ in ''} ${optionalString cfg.prezto.enable - (builtins.readFile "${pkgs.zsh-prezto}/runcoms/zshrc")} + (builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshrc")} ${concatStrings (map (plugin: '' - if [ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]; then + if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" fi '') cfg.plugins)} @@ -468,6 +524,7 @@ in # See https://github.com/nix-community/home-manager/issues/177. HISTSIZE="${toString cfg.history.size}" SAVEHIST="${toString cfg.history.save}" + ${optionalString (cfg.history.ignorePatterns != []) "HISTORY_IGNORE=${lib.escapeShellArg "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"}"} ${if versionAtLeast config.home.stateVersion "20.03" then ''HISTFILE="${cfg.history.path}"'' else ''HISTFILE="$HOME/${cfg.history.path}"''} @@ -488,6 +545,9 @@ in # Global Aliases ${globalAliasesStr} + + # Named Directory Hashes + ${dirHashesStr} ''; } diff --git a/third_party/home-manager/modules/programs/zsh/prezto.nix b/third_party/home-manager/modules/programs/zsh/prezto.nix index 1bd1be5843..5c2853e7a6 100644 --- a/third_party/home-manager/modules/programs/zsh/prezto.nix +++ b/third_party/home-manager/modules/programs/zsh/prezto.nix @@ -352,15 +352,15 @@ in { }; config = mkIf cfg.enable (mkMerge [{ home.file."${relToDotDir ".zprofile"}".text = - builtins.readFile "${pkgs.zsh-prezto}/runcoms/zprofile"; + builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zprofile"; home.file."${relToDotDir ".zlogin"}".text = - builtins.readFile "${pkgs.zsh-prezto}/runcoms/zlogin"; + builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zlogin"; home.file."${relToDotDir ".zlogout"}".text = - builtins.readFile "${pkgs.zsh-prezto}/runcoms/zlogout"; + builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zlogout"; home.packages = with pkgs; [ zsh-prezto ]; home.file."${relToDotDir ".zshenv"}".text = - (builtins.readFile "${pkgs.zsh-prezto}/runcoms/zshenv"); + builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshenv"; home.file."${relToDotDir ".zpreztorc"}".text = '' # Generated by Nix ${optionalString (cfg.caseSensitive != null) '' diff --git a/third_party/home-manager/modules/services/barrier.nix b/third_party/home-manager/modules/services/barrier.nix new file mode 100644 index 0000000000..ae9b7d9364 --- /dev/null +++ b/third_party/home-manager/modules/services/barrier.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs, ... }: + +with lib; +let cfg = config.services.barrier; +in { + + meta.maintainers = with maintainers; [ kritnich ]; + + options.services.barrier = { + + client = { + + enable = mkEnableOption "Barrier Client daemon"; + + name = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Screen name of client. Defaults to hostname. + ''; + }; + + server = mkOption { + type = types.str; + description = '' + Server to connect to formatted as + <host>[:<port>]. + Port defaults to 24800. + ''; + }; + + tray = mkEnableOption "the system tray icon" // { default = true; }; + + enableCrypto = mkEnableOption "crypto (SSL) plugin" // { + default = true; + }; + + enableDragDrop = mkEnableOption "file drag & drop"; + + extraFlags = mkOption { + type = types.listOf types.str; + default = [ "-f" ]; + defaultText = literalExample ''[ "-f" ]''; + description = '' + Additional flags to pass to barrierc. + See barrierc --help. + ''; + }; + + }; + }; + + config = mkIf cfg.client.enable { + systemd.user.services.barrierc = { + Unit = { + Description = "Barrier Client daemon"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Install.WantedBy = [ "graphical-session.target" ]; + Service.ExecStart = with cfg.client; + toString ([ "${pkgs.barrier}/bin/barrierc" ] + ++ optional (name != null) "--name ${name}" + ++ optional (!tray) "--no-tray" + ++ optional enableCrypto "--enable-crypto" + ++ optional enableDragDrop "--enable-drag-drop" ++ extraFlags + ++ [ server ]); + }; + }; + +} diff --git a/third_party/home-manager/modules/services/blueman-applet.nix b/third_party/home-manager/modules/services/blueman-applet.nix index 5a57acccc2..460dd1677c 100644 --- a/third_party/home-manager/modules/services/blueman-applet.nix +++ b/third_party/home-manager/modules/services/blueman-applet.nix @@ -24,7 +24,8 @@ with lib; systemd.user.services.blueman-applet = { Unit = { Description = "Blueman applet"; - After = [ "graphical-session-pre.target" ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/caffeine.nix b/third_party/home-manager/modules/services/caffeine.nix new file mode 100644 index 0000000000..bb24a0e052 --- /dev/null +++ b/third_party/home-manager/modules/services/caffeine.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.caffeine; + +in { + meta.maintainers = [ maintainers.uvnikita ]; + + options = { + services.caffeine = { enable = mkEnableOption "Caffeine service"; }; + }; + + config = mkIf cfg.enable { + systemd.user.services.caffeine = { + Unit = { Description = "caffeine"; }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + + Service = { + Restart = "on-failure"; + PrivateTmp = true; + ProtectSystem = "full"; + ProtectHome = "yes"; + Type = "exec"; + Slice = "session.slice"; + ExecStart = "${pkgs.caffeine-ng}/bin/caffeine"; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/cbatticon.nix b/third_party/home-manager/modules/services/cbatticon.nix index 0de69c5f9e..a86805ddca 100644 --- a/third_party/home-manager/modules/services/cbatticon.nix +++ b/third_party/home-manager/modules/services/cbatticon.nix @@ -103,7 +103,8 @@ in { systemd.user.services.cbatticon = { Unit = { Description = "cbatticon system tray battery icon"; - After = [ "graphical-session-pre.target" ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/dunst.nix b/third_party/home-manager/modules/services/dunst.nix index 5fbbb884a8..cf832f4bf2 100644 --- a/third_party/home-manager/modules/services/dunst.nix +++ b/third_party/home-manager/modules/services/dunst.nix @@ -25,7 +25,7 @@ let options = { package = mkOption { type = types.package; - example = literalExample "pkgs.gnome3.adwaita-icon-theme"; + example = literalExample "pkgs.gnome.adwaita-icon-theme"; description = "Package providing the theme."; }; @@ -57,16 +57,38 @@ in { services.dunst = { enable = mkEnableOption "the dunst notification daemon"; + package = mkOption { + type = types.package; + default = pkgs.dunst; + defaultText = literalExample "pkgs.dunst"; + description = "Package providing dunst."; + }; + iconTheme = mkOption { type = themeType; default = hicolorTheme; description = "Set the icon theme."; }; + waylandDisplay = mkOption { + type = types.str; + default = ""; + description = + "Set the service's WAYLAND_DISPLAY environment variable."; + }; + settings = mkOption { - type = with types; attrsOf (attrsOf eitherStrBoolIntList); + type = types.submodule { + freeformType = with types; attrsOf (attrsOf eitherStrBoolIntList); + options = { + global.icon_path = mkOption { + type = types.separatedString ":"; + description = "Paths where dunst will look for icons."; + }; + }; + }; default = { }; - description = "Configuration written to ~/.config/dunstrc"; + description = "Configuration written to ~/.config/dunst/dunstrc"; example = literalExample '' { global = { @@ -89,7 +111,7 @@ in { config = mkIf cfg.enable (mkMerge [ { - home.packages = [ (getOutput "man" pkgs.dunst) ]; + home.packages = [ cfg.package ]; xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source = "${pkgs.dunst}/share/dbus-1/services/org.knopwob.dunst.service"; @@ -118,16 +140,20 @@ in { "emotes" "filesystem" "intl" + "legacy" "mimetypes" "places" "status" "stock" ]; - in concatStringsSep ":" (concatMap (theme: - concatMap (basePath: - map (category: - "${basePath}/share/icons/${theme.name}/${theme.size}/${category}") - categories) basePaths) themes); + + mkPath = { basePath, theme, category }: + "${basePath}/share/icons/${theme.name}/${theme.size}/${category}"; + in concatMapStringsSep ":" mkPath (cartesianProductOfSets { + basePath = basePaths; + theme = themes; + category = categories; + }); systemd.user.services.dunst = { Unit = { @@ -139,7 +165,9 @@ in { Service = { Type = "dbus"; BusName = "org.freedesktop.Notifications"; - ExecStart = "${pkgs.dunst}/bin/dunst"; + ExecStart = "${cfg.package}/bin/dunst"; + Environment = optionalString (cfg.waylandDisplay != "") + "WAYLAND_DISPLAY=${cfg.waylandDisplay}"; }; }; } diff --git a/third_party/home-manager/modules/services/dwm-status.nix b/third_party/home-manager/modules/services/dwm-status.nix index 7a19e5e5fc..a0c2a72436 100644 --- a/third_party/home-manager/modules/services/dwm-status.nix +++ b/third_party/home-manager/modules/services/dwm-status.nix @@ -5,11 +5,13 @@ with lib; let cfg = config.services.dwm-status; + jsonFormat = pkgs.formats.json { }; + features = [ "audio" "backlight" "battery" "cpu_load" "network" "time" ]; - configText = builtins.toJSON ({ inherit (cfg) order; } // cfg.extraConfig); + finalConfig = { inherit (cfg) order; } // cfg.extraConfig; - configFile = pkgs.writeText "dwm-status.json" configText; + configFile = jsonFormat.generate "dwm-status.json" finalConfig; in { options = { @@ -30,7 +32,7 @@ in { }; extraConfig = mkOption { - type = types.attrs; + type = jsonFormat.type; default = { }; example = literalExample '' { diff --git a/third_party/home-manager/modules/services/emacs.nix b/third_party/home-manager/modules/services/emacs.nix index 7910861fb0..96c86ee782 100644 --- a/third_party/home-manager/modules/services/emacs.nix +++ b/third_party/home-manager/modules/services/emacs.nix @@ -6,8 +6,11 @@ let cfg = config.services.emacs; emacsCfg = config.programs.emacs; - emacsBinPath = "${emacsCfg.finalPackage}/bin"; - emacsVersion = getVersion emacsCfg.finalPackage; + emacsBinPath = "${cfg.package}/bin"; + emacsVersion = getVersion cfg.package; + + clientWMClass = + if versionAtLeast emacsVersion "28" then "Emacsd" else "Emacs"; # Adapted from upstream emacs.desktop clientDesktopItem = pkgs.writeTextDir "share/applications/emacsclient.desktop" @@ -24,26 +27,16 @@ let GenericName = "Text Editor"; MimeType = "text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;"; - Categories = "Utility;TextEditor;"; - StartupWMClass = "Emacs"; + Categories = "Development;TextEditor;"; + Keywords = "Text;Editor;"; + StartupWMClass = clientWMClass; }; }); # Match the default socket path for the Emacs version so emacsclient continues - # to work without wrapping it. It might be worthwhile to allow customizing the - # socket path, but we would want to wrap emacsclient in the user profile to - # connect to the alternative socket by default for Emacs 26, and set - # EMACS_SOCKET_NAME for Emacs 27. - # - # As systemd doesn't perform variable expansion for the ListenStream param, we - # would also have to solve the problem of matching the shell path to the path - # used in the socket unit, which would likely involve templating. It seems of - # little value for the most common use case of one Emacs daemon per user - # session. - socketPath = if versionAtLeast emacsVersion "27" then - "%t/emacs/server" - else - "%T/emacs%U/server"; + # to work without wrapping it. + socketDir = "%t/emacs"; + socketPath = "${socketDir}/server"; in { meta.maintainers = [ maintainers.tadfisher ]; @@ -51,6 +44,16 @@ in { options.services.emacs = { enable = mkEnableOption "the Emacs daemon"; + package = mkOption { + type = types.package; + default = if emacsCfg.enable then emacsCfg.finalPackage else pkgs.emacs; + defaultText = literalExample '' + if config.programs.emacs.enable then config.programs.emacs.finalPackage + else pkgs.emacs + ''; + description = "The Emacs package to use."; + }; + client = { enable = mkEnableOption "generation of Emacs client desktop file"; arguments = mkOption { @@ -72,31 +75,25 @@ in { config = mkIf cfg.enable (mkMerge [ { - assertions = [ - { - assertion = emacsCfg.enable; - message = "The Emacs service module requires" - + " 'programs.emacs.enable = true'."; - } - { - assertion = cfg.socketActivation.enable - -> versionAtLeast emacsVersion "26"; - message = "Socket activation requires Emacs 26 or newer."; - } - ]; - systemd.user.services.emacs = { Unit = { - Description = "Emacs: the extensible, self-documenting text editor"; + Description = "Emacs text editor"; Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/"; # Avoid killing the Emacs session, which may be full of # unsaved buffers. X-RestartIfChanged = false; + } // optionalAttrs (cfg.socketActivation.enable) { + # Emacs deletes its socket when shutting down, which systemd doesn't + # handle, resulting in a server without a socket. + # See https://github.com/nix-community/home-manager/issues/2018 + RefuseManualStart = true; }; Service = { + Type = "notify"; + # We wrap ExecStart in a login shell so Emacs starts with the user's # environment, most importantly $PATH and $NIX_PROFILES. It may be # worth investigating a more targeted approach for user services to @@ -110,22 +107,31 @@ in { optionalString cfg.socketActivation.enable "=${escapeShellArg socketPath}" }"''; - # We use '(kill-emacs 0)' to avoid exiting with a failure code, which - # would restart the service immediately. - ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs 0)'"; + + # Emacs will exit with status 15 after having received SIGTERM, which + # is the default "KillSignal" value systemd uses to stop services. + SuccessExitStatus = 15; + Restart = "on-failure"; + } // optionalAttrs (cfg.socketActivation.enable) { + # Use read-only directory permissions to prevent emacs from + # deleting systemd's socket file before exiting. + ExecStartPost = + "${pkgs.coreutils}/bin/chmod --changes -w ${socketDir}"; + ExecStopPost = + "${pkgs.coreutils}/bin/chmod --changes +w ${socketDir}"; }; } // optionalAttrs (!cfg.socketActivation.enable) { Install = { WantedBy = [ "default.target" ]; }; }; - home.packages = optional cfg.client.enable clientDesktopItem; + home.packages = optional cfg.client.enable (hiPrio clientDesktopItem); } (mkIf cfg.socketActivation.enable { systemd.user.sockets.emacs = { Unit = { - Description = "Emacs: the extensible, self-documenting text editor"; + Description = "Emacs text editor"; Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/"; }; diff --git a/third_party/home-manager/modules/services/etesync-dav.nix b/third_party/home-manager/modules/services/etesync-dav.nix new file mode 100644 index 0000000000..8bc5aa7a04 --- /dev/null +++ b/third_party/home-manager/modules/services/etesync-dav.nix @@ -0,0 +1,62 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.etesync-dav; + + toEnvironmentCfg = vars: + (concatStringsSep " " + (mapAttrsToList (k: v: "${k}=${escapeShellArg v}") vars)); + +in { + meta.maintainers = [ maintainers.valodim ]; + + options.services.etesync-dav = { + enable = mkEnableOption "etesync-dav"; + + package = mkOption { + type = types.package; + default = pkgs.etesync-dav; + defaultText = "pkgs.etesync-dav"; + description = "The etesync-dav derivation to use."; + }; + + serverUrl = mkOption { + type = types.str; + default = "https://api.etesync.com/"; + description = "The URL to the etesync server."; + }; + + settings = mkOption { + type = types.attrsOf (types.oneOf [ types.str types.int ]); + default = { }; + example = literalExample '' + { + ETESYNC_LISTEN_ADDRESS = "localhost"; + ETESYNC_LISTEN_PORT = 37358; + } + ''; + description = '' + Settings for etesync-dav, passed as environment variables. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + systemd.user.services.etesync-dav = { + Unit = { Description = "etesync-dav"; }; + + Service = { + ExecStart = "${cfg.package}/bin/etesync-dav"; + Environment = + toEnvironmentCfg ({ ETESYNC_URL = cfg.serverUrl; } // cfg.settings); + }; + + Install = { WantedBy = [ "default.target" ]; }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/flameshot.nix b/third_party/home-manager/modules/services/flameshot.nix index c8659d51d1..13fb7ea200 100644 --- a/third_party/home-manager/modules/services/flameshot.nix +++ b/third_party/home-manager/modules/services/flameshot.nix @@ -18,12 +18,8 @@ in { systemd.user.services.flameshot = { Unit = { Description = "Flameshot screenshot tool"; - After = [ - "graphical-session-pre.target" - "polybar.service" - "stalonetray.service" - "taffybar.service" - ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/gammastep.nix b/third_party/home-manager/modules/services/gammastep.nix deleted file mode 100644 index 7740c462cb..0000000000 --- a/third_party/home-manager/modules/services/gammastep.nix +++ /dev/null @@ -1,166 +0,0 @@ -# Adapted from Nixpkgs. - -{ config, lib, pkgs, ... }: - -with lib; - -let - - cfg = config.services.gammastep; - -in { - meta.maintainers = [ maintainers.petabyteboy ]; - - options.services.gammastep = { - enable = mkOption { - type = types.bool; - default = false; - example = true; - description = '' - Enable Gammastep to change your screen's colour temperature depending on - the time of day. - ''; - }; - - latitude = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Your current latitude, between -90.0 and - 90.0. Must be provided along with - longitude. - ''; - }; - - longitude = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Your current longitude, between -180.0 and - 180.0. Must be provided along with - latitude. - ''; - }; - - provider = mkOption { - type = types.enum [ "manual" "geoclue2" ]; - default = "manual"; - description = '' - The location provider to use for determining your location. If set to - manual you must also provide latitude/longitude. - If set to geoclue2, you must also enable the global - geoclue2 service. - ''; - }; - - temperature = { - day = mkOption { - type = types.int; - default = 5500; - description = '' - Colour temperature to use during the day, between - 1000 and 25000 K. - ''; - }; - - night = mkOption { - type = types.int; - default = 3700; - description = '' - Colour temperature to use at night, between - 1000 and 25000 K. - ''; - }; - }; - - brightness = { - day = mkOption { - type = types.str; - default = "1"; - description = '' - Screen brightness to apply during the day, - between 0.1 and 1.0. - ''; - }; - - night = mkOption { - type = types.str; - default = "1"; - description = '' - Screen brightness to apply during the night, - between 0.1 and 1.0. - ''; - }; - }; - - package = mkOption { - type = types.package; - default = pkgs.gammastep; - defaultText = literalExample "pkgs.gammastep"; - description = '' - gammastep derivation to use. - ''; - }; - - tray = mkOption { - type = types.bool; - default = false; - example = true; - description = '' - Start the gammastep-indicator tray applet. - ''; - }; - - extraOptions = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "-v" "-m randr" ]; - description = '' - Additional command-line arguments to pass to - gammastep. - ''; - }; - }; - - config = mkIf cfg.enable { - assertions = [{ - assertion = cfg.provider == "manual" -> cfg.latitude != null - && cfg.longitude != null; - message = "Must provide services.gammastep.latitude and" - + " services.gammastep.latitude when" - + " services.gammastep.provider is set to \"manual\"."; - }]; - - systemd.user.services.gammastep = { - Unit = { - Description = "Gammastep colour temperature adjuster"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - - Install = { WantedBy = [ "graphical-session.target" ]; }; - - Service = { - ExecStart = let - providerString = if cfg.provider == "manual" then - "${cfg.latitude}:${cfg.longitude}" - else - cfg.provider; - - args = [ - "-l ${providerString}" - "-t ${toString cfg.temperature.day}:${ - toString cfg.temperature.night - }" - "-b ${toString cfg.brightness.day}:${toString cfg.brightness.night}" - ] ++ cfg.extraOptions; - - command = if cfg.tray then "gammastep-indicator" else "gammastep"; - in "${cfg.package}/bin/${command} ${concatStringsSep " " args}"; - RestartSec = 3; - Restart = "always"; - }; - }; - }; - -} diff --git a/third_party/home-manager/modules/services/gnome-keyring.nix b/third_party/home-manager/modules/services/gnome-keyring.nix index ce39cea93f..7e3f8bbce2 100644 --- a/third_party/home-manager/modules/services/gnome-keyring.nix +++ b/third_party/home-manager/modules/services/gnome-keyring.nix @@ -36,7 +36,7 @@ in { args = concatStringsSep " " ([ "--start" "--foreground" ] ++ optional (cfg.components != [ ]) ("--components=" + concatStringsSep "," cfg.components)); - in "${pkgs.gnome3.gnome-keyring}/bin/gnome-keyring-daemon ${args}"; + in "${pkgs.gnome.gnome-keyring}/bin/gnome-keyring-daemon ${args}"; Restart = "on-abort"; }; diff --git a/third_party/home-manager/modules/services/gpg-agent.nix b/third_party/home-manager/modules/services/gpg-agent.nix index 16a4723fea..785c23b4b1 100644 --- a/third_party/home-manager/modules/services/gpg-agent.nix +++ b/third_party/home-manager/modules/services/gpg-agent.nix @@ -1,17 +1,41 @@ -{ config, lib, pkgs, ... }: +{ config, options, lib, pkgs, ... }: with lib; let cfg = config.services.gpg-agent; + gpgPkg = config.programs.gpg.package; + + homedir = config.programs.gpg.homedir; gpgInitStr = '' GPG_TTY="$(tty)" export GPG_TTY '' + optionalString cfg.enableSshSupport - "${pkgs.gnupg}/bin/gpg-connect-agent updatestartuptty /bye > /dev/null"; + "${gpgPkg}/bin/gpg-connect-agent updatestartuptty /bye > /dev/null"; + + # mimic `gpgconf` output for use in `systemd` unit definitions. + # we cannot use `gpgconf` directly because it heavily depends on system + # state, but we need the values at build time. original: + # https://github.com/gpg/gnupg/blob/c6702d77d936b3e9d91b34d8fdee9599ab94ee1b/common/homedir.c#L672-L681 + gpgconf = dir: let + f = pkgs.runCommand dir {} '' + PATH=${pkgs.coreutils}/bin:${pkgs.xxd}/bin:$PATH + + if [[ ${homedir} = ${options.programs.gpg.homedir.default} ]] + then + echo -n "%t/gnupg/${dir}" > $out + else + hash=$(echo -n ${homedir} | sha1sum -b | xxd -r -p | base32 | \ + cut -c -24 | tr '[:upper:]' '[:lower:]' | \ + tr abcdefghijklmnopqrstuvwxyz234567 \ + ybndrfg8ejkmcpqxot1uwisza345h769) + echo -n "%t/gnupg/d.$hash/${dir}" > $out + fi + ''; + in "${builtins.readFile f}"; in @@ -154,7 +178,7 @@ in config = mkIf cfg.enable (mkMerge [ { - home.file.".gnupg/gpg-agent.conf".text = concatStringsSep "\n" ( + home.file."${homedir}/gpg-agent.conf".text = concatStringsSep "\n" ( optional (cfg.enableSshSupport) "enable-ssh-support" ++ optional (!cfg.grabKeyboardAndMouse) "no-grab" @@ -181,22 +205,25 @@ in home.sessionVariables = optionalAttrs cfg.enableSshSupport { - SSH_AUTH_SOCK = "$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)"; + SSH_AUTH_SOCK = "$(${gpgPkg}/bin/gpgconf --list-dirs agent-ssh-socket)"; }; programs.bash.initExtra = gpgInitStr; programs.zsh.initExtra = gpgInitStr; + programs.fish.interactiveShellInit = '' + set -gx GPG_TTY (tty) + ''; } (mkIf (cfg.sshKeys != null) { # Trailing newlines are important - home.file.".gnupg/sshcontrol".text = concatMapStrings (s: "${s}\n") cfg.sshKeys; + home.file."${homedir}/sshcontrol".text = concatMapStrings (s: "${s}\n") cfg.sshKeys; }) # The systemd units below are direct translations of the # descriptions in the # - # ${pkgs.gnupg}/share/doc/gnupg/examples/systemd-user + # ${gpgPkg}/share/doc/gnupg/examples/systemd-user # # directory. { @@ -211,9 +238,10 @@ in }; Service = { - ExecStart = "${pkgs.gnupg}/bin/gpg-agent --supervised" + ExecStart = "${gpgPkg}/bin/gpg-agent --supervised" + optionalString cfg.verbose " --verbose"; - ExecReload = "${pkgs.gnupg}/bin/gpgconf --reload gpg-agent"; + ExecReload = "${gpgPkg}/bin/gpgconf --reload gpg-agent"; + Environment = "GNUPGHOME=${homedir}"; }; }; @@ -224,7 +252,7 @@ in }; Socket = { - ListenStream = "%t/gnupg/S.gpg-agent"; + ListenStream = gpgconf "S.gpg-agent"; FileDescriptorName = "std"; SocketMode = "0600"; DirectoryMode = "0700"; @@ -244,7 +272,7 @@ in }; Socket = { - ListenStream = "%t/gnupg/S.gpg-agent.ssh"; + ListenStream = gpgconf "S.gpg-agent.ssh"; FileDescriptorName = "ssh"; Service = "gpg-agent.service"; SocketMode = "0600"; @@ -265,7 +293,7 @@ in }; Socket = { - ListenStream = "%t/gnupg/S.gpg-agent.extra"; + ListenStream = gpgconf "S.gpg-agent.extra"; FileDescriptorName = "extra"; Service = "gpg-agent.service"; SocketMode = "0600"; diff --git a/third_party/home-manager/modules/services/hound.nix b/third_party/home-manager/modules/services/hound.nix index 00589f3405..07b5d47653 100644 --- a/third_party/home-manager/modules/services/hound.nix +++ b/third_party/home-manager/modules/services/hound.nix @@ -6,12 +6,14 @@ let cfg = config.services.hound; - configFile = pkgs.writeText "hound-config.json" (builtins.toJSON { + jsonFormat = pkgs.formats.json { }; + + configFile = jsonFormat.generate "hound-config.json" { max-concurrent-indexers = cfg.maxConcurrentIndexers; dbpath = cfg.databasePath; repos = cfg.repositories; health-check-url = "/healthz"; - }); + }; houndOptions = [ "--addr ${cfg.listenAddress}" "--conf ${configFile}" ]; @@ -41,7 +43,7 @@ in { }; repositories = mkOption { - type = types.attrsOf (types.uniq types.attrs); + type = types.attrsOf jsonFormat.type; default = { }; example = literalExample '' { diff --git a/third_party/home-manager/modules/services/imapnotify.nix b/third_party/home-manager/modules/services/imapnotify.nix index b59b006e33..4b3ebda71c 100644 --- a/third_party/home-manager/modules/services/imapnotify.nix +++ b/third_party/home-manager/modules/services/imapnotify.nix @@ -19,8 +19,12 @@ let Unit = { Description = "imapnotify for ${name}"; }; Service = { - ExecStart = - "${pkgs.imapnotify}/bin/imapnotify -c ${genAccountConfig account}"; + ExecStart = "${pkgs.goimapnotify}/bin/goimapnotify -conf ${ + genAccountConfig account + }"; + Restart = "always"; + RestartSec = 30; + Type = "simple"; } // optionalAttrs account.notmuch.enable { Environment = "NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc"; @@ -31,7 +35,7 @@ let }; genAccountConfig = account: - pkgs.writeText "imapnotify-${safeName account.name}-config.js" (let + pkgs.writeText "imapnotify-${safeName account.name}-config.json" (let port = if account.imap.port != null then account.imap.port else if account.imap.tls.enable then @@ -40,23 +44,17 @@ let 143; toJSON = builtins.toJSON; - in '' - var child_process = require('child_process'); - - function getStdout(cmd) { - var stdout = child_process.execSync(cmd); - return stdout.toString().trim(); - } - - exports.host = ${toJSON account.imap.host} - exports.port = ${toJSON port}; - exports.tls = ${toJSON account.imap.tls.enable}; - exports.username = ${toJSON account.userName}; - exports.password = getStdout("${toString account.passwordCommand}"); - exports.onNotify = ${toJSON account.imapnotify.onNotify}; - exports.onNotifyPost = ${toJSON account.imapnotify.onNotifyPost}; - exports.boxes = ${toJSON account.imapnotify.boxes}; - ''); + in toJSON { + inherit (account.imap) host; + inherit port; + tls = account.imap.tls.enable; + username = account.userName; + passwordCmd = + lib.concatMapStringsSep " " lib.escapeShellArg account.passwordCommand; + onNewMail = account.imapnotify.onNotify; + onNewMailPost = account.imapnotify.onNotifyPost; + inherit (account.imapnotify) boxes; + }); in { meta.maintainers = [ maintainers.nickhu ]; diff --git a/third_party/home-manager/modules/services/kanshi.nix b/third_party/home-manager/modules/services/kanshi.nix index 4e5e5f104e..8df32121af 100644 --- a/third_party/home-manager/modules/services/kanshi.nix +++ b/third_party/home-manager/modules/services/kanshi.nix @@ -146,6 +146,26 @@ in { description = '' List of profiles. ''; + example = literalExample '' + undocked = { + outputs = [ + { + criteria = "eDP-1"; + } + ]; + }; + docked = { + outputs = [ + { + criteria = "eDP-1"; + } + { + criteria = "Some Company ASDF 4242"; + transform = "90"; + } + ]; + }; + ''; }; extraConfig = mkOption { diff --git a/third_party/home-manager/modules/services/kbfs.nix b/third_party/home-manager/modules/services/kbfs.nix index 863f4feea3..d4be2592c0 100644 --- a/third_party/home-manager/modules/services/kbfs.nix +++ b/third_party/home-manager/modules/services/kbfs.nix @@ -6,9 +6,7 @@ let cfg = config.services.kbfs; -in - -{ +in { options = { services.kbfs = { enable = mkEnableOption "Keybase File System"; @@ -24,11 +22,8 @@ in extraFlags = mkOption { type = types.listOf types.str; - default = []; - example = [ - "-label kbfs" - "-mount-type normal" - ]; + default = [ ]; + example = [ "-label kbfs" "-mount-type normal" ]; description = '' Additional flags to pass to the Keybase filesystem on launch. ''; @@ -44,21 +39,18 @@ in After = [ "keybase.service" ]; }; - Service = - let - mountPoint = "\"%h/${cfg.mountPoint}\""; - in { - Environment = "PATH=/run/wrappers/bin KEYBASE_SYSTEMD=1"; - ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${mountPoint}"; - ExecStart ="${pkgs.kbfs}/bin/kbfsfuse ${toString cfg.extraFlags} ${mountPoint}"; - ExecStopPost = "/run/wrappers/bin/fusermount -u ${mountPoint}"; - Restart = "on-failure"; - PrivateTmp = true; - }; - - Install = { - WantedBy = [ "default.target" ]; + Service = let mountPoint = ''"%h/${cfg.mountPoint}"''; + in { + Environment = "PATH=/run/wrappers/bin KEYBASE_SYSTEMD=1"; + ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${mountPoint}"; + ExecStart = + "${pkgs.kbfs}/bin/kbfsfuse ${toString cfg.extraFlags} ${mountPoint}"; + ExecStopPost = "/run/wrappers/bin/fusermount -u ${mountPoint}"; + Restart = "on-failure"; + PrivateTmp = true; }; + + Install.WantedBy = [ "default.target" ]; }; home.packages = [ pkgs.kbfs ]; diff --git a/third_party/home-manager/modules/services/keybase.nix b/third_party/home-manager/modules/services/keybase.nix index 2d0a06b06a..0aec0bbc85 100644 --- a/third_party/home-manager/modules/services/keybase.nix +++ b/third_party/home-manager/modules/services/keybase.nix @@ -6,22 +6,14 @@ let cfg = config.services.keybase; -in - -{ - options = { - services.keybase = { - enable = mkEnableOption "Keybase"; - }; - }; +in { + options.services.keybase.enable = mkEnableOption "Keybase"; config = mkIf cfg.enable { home.packages = [ pkgs.keybase ]; systemd.user.services.keybase = { - Unit = { - Description = "Keybase service"; - }; + Unit.Description = "Keybase service"; Service = { ExecStart = "${pkgs.keybase}/bin/keybase service --auto-forked"; @@ -29,9 +21,7 @@ in PrivateTmp = true; }; - Install = { - WantedBy = [ "default.target" ]; - }; + Install.WantedBy = [ "default.target" ]; }; }; } diff --git a/third_party/home-manager/modules/services/lieer.nix b/third_party/home-manager/modules/services/lieer.nix index 571e2af75c..71f0a66e5d 100644 --- a/third_party/home-manager/modules/services/lieer.nix +++ b/third_party/home-manager/modules/services/lieer.nix @@ -26,6 +26,8 @@ let Type = "oneshot"; ExecStart = "${pkgs.gmailieer}/bin/gmi sync"; WorkingDirectory = account.maildir.absPath; + Environment = + "NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc"; }; }; }; diff --git a/third_party/home-manager/modules/services/mako.nix b/third_party/home-manager/modules/services/mako.nix index 77ea301167..e8f4d38c2e 100644 --- a/third_party/home-manager/modules/services/mako.nix +++ b/third_party/home-manager/modules/services/mako.nix @@ -271,6 +271,15 @@ in { ''; }; + extraConfig = mkOption { + default = ""; + type = types.lines; + example = literalExample '' + [urgency=low] + border-color=#b8bb26 + ''; + description = "Additional configuration."; + }; }; }; @@ -311,6 +320,8 @@ in { ${optionalInteger "default-timeout" cfg.defaultTimeout} ${optionalBoolean "ignore-timeout" cfg.ignoreTimeout} ${optionalString "group-by" cfg.groupBy} + + ${cfg.extraConfig} ''; }; } diff --git a/third_party/home-manager/modules/services/mpd.nix b/third_party/home-manager/modules/services/mpd.nix index 13b3ae78f2..a6ed0a4831 100644 --- a/third_party/home-manager/modules/services/mpd.nix +++ b/third_party/home-manager/modules/services/mpd.nix @@ -41,7 +41,16 @@ in { ''; }; - musicDirectory = mkOption { + package = mkOption { + type = types.package; + default = pkgs.mpd; + defaultText = "pkgs.mpd"; + description = '' + The MPD package to run. + ''; + }; + + musicDirectory = mkOption { type = with types; either path str; default = "${config.home.homeDirectory}/music"; defaultText = "$HOME/music"; @@ -87,7 +96,14 @@ in { ''; }; - network = { + network = { + startWhenNeeded = mkOption { + type = types.bool; + default = false; + description = '' + Enable systemd socket activation. + ''; + }; listenAddress = mkOption { type = types.str; @@ -134,17 +150,34 @@ in { Description = "Music Player Daemon"; }; - Install = { + Install = mkIf (!cfg.network.startWhenNeeded) { WantedBy = [ "default.target" ]; }; Service = { Environment = "PATH=${config.home.profileDirectory}/bin"; - ExecStart = "${pkgs.mpd}/bin/mpd --no-daemon ${mpdConf}"; + ExecStart = "${cfg.package}/bin/mpd --no-daemon ${mpdConf}"; Type = "notify"; ExecStartPre = ''${pkgs.bash}/bin/bash -c "${pkgs.coreutils}/bin/mkdir -p '${cfg.dataDir}' '${cfg.playlistDirectory}'"''; }; }; + systemd.user.sockets.mpd = mkIf cfg.network.startWhenNeeded { + Socket = { + ListenStream = let + listen = + if cfg.network.listenAddress == "any" + then toString cfg.network.port + else "${cfg.network.listenAddress}:${toString cfg.network.port}"; + in [ listen "%t/mpd/socket" ]; + + Backlog = 5; + KeepAlive = true; + }; + + Install = { + WantedBy = [ "sockets.target" ]; + }; + }; }; } diff --git a/third_party/home-manager/modules/services/mpris-proxy.nix b/third_party/home-manager/modules/services/mpris-proxy.nix new file mode 100644 index 0000000000..69f56c21f5 --- /dev/null +++ b/third_party/home-manager/modules/services/mpris-proxy.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.mpris-proxy; + +in { + meta.maintainers = [ maintainers.thibautmarty ]; + + options.services.mpris-proxy.enable = mkEnableOption + "a proxy forwarding Bluetooth MIDI controls via MPRIS2 to control media players"; + + config = mkIf cfg.enable { + systemd.user.services.mpris-proxy = { + Unit = { + Description = + "Proxy forwarding Bluetooth MIDI controls via MPRIS2 to control media players"; + BindsTo = [ "bluetooth.target" ]; + After = [ "bluetooth.target" ]; + }; + + Install.WantedBy = [ "bluetooth.target" ]; + + Service = { + Type = "simple"; + ExecStart = "${pkgs.bluez}/bin/mpris-proxy"; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/network-manager-applet.nix b/third_party/home-manager/modules/services/network-manager-applet.nix index bf57ed6509..b84861a998 100644 --- a/third_party/home-manager/modules/services/network-manager-applet.nix +++ b/third_party/home-manager/modules/services/network-manager-applet.nix @@ -19,7 +19,8 @@ in { systemd.user.services.network-manager-applet = { Unit = { Description = "Network Manager applet"; - After = [ "graphical-session-pre.target" ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/nextcloud-client.nix b/third_party/home-manager/modules/services/nextcloud-client.nix index 555ca11ad6..4e56c4f50f 100644 --- a/third_party/home-manager/modules/services/nextcloud-client.nix +++ b/third_party/home-manager/modules/services/nextcloud-client.nix @@ -2,12 +2,32 @@ with lib; -{ +let + + cfg = config.services.nextcloud-client; + +in { options = { - services.nextcloud-client = { enable = mkEnableOption "Nextcloud Client"; }; + services.nextcloud-client = { + enable = mkEnableOption "Nextcloud Client"; + + package = mkOption { + type = types.package; + default = pkgs.nextcloud-client; + defaultText = literalExample "pkgs.nextcloud-client"; + description = "The package to use for the nextcloud client binary."; + }; + + startInBackground = mkOption { + type = types.bool; + default = false; + description = + "Whether to start the Nextcloud client in the background."; + }; + }; }; - config = mkIf config.services.nextcloud-client.enable { + config = mkIf cfg.enable { systemd.user.services.nextcloud-client = { Unit = { Description = "Nextcloud Client"; @@ -17,7 +37,8 @@ with lib; Service = { Environment = "PATH=${config.home.profileDirectory}/bin"; - ExecStart = "${pkgs.nextcloud-client}/bin/nextcloud"; + ExecStart = "${cfg.package}/bin/nextcloud" + + (optionalString cfg.startInBackground " --background"); }; Install = { WantedBy = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/pantalaimon.nix b/third_party/home-manager/modules/services/pantalaimon.nix new file mode 100644 index 0000000000..38662a346c --- /dev/null +++ b/third_party/home-manager/modules/services/pantalaimon.nix @@ -0,0 +1,79 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.pantalaimon; + + iniFmt = pkgs.formats.ini { }; +in { + meta.maintainers = [ maintainers.jojosch ]; + + options = { + services.pantalaimon = { + enable = mkEnableOption + "Pantalaimon, an E2EE aware proxy daemon for matrix clients"; + + package = mkOption { + type = types.package; + default = pkgs.pantalaimon; + defaultText = literalExample "pkgs.pantalaimon"; + description = + "Package providing the pantalaimon executable to use."; + }; + + settings = mkOption { + type = iniFmt.type; + default = { }; + defaultText = literalExample "{ }"; + example = literalExample '' + { + Default = { + LogLevel = "Debug"; + SSL = true; + }; + local-matrix = { + Homeserver = "https://matrix.org"; + ListenAddress = "127.0.0.1"; + ListenPort = 8008; + }; + } + ''; + description = '' + Configuration written to + $XDG_CONFIG_HOME/pantalaimon/pantalaimon.conf. + + See or + + pantalaimon + 5 + + for options. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + systemd.user.services = { + pantalaimon = { + Unit = { + Description = + "Pantalaimon - E2EE aware proxy daemon for matrix clients"; + After = [ "network-online.target" ]; + }; + + Service = { + ExecStart = "${cfg.package}/bin/pantalaimon -c ${ + iniFmt.generate "pantalaimon.conf" cfg.settings + }"; + Restart = "on-failure"; + }; + + Install.WantedBy = [ "default.target" ]; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/parcellite.nix b/third_party/home-manager/modules/services/parcellite.nix index ce04238613..dddb0631de 100644 --- a/third_party/home-manager/modules/services/parcellite.nix +++ b/third_party/home-manager/modules/services/parcellite.nix @@ -5,29 +5,37 @@ with lib; let cfg = config.services.parcellite; - package = pkgs.parcellite; in { meta.maintainers = [ maintainers.gleber ]; - options = { - services.parcellite = { enable = mkEnableOption "Parcellite"; }; + options.services.parcellite = { + enable = mkEnableOption "Parcellite"; + + package = mkOption { + type = types.package; + default = pkgs.parcellite; + defaultText = literalExample "pkgs.parcellite"; + example = literalExample "pkgs.clipit"; + description = "Parcellite derivation to use."; + }; }; config = mkIf cfg.enable { - home.packages = [ package ]; + home.packages = [ cfg.package ]; systemd.user.services.parcellite = { Unit = { Description = "Lightweight GTK+ clipboard manager"; - After = [ "graphical-session-pre.target" ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; }; Service = { - ExecStart = "${package}/bin/parcellite"; + ExecStart = "${cfg.package}/bin/${cfg.package.pname}"; Restart = "on-abort"; }; }; diff --git a/third_party/home-manager/modules/services/pass-secret-service.nix b/third_party/home-manager/modules/services/pass-secret-service.nix new file mode 100644 index 0000000000..d2ed11ee70 --- /dev/null +++ b/third_party/home-manager/modules/services/pass-secret-service.nix @@ -0,0 +1,28 @@ +{ pkgs, config, lib, ... }: + +with lib; + +let serviceCfg = config.services.pass-secret-service; +in { + meta.maintainers = [ maintainers.cab404 ]; + options.services.pass-secret-service = { + enable = mkEnableOption "Pass libsecret service"; + }; + config = mkIf serviceCfg.enable { + assertions = [{ + 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"; }; + 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}"; + }; + Install = { WantedBy = [ "default.target" ]; }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/pasystray.nix b/third_party/home-manager/modules/services/pasystray.nix index 7c6651d949..d41d6c9347 100644 --- a/third_party/home-manager/modules/services/pasystray.nix +++ b/third_party/home-manager/modules/services/pasystray.nix @@ -13,7 +13,8 @@ with lib; systemd.user.services.pasystray = { Unit = { Description = "PulseAudio system tray"; - After = [ "graphical-session-pre.target" ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/pbgopy.nix b/third_party/home-manager/modules/services/pbgopy.nix new file mode 100644 index 0000000000..f4fd4f53fe --- /dev/null +++ b/third_party/home-manager/modules/services/pbgopy.nix @@ -0,0 +1,68 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.pbgopy; + package = pkgs.pbgopy; + + commandLine = concatStringsSep " " ([ + "${package}/bin/pbgopy serve" + "--port ${toString cfg.port}" + "--ttl ${cfg.cache.ttl}" + ] ++ optional (cfg.httpAuth != null) + "--basic-auth ${escapeShellArg cfg.httpAuth}"); + +in { + meta.maintainers = [ maintainers.ivar ]; + + options.services.pbgopy = { + enable = mkEnableOption "pbgopy"; + + port = mkOption { + type = types.port; + default = 9090; + example = 8080; + description = '' + The port to host the pbgopy server on. + ''; + }; + + cache.ttl = mkOption { + type = types.str; + default = "24h"; + example = "10m"; + description = '' + The TTL for the cache. Use "0s" to disable it. + ''; + }; + + httpAuth = mkOption { + type = types.nullOr types.str; + default = null; + example = "user:pass"; + description = '' + Basic HTTP authentication's username and password. Both the username and + password are escaped. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ package ]; + + systemd.user.services.pbgopy = { + Unit = { + Description = "pbgopy server for sharing the clipboard between devices"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = commandLine; + Restart = "on-abort"; + }; + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/plan9port.nix b/third_party/home-manager/modules/services/plan9port.nix new file mode 100644 index 0000000000..0f5893f21b --- /dev/null +++ b/third_party/home-manager/modules/services/plan9port.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.plan9port; + +in { + meta.maintainers = [ maintainers.ehmry ]; + + options.services.plan9port = { + fontsrv.enable = + mkEnableOption "the Plan 9 file system access to host fonts"; + plumber.enable = + mkEnableOption "the Plan 9 file system for interprocess messaging"; + }; + + config = { + + systemd.user.services.fontsrv = mkIf cfg.fontsrv.enable { + Unit.Description = "the Plan 9 file system access to host fonts"; + Install.WantedBy = [ "default.target" ]; + Service.ExecStart = "${pkgs.plan9port}/bin/9 fontsrv"; + }; + + systemd.user.services.plumber = mkIf cfg.plumber.enable { + Unit.Description = "file system for interprocess messaging"; + Install.WantedBy = [ "default.target" ]; + Service.ExecStart = "${pkgs.plan9port}/bin/9 plumber -f"; + }; + + }; + +} diff --git a/third_party/home-manager/modules/services/playerctld.nix b/third_party/home-manager/modules/services/playerctld.nix new file mode 100644 index 0000000000..63e7b8feb2 --- /dev/null +++ b/third_party/home-manager/modules/services/playerctld.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.playerctld; + +in { + meta.maintainers = [ maintainers.fendse ]; + + options.services.playerctld = { + enable = mkEnableOption "playerctld daemon"; + + package = mkOption { + type = types.package; + default = pkgs.playerctl; + defaultText = literalExample "pkgs.playerctl"; + description = "The playerctl package to use."; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.playerctld = { + Unit.Description = "MPRIS media player daemon"; + + Install.WantedBy = [ "default.target" ]; + + Service = { + ExecStart = "${cfg.package}/bin/playerctld"; + Type = "dbus"; + BusName = "org.mpris.MediaPlayer2.playerctld"; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/polybar.nix b/third_party/home-manager/modules/services/polybar.nix index 934a990638..8a8e99942b 100644 --- a/third_party/home-manager/modules/services/polybar.nix +++ b/third_party/home-manager/modules/services/polybar.nix @@ -9,6 +9,36 @@ let eitherStrBoolIntList = with types; either str (either bool (either int (listOf str))); + # Convert a key/val pair to the insane format that polybar uses. + # Each input key/val pair may return several output key/val pairs. + convertPolybarKeyVal = key: val: + # Convert { foo = [ "a" "b" ]; } + # to { + # foo-0 = "a"; + # foo-1 = "b"; + # } + if isList val then + concatLists (imap0 (i: convertPolybarKeyVal "${key}-${toString i}") val) + # Convert { + # foo.text = "a"; + # foo.font = 1; + # } to { + # foo = "a"; + # foo-font = 1; + # } + else if isAttrs val && !lib.isDerivation val then + concatLists (mapAttrsToList + (k: convertPolybarKeyVal (if k == "text" then key else "${key}-${k}")) + val) + # Base case + else + [ (nameValuePair key val) ]; + + convertPolybarSection = _: attrs: + listToAttrs (concatLists (mapAttrsToList convertPolybarKeyVal attrs)); + + # Converts an attrset to INI text, quoting values as expected by polybar. + # This does no more fancy conversion. toPolybarIni = generators.toINI { mkKeyValue = key: value: let @@ -24,8 +54,11 @@ let in "${key}=${value'}"; }; - configFile = pkgs.writeText "polybar.conf" - (toPolybarIni cfg.config + "\n" + cfg.extraConfig); + configFile = pkgs.writeText "polybar.conf" '' + ${toPolybarIni cfg.config} + ${toPolybarIni (mapAttrs convertPolybarSection cfg.settings)} + ${cfg.extraConfig} + ''; in { options = { @@ -54,6 +87,7 @@ in { description = '' Polybar configuration. Can be either path to a file, or set of attributes that will be used to create the final configuration. + See also for a more nix-friendly format. ''; default = { }; example = literalExample '' @@ -77,6 +111,56 @@ in { ''; }; + settings = mkOption { + type = types.attrsOf types.attrs; + description = '' + Polybar configuration. This takes a nix attrset and converts it to the + strange data format that polybar uses. + Each entry will be converted to a section in the output file. + Several things are treated specially: nested keys are converted + to dash-separated keys; the special text key is ignored as a nested key, + to allow mixing different levels of nesting; and lists are converted to + polybar's foo-0, foo-1, ... format. + + For example: + + "module/volume" = { + type = "internal/pulseaudio"; + format.volume = "<ramp-volume> <label-volume>"; + label.muted.text = "🔇"; + label.muted.foreground = "#666"; + ramp.volume = ["🔈" "🔉" "🔊"]; + click.right = "pavucontrol &"; + } + + becomes: + + [module/volume] + type=internal/pulseaudio + format-volume=<ramp-volume> <label-volume> + label-muted=🔇 + label-muted-foreground=#666 + ramp-volume-0=🔈 + ramp-volume-1=🔉 + ramp-volume-2=🔊 + click-right=pavucontrol & + + ''; + default = { }; + example = literalExample '' + { + "module/volume" = { + type = "internal/pulseaudio"; + format.volume = " "; + label.muted.text = "🔇"; + label.muted.foreground = "#666"; + ramp.volume = ["🔈" "🔉" "🔊"]; + click.right = "pavucontrol &"; + }; + } + ''; + }; + extraConfig = mkOption { type = types.lines; description = "Additional configuration to add."; @@ -113,8 +197,7 @@ in { systemd.user.services.polybar = { Unit = { Description = "Polybar status bar"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; + PartOf = [ "tray.target" ]; X-Restart-Triggers = [ "${config.xdg.configFile."polybar/config".source}" ]; }; @@ -128,7 +211,7 @@ in { Restart = "on-failure"; }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Install = { WantedBy = [ "tray.target" ]; }; }; }; diff --git a/third_party/home-manager/modules/services/poweralertd.nix b/third_party/home-manager/modules/services/poweralertd.nix new file mode 100644 index 0000000000..39fffd7cdd --- /dev/null +++ b/third_party/home-manager/modules/services/poweralertd.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.poweralertd; + +in { + meta.maintainers = [ maintainers.thibautmarty ]; + + options.services.poweralertd.enable = + mkEnableOption "the Upower-powered power alerterd"; + + config = mkIf cfg.enable { + systemd.user.services.poweralertd = { + Unit = { + Description = "UPower-powered power alerter"; + Documentation = "man:poweralertd(1)"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Install.WantedBy = [ "graphical-session.target" ]; + + Service = { + Type = "simple"; + ExecStart = "${pkgs.poweralertd}/bin/poweralertd"; + Restart = "always"; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/pulseeffects.nix b/third_party/home-manager/modules/services/pulseeffects.nix index 445b1c0a1f..184c2af791 100644 --- a/third_party/home-manager/modules/services/pulseeffects.nix +++ b/third_party/home-manager/modules/services/pulseeffects.nix @@ -14,6 +14,14 @@ in { options.services.pulseeffects = { enable = mkEnableOption "Pulseeffects daemon"; + package = mkOption { + type = types.package; + default = pkgs.pulseeffects; + defaultText = literalExample "pkgs.pulseeffects"; + description = "Pulseeffects package to use."; + example = literalExample "pkgs.pulseeffects-pw"; + }; + preset = mkOption { type = types.str; default = ""; @@ -28,9 +36,9 @@ in { # running pulseeffects 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 = [ pkgs.pulseeffects pkgs.at-spi2-core ]; + home.packages = [ cfg.package pkgs.at-spi2-core ]; - # Will need to add `services.dbus.packages = with pkgs; [ gnome3.dconf ];` + # Will need to add `services.dbus.packages = with pkgs; [ gnome.dconf ];` # to /etc/nixos/configuration.nix for daemon to work correctly systemd.user.services.pulseeffects = { @@ -45,8 +53,8 @@ in { Service = { ExecStart = - "${pkgs.pulseeffects}/bin/pulseeffects --gapplication-service ${presetOpts}"; - ExecStop = "${pkgs.pulseeffects}/bin/pulseeffects --quit"; + "${cfg.package}/bin/pulseeffects --gapplication-service ${presetOpts}"; + ExecStop = "${cfg.package}/bin/pulseeffects --quit"; Restart = "on-failure"; RestartSec = 5; }; diff --git a/third_party/home-manager/modules/services/redshift-gammastep/gammastep.nix b/third_party/home-manager/modules/services/redshift-gammastep/gammastep.nix new file mode 100644 index 0000000000..0a7f785a24 --- /dev/null +++ b/third_party/home-manager/modules/services/redshift-gammastep/gammastep.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + commonOptions = import ./lib/options.nix { + inherit config lib pkgs; + + moduleName = "gammastep"; + programName = "Gammastep"; + # https://gitlab.com/chinstrap/gammastep/-/commit/1608ed61154cc652b087e85c4ce6125643e76e2f + mainSection = "general"; + defaultPackage = pkgs.gammastep; + examplePackage = "pkgs.gammastep"; + mainExecutable = "gammastep"; + appletExecutable = "gammastep-indicator"; + xdgConfigFilePath = "gammastep/config.ini"; + serviceDocumentation = "https://gitlab.com/chinstrap/gammastep/"; + }; + +in { + inherit (commonOptions) imports meta; + options.services.gammastep = commonOptions.options; + config = mkIf config.services.gammastep.enable commonOptions.config; +} diff --git a/third_party/home-manager/modules/services/redshift-gammastep/lib/options.nix b/third_party/home-manager/modules/services/redshift-gammastep/lib/options.nix new file mode 100644 index 0000000000..11ce9d7ce1 --- /dev/null +++ b/third_party/home-manager/modules/services/redshift-gammastep/lib/options.nix @@ -0,0 +1,201 @@ +{ config, lib, pkgs, moduleName, mainSection, programName, defaultPackage +, examplePackage, mainExecutable, appletExecutable, xdgConfigFilePath +, serviceDocumentation }: + +with lib; + +let + + cfg = config.services.${moduleName}; + settingsFormat = pkgs.formats.ini { }; + +in { + meta = { + maintainers = with maintainers; [ rycee petabyteboy thiagokokada ]; + }; + + imports = let + mkRenamed = old: new: + mkRenamedOptionModule ([ "services" moduleName ] ++ old) [ + "services" + moduleName + "settings" + mainSection + new + ]; + in [ + (mkRemovedOptionModule [ "services" moduleName "extraOptions" ] + "All ${programName} configuration is now available through services.${moduleName}.settings instead.") + (mkRenamed [ "brightness" "day" ] "brightness-day") + (mkRenamed [ "brightness" "night" ] "brightness-night") + ]; + + options = { + enable = mkEnableOption programName; + + dawnTime = mkOption { + type = types.nullOr types.str; + default = null; + example = "6:00-7:45"; + description = '' + Set the time interval of dawn manually. + The times must be specified as HH:MM in 24-hour format. + ''; + }; + + duskTime = mkOption { + type = types.nullOr types.str; + default = null; + example = "18:35-20:15"; + description = '' + Set the time interval of dusk manually. + The times must be specified as HH:MM in 24-hour format. + ''; + }; + + latitude = mkOption { + type = with types; nullOr (either str float); + default = null; + description = '' + Your current latitude, between -90.0 and + 90.0. Must be provided along with + longitude. + ''; + }; + + longitude = mkOption { + type = with types; nullOr (either str float); + default = null; + description = '' + Your current longitude, between -180.0 and + 180.0. Must be provided along with + latitude. + ''; + }; + + provider = mkOption { + type = types.enum [ "manual" "geoclue2" ]; + default = "manual"; + description = '' + The location provider to use for determining your location. If set to + manual you must also provide latitude/longitude. + If set to geoclue2, you must also enable the global + geoclue2 service. + ''; + }; + + temperature = { + day = mkOption { + type = types.int; + default = 5500; + description = '' + Colour temperature to use during the day, between + 1000 and 25000 K. + ''; + }; + night = mkOption { + type = types.int; + default = 3700; + description = '' + Colour temperature to use at night, between + 1000 and 25000 K. + ''; + }; + }; + + package = mkOption { + type = types.package; + default = defaultPackage; + defaultText = literalExample examplePackage; + description = '' + ${programName} derivation to use. + ''; + }; + + tray = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Start the ${appletExecutable} tray applet. + ''; + }; + + settings = mkOption { + type = types.submodule { freeformType = settingsFormat.type; }; + default = { }; + example = literalExample '' + { + ${mainSection} = { + adjustment-method = "randr"; + }; + randr = { + screen = 0; + }; + }; + ''; + description = '' + The configuration to pass to ${programName}. + Available options for ${programName} described in + + ${moduleName} + 1 + . + ''; + }; + }; + + config = { + assertions = [{ + assertion = (cfg.settings ? ${mainSection}.dawn-time || cfg.settings + ? ${mainSection}.dusk-time) + || (cfg.settings.${mainSection}.location-provider) == "geoclue2" + || ((cfg.settings.${mainSection}.location-provider) == "manual" + && (cfg.settings ? manual.lat || cfg.settings ? manual.lon)); + message = '' + In order for ${programName} to know the time of action, you need to set one of + - services.${moduleName}.provider = "geoclue2" for automatically inferring your location + (you also need to enable Geoclue2 service separately) + - services.${moduleName}.longitude and .latitude for specifying your location manually + - services.${moduleName}.dawnTime and .duskTime for specifying the times manually + ''; + }]; + + services.${moduleName}.settings = { + ${mainSection} = { + temp-day = cfg.temperature.day; + temp-night = cfg.temperature.night; + location-provider = cfg.provider; + dawn-time = mkIf (cfg.dawnTime != null) cfg.dawnTime; + dusk-time = mkIf (cfg.duskTime != null) cfg.duskTime; + }; + manual = mkIf (cfg.provider == "manual") { + lat = mkIf (cfg.latitude != null) (toString cfg.latitude); + lon = mkIf (cfg.longitude != null) (toString cfg.longitude); + }; + }; + + xdg.configFile.${xdgConfigFilePath}.source = + settingsFormat.generate xdgConfigFilePath cfg.settings; + + systemd.user.services.${moduleName} = { + Unit = { + Description = "${programName} colour temperature adjuster"; + Documentation = serviceDocumentation; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + + Service = { + ExecStart = let + command = if cfg.tray then appletExecutable else mainExecutable; + configFullPath = config.xdg.configHome + "/${xdgConfigFilePath}"; + in "${cfg.package}/bin/${command} -v -c ${configFullPath}"; + RestartSec = 3; + Restart = "on-failure"; + }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/redshift-gammastep/redshift.nix b/third_party/home-manager/modules/services/redshift-gammastep/redshift.nix new file mode 100644 index 0000000000..ffccb35cec --- /dev/null +++ b/third_party/home-manager/modules/services/redshift-gammastep/redshift.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + commonOptions = import ./lib/options.nix { + inherit config lib pkgs; + + moduleName = "redshift"; + programName = "Redshift"; + mainSection = "redshift"; + defaultPackage = pkgs.redshift; + examplePackage = "pkgs.redshift"; + mainExecutable = "redshift"; + appletExecutable = "redshift-gtk"; + xdgConfigFilePath = "redshift/redshift.conf"; + serviceDocumentation = "http://jonls.dk/redshift/"; + }; + +in { + inherit (commonOptions) imports meta; + options.services.redshift = commonOptions.options; + config = mkIf config.services.redshift.enable commonOptions.config; +} diff --git a/third_party/home-manager/modules/services/redshift.nix b/third_party/home-manager/modules/services/redshift.nix deleted file mode 100644 index 86cbab205f..0000000000 --- a/third_party/home-manager/modules/services/redshift.nix +++ /dev/null @@ -1,164 +0,0 @@ -# Adapted from Nixpkgs. - -{ config, lib, pkgs, ... }: - -with lib; - -let - - cfg = config.services.redshift; - -in { - meta.maintainers = [ maintainers.rycee ]; - - options.services.redshift = { - enable = mkOption { - type = types.bool; - default = false; - example = true; - description = '' - Enable Redshift to change your screen's colour temperature depending on - the time of day. - ''; - }; - - latitude = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Your current latitude, between -90.0 and - 90.0. Must be provided along with - longitude. - ''; - }; - - longitude = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Your current longitude, between -180.0 and - 180.0. Must be provided along with - latitude. - ''; - }; - - provider = mkOption { - type = types.enum [ "manual" "geoclue2" ]; - default = "manual"; - description = '' - The location provider to use for determining your location. If set to - manual you must also provide latitude/longitude. - If set to geoclue2, you must also enable the global - geoclue2 service. - ''; - }; - - temperature = { - day = mkOption { - type = types.int; - default = 5500; - description = '' - Colour temperature to use during the day, between - 1000 and 25000 K. - ''; - }; - night = mkOption { - type = types.int; - default = 3700; - description = '' - Colour temperature to use at night, between - 1000 and 25000 K. - ''; - }; - }; - - brightness = { - day = mkOption { - type = types.str; - default = "1"; - description = '' - Screen brightness to apply during the day, - between 0.1 and 1.0. - ''; - }; - night = mkOption { - type = types.str; - default = "1"; - description = '' - Screen brightness to apply during the night, - between 0.1 and 1.0. - ''; - }; - }; - - package = mkOption { - type = types.package; - default = pkgs.redshift; - defaultText = literalExample "pkgs.redshift"; - description = '' - redshift derivation to use. - ''; - }; - - tray = mkOption { - type = types.bool; - default = false; - example = true; - description = '' - Start the redshift-gtk tray applet. - ''; - }; - - extraOptions = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "-v" "-m randr" ]; - description = '' - Additional command-line arguments to pass to - redshift. - ''; - }; - }; - - config = mkIf cfg.enable { - assertions = [{ - assertion = cfg.provider == "manual" -> cfg.latitude != null - && cfg.longitude != null; - message = "Must provide services.redshift.latitude and" - + " services.redshift.latitude when" - + " services.redshift.provider is set to \"manual\"."; - }]; - - systemd.user.services.redshift = { - Unit = { - Description = "Redshift colour temperature adjuster"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - - Install = { WantedBy = [ "graphical-session.target" ]; }; - - Service = { - ExecStart = let - providerString = if cfg.provider == "manual" then - "${cfg.latitude}:${cfg.longitude}" - else - cfg.provider; - - args = [ - "-l ${providerString}" - "-t ${toString cfg.temperature.day}:${ - toString cfg.temperature.night - }" - "-b ${toString cfg.brightness.day}:${toString cfg.brightness.night}" - ] ++ cfg.extraOptions; - - command = if cfg.tray then "redshift-gtk" else "redshift"; - in "${cfg.package}/bin/${command} ${concatStringsSep " " args}"; - RestartSec = 3; - Restart = "always"; - }; - }; - }; - -} diff --git a/third_party/home-manager/modules/services/rsibreak.nix b/third_party/home-manager/modules/services/rsibreak.nix index 77eaa71f95..5f07e6a092 100644 --- a/third_party/home-manager/modules/services/rsibreak.nix +++ b/third_party/home-manager/modules/services/rsibreak.nix @@ -14,6 +14,7 @@ in { }; config = mkIf cfg.enable { + home.packages = [ pkgs.rsibreak ]; systemd.user.services.rsibreak = { Unit = { Description = "RSI break timer"; diff --git a/third_party/home-manager/modules/services/spotifyd.nix b/third_party/home-manager/modules/services/spotifyd.nix index dfe0ecd318..ee5af34518 100644 --- a/third_party/home-manager/modules/services/spotifyd.nix +++ b/third_party/home-manager/modules/services/spotifyd.nix @@ -6,9 +6,9 @@ let cfg = config.services.spotifyd; - configFile = pkgs.writeText "spotifyd.conf" '' - ${generators.toINI { } cfg.settings} - ''; + tomlFormat = pkgs.formats.toml { }; + + configFile = tomlFormat.generate "spotifyd.conf" cfg.settings; in { options.services.spotifyd = { @@ -27,7 +27,7 @@ in { }; settings = mkOption { - type = types.attrsOf (types.attrsOf types.str); + type = tomlFormat.type; default = { }; description = "Configuration for spotifyd"; example = literalExample '' diff --git a/third_party/home-manager/modules/services/stalonetray.nix b/third_party/home-manager/modules/services/stalonetray.nix index cca6049896..ec83a9a496 100644 --- a/third_party/home-manager/modules/services/stalonetray.nix +++ b/third_party/home-manager/modules/services/stalonetray.nix @@ -56,11 +56,10 @@ in { systemd.user.services.stalonetray = { Unit = { Description = "Stalonetray system tray"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; + PartOf = [ "tray.target" ]; }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Install = { WantedBy = [ "tray.target" ]; }; Service = { ExecStart = "${cfg.package}/bin/stalonetray"; diff --git a/third_party/home-manager/modules/services/status-notifier-watcher.nix b/third_party/home-manager/modules/services/status-notifier-watcher.nix index ed0537e22e..8ff1caceb8 100644 --- a/third_party/home-manager/modules/services/status-notifier-watcher.nix +++ b/third_party/home-manager/modules/services/status-notifier-watcher.nix @@ -29,23 +29,17 @@ in { systemd.user.services.status-notifier-watcher = { Unit = { Description = "SNI watcher"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; + PartOf = [ "tray.target" ]; Before = [ "taffybar.service" ]; }; Service = { + Type = "dbus"; + BusName = "org.kde.StatusNotifierWatcher"; ExecStart = "${cfg.package}/bin/status-notifier-watcher"; - # Delay the unit start a bit to allow the program to get fully - # set up before letting dependent services start. This is - # brittle and a better solution using, e.g., `BusName=` might - # be possible. - ExecStartPost = "${pkgs.coreutils}/bin/sleep 1"; }; - Install = { - WantedBy = [ "graphical-session.target" "taffybar.service" ]; - }; + Install = { WantedBy = [ "tray.target" "taffybar.service" ]; }; }; }; } diff --git a/third_party/home-manager/modules/services/sxhkd.nix b/third_party/home-manager/modules/services/sxhkd.nix index d9f0a96851..9a2027a83e 100644 --- a/third_party/home-manager/modules/services/sxhkd.nix +++ b/third_party/home-manager/modules/services/sxhkd.nix @@ -19,9 +19,28 @@ let in { + imports = [ + (mkRemovedOptionModule ["services" "sxhkd" "extraPath"] + "This option is no longer needed and can be removed.") + ]; + options.services.sxhkd = { enable = mkEnableOption "simple X hotkey daemon"; + package = mkOption { + type = types.package; + default = pkgs.sxhkd; + defaultText = "pkgs.sxhkd"; + description = "Package containing the sxhkd executable."; + }; + + extraOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "Command line arguments to invoke sxhkd with."; + example = literalExample ''[ "-m 1" ]''; + }; + keybindings = mkOption { type = types.attrsOf (types.nullOr types.str); default = {}; @@ -43,44 +62,22 @@ in i3-msg {workspace,move container to workspace} {1-10} ''; }; - - extraPath = mkOption { - default = ""; - type = types.envVar; - description = '' - Additional PATH entries to search for commands. - ''; - example = "/home/some-user/bin:/extra/path/bin"; - }; }; config = mkIf cfg.enable { - home.packages = [ pkgs.sxhkd ]; + home.packages = [ cfg.package ]; xdg.configFile."sxhkd/sxhkdrc".text = concatStringsSep "\n" [ keybindingsStr cfg.extraConfig ]; - systemd.user.services.sxhkd = { - Unit = { - Description = "simple X hotkey daemon"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - - Service = { - Environment = - "PATH=" - + "${config.home.profileDirectory}/bin" - + optionalString (cfg.extraPath != "") ":" - + cfg.extraPath; - ExecStart = "${pkgs.sxhkd}/bin/sxhkd"; - }; - - Install = { - WantedBy = [ "graphical-session.target" ]; - }; - }; + xsession.initExtra = + let + sxhkdCommand = "${cfg.package}/bin/sxhkd ${toString cfg.extraOptions}"; + in '' + systemctl --user stop sxhkd.scope 2> /dev/null || true + systemd-cat -t sxhkd systemd-run --user --scope -u sxhkd ${sxhkdCommand} & + ''; }; } diff --git a/third_party/home-manager/modules/services/syncthing.nix b/third_party/home-manager/modules/services/syncthing.nix index 4622ac2e94..e63f3707e9 100644 --- a/third_party/home-manager/modules/services/syncthing.nix +++ b/third_party/home-manager/modules/services/syncthing.nix @@ -10,9 +10,34 @@ with lib; enable = mkEnableOption "Syncthing continuous file synchronization"; tray = mkOption { - type = types.bool; - default = false; - description = "Whether to enable QSyncthingTray service."; + type = with types; + either bool (submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable a syncthing tray service."; + }; + + command = mkOption { + type = types.str; + default = "syncthingtray"; + defaultText = literalExample "syncthingtray"; + example = literalExample "qsyncthingtray"; + description = "Syncthing tray command to use."; + }; + + package = mkOption { + type = types.package; + default = pkgs.syncthingtray-minimal; + defaultText = literalExample "pkgs.syncthingtray-minimal"; + example = literalExample "pkgs.qsyncthingtray"; + description = "Syncthing tray package to use."; + }; + }; + }); + default = { enable = false; }; + description = "Syncthing tray service configuration."; }; }; }; @@ -43,28 +68,49 @@ with lib; }; }) - (mkIf config.services.syncthing.tray { - systemd.user.services = { - qsyncthingtray = { - Unit = { - Description = "QSyncthingTray"; - After = [ - "graphical-session-pre.target" - "polybar.service" - "taffybar.service" - "stalonetray.service" - ]; - PartOf = [ "graphical-session.target" ]; - }; + (mkIf (isAttrs config.services.syncthing.tray + && config.services.syncthing.tray.enable) { + systemd.user.services = { + ${config.services.syncthing.tray.package.pname} = { + Unit = { + Description = config.services.syncthing.tray.package.pname; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; + PartOf = [ "graphical-session.target" ]; + }; - Service = { - Environment = "PATH=${config.home.profileDirectory}/bin"; - ExecStart = "${pkgs.qsyncthingtray}/bin/QSyncthingTray"; - }; + Service = { + ExecStart = + "${config.services.syncthing.tray.package}/bin/${config.services.syncthing.tray.command}"; + }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; }; - }; - }) + }) + + # deprecated + (mkIf (isBool config.services.syncthing.tray + && config.services.syncthing.tray) { + systemd.user.services = { + "syncthingtray" = { + Unit = { + Description = "syncthingtray"; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = "${pkgs.syncthingtray-minimal}/bin/syncthingtray"; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; + }; + warnings = [ + "Specifying 'services.syncthing.tray' as a boolean is deprecated, set 'services.syncthing.tray.enable' instead. See https://github.com/nix-community/home-manager/pull/1257." + ]; + }) ]; } diff --git a/third_party/home-manager/modules/services/taffybar.nix b/third_party/home-manager/modules/services/taffybar.nix index 5392755423..ef4c62e42d 100644 --- a/third_party/home-manager/modules/services/taffybar.nix +++ b/third_party/home-manager/modules/services/taffybar.nix @@ -27,16 +27,17 @@ in { systemd.user.services.taffybar = { Unit = { Description = "Taffybar desktop bar"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; + PartOf = [ "tray.target" ]; }; Service = { + Type = "dbus"; + BusName = "org.taffybar.Bar"; ExecStart = "${cfg.package}/bin/taffybar"; Restart = "on-failure"; }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Install = { WantedBy = [ "tray.target" ]; }; }; xsession.importedVariables = [ "GDK_PIXBUF_MODULE_FILE" ]; diff --git a/third_party/home-manager/modules/services/udiskie.nix b/third_party/home-manager/modules/services/udiskie.nix index ca31021cb5..331e65ffc8 100644 --- a/third_party/home-manager/modules/services/udiskie.nix +++ b/third_party/home-manager/modules/services/udiskie.nix @@ -77,7 +77,8 @@ in { systemd.user.services.udiskie = { Unit = { Description = "udiskie mount daemon"; - After = [ "graphical-session-pre.target" ]; + Requires = [ "tray.target" ]; + After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/third_party/home-manager/modules/services/window-managers/bspwm/default.nix b/third_party/home-manager/modules/services/window-managers/bspwm/default.nix index 9ea5adbc88..c43be07402 100644 --- a/third_party/home-manager/modules/services/window-managers/bspwm/default.nix +++ b/third_party/home-manager/modules/services/window-managers/bspwm/default.nix @@ -5,70 +5,62 @@ with lib; let cfg = config.xsession.windowManager.bspwm; - bspwm = cfg.package; - camelToSnake = s: - builtins.replaceStrings lib.upperChars (map (c: "_${c}") lib.lowerChars) s; + camelToSnake = + builtins.replaceStrings upperChars (map (c: "_${c}") lowerChars); - formatConfig = n: v: + formatMonitor = monitor: desktops: + "bspc monitor ${escapeShellArg monitor} -d ${escapeShellArgs desktops}"; + + formatValue = v: + if isList v then + concatMapStringsSep "," formatValue v + else if isBool v then + if v then "on" else "off" + else if isInt v || isFloat v then + toString v + else if isString v then + v + else + throw "unsupported type"; # should not happen + + formatSetting = n: v: "bspc config ${escapeShellArgs [ n (formatValue v) ]}"; + + formatRule = target: directives: let - formatList = x: - if isList x then - throw "can not convert 2-dimensional lists to bspwm format" - else - formatValue x; + formatDirective = n: v: "${camelToSnake n}=${formatValue v}"; - formatValue = v: - if isBool v then - (if v then "true" else "false") - else if isList v then - concatMapStringsSep ", " formatList v - else if isString v then - "${lib.strings.escapeShellArg v}" - else - toString v; - in "bspc config ${n} ${formatValue v}"; + directivesStr = escapeShellArgs (mapAttrsToList formatDirective + (filterAttrs (n: v: v != null) directives)); + in "bspc rule -a ${escapeShellArg target} ${directivesStr}"; - formatMonitors = n: v: "bspc monitor ${n} -d ${concatStringsSep " " v}"; - - formatRules = target: directiveOptions: - let - formatDirective = n: v: - if isBool v then - (if v then "${camelToSnake n}=on" else "${camelToSnake n}=off") - else if (n == "desktop" || n == "node") then - "${camelToSnake n}='${v}'" - else - "${camelToSnake n}=${lib.strings.escapeShellArg v}"; - - directives = - filterAttrs (n: v: v != null && !(lib.strings.hasPrefix "_" n)) - directiveOptions; - directivesStr = builtins.concatStringsSep " " - (mapAttrsToList formatDirective directives); - in "bspc rule -a ${target} ${directivesStr}"; - - formatStartupPrograms = map (s: "${s} &"); + formatStartupProgram = s: "${s} &"; in { - options = import ./options.nix { - inherit pkgs; - inherit lib; - }; + meta.maintainers = [ maintainers.ncfavier ]; + + options = import ./options.nix { inherit pkgs lib; }; config = mkIf cfg.enable { - home.packages = [ bspwm ]; - xsession.windowManager.command = let - configFile = pkgs.writeShellScript "bspwmrc" (concatStringsSep "\n" - ((mapAttrsToList formatMonitors cfg.monitors) - ++ (mapAttrsToList formatConfig cfg.settings) - ++ (mapAttrsToList formatRules cfg.rules) ++ ['' - # java gui fixes - export _JAVA_AWT_WM_NONREPARENTING=1 - bspc rule -a sun-awt-X11-XDialogPeer state=floating - ''] ++ [ cfg.extraConfig ] - ++ (formatStartupPrograms cfg.startupPrograms))); - configCmdOpt = optionalString (cfg.settings != null) "-c ${configFile}"; - in "${cfg.package}/bin/bspwm ${configCmdOpt}"; + home.packages = [ cfg.package ]; + + xdg.configFile."bspwm/bspwmrc".source = pkgs.writeShellScript "bspwmrc" '' + ${concatStringsSep "\n" (mapAttrsToList formatMonitor cfg.monitors)} + + ${concatStringsSep "\n" (mapAttrsToList formatSetting cfg.settings)} + + bspc rule -r '*' + ${concatStringsSep "\n" (mapAttrsToList formatRule cfg.rules)} + + # java gui fixes + export _JAVA_AWT_WM_NONREPARENTING=1 + bspc rule -a sun-awt-X11-XDialogPeer state=floating + + ${cfg.extraConfig} + ${concatMapStringsSep "\n" formatStartupProgram cfg.startupPrograms} + ''; + + xsession.windowManager.command = + "${cfg.package}/bin/bspwm -c ${config.xdg.configHome}/bspwm/bspwmrc"; }; } diff --git a/third_party/home-manager/modules/services/window-managers/bspwm/options.nix b/third_party/home-manager/modules/services/window-managers/bspwm/options.nix index 58a58a1a78..25b2098017 100644 --- a/third_party/home-manager/modules/services/window-managers/bspwm/options.nix +++ b/third_party/home-manager/modules/services/window-managers/bspwm/options.nix @@ -150,7 +150,7 @@ in { type = types.package; default = pkgs.bspwm; defaultText = literalExample "pkgs.bspwm"; - description = "bspwm package to use."; + description = "The bspwm package to use."; example = literalExample "pkgs.bspwm-unstable"; }; @@ -159,7 +159,7 @@ in { let primitive = either bool (either int (either float str)); in attrsOf (either primitive (listOf primitive)); default = { }; - description = "bspwm configuration"; + description = "General settings given to bspc config."; example = { "border_width" = 2; "split_ratio" = 0.52; @@ -170,7 +170,8 @@ in { extraConfig = mkOption { type = types.lines; default = ""; - description = "Additional configuration to add."; + description = + "Additional shell commands to be run at the end of the config file."; example = '' bspc subscribe all > ~/bspc-report.log & ''; @@ -179,14 +180,16 @@ in { monitors = mkOption { type = types.attrsOf (types.listOf types.str); default = { }; - description = "bspc monitor configurations"; + description = + "Specifies the names of desktops to create on each monitor."; example = { "HDMI-0" = [ "web" "terminal" "III" "IV" ]; }; }; rules = mkOption { type = types.attrsOf rule; default = { }; - description = "bspc rules"; + description = + "Rule configuration. The keys of the attribute set are the targets of the rules."; example = literalExample '' { "Gimp" = { diff --git a/third_party/home-manager/modules/services/window-managers/i3-sway/i3.nix b/third_party/home-manager/modules/services/window-managers/i3-sway/i3.nix index 8cc01cd62b..6e779b4f1a 100644 --- a/third_party/home-manager/modules/services/window-managers/i3-sway/i3.nix +++ b/third_party/home-manager/modules/services/window-managers/i3-sway/i3.nix @@ -17,7 +17,7 @@ let inherit (commonOptions) fonts window floating focus assigns modifier workspaceLayout workspaceAutoBackAndForth keycodebindings colors bars startup gaps menu - terminal; + terminal defaultWorkspace workspaceOutputAssign; keybindings = mkOption { type = types.attrsOf (types.nullOr types.str); @@ -140,7 +140,8 @@ let inherit (commonFunctions) keybindingsStr keycodebindingsStr modeStr assignStr barStr gapsStr - floatingCriteriaStr windowCommandsStr colorSetStr; + floatingCriteriaStr windowCommandsStr colorSetStr windowBorderString + fontConfigStr keybindingDefaultWorkspace keybindingsRest workspaceOutputStr; startupEntryStr = { command, always, notification, workspace, ... }: '' ${if always then "exec_always" else "exec"} ${ @@ -155,14 +156,9 @@ let configFile = pkgs.writeText "i3.conf" ((if cfg.config != null then with cfg.config; '' - font pango:${concatStringsSep ", " fonts} + ${fontConfigStr fonts} floating_modifier ${floating.modifier} - new_window ${if window.titlebar then "normal" else "pixel"} ${ - toString window.border - } - new_float ${if floating.titlebar then "normal" else "pixel"} ${ - toString floating.border - } + ${windowBorderString window floating} hide_edge_borders ${window.hideEdgeBorders} force_focus_wrapping ${if focus.forceWrapping then "yes" else "no"} focus_follows_mouse ${if focus.followMouse then "yes" else "no"} @@ -180,7 +176,8 @@ let client.placeholder ${colorSetStr colors.placeholder} client.background ${colors.background} - ${keybindingsStr { inherit keybindings; }} + ${keybindingsStr { keybindings = keybindingDefaultWorkspace; }} + ${keybindingsStr { keybindings = keybindingsRest; }} ${keycodebindingsStr keycodebindings} ${concatStringsSep "\n" (mapAttrsToList modeStr modes)} ${concatStringsSep "\n" (mapAttrsToList assignStr assigns)} @@ -189,11 +186,29 @@ let ${concatStringsSep "\n" (map floatingCriteriaStr floating.criteria)} ${concatStringsSep "\n" (map windowCommandsStr window.commands)} ${concatStringsSep "\n" (map startupEntryStr startup)} + ${concatStringsSep "\n" (map workspaceOutputStr workspaceOutputAssign)} '' else "") + "\n" + cfg.extraConfig); + # Validates the i3 configuration + checkI3Config = + pkgs.runCommandLocal "i3-config" { buildInputs = [ cfg.package ]; } '' + # We have to make sure the wrapper does not start a dbus session + export DBUS_SESSION_BUS_ADDRESS=1 + + # A zero exit code means i3 succesfully validated the configuration + i3 -c ${configFile} -C -d all || { + echo "i3 configuration validation failed" + echo "For a verbose log of the failure, run 'i3 -c ${configFile} -C -d all'" + exit 1 + }; + cp ${configFile} $out + ''; + in { + meta.maintainers = with maintainers; [ sumnerevans ]; + options = { xsession.windowManager.i3 = { enable = mkEnableOption "i3 window manager."; @@ -229,7 +244,7 @@ in { home.packages = [ cfg.package ]; xsession.windowManager.command = "${cfg.package}/bin/i3"; xdg.configFile."i3/config" = { - source = configFile; + source = checkI3Config; onChange = '' i3Socket=''${XDG_RUNTIME_DIR:-/run/user/$UID}/i3/ipc-socket.* if [ -S $i3Socket ]; then @@ -245,6 +260,15 @@ in { 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); + }) + (mkIf (cfg.config != null && (any (s: s.workspace != null) cfg.config.startup)) { warnings = [ diff --git a/third_party/home-manager/modules/services/window-managers/i3-sway/lib/functions.nix b/third_party/home-manager/modules/services/window-managers/i3-sway/lib/functions.nix index 9391e6e92f..1317f5dbb7 100644 --- a/third_party/home-manager/modules/services/window-managers/i3-sway/lib/functions.nix +++ b/third_party/home-manager/modules/services/window-managers/i3-sway/lib/functions.nix @@ -8,6 +8,14 @@ rec { concatStringsSep " " (mapAttrsToList (k: v: ''${k}="${v}"'') criteria) }]"; + keybindingDefaultWorkspace = filterAttrs (n: v: + cfg.config.defaultWorkspace != null && v == cfg.config.defaultWorkspace) + cfg.config.keybindings; + + keybindingsRest = filterAttrs (n: v: + cfg.config.defaultWorkspace == null || v != cfg.config.defaultWorkspace) + cfg.config.keybindings; + keybindingsStr = { keybindings, bindsymArgs ? "" }: concatStringsSep "\n" (mapAttrsToList (keycomb: action: optionalString (action != null) "bindsym ${ @@ -39,6 +47,23 @@ rec { concatStringsSep "\n" (map (c: "assign ${criteriaStr c} ${workspace}") criteria); + fontConfigStr = let + toFontStr = { names, style ? "", size ? "" }: + optionalString (names != [ ]) concatStringsSep " " (filter (x: x != "") [ + "font" + "pango:${concatStringsSep ", " names}" + style + size + ]); + in fontCfg: + if isList fontCfg then + toFontStr { names = fontCfg; } + else + toFontStr { + inherit (fontCfg) names style; + size = toString fontCfg.size; + }; + barStr = { id, fonts, mode, hiddenState, position, workspaceButtons , workspaceNumbers, command, statusCommand, colors, trayOutput, extraConfig , ... }: @@ -46,10 +71,7 @@ rec { in '' bar { ${optionalString (id != null) "id ${id}"} - ${ - optionalString (fonts != [ ]) - "font pango:${concatStringsSep ", " fonts}" - } + ${fontConfigStr fonts} ${optionalString (mode != null) "mode ${mode}"} ${optionalString (hiddenState != null) "hidden_state ${hiddenState}"} ${optionalString (position != null) "position ${position}"} @@ -80,6 +102,18 @@ rec { optionalString (colors.separator != null) "separator ${colors.separator}" } + ${ + optionalString (colors.focusedBackground != null) + "focused_background ${colors.focusedBackground}" + } + ${ + optionalString (colors.focusedStatusline != null) + "focused_statusline ${colors.focusedStatusline}" + } + ${ + optionalString (colors.focusedSeparator != null) + "focused_separator ${colors.focusedSeparator}" + } ${ optionalString (colors.focusedWorkspace != null) "focused_workspace ${barColorSetStr colors.focusedWorkspace}" @@ -120,8 +154,19 @@ rec { ${optionalString (smartBorders != "off") "smart_borders ${smartBorders}"} ''; + windowBorderString = window: floating: + let + titlebarString = { titlebar, border, ... }: + "${if titlebar then "normal" else "pixel"} ${toString border}"; + in concatStringsSep "\n" [ + "default_border ${titlebarString window}" + "default_floating_border ${titlebarString floating}" + ]; + floatingCriteriaStr = criteria: "for_window ${criteriaStr criteria} floating enable"; windowCommandsStr = { command, criteria, ... }: "for_window ${criteriaStr criteria} ${command}"; + workspaceOutputStr = item: + ''workspace "${item.workspace}" output ${item.output}''; } diff --git a/third_party/home-manager/modules/services/window-managers/i3-sway/lib/options.nix b/third_party/home-manager/modules/services/window-managers/i3-sway/lib/options.nix index f1d0436a5e..af72f2e6bd 100644 --- a/third_party/home-manager/modules/services/window-managers/i3-sway/lib/options.nix +++ b/third_party/home-manager/modules/services/window-managers/i3-sway/lib/options.nix @@ -4,14 +4,40 @@ with lib; let - fonts = mkOption { - type = types.listOf types.str; - default = [ "monospace 8" ]; - description = '' - Font list used for window titles. Only FreeType fonts are supported. - The order here is important (e.g. icons font should go before the one used for text). - ''; - example = [ "FontAwesome 10" "Terminus 10" ]; + isI3 = moduleName == "i3"; + isSway = !isI3; + + fontOptions = types.submodule { + options = { + names = mkOption { + type = types.listOf types.str; + default = [ "monospace" ]; + defaultText = literalExample ''[ "monospace" ]''; + description = '' + List of font names list used for window titles. Only FreeType fonts are supported. + The order here is important (e.g. icons font should go before the one used for text). + ''; + example = literalExample ''[ "FontAwesome" "Terminus" ]''; + }; + + style = mkOption { + type = types.str; + default = ""; + description = '' + The font style to use for window titles. + ''; + example = "Bold Semi-Condensed"; + }; + + size = mkOption { + type = types.float; + default = 8.0; + description = '' + The font size to use for window titles. + ''; + example = 11.5; + }; + }; }; startupModule = types.submodule { @@ -26,7 +52,7 @@ let default = false; description = "Whether to run command on each ${moduleName} restart."; }; - } // optionalAttrs (moduleName == "i3") { + } // optionalAttrs isI3 { notification = mkOption { type = types.bool; default = true; @@ -53,20 +79,27 @@ let options = let versionAtLeast2009 = versionAtLeast config.home.stateVersion "20.09"; mkNullableOption = { type, default, ... }@args: - mkOption (args // optionalAttrs versionAtLeast2009 { + mkOption (args // { type = types.nullOr type; - default = null; - example = default; - } // { + default = if versionAtLeast2009 then null else default; defaultText = literalExample '' - ${ - if isString default then default else "See code" - } for state version < 20.09, - null for state version ≥ 20.09 + null for state version ≥ 20.09, as example otherwise ''; + example = default; }); in { - fonts = fonts // optionalAttrs versionAtLeast2009 { default = [ ]; }; + fonts = mkOption { + type = with types; either (listOf str) fontOptions; + default = { }; + example = literalExample '' + { + names = [ "DejaVu Sans Mono" "FontAwesome5Free" ]; + style = "Bold Semi-Condensed"; + size = 11.0; + } + ''; + description = "Font configuration for this bar."; + }; extraConfig = mkOption { type = types.lines; @@ -117,20 +150,22 @@ let command = mkOption { type = types.str; - default = "${cfg.package}/bin/${moduleName}bar"; + default = let + # If the user uses the "system" Sway (i.e. cfg.package == null) then the bar has + # to come from a different package + pkg = if isSway && isNull cfg.package then pkgs.sway else cfg.package; + in "${pkg}/bin/${moduleName}bar"; defaultText = "i3bar"; description = "Command that will be used to start a bar."; - example = if moduleName == "i3" then + example = if isI3 then "\${pkgs.i3-gaps}/bin/i3bar -t" else "\${pkgs.waybar}/bin/waybar"; }; - statusCommand = mkOption { - type = types.nullOr types.str; - default = - if versionAtLeast2009 then null else "${pkgs.i3status}/bin/i3status"; - example = "i3status"; + statusCommand = mkNullableOption { + type = types.str; + default = "${pkgs.i3status}/bin/i3status"; description = "Command that will be used to get status lines."; }; @@ -155,6 +190,30 @@ let description = "Text color to be used for the separator."; }; + focusedBackground = mkOption { + type = types.nullOr types.str; + default = null; + description = + "Background color of the bar on the currently focused monitor output."; + example = "#000000"; + }; + + focusedStatusline = mkOption { + type = types.nullOr types.str; + default = null; + description = + "Text color to be used for the statusline on the currently focused monitor output."; + example = "#ffffff"; + }; + + focusedSeparator = mkOption { + type = types.nullOr types.str; + default = null; + description = + "Text color to be used for the separator on the currently focused monitor output."; + example = "#666666"; + }; + focusedWorkspace = mkNullableOption { type = barColorSetModule; default = { @@ -303,7 +362,18 @@ let criteriaModule = types.attrsOf types.str; in { - inherit fonts; + fonts = mkOption { + type = with types; either (listOf str) fontOptions; + default = { }; + example = literalExample '' + { + names = [ "DejaVu Sans Mono" "FontAwesome5Free" ]; + style = "Bold Semi-Condensed"; + size = 11.0; + } + ''; + description = "Font configuration for window titles, nagbar..."; + }; window = mkOption { type = types.submodule { @@ -311,7 +381,7 @@ in { titlebar = mkOption { type = types.bool; default = !isGaps; - defaultText = if moduleName == "i3" then + defaultText = if isI3 then "xsession.windowManager.i3.package != nixpkgs.i3-gaps (titlebar should be disabled for i3-gaps)" else "false"; @@ -354,7 +424,7 @@ in { titlebar = mkOption { type = types.bool; default = !isGaps; - defaultText = if moduleName == "i3" then + defaultText = if isI3 then "xsession.windowManager.i3.package != nixpkgs.i3-gaps (titlebar should be disabled for i3-gaps)" else "false"; @@ -408,14 +478,14 @@ in { }; followMouse = mkOption { - type = if moduleName == "sway" then + type = if isSway then types.either (types.enum [ "yes" "no" "always" ]) types.bool else types.bool; - default = if moduleName == "sway" then "yes" else true; + default = if isSway then "yes" else true; description = "Whether focus should follow the mouse."; apply = val: - if (moduleName == "sway" && isBool val) then + if (isSway && isBool val) then (if val then "yes" else "no") else val; @@ -598,7 +668,10 @@ in { workspaceButtons = true; workspaceNumbers = true; statusCommand = "${pkgs.i3status}/bin/i3status"; - fonts = [ "monospace 8" ]; + fonts = { + names = [ "monospace" ]; + size = 8.0; + }; trayOutput = "primary"; colors = { background = "#000000"; @@ -632,6 +705,7 @@ in { }; }] else [ { } ]; + defaultText = literalExample "see code"; description = '' ${capitalModuleName} bars settings blocks. Set to empty list to remove bars completely. ''; @@ -645,7 +719,7 @@ in { See . ''; - example = if moduleName == "i3" then + example = if isI3 then literalExample '' [ { command = "systemctl --user restart polybar"; always = true; notification = false; } @@ -743,7 +817,7 @@ in { }; }); default = null; - description = if moduleName == "sway" then '' + description = if isSway then '' Gaps related settings. '' else '' i3Gaps related settings. The i3-gaps package must be used for these features to work. @@ -752,7 +826,7 @@ in { terminal = mkOption { type = types.str; - default = if moduleName == "i3" then + default = if isI3 then "i3-sensible-terminal" else "${pkgs.rxvt-unicode-unwrapped}/bin/urxvt"; @@ -762,11 +836,54 @@ in { menu = mkOption { type = types.str; - default = if moduleName == "sway" then + default = if isSway then "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.dmenu}/bin/dmenu | ${pkgs.findutils}/bin/xargs swaymsg exec --" else "${pkgs.dmenu}/bin/dmenu_run"; description = "Default launcher to use."; example = "bemenu-run"; }; + + defaultWorkspace = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The default workspace to show when ${ + if isSway then "sway" else "i3" + } is launched. + This must to correspond to the value of the keybinding of the default workspace. + ''; + example = "workspace number 9"; + }; + + workspaceOutputAssign = mkOption { + type = with types; + let + workspaceOutputOpts = submodule { + options = { + workspace = mkOption { + type = str; + default = ""; + example = "Web"; + description = '' + Name of the workspace to assign. + ''; + }; + + output = mkOption { + type = str; + default = ""; + example = "eDP"; + description = '' + Name of the output from + ${if isSway then "swaymsg" else "i3-msg"} -t get_outputs + . + ''; + }; + }; + }; + in listOf workspaceOutputOpts; + default = [ ]; + description = "Assign workspaces to outputs."; + }; } diff --git a/third_party/home-manager/modules/services/window-managers/i3-sway/sway.nix b/third_party/home-manager/modules/services/window-managers/i3-sway/sway.nix index 14d82d2671..1dcd8662fb 100644 --- a/third_party/home-manager/modules/services/window-managers/i3-sway/sway.nix +++ b/third_party/home-manager/modules/services/window-managers/i3-sway/sway.nix @@ -17,7 +17,7 @@ let inherit (commonOptions) fonts window floating focus assigns workspaceLayout workspaceAutoBackAndForth modifier keycodebindings colors bars startup - gaps menu terminal; + gaps menu terminal defaultWorkspace workspaceOutputAssign; left = mkOption { type = types.str; @@ -153,7 +153,12 @@ let default = { }; example = { "*" = { xkb_variant = "dvorak"; }; }; description = '' - An attribute set that defines input modules. See man sway_input for options. + An attribute set that defines input modules. See + + sway-input + 5 + + for options. ''; }; @@ -162,7 +167,26 @@ let default = { }; example = { "HDMI-A-2" = { bg = "~/path/to/background.png fill"; }; }; description = '' - An attribute set that defines output modules. See man sway_output for options. + An attribute set that defines output modules. See + + sway-output + 5 + + for options. + ''; + }; + + seat = mkOption { + type = types.attrsOf (types.attrsOf types.str); + default = { }; + example = { "*" = { hide_cursor = "when-typing enable"; }; }; + description = '' + An attribute set that defines seat modules. See + + sway-input + 5 + + for options. ''; }; @@ -221,36 +245,28 @@ let inherit (commonFunctions) keybindingsStr keycodebindingsStr modeStr assignStr barStr gapsStr - floatingCriteriaStr windowCommandsStr colorSetStr; + floatingCriteriaStr windowCommandsStr colorSetStr windowBorderString + fontConfigStr keybindingDefaultWorkspace keybindingsRest workspaceOutputStr; startupEntryStr = { command, always, ... }: '' ${if always then "exec_always" else "exec"} ${command} ''; - inputStr = name: attrs: '' - input "${name}" { - ${concatStringsSep "\n" - (mapAttrsToList (name: value: "${name} ${value}") attrs)} - } - ''; - - outputStr = name: attrs: '' - output "${name}" { + moduleStr = moduleType: name: attrs: '' + ${moduleType} "${name}" { ${concatStringsSep "\n" (mapAttrsToList (name: value: "${name} ${value}") attrs)} } ''; + inputStr = moduleStr "input"; + outputStr = moduleStr "output"; + seatStr = moduleStr "seat"; configFile = pkgs.writeText "sway.conf" ((if cfg.config != null then with cfg.config; '' - font pango:${concatStringsSep ", " fonts} + ${fontConfigStr fonts} floating_modifier ${floating.modifier} - default_border ${if window.titlebar then "normal" else "pixel"} ${ - toString window.border - } - default_floating_border ${ - if floating.titlebar then "normal" else "pixel" - } ${toString floating.border} + ${windowBorderString window floating} hide_edge_borders ${window.hideEdgeBorders} focus_wrapping ${if focus.forceWrapping then "yes" else "no"} focus_follows_mouse ${focus.followMouse} @@ -269,20 +285,30 @@ let client.background ${colors.background} ${keybindingsStr { - inherit keybindings; + keybindings = keybindingDefaultWorkspace; + bindsymArgs = + lib.optionalString (cfg.config.bindkeysToCode) "--to-code"; + }} + ${keybindingsStr { + keybindings = keybindingsRest; bindsymArgs = lib.optionalString (cfg.config.bindkeysToCode) "--to-code"; }} ${keycodebindingsStr keycodebindings} - ${concatStringsSep "\n" (mapAttrsToList inputStr input)} - ${concatStringsSep "\n" (mapAttrsToList outputStr output)} - ${concatStringsSep "\n" (mapAttrsToList modeStr modes)} - ${concatStringsSep "\n" (mapAttrsToList assignStr assigns)} - ${concatStringsSep "\n" (map barStr bars)} - ${optionalString (gaps != null) gapsStr} - ${concatStringsSep "\n" (map floatingCriteriaStr floating.criteria)} - ${concatStringsSep "\n" (map windowCommandsStr window.commands)} - ${concatStringsSep "\n" (map startupEntryStr startup)} + ${concatStringsSep "\n" ( + # Append all of the lists together to avoid unnecessary whitespace. + mapAttrsToList inputStr input # inputs + ++ mapAttrsToList outputStr output # outputs + ++ mapAttrsToList seatStr seat # seats + ++ mapAttrsToList modeStr modes # modes + ++ mapAttrsToList assignStr assigns # assigns + ++ map barStr bars # bars + ++ optional (gaps != null) gapsStr # gaps + ++ map floatingCriteriaStr floating.criteria # floating + ++ map windowCommandsStr window.commands # window commands + ++ map startupEntryStr startup # startup + ++ map workspaceOutputStr workspaceOutputAssign # custom mapping + )} '' else "") + "\n" + (if cfg.systemdIntegration then '' @@ -298,7 +324,7 @@ let }; in { - meta.maintainers = [ maintainers.alexarice ]; + meta.maintainers = with maintainers; [ alexarice sumnerevans ]; options.wayland.windowManager.sway = { enable = mkEnableOption "sway wayland compositor"; @@ -390,27 +416,38 @@ in { }; }; - config = mkIf cfg.enable { - home.packages = optional (cfg.package != null) cfg.package - ++ optional cfg.xwayland pkgs.xwayland; - xdg.configFile."sway/config" = { - source = configFile; - onChange = '' - swaySocket=''${XDG_RUNTIME_DIR:-/run/user/$UID}/sway-ipc.$UID.$(${pkgs.procps}/bin/pgrep -x sway || ${pkgs.coreutils}/bin/true).sock - if [ -S $swaySocket ]; then - echo "Reloading sway" - $DRY_RUN_CMD ${pkgs.sway}/bin/swaymsg -s $swaySocket reload - fi - ''; - }; - systemd.user.targets.sway-session = mkIf cfg.systemdIntegration { - Unit = { - Description = "sway compositor session"; - Documentation = [ "man:systemd.special(7)" ]; - BindsTo = [ "graphical-session.target" ]; - Wants = [ "graphical-session-pre.target" ]; - After = [ "graphical-session-pre.target" ]; + config = mkIf cfg.enable (mkMerge [ + (mkIf (cfg.config != null) { + warnings = (optional (isList cfg.config.fonts) + "Specifying sway.config.fonts as a list is deprecated. Use the attrset version instead.") + ++ 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); + }) + + { + home.packages = optional (cfg.package != null) cfg.package + ++ optional cfg.xwayland pkgs.xwayland; + xdg.configFile."sway/config" = { + source = configFile; + onChange = '' + swaySocket=''${XDG_RUNTIME_DIR:-/run/user/$UID}/sway-ipc.$UID.$(${pkgs.procps}/bin/pgrep -x sway || ${pkgs.coreutils}/bin/true).sock + if [ -S $swaySocket ]; then + echo "Reloading sway" + $DRY_RUN_CMD ${pkgs.sway}/bin/swaymsg -s $swaySocket reload + fi + ''; }; - }; - }; + systemd.user.targets.sway-session = mkIf cfg.systemdIntegration { + Unit = { + Description = "sway compositor session"; + Documentation = [ "man:systemd.special(7)" ]; + BindsTo = [ "graphical-session.target" ]; + Wants = [ "graphical-session-pre.target" ]; + After = [ "graphical-session-pre.target" ]; + }; + }; + } + ]); } diff --git a/third_party/home-manager/modules/services/window-managers/xmonad.nix b/third_party/home-manager/modules/services/window-managers/xmonad.nix index 7be03874a8..6d05d68ede 100644 --- a/third_party/home-manager/modules/services/window-managers/xmonad.nix +++ b/third_party/home-manager/modules/services/window-managers/xmonad.nix @@ -73,29 +73,93 @@ in { an absolute path or null in which case ~/.xmonad/xmonad.hs will not be managed by Home Manager. + + + If this option is set to a non-null value, + recompilation of xmonad outside of Home Manager (e.g. via + xmonad --recompile) will fail. + ''; + }; + + libFiles = mkOption { + type = types.attrsOf (types.oneOf [ types.path ]); + default = { }; + example = literalExample '' + { + "Tools.hs" = pkgs.writeText "Tools.hs" ''' + module Tools where + screenshot = "scrot" + '''; + } + ''; + description = '' + Additional files that will be saved in + ~/.xmonad/lib/ and included in the configuration + build. The keys are the file names while the values are paths to the + contents of the files. ''; }; }; }; - config = mkIf cfg.enable (mkMerge [ - { - home.packages = [ (lowPrio xmonad) ]; + config = let + + xmonadBin = "${ + pkgs.runCommandLocal "xmonad-compile" { + nativeBuildInputs = [ xmonad ]; + } '' + mkdir -p $out/bin + + export XMONAD_CONFIG_DIR="$(pwd)/xmonad-config" + export XMONAD_DATA_DIR="$(pwd)/data" + export XMONAD_CACHE_DIR="$(pwd)/cache" + + mkdir -p "$XMONAD_CONFIG_DIR/lib" "$XMONAD_CACHE_DIR" "$XMONAD_DATA_DIR" + + cp ${cfg.config} xmonad-config/xmonad.hs + + declare -A libFiles + libFiles=(${ + concatStringsSep " " + (mapAttrsToList (name: value: "['${name}']='${value}'") + cfg.libFiles) + }) + for key in "''${!libFiles[@]}"; do + cp "''${libFiles[$key]}" "xmonad-config/lib/$key"; + done + + xmonad --recompile + + # The resulting binary name depends on the arch and os + # https://github.com/xmonad/xmonad/blob/56b0f850bc35200ec23f05c079eca8b0a1f90305/src/XMonad/Core.hs#L565-L572 + mv "$XMONAD_DATA_DIR/xmonad-${pkgs.hostPlatform.system}" $out/bin/ + '' + }/bin/xmonad-${pkgs.hostPlatform.system}"; + + in mkIf cfg.enable (mkMerge [ + { home.packages = [ (lowPrio xmonad) ]; } + (mkIf (cfg.config == null) { xsession.windowManager.command = "${xmonad}/bin/xmonad"; - } - - (mkIf (cfg.config != null) { - home.file.".xmonad/xmonad.hs".source = cfg.config; - home.file.".xmonad/xmonad.hs".onChange = '' - echo "Recompiling xmonad" - $DRY_RUN_CMD ${config.xsession.windowManager.command} --recompile - - # Attempt to restart xmonad if X is running. - if [[ -v DISPLAY ]] ; then - echo "Restarting xmonad" - $DRY_RUN_CMD ${config.xsession.windowManager.command} --restart - fi - ''; }) + (mkIf (cfg.config != null) { + xsession.windowManager.command = xmonadBin; + home.file.".xmonad/xmonad.hs".source = cfg.config; + home.file.".xmonad/xmonad-${pkgs.hostPlatform.system}" = { + source = xmonadBin; + onChange = '' + # Attempt to restart xmonad if X is running. + if [[ -v DISPLAY ]] ; then + echo "Restarting xmonad" + $DRY_RUN_CMD ${config.xsession.windowManager.command} --restart + fi + ''; + }; + }) + + { + home.file = mapAttrs' (name: value: + attrsets.nameValuePair (".xmonad/lib/" + name) { source = value; }) + cfg.libFiles; + } ]); } diff --git a/third_party/home-manager/modules/services/wlsunset.nix b/third_party/home-manager/modules/services/wlsunset.nix new file mode 100644 index 0000000000..084dbdb7c3 --- /dev/null +++ b/third_party/home-manager/modules/services/wlsunset.nix @@ -0,0 +1,97 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.wlsunset; + +in { + meta.maintainers = [ maintainers.matrss ]; + + options.services.wlsunset = { + enable = mkEnableOption "Whether to enable wlsunset."; + + package = mkOption { + type = types.package; + default = pkgs.wlsunset; + defaultText = "pkgs.wlsunset"; + description = '' + wlsunset derivation to use. + ''; + }; + + latitude = mkOption { + type = types.str; + description = '' + Your current latitude, between -90.0 and + 90.0. + ''; + }; + + longitude = mkOption { + type = types.str; + description = '' + Your current longitude, between -180.0 and + 180.0. + ''; + }; + + temperature = { + day = mkOption { + type = types.int; + default = 6500; + description = '' + Colour temperature to use during the day, in Kelvin (K). + This value must be greater than temperature.night. + ''; + }; + + night = mkOption { + type = types.int; + default = 4000; + description = '' + Colour temperature to use during the night, in Kelvin (K). + This value must be smaller than temperature.day. + ''; + }; + }; + + gamma = mkOption { + type = types.str; + default = "1.0"; + description = '' + Gamma value to use. + ''; + }; + + systemdTarget = mkOption { + type = types.str; + default = "graphical-session.target"; + description = '' + Systemd target to bind to. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.wlsunset = { + Unit = { + Description = "Day/night gamma adjustments for Wayland compositors."; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = let + args = [ + "-l ${cfg.latitude}" + "-L ${cfg.longitude}" + "-t ${toString cfg.temperature.night}" + "-T ${toString cfg.temperature.day}" + "-g ${cfg.gamma}" + ]; + in "${cfg.package}/bin/wlsunset ${concatStringsSep " " args}"; + }; + + Install = { WantedBy = [ cfg.systemdTarget ]; }; + }; + }; +} diff --git a/third_party/home-manager/modules/services/xidlehook.nix b/third_party/home-manager/modules/services/xidlehook.nix new file mode 100644 index 0000000000..da91de8504 --- /dev/null +++ b/third_party/home-manager/modules/services/xidlehook.nix @@ -0,0 +1,149 @@ +# Wrapper around xidlehook. + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xidlehook; + + notEmpty = list: filter (x: x != "" && x != null) (flatten list); + + timers = let + toTimer = timer: + "--timer ${toString timer.delay} ${ + escapeShellArgs [ timer.command timer.canceller ] + }"; + in map toTimer (filter (timer: timer.command != null) cfg.timers); + + script = pkgs.writeShellScript "xidlehook" '' + ${concatStringsSep "\n" + (mapAttrsToList (name: value: "export ${name}=${value}") + cfg.environment or { })} + ${concatStringsSep " " (notEmpty [ + "${cfg.package}/bin/xidlehook" + (optionalString cfg.once "--once") + (optionalString cfg.not-when-fullscreen "--not-when-fullscreen") + (optionalString cfg.not-when-audio "--not-when-audio") + timers + ])} + ''; +in { + meta.maintainers = [ maintainers.dschrempf ]; + + options.services.xidlehook = { + enable = mkEnableOption "xidlehook systemd service"; + + package = mkOption { + type = types.package; + default = pkgs.xidlehook; + defaultText = "pkgs.xidlehook"; + description = "The package to use for xidlehook."; + }; + + environment = mkOption { + type = types.attrsOf types.str; + default = { }; + example = literalExample '' + { + "primary-display" = "$(xrandr | awk '/ primary/{print $1}')"; + } + ''; + description = '' + Extra environment variables to be exported in the script. + These options are passed unescaped as export name=value. + ''; + }; + + not-when-fullscreen = mkOption { + type = types.bool; + default = false; + example = true; + description = "Disable locking when a fullscreen application is in use."; + }; + + not-when-audio = mkOption { + type = types.bool; + default = false; + example = true; + description = "Disable locking when audio is playing."; + }; + + once = mkEnableOption "running the program once and exiting"; + + timers = mkOption { + type = types.listOf (types.submodule { + options = { + delay = mkOption { + type = types.ints.unsigned; + example = 60; + description = "Time before executing the command."; + }; + command = mkOption { + type = types.nullOr types.str; + example = literalExample '' + ''${pkgs.libnotify}/bin/notify-send "Idle" "Sleeping in 1 minute" + ''; + description = '' + Command executed after the idle timeout is reached. + Path to executables are accepted. + The command is automatically escaped. + ''; + }; + canceller = mkOption { + type = types.str; + default = ""; + example = literalExample '' + ''${pkgs.libnotify}/bin/notify-send "Idle" "Resuming activity" + ''; + description = '' + Command executed when the user becomes active again. + This is only executed if the next timer has not been reached. + Path to executables are accepted. + The command is automatically escaped. + ''; + }; + }; + }); + default = [ ]; + example = literalExample '' + [ + { + delay = 60; + command = "xrandr --output \"$PRIMARY_DISPLAY\" --brightness .1"; + canceller = "xrandr --output \"$PRIMARY_DISPLAY\" --brightness 1"; + } + { + delay = 120; + command = "''${pkgs.writeShellScript "my-script" ''' + # A complex script to run + '''}"; + } + ] + ''; + description = '' + A set of commands to be executed after a specific idle timeout. + The commands specified in command and canceller + are passed escaped to the script. + To use or re-use environment variables that are script-dependent, specify them + in the environment section. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.xidlehook = { + Unit = { + Description = "xidlehook service"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + ConditionEnvironment = [ "DISPLAY" ]; + }; + Service = { + Type = if cfg.once then "oneshot" else "simple"; + ExecStart = "${script}"; + }; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; +} diff --git a/third_party/home-manager/modules/services/xsuspender.nix b/third_party/home-manager/modules/services/xsuspender.nix index 2eb40f5dd3..7d855f05d5 100644 --- a/third_party/home-manager/modules/services/xsuspender.nix +++ b/third_party/home-manager/modules/services/xsuspender.nix @@ -6,6 +6,8 @@ let cfg = config.services.xsuspender; + iniFormat = pkgs.formats.ini { }; + xsuspenderOptions = types.submodule { options = { matchWmClassContains = mkOption { @@ -139,7 +141,7 @@ in { }; iniContent = mkOption { - type = types.attrsOf types.attrs; + type = iniFormat.type; internal = true; }; }; @@ -170,7 +172,8 @@ in { # To make the xsuspender tool available. home.packages = [ pkgs.xsuspender ]; - xdg.configFile."xsuspender.conf".text = generators.toINI { } cfg.iniContent; + xdg.configFile."xsuspender.conf".source = + iniFormat.generate "xsuspender.conf" cfg.iniContent; systemd.user.services.xsuspender = { Unit = { diff --git a/third_party/home-manager/modules/systemd.nix b/third_party/home-manager/modules/systemd.nix index 66fffadf73..a5a069c5d7 100644 --- a/third_party/home-manager/modules/systemd.nix +++ b/third_party/home-manager/modules/systemd.nix @@ -1,19 +1,26 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.systemd.user; + inherit (lib) getAttr hm isBool literalExample mkIf mkMerge mkOption types; + + # From + mkPathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""]; + enabled = cfg.services != {} + || cfg.slices != {} || cfg.sockets != {} || cfg.targets != {} || cfg.timers != {} || cfg.paths != {} + || cfg.mounts != {} + || cfg.automounts != {} || cfg.sessionVariables != {}; - toSystemdIni = generators.toINI { + toSystemdIni = lib.generators.toINI { + listsAsDuplicateKeys = true; mkKeyValue = key: value: let value' = @@ -26,16 +33,14 @@ let buildService = style: name: serviceCfg: let filename = "${name}.${style}"; - pathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"] - ["-" "-" "-" "" "" ] - filename; + pathSafeName = mkPathSafeName filename; # Needed because systemd derives unit names from the ultimate # link target. source = pkgs.writeTextFile { name = pathSafeName; text = toSystemdIni serviceCfg; - destination = "/${filename}"; + destination = lib.escapeShellArg "/${filename}"; } + "/${filename}"; wantedBy = target: @@ -44,7 +49,7 @@ let value = { inherit source; }; }; in - singleton { + lib.singleton { name = "systemd/user/${filename}"; value = { inherit source; }; } @@ -52,7 +57,7 @@ let map wantedBy (serviceCfg.Install.WantedBy or []); buildServices = style: serviceCfgs: - concatLists (mapAttrsToList (buildService style) serviceCfgs); + lib.concatLists (lib.mapAttrsToList (buildService style) serviceCfgs); servicesStartTimeoutMs = builtins.toString cfg.servicesStartTimeoutMs; @@ -79,7 +84,7 @@ let unitExample = type: literalExample '' { - ${toLower type}-name = { + ${lib.toLower type}-name = { Unit = { Description = "Example description"; Documentation = [ "man:example(1)" "man:example(5)" ]; @@ -88,21 +93,21 @@ let ${type} = { … }; - } + }; }; ''; sessionVariables = mkIf (cfg.sessionVariables != {}) { "environment.d/10-home-manager.conf".text = - concatStringsSep "\n" ( - mapAttrsToList (n: v: "${n}=${toString v}") cfg.sessionVariables + lib.concatStringsSep "\n" ( + lib.mapAttrsToList (n: v: "${n}=${toString v}") cfg.sessionVariables ) + "\n"; }; in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; options = { systemd.user = { @@ -124,6 +129,13 @@ in example = unitExample "Service"; }; + slices = mkOption { + default = {}; + type = unitType "slices"; + description = unitDescription "slices"; + example = unitExample "Slices"; + }; + sockets = mkOption { default = {}; type = unitType "socket"; @@ -152,22 +164,69 @@ in example = unitExample "Path"; }; + mounts = mkOption { + default = {}; + type = unitType "mount"; + description = unitDescription "mount"; + example = unitExample "Mount"; + }; + + automounts = mkOption { + default = {}; + type = unitType "automount"; + description = unitDescription "automount"; + example = unitExample "Automount"; + }; + startServices = mkOption { - default = false; - type = types.bool; + default = "suggest"; + type = with types; either bool (enum ["suggest" "legacy" "sd-switch"]); + apply = p: + if isBool p then if p then "legacy" else "suggest" + else p; description = '' - Start all services that are wanted by active targets. - Additionally, stop obsolete services from the previous - generation. + Whether new or changed services that are wanted by active targets + should be started. Additionally, stop obsolete services from the + previous generation. + + The alternatives are + + + suggest (or false) + + Use a very simple shell script to print suggested + systemctl commands to run. You will have to + manually run those commands after the switch. + + + + legacy (or true) + + Use a Ruby script to, in a more robust fashion, determine the + necessary changes and automatically run the + systemctl commands. + + + + sd-switch + + Use sd-switch, a third party application, to perform the service + updates. This tool offers more features while having a small + closure size. Note, it requires a fully functional user D-Bus + session. Once tested and deemed sufficiently robust, this will + become the default. + + + ''; }; servicesStartTimeoutMs = mkOption { default = 0; - type = types.int; + type = types.ints.unsigned; description = '' - How long to wait for started services to fail until their - start is considered successful. + How long to wait for started services to fail until their start is + considered successful. The value 0 indicates no timeout. ''; }; @@ -194,9 +253,10 @@ in assertion = enabled -> pkgs.stdenv.isLinux; message = let - names = concatStringsSep ", " ( - attrNames ( - cfg.services // cfg.sockets // cfg.targets // cfg.timers // cfg.paths // cfg.sessionVariables + names = lib.concatStringsSep ", " ( + lib.attrNames ( + cfg.services // cfg.slices // cfg.sockets // cfg.targets + // cfg.timers // cfg.paths // cfg.mounts // cfg.sessionVariables ) ); in @@ -209,9 +269,11 @@ in # available, in particular we assume that systemctl is in PATH. (mkIf pkgs.stdenv.isLinux { xdg.configFile = mkMerge [ - (listToAttrs ( + (lib.listToAttrs ( (buildServices "service" cfg.services) ++ + (buildServices "slices" cfg.slices) + ++ (buildServices "socket" cfg.sockets) ++ (buildServices "target" cfg.targets) @@ -219,6 +281,10 @@ in (buildServices "timer" cfg.timers) ++ (buildServices "path" cfg.paths) + ++ + (buildServices "mount" cfg.mounts) + ++ + (buildServices "automount" cfg.automounts) )) sessionVariables @@ -230,14 +296,30 @@ in # set it ourselves in that case. home.activation.reloadSystemd = hm.dag.entryAfter ["linkGeneration"] ( let - autoReloadCmd = '' - ${pkgs.ruby}/bin/ruby ${./systemd-activate.rb} \ - "''${oldGenPath=}" "$newGenPath" "${servicesStartTimeoutMs}" - ''; - - legacyReloadCmd = '' - bash ${./systemd-activate.sh} "''${oldGenPath=}" "$newGenPath" - ''; + 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)}"; @@ -254,8 +336,7 @@ in fi ${ensureRuntimeDir} \ - PATH=${dirOf cfg.systemctlPath}:$PATH \ - ${if cfg.startServices then autoReloadCmd else legacyReloadCmd} + ${getAttr cfg.startServices cmd} else echo "User systemd daemon not running. Skipping reload." fi diff --git a/third_party/home-manager/modules/targets/darwin/default.nix b/third_party/home-manager/modules/targets/darwin/default.nix new file mode 100644 index 0000000000..b971e18d21 --- /dev/null +++ b/third_party/home-manager/modules/targets/darwin/default.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.targets.darwin; + + toDefaultsFile = domain: attrs: + pkgs.writeText "${domain}.plist" (lib.generators.toPlist { } attrs); + + toActivationCmd = domain: attrs: + "$DRY_RUN_CMD defaults import ${escapeShellArg domain} ${ + toDefaultsFile domain attrs + }"; + + nonNullDefaults = + mapAttrs (domain: attrs: (filterAttrs (n: v: v != null) attrs)) + cfg.defaults; + writableDefaults = filterAttrs (domain: attrs: attrs != { }) nonNullDefaults; + activationCmds = mapAttrsToList toActivationCmd writableDefaults; +in { + imports = [ ./fonts.nix ./keybindings.nix ./linkapps.nix ./search.nix ]; + + options.targets.darwin.defaults = mkOption { + type = types.submodule ./options.nix; + default = { }; + example = { + "com.apple.desktopservices" = { + DSDontWriteNetworkStores = true; + DSDontWriteUSBStores = true; + }; + }; + description = '' + Set macOS user defaults. Values set to null are + ignored. + + + + Some settings might require a re-login to take effect. + + + ''; + }; + + config = mkIf (activationCmds != [ ]) { + home.activation.setDarwinDefaults = hm.dag.entryAfter [ "writeBoundary" ] '' + $VERBOSE_ECHO "Configuring macOS user defaults" + ${concatStringsSep "\n" activationCmds} + ''; + }; +} diff --git a/third_party/home-manager/modules/targets/darwin/fonts.nix b/third_party/home-manager/modules/targets/darwin/fonts.nix new file mode 100644 index 0000000000..bc4042a8d7 --- /dev/null +++ b/third_party/home-manager/modules/targets/darwin/fonts.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + homeDir = config.home.homeDirectory; + fontsEnv = pkgs.buildEnv { + name = "home-manager-fonts"; + paths = config.home.packages; + pathsToLink = "/share/fonts"; + }; + fonts = "${fontsEnv}/share/fonts"; +in { + # macOS won't recognize symlinked fonts + config.home.activation.copyFonts = hm.dag.entryAfter [ "writeBoundary" ] '' + copyFonts() { + rm -rf ${homeDir}/Library/Fonts/HomeManager || : + + local f + find -L "${fonts}" -type f -printf '%P\0' | while IFS= read -rd "" f; do + $DRY_RUN_CMD install $VERBOSE_ARG -Dm644 -T \ + "${fonts}/$f" "${homeDir}/Library/Fonts/HomeManager/$f" + done + } + copyFonts + ''; +} diff --git a/third_party/home-manager/modules/targets/darwin/keybindings.nix b/third_party/home-manager/modules/targets/darwin/keybindings.nix new file mode 100644 index 0000000000..4481f33bd8 --- /dev/null +++ b/third_party/home-manager/modules/targets/darwin/keybindings.nix @@ -0,0 +1,42 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.targets.darwin; + homeDir = config.home.homeDirectory; + confFile = pkgs.writeText "DefaultKeybinding.dict" + (lib.generators.toPlist { } cfg.keybindings); +in { + options.targets.darwin.keybindings = mkOption { + type = with types; attrsOf anything; + default = { }; + example = { + "^u" = "deleteToBeginningOfLine:"; + "^w" = "deleteWordBackward:"; + }; + description = '' + This will configure the default keybindings for text fields in macOS + applications. See + Apple's documentation + for more details. + + + + Existing keybinding configuration will be wiped when using this + option. + + + ''; + }; + + config = mkIf (cfg.keybindings != { }) { + # NOTE: just copy the files because symlinks won't be recognized by macOS + home.activation.setCocoaKeybindings = + hm.dag.entryAfter [ "writeBoundary" ] '' + $VERBOSE_ECHO "Configuring keybindings for the Cocoa Text System" + $DRY_RUN_CMD install -Dm644 $VERBOSE_ARG \ + "${confFile}" "${homeDir}/Library/KeyBindings/DefaultKeyBinding.dict" + ''; + }; +} diff --git a/third_party/home-manager/modules/targets/darwin.nix b/third_party/home-manager/modules/targets/darwin/linkapps.nix similarity index 100% rename from third_party/home-manager/modules/targets/darwin.nix rename to third_party/home-manager/modules/targets/darwin/linkapps.nix diff --git a/third_party/home-manager/modules/targets/darwin/options.nix b/third_party/home-manager/modules/targets/darwin/options.nix new file mode 100644 index 0000000000..f722fbfae2 --- /dev/null +++ b/third_party/home-manager/modules/targets/darwin/options.nix @@ -0,0 +1,189 @@ +{ config, lib, ... }: + +with lib; + +let + mkNullableOption = args: + lib.mkOption (args // { + type = types.nullOr args.type; + default = null; + }); + + mkNullableEnableOption = name: + lib.mkOption { + type = with types; nullOr bool; + default = null; + example = true; + description = "Whether to enable ${name}."; + }; + + safari = config."com.apple.Safari"; +in { + freeformType = with types; attrsOf (attrsOf anything); + + options = { + NSGlobalDomain = { + AppleLanguages = mkNullableOption { + type = with types; listOf str; + example = [ "en" ]; + description = "Sets the language to use in the preferred order."; + }; + + AppleLocale = mkNullableOption { + type = types.str; + example = "en_US"; + description = "Configures the user locale."; + }; + + AppleMeasurementUnits = mkNullableOption { + type = types.enum [ "Centimeters" "Inches" ]; + example = "Centimeters"; + description = "Sets the measurement unit."; + }; + + AppleTemperatureUnit = mkNullableOption { + type = types.enum [ "Celsius" "Fahrenheit" ]; + example = "Celsius"; + description = "Sets the temperature unit."; + }; + + AppleMetricUnits = mkNullableEnableOption "the metric system"; + + NSAutomaticCapitalizationEnabled = + mkNullableEnableOption "automatic captilization"; + + NSAutomaticDashSubstitutionEnabled = + mkNullableEnableOption "smart dashes"; + + NSAutomaticPeriodSubstitutionEnabled = + mkNullableEnableOption "period with double space"; + + NSAutomaticQuoteSubstitutionEnabled = + mkNullableEnableOption "smart quotes"; + + NSAutomaticSpellingCorrectionEnabled = + mkNullableEnableOption "spelling correction"; + }; + + "com.apple.desktopservices" = { + DSDontWriteNetworkStores = mkNullableOption { + type = types.bool; + example = false; + description = '' + Disable use of .DS_Store files on network shares. + See the + official article for more info. + ''; + }; + DSDontWriteUSBStores = mkNullableOption { + type = types.bool; + example = false; + description = '' + Disable use of .DS_Store files on thumb drives. + ''; + }; + }; + + "com.apple.dock" = { + tilesize = mkNullableOption { + type = types.int; + example = 64; + description = "Sets the size of the dock."; + }; + size-immutable = mkNullableEnableOption "locking of the dock size"; + expose-group-apps = mkNullableEnableOption + "grouping of windows by application in Mission Control"; + }; + + "com.apple.menuextra.battery".ShowPercent = mkNullableOption { + type = types.enum [ "YES" "NO" ]; + example = "NO"; + description = "Whether to show battery percentage in the menu bar."; + }; + + "com.apple.Safari" = { + AutoOpenSafeDownloads = + mkNullableEnableOption "opening of downloaded files"; + AutoFillPasswords = + mkNullableEnableOption "autofill of usernames and passwords"; + AutoFillCreditCardData = + mkNullableEnableOption "autofill of credit card numbers"; + IncludeDevelopMenu = + mkNullableEnableOption ''"Develop" menu in the menu bar''; + ShowOverlayStatusBar = mkNullableEnableOption "status bar"; + + WebKitDeveloperExtrasEnabledPreferenceKey = mkNullableOption { + type = types.bool; + description = '' + Configures the web inspector. + + + + Instead of setting this option directly, set + instead. + + + ''; + }; + "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" = + mkNullableOption { + type = types.bool; + description = '' + Configures the web inspector. + + + + Instead of setting this option directly, set + instead. + + + ''; + }; + }; + + "com.googlecode.iterm2" = { + AddNewTabAtEndOfTabs = mkNullableEnableOption + "placement of new tabs at the end of the tab bar"; + + AlternateMouseScroll = mkNullableEnableOption + "arrow keys when scrolling in alternate screen mode"; + + CopySelection = + mkNullableEnableOption "copy to clipboard upon selecting text"; + + OpenTmuxWindowsIn = mkNullableOption { + type = types.int; + example = 2; + description = '' + Configures how to restore tmux windows when attaching to a session. + + Possible Values + + 0 + Native windows + + + 1 + Native tabs in a new window + + + 2 + Tabs in the attaching window + + + ''; + }; + + ExperimentalKeyHandling = mkNullableEnableOption + "experimental key handling for AquaSKK compatibility"; + }; + }; + + config = { + "com.apple.Safari" = mkIf (safari.IncludeDevelopMenu != null) { + WebKitDeveloperExtrasEnabledPreferenceKey = safari.IncludeDevelopMenu; + "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" = + safari.IncludeDevelopMenu; + }; + }; +} diff --git a/third_party/home-manager/modules/targets/darwin/search.nix b/third_party/home-manager/modules/targets/darwin/search.nix new file mode 100644 index 0000000000..2afbae4af3 --- /dev/null +++ b/third_party/home-manager/modules/targets/darwin/search.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.targets.darwin; + searchEngines = { + Bing = "com.bing.www"; + DuckDuckGo = "com.duckduckgo"; + Ecosia = "org.ecosia.www"; + Google = "com.google.www"; + Yahoo = "com.yahoo.www"; + }; + searchId = getAttr cfg.search searchEngines; +in { + options.targets.darwin.search = mkOption { + type = with types; nullOr (enum (attrNames searchEngines)); + default = null; + description = "Default search engine."; + }; + + config = mkIf (cfg.search != null) { + targets.darwin.defaults = { + NSGlobalDomain.NSPreferredWebServices = { + NSWebServicesProviderWebSearch = { + NSDefaultDisplayName = cfg.search; + NSProviderIdentifier = searchId; + }; + }; + "com.apple.Safari".SearchProviderIdentifier = searchId; + }; + }; +} diff --git a/third_party/home-manager/modules/targets/generic-linux.nix b/third_party/home-manager/modules/targets/generic-linux.nix index cf6b2bd87a..6e17bd2829 100644 --- a/third_party/home-manager/modules/targets/generic-linux.nix +++ b/third_party/home-manager/modules/targets/generic-linux.nix @@ -4,9 +4,19 @@ with lib; let + cfg = config.targets.genericLinux; + profileDirectory = config.home.profileDirectory; in { + imports = [ + (mkRenamedOptionModule [ "targets" "genericLinux" "extraXdgDataDirs" ] [ + "xdg" + "systemDirs" + "data" + ]) + ]; + options.targets.genericLinux = { enable = mkEnableOption "" // { description = '' @@ -14,28 +24,26 @@ in { GNU/Linux distributions other than NixOS. ''; }; - - extraXdgDataDirs = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "/usr/share" "/usr/local/share" ]; - description = '' - List of directory names to add to XDG_DATA_DIRS. - ''; - }; }; - config = mkIf config.targets.genericLinux.enable { - home.sessionVariables = let - profiles = - [ "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default" profileDirectory ]; - dataDirs = concatStringsSep ":" - (map (profile: "${profile}/share") profiles - ++ config.targets.genericLinux.extraXdgDataDirs); - in { XDG_DATA_DIRS = "${dataDirs}\${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS"; }; + config = mkIf cfg.enable { + xdg.systemDirs.data = [ + # Nix profiles + "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share" + "${profileDirectory}/share" + + # Distribution-specific + "/usr/share/ubuntu" + "/usr/local/share" + "/usr/share" + "/var/lib/snapd/desktop" + ]; home.sessionVariablesExtra = '' . "${pkgs.nix}/etc/profile.d/nix.sh" + + # reset TERM with new TERMINFO available (if any) + export TERM="$TERM" ''; # We need to source both nix.sh and hm-session-vars.sh as noted in @@ -45,8 +53,20 @@ in { . "${profileDirectory}/etc/profile.d/hm-session-vars.sh" ''; - systemd.user.sessionVariables = { + systemd.user.sessionVariables = let + # https://github.com/archlinux/svntogit-packages/blob/packages/ncurses/trunk/PKGBUILD + # https://salsa.debian.org/debian/ncurses/-/blob/master/debian/rules + # https://src.fedoraproject.org/rpms/ncurses/blob/main/f/ncurses.spec + # https://gitweb.gentoo.org/repo/gentoo.git/tree/sys-libs/ncurses/ncurses-6.2-r1.ebuild + distroTerminfoDirs = concatStringsSep ":" [ + "/etc/terminfo" # debian, fedora, gentoo + "/lib/terminfo" # debian + "/usr/share/terminfo" # package default, all distros + ]; + in { NIX_PATH = "$HOME/.nix-defexpr/channels\${NIX_PATH:+:}$NIX_PATH"; + TERMINFO_DIRS = + "${profileDirectory}/share/terminfo:$TERMINFO_DIRS\${TERMINFO_DIRS:+:}${distroTerminfoDirs}"; }; }; } diff --git a/third_party/home-manager/modules/xcursor.nix b/third_party/home-manager/modules/xcursor.nix index 63ceef387d..65b5c77068 100644 --- a/third_party/home-manager/modules/xcursor.nix +++ b/third_party/home-manager/modules/xcursor.nix @@ -79,5 +79,14 @@ in { "gtk-cursor-theme-size" = cfg.size; }; + # Set name in icons theme, for compatibility with AwesomeWM etc. See: + # https://github.com/nix-community/home-manager/issues/2081 + # https://wiki.archlinux.org/title/Cursor_themes#XDG_specification + home.file.".icons/default/index.theme".text = '' + [icon theme] + Name=Default + Comment=Default Cursor Theme + Inherits=${cfg.name} + ''; }; } diff --git a/third_party/home-manager/modules/xresources.nix b/third_party/home-manager/modules/xresources.nix index dc59e50c46..ef91906e00 100644 --- a/third_party/home-manager/modules/xresources.nix +++ b/third_party/home-manager/modules/xresources.nix @@ -23,6 +23,8 @@ let toString v; in "${n}: ${formatValue v}"; + xrdbMerge = "${pkgs.xorg.xrdb}/bin/xrdb -merge ${cfg.path}"; + in { meta.maintainers = [ maintainers.rycee ]; @@ -45,7 +47,7 @@ in { X server resources that should be set. Booleans are formatted as "true" or "false" respectively. List elements are recursively formatted as a string and joined by commas. - All other values are directly formatted using builtins.toString. + All other values are directly formatted using builtins.toString. Note, that 2-dimensional lists are not supported and specifying one will throw an exception. If this and all other xresources options are null, then this feature is disabled and no @@ -73,20 +75,30 @@ in { ~/.Xresources link is produced. ''; }; + + xresources.path = mkOption { + type = types.str; + default = "${config.home.homeDirectory}/.Xresources"; + defaultText = "$HOME/.Xresources"; + description = + "Path where Home Manager should link the .Xresources file."; + }; }; config = mkIf ((cfg.properties != null && cfg.properties != { }) || cfg.extraConfig != "") { - home.file.".Xresources" = { + home.file.${cfg.path} = { text = concatStringsSep "\n" ([ ] ++ optional (cfg.extraConfig != "") cfg.extraConfig ++ optionals (cfg.properties != null) (mapAttrsToList formatLine cfg.properties)) + "\n"; onChange = '' if [[ -v DISPLAY ]] ; then - $DRY_RUN_CMD ${pkgs.xorg.xrdb}/bin/xrdb -merge $HOME/.Xresources + $DRY_RUN_CMD ${xrdbMerge} fi ''; }; + + xsession.initExtra = xrdbMerge; }; } diff --git a/third_party/home-manager/modules/xsession.nix b/third_party/home-manager/modules/xsession.nix index d32c284916..6dc2968a63 100644 --- a/third_party/home-manager/modules/xsession.nix +++ b/third_party/home-manager/modules/xsession.nix @@ -18,11 +18,21 @@ in { default = ".xsession"; example = ".xsession-hm"; description = '' - Path, relative HOME, where Home Manager + Path, relative to HOME, where Home Manager should write the X session script. ''; }; + profilePath = mkOption { + type = types.str; + default = ".xprofile"; + example = ".xprofile-hm"; + description = '' + Path, relative to HOME, where Home Manager + should write the X profile script. + ''; + }; + windowManager.command = mkOption { type = types.str; example = literalExample '' @@ -110,17 +120,26 @@ in { }; }; - # A basic graphical session target for Home Manager. - targets.hm-graphical-session = { - Unit = { - Description = "Home Manager X session"; - Requires = [ "graphical-session-pre.target" ]; - BindsTo = [ "graphical-session.target" ]; + targets = { + # A basic graphical session target for Home Manager. + hm-graphical-session = { + Unit = { + Description = "Home Manager X session"; + Requires = [ "graphical-session-pre.target" ]; + BindsTo = [ "graphical-session.target" "tray.target" ]; + }; + }; + + tray = { + Unit = { + Description = "Home Manager System Tray"; + Requires = [ "graphical-session-pre.target" ]; + }; }; }; }; - home.file.".xprofile".text = '' + home.file.${cfg.profilePath}.text = '' . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" if [ -e "$HOME/.profile" ]; then @@ -145,7 +164,7 @@ in { executable = true; text = '' if [ -z "$HM_XPROFILE_SOURCED" ]; then - . ~/.xprofile + . "${config.home.homeDirectory}/${cfg.profilePath}" fi unset HM_XPROFILE_SOURCED diff --git a/third_party/home-manager/nix-darwin/default.nix b/third_party/home-manager/nix-darwin/default.nix index 12d0217433..9e37f35824 100644 --- a/third_party/home-manager/nix-darwin/default.nix +++ b/third_party/home-manager/nix-darwin/default.nix @@ -9,7 +9,10 @@ let extendedLib = import ../modules/lib/stdlib-extended.nix pkgs.lib; hmModule = types.submoduleWith { - specialArgs = { lib = extendedLib; }; + specialArgs = { + lib = extendedLib; + darwinConfig = config; + } // cfg.extraSpecialArgs; modules = [ ({ name, ... }: { imports = import ../modules/modules.nix { @@ -26,7 +29,7 @@ let home.homeDirectory = config.users.users.${name}.home; }; }) - ]; + ] ++ cfg.sharedModules; }; in @@ -36,7 +39,7 @@ in home-manager = { useUserPackages = mkEnableOption '' installation of user packages through the - option. + option. ''; useGlobalPkgs = mkEnableOption '' @@ -55,11 +58,36 @@ in ''; }; + extraSpecialArgs = mkOption { + type = types.attrs; + default = { }; + example = literalExample "{ modulesPath = ../modules; }"; + description = '' + Extra specialArgs passed to Home Manager. + ''; + }; + + sharedModules = mkOption { + type = with types; + listOf (anything // { + inherit (submodule { }) check; + description = "Home Manager modules"; + }); + default = [ ]; + example = literalExample "[ { home.packages = [ nixpkgs-fmt ]; } ]"; + description = '' + Extra modules added to all users. + ''; + }; + verbose = mkEnableOption "verbose output on activation"; users = mkOption { type = types.attrsOf hmModule; default = {}; + # Set as not visible to prevent the entire submodule being included in + # the documentation. + visible = false; description = '' Per-user Home Manager configuration. ''; diff --git a/third_party/home-manager/nixos/default.nix b/third_party/home-manager/nixos/default.nix index e5ca61c02f..fec59c624c 100644 --- a/third_party/home-manager/nixos/default.nix +++ b/third_party/home-manager/nixos/default.nix @@ -12,7 +12,7 @@ let specialArgs = { lib = extendedLib; nixosConfig = config; - }; + } // cfg.extraSpecialArgs; modules = [ ({ name, ... }: { imports = import ../modules/modules.nix { @@ -34,7 +34,7 @@ let home.homeDirectory = config.users.users.${name}.home; }; }) - ]; + ] ++ cfg.sharedModules; }; serviceEnvironment = optionalAttrs (cfg.backupFileExtension != null) { @@ -46,7 +46,7 @@ in { home-manager = { useUserPackages = mkEnableOption '' installation of user packages through the - option. + option. ''; useGlobalPkgs = mkEnableOption '' @@ -65,11 +65,36 @@ in { ''; }; + extraSpecialArgs = mkOption { + type = types.attrs; + default = { }; + example = literalExample "{ modulesPath = ../modules; }"; + description = '' + Extra specialArgs passed to Home Manager. + ''; + }; + + sharedModules = mkOption { + type = with types; + listOf (anything // { + inherit (submodule { }) check; + description = "Home Manager modules"; + }); + default = [ ]; + example = literalExample "[ { home.packages = [ nixpkgs-fmt ]; } ]"; + description = '' + Extra modules added to all users. + ''; + }; + verbose = mkEnableOption "verbose output on activation"; users = mkOption { type = types.attrsOf hmModule; default = { }; + # Set as not visible to prevent the entire submodule being included in + # the documentation. + visible = false; description = '' Per-user Home Manager configuration. ''; @@ -105,6 +130,8 @@ in { unitConfig = { RequiresMountsFor = usercfg.home.homeDirectory; }; + stopIfChanged = false; + serviceConfig = { User = usercfg.home.username; Type = "oneshot"; diff --git a/third_party/home-manager/tests/asserts.nix b/third_party/home-manager/tests/asserts.nix new file mode 100644 index 0000000000..6d1b100227 --- /dev/null +++ b/third_party/home-manager/tests/asserts.nix @@ -0,0 +1,73 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + options.test.asserts = { + warnings = { + enable = mkOption { + type = types.bool; + default = true; + description = "Whether warning asserts are enabled."; + }; + + expected = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + List of expected warnings. + ''; + }; + }; + + assertions = { + enable = mkOption { + type = types.bool; + default = true; + description = "Whether assertion asserts are enabled."; + }; + + expected = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + List of expected assertions. + ''; + }; + }; + }; + + config = mkIf config.test.asserts.warnings.enable { + home.file = { + "asserts/warnings.actual".text = concatStringsSep '' + + -- + '' config.warnings; + + "asserts/assertions.actual".text = concatStringsSep '' + + -- + '' (map (x: x.message) (filter (x: !x.assertion) config.assertions)); + }; + + nmt.script = '' + assertFileContent \ + home-files/asserts/warnings.actual \ + ${ + pkgs.writeText "warnings.expected" (concatStringsSep '' + + -- + '' config.test.asserts.warnings.expected) + } + + assertFileContent \ + home-files/asserts/assertions.actual \ + ${ + pkgs.writeText "assertions.expected" (concatStringsSep '' + + -- + '' config.test.asserts.assertions.expected) + } + ''; + }; +} diff --git a/third_party/home-manager/tests/default.nix b/third_party/home-manager/tests/default.nix index 6ece9dfdb8..130eab4c0e 100644 --- a/third_party/home-manager/tests/default.nix +++ b/third_party/home-manager/tests/default.nix @@ -7,8 +7,8 @@ let nmt = pkgs.fetchFromGitLab { owner = "rycee"; repo = "nmt"; - rev = "8e130d655ec396ce165763c95bbf4ac429810ca8"; - sha256 = "1jbljr06kg1ycdn24hj8xap16axq11rhb6hm4949fz48n57pwwps"; + rev = "89924d8e6e0fcf866a11324d32c6bcaa89cda506"; + sha256 = "02wzrbmpdpgig58a1rhz8sb0p2rvbapnlcmhi4d4bi8w9md6pmdl"; }; modules = import ../modules/modules.nix { @@ -25,6 +25,8 @@ let # Avoid including documentation since this will cause # unnecessary rebuilds of the tests. manual.manpages.enable = false; + + imports = [ ./asserts.nix ]; } ]; @@ -51,24 +53,34 @@ import nmt { ./modules/programs/gh ./modules/programs/git ./modules/programs/gpg + ./modules/programs/himalaya + ./modules/programs/htop ./modules/programs/i3status + ./modules/programs/irsii ./modules/programs/kakoune + ./modules/programs/kitty ./modules/programs/lf ./modules/programs/lieer ./modules/programs/man ./modules/programs/mbsync + ./modules/programs/mpv ./modules/programs/ncmpcpp ./modules/programs/ne ./modules/programs/neomutt ./modules/programs/newsboat + ./modules/programs/nix-index ./modules/programs/nushell + ./modules/programs/pet ./modules/programs/powerline-go ./modules/programs/qutebrowser ./modules/programs/readline + ./modules/programs/sbt + ./modules/programs/scmpuff ./modules/programs/ssh ./modules/programs/starship ./modules/programs/texlive ./modules/programs/tmux + ./modules/programs/topgrade ./modules/programs/vscode ./modules/programs/zplug ./modules/programs/zsh @@ -76,29 +88,48 @@ import nmt { ] ++ lib.optionals pkgs.stdenv.hostPlatform.isDarwin [ ./modules/targets-darwin ] ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [ - ./meta # Suffices to run on one platform. + ./modules/config/i18n + ./modules/i18n/input-method ./modules/misc/debug + ./modules/misc/gtk ./modules/misc/numlock ./modules/misc/pam + ./modules/misc/qt ./modules/misc/xdg ./modules/misc/xsession ./modules/programs/abook ./modules/programs/autorandr ./modules/programs/firefox + ./modules/programs/foot ./modules/programs/getmail + ./modules/programs/gnome-terminal + ./modules/programs/i3status-rust + ./modules/programs/mangohud ./modules/programs/ncmpcpp-linux ./modules/programs/neovim # Broken package dependency on Darwin. + ./modules/programs/rbw ./modules/programs/rofi + ./modules/programs/rofi-pass + ./modules/programs/terminator ./modules/programs/waybar + ./modules/programs/xmobar + ./modules/services/barrier ./modules/services/dropbox ./modules/services/emacs ./modules/services/fluidsynth ./modules/services/kanshi ./modules/services/lieer + ./modules/services/pantalaimon + ./modules/services/pbgopy + ./modules/services/playerctld ./modules/services/polybar + ./modules/services/redshift-gammastep ./modules/services/sxhkd + ./modules/services/syncthing + ./modules/services/window-managers/bspwm ./modules/services/window-managers/i3 ./modules/services/window-managers/sway + ./modules/services/wlsunset ./modules/systemd ./modules/targets-linux ]); diff --git a/third_party/home-manager/tests/lib/types/dag-merge.nix b/third_party/home-manager/tests/lib/types/dag-merge.nix index 138a0b64fb..40214bb45d 100644 --- a/third_party/home-manager/tests/lib/types/dag-merge.nix +++ b/third_party/home-manager/tests/lib/types/dag-merge.nix @@ -4,7 +4,7 @@ with lib; let - dag = config.lib.dag; + dag = lib.hm.dag; result = let sorted = dag.topoSort config.tested.dag; diff --git a/third_party/home-manager/tests/lib/types/dag-submodule.nix b/third_party/home-manager/tests/lib/types/dag-submodule.nix index 552e804acb..29819ceb66 100644 --- a/third_party/home-manager/tests/lib/types/dag-submodule.nix +++ b/third_party/home-manager/tests/lib/types/dag-submodule.nix @@ -4,7 +4,7 @@ with lib; let - dag = config.lib.dag; + dag = lib.hm.dag; result = let sorted = dag.topoSort config.tested.dag; diff --git a/third_party/home-manager/tests/lib/types/list-or-dag-merge.nix b/third_party/home-manager/tests/lib/types/list-or-dag-merge.nix index 08216140e5..389938774a 100644 --- a/third_party/home-manager/tests/lib/types/list-or-dag-merge.nix +++ b/third_party/home-manager/tests/lib/types/list-or-dag-merge.nix @@ -4,7 +4,7 @@ with lib; let - dag = config.lib.dag; + dag = lib.hm.dag; result = let sorted = dag.topoSort config.tested.dag; diff --git a/third_party/home-manager/tests/meta/default.nix b/third_party/home-manager/tests/meta/default.nix deleted file mode 100644 index 0f02fcfb45..0000000000 --- a/third_party/home-manager/tests/meta/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ meta-formatting = ./formatting.nix; } diff --git a/third_party/home-manager/tests/meta/formatting.nix b/third_party/home-manager/tests/meta/formatting.nix deleted file mode 100644 index 2d5800c53c..0000000000 --- a/third_party/home-manager/tests/meta/formatting.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - - pinnedNixpkgs = builtins.fetchTarball { - url = - "https://github.com/NixOS/nixpkgs/archive/05f0934825c2a0750d4888c4735f9420c906b388.tar.gz"; - sha256 = "1g8c2w0661qn89ajp44znmwfmghbbiygvdzq0rzlvlpdiz28v6gy"; - }; - - pinnedPkgs = import pinnedNixpkgs { }; - -in { - config = { - nmt.script = '' - PATH="${with pinnedPkgs; lib.makeBinPath [ findutils nixfmt ]}:$PATH" - cd ${../..} - if ! ${pkgs.runtimeShell} format -c; then - fail "${'' - Expected source code to be formatted with nixfmt but it was not. - This error can be resolved by running the './format' in the project root directory.''}" - fi - ''; - }; -} diff --git a/third_party/home-manager/tests/modules/accounts/email-test-accounts.nix b/third_party/home-manager/tests/modules/accounts/email-test-accounts.nix index 9a4e0b8e72..e66e58949e 100644 --- a/third_party/home-manager/tests/modules/accounts/email-test-accounts.nix +++ b/third_party/home-manager/tests/modules/accounts/email-test-accounts.nix @@ -6,6 +6,7 @@ accounts = { "hm@example.com" = { + primary = true; address = "hm@example.com"; userName = "home.manager"; realName = "H. M. Test"; diff --git a/third_party/home-manager/tests/modules/config/i18n/default.nix b/third_party/home-manager/tests/modules/config/i18n/default.nix new file mode 100644 index 0000000000..10b35b6f46 --- /dev/null +++ b/third_party/home-manager/tests/modules/config/i18n/default.nix @@ -0,0 +1,17 @@ +{ + i18n = { ... }: { + config = { + nmt.script = '' + hmEnvFile=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $hmEnvFile + assertFileRegex $hmEnvFile \ + '^export LOCALE_ARCHIVE_._..=".*/lib/locale/locale-archive"$' + + envFile=home-files/.config/environment.d/10-home-manager.conf + assertFileExists $envFile + assertFileRegex $envFile \ + '^LOCALE_ARCHIVE_._..=.*/lib/locale/locale-archive$' + ''; + }; + }; +} diff --git a/third_party/home-manager/tests/modules/files/default.nix b/third_party/home-manager/tests/modules/files/default.nix index 6f1ef24b81..52e44d22b1 100644 --- a/third_party/home-manager/tests/modules/files/default.nix +++ b/third_party/home-manager/tests/modules/files/default.nix @@ -3,6 +3,7 @@ files-hidden-source = ./hidden-source.nix; files-out-of-store-symlink = ./out-of-store-symlink.nix; files-source-with-spaces = ./source-with-spaces.nix; + files-target-conflict = ./target-conflict.nix; files-target-with-shellvar = ./target-with-shellvar.nix; files-text = ./text.nix; } diff --git a/third_party/home-manager/tests/modules/files/target-conflict.nix b/third_party/home-manager/tests/modules/files/target-conflict.nix new file mode 100644 index 0000000000..dbcee80a00 --- /dev/null +++ b/third_party/home-manager/tests/modules/files/target-conflict.nix @@ -0,0 +1,26 @@ +{ ... }: + +{ + config = { + home.file = { + conflict1 = { + text = ""; + target = "baz"; + }; + conflict2 = { + source = ./target-conflict.nix; + target = "baz"; + }; + }; + + test.asserts.assertions.expected = ['' + Conflicting managed target files: baz + + This may happen, for example, if you have a configuration similar to + + home.file = { + conflict1 = { source = ./foo.nix; target = "baz"; }; + conflict2 = { source = ./bar.nix; target = "baz"; }; + }'']; + }; +} diff --git a/third_party/home-manager/tests/modules/home-environment/session-path.nix b/third_party/home-manager/tests/modules/home-environment/session-path.nix index 3b40059eac..57cfeceda3 100644 --- a/third_party/home-manager/tests/modules/home-environment/session-path.nix +++ b/third_party/home-manager/tests/modules/home-environment/session-path.nix @@ -7,21 +7,9 @@ ]; nmt.script = '' - assertFileExists home-path/etc/profile.d/hm-session-vars.sh - assertFileContent \ - home-path/etc/profile.d/hm-session-vars.sh \ - ${ - pkgs.writeText "session-path-expected.txt" '' - # Only source this once. - if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi - export __HM_SESS_VARS_SOURCED=1 - - export XDG_CACHE_HOME="/home/hm-user/.cache" - export XDG_CONFIG_HOME="/home/hm-user/.config" - export XDG_DATA_HOME="/home/hm-user/.local/share" - export PATH="$PATH''${PATH:+:}bar:baz:foo" - '' - } + hmSessVars=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $hmSessVars + assertFileContains $hmSessVars \ + 'export PATH="$PATH''${PATH:+:}bar:baz:foo"' ''; - } diff --git a/third_party/home-manager/tests/modules/home-environment/session-variables-expected.txt b/third_party/home-manager/tests/modules/home-environment/session-variables-expected.txt index 4e18e2b31a..a96f61956b 100644 --- a/third_party/home-manager/tests/modules/home-environment/session-variables-expected.txt +++ b/third_party/home-manager/tests/modules/home-environment/session-variables-expected.txt @@ -1,7 +1,7 @@ # Only source this once. if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi export __HM_SESS_VARS_SOURCED=1 - +@exportLocaleVar@ export V1="v1" export V2="v2-v1" export XDG_CACHE_HOME="/home/hm-user/.cache" diff --git a/third_party/home-manager/tests/modules/home-environment/session-variables.nix b/third_party/home-manager/tests/modules/home-environment/session-variables.nix index 9f326ebc1b..d939c05eba 100644 --- a/third_party/home-manager/tests/modules/home-environment/session-variables.nix +++ b/third_party/home-manager/tests/modules/home-environment/session-variables.nix @@ -1,8 +1,37 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: -with lib; +let -{ + inherit (pkgs.stdenv.hostPlatform) isDarwin; + + linuxExpected = '' + # Only source this once. + if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi + export __HM_SESS_VARS_SOURCED=1 + + export LOCALE_ARCHIVE_2_27="${pkgs.glibcLocales}/lib/locale/locale-archive" + export V1="v1" + export V2="v2-v1" + export XDG_CACHE_HOME="/home/hm-user/.cache" + export XDG_CONFIG_HOME="/home/hm-user/.config" + export XDG_DATA_HOME="/home/hm-user/.local/share" + ''; + + darwinExpected = '' + # Only source this once. + if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi + export __HM_SESS_VARS_SOURCED=1 + + export V1="v1" + export V2="v2-v1" + export XDG_CACHE_HOME="/home/hm-user/.cache" + export XDG_CONFIG_HOME="/home/hm-user/.config" + export XDG_DATA_HOME="/home/hm-user/.local/share" + ''; + + expected = pkgs.writeText "expected" (if isDarwin then darwinExpected else linuxExpected); + +in { config = { home.sessionVariables = { V1 = "v1"; @@ -11,9 +40,8 @@ with lib; nmt.script = '' assertFileExists home-path/etc/profile.d/hm-session-vars.sh - assertFileContent \ - home-path/etc/profile.d/hm-session-vars.sh \ - ${./session-variables-expected.txt} + assertFileContent home-path/etc/profile.d/hm-session-vars.sh \ + ${expected} ''; }; } diff --git a/third_party/home-manager/tests/modules/i18n/input-method/default.nix b/third_party/home-manager/tests/modules/i18n/input-method/default.nix new file mode 100644 index 0000000000..f214d85136 --- /dev/null +++ b/third_party/home-manager/tests/modules/i18n/input-method/default.nix @@ -0,0 +1 @@ +{ input-method-fcitx5-configuration = ./fcitx5-configuration.nix; } diff --git a/third_party/home-manager/tests/modules/i18n/input-method/fcitx5-configuration.nix b/third_party/home-manager/tests/modules/i18n/input-method/fcitx5-configuration.nix new file mode 100644 index 0000000000..b29a94aa5e --- /dev/null +++ b/third_party/home-manager/tests/modules/i18n/input-method/fcitx5-configuration.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: + +{ + config = { + nixpkgs.overlays = [ (import ./fcitx5-overlay.nix) ]; + i18n.inputMethod = { + enabled = "fcitx5"; + fcitx5.addons = with pkgs; [ fcitx5-chinese-addons ]; + }; + + nmt.script = '' + assertFileExists home-files/.config/systemd/user/fcitx5-daemon.service + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/i18n/input-method/fcitx5-overlay.nix b/third_party/home-manager/tests/modules/i18n/input-method/fcitx5-overlay.nix new file mode 100644 index 0000000000..4007552cb9 --- /dev/null +++ b/third_party/home-manager/tests/modules/i18n/input-method/fcitx5-overlay.nix @@ -0,0 +1,22 @@ +final: prev: + +let + + dummy = prev.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { + fcitx5 = prev.runCommandLocal "fcitx5" { version = "0"; } '' + mkdir -p $out/bin $out/share/applications $out/etc/xdg/autostart + touch $out/bin/fcitx5 \ + $out/share/applications/org.fcitx.Fcitx5.desktop \ + $out/etc/xdg/autostart/org.fcitx.Fcitx5.desktop + chmod +x $out/bin/fcitx5 + ''; + fcitx5-configtool = dummy; + fcitx5-lua = dummy; + fcitx5-qt = dummy; + fcitx5-gtk = dummy; + fcitx5-with-addons = + prev.fcitx5-with-addons.override { inherit (final) fcitx5-qt; }; + fcitx5-chinese-addons = dummy; +} diff --git a/third_party/home-manager/tests/modules/misc/gtk/default.nix b/third_party/home-manager/tests/modules/misc/gtk/default.nix new file mode 100644 index 0000000000..0dbae61ebb --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/gtk/default.nix @@ -0,0 +1,5 @@ +{ + gtk2-basic-config = ./gtk2-basic-config.nix; + gtk2-config-file-location = ./gtk2-config-file-location.nix; +} + diff --git a/third_party/home-manager/tests/modules/misc/gtk/gtk-basic-config-expected.conf b/third_party/home-manager/tests/modules/misc/gtk/gtk-basic-config-expected.conf new file mode 100644 index 0000000000..3970b6e917 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/gtk/gtk-basic-config-expected.conf @@ -0,0 +1,2 @@ + +gtk-can-change-accels = 1 \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/misc/gtk/gtk2-basic-config.nix b/third_party/home-manager/tests/modules/misc/gtk/gtk2-basic-config.nix new file mode 100644 index 0000000000..4ac7299a20 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/gtk/gtk2-basic-config.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + gtk = { + enable = true; + gtk2.extraConfig = "gtk-can-change-accels = 1"; + }; + + nmt.script = '' + assertFileExists home-files/.gtkrc-2.0 + assertFileContent home-files/.gtkrc-2.0 ${ + ./gtk-basic-config-expected.conf + } + assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \ + 'GTK2_RC_FILES=.*/.gtkrc-2.0' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/misc/gtk/gtk2-config-file-location.nix b/third_party/home-manager/tests/modules/misc/gtk/gtk2-config-file-location.nix new file mode 100644 index 0000000000..41de2877f9 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/gtk/gtk2-config-file-location.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + gtk.enable = true; + gtk.gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc"; + + nmt.script = '' + assertFileExists home-files/.config/gtk-2.0/gtkrc + assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \ + 'GTK2_RC_FILES=.*/\.config/gtk-2.0/gtkrc' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/misc/qt/default.nix b/third_party/home-manager/tests/modules/misc/qt/default.nix new file mode 100644 index 0000000000..c676b784e5 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/qt/default.nix @@ -0,0 +1,4 @@ +{ + qt-platform-theme-gtk = ./qt-platform-theme-gtk.nix; + qt-platform-theme-gnome = ./qt-platform-theme-gnome.nix; +} diff --git a/third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gnome.nix b/third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gnome.nix new file mode 100644 index 0000000000..e9aa1a2506 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gnome.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + qt = { + enable = true; + platformTheme = "gnome"; + style = { + name = "adwaita"; + package = pkgs.dummyTheme; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + dummyTheme = pkgs.runCommandLocal "theme" { } "mkdir $out"; + }) + ]; + + nmt.script = '' + assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \ + 'QT_QPA_PLATFORMTHEME="gnome"' + assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \ + 'QT_STYLE_OVERRIDE="adwaita"' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gtk.nix b/third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gtk.nix new file mode 100644 index 0000000000..d332465283 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/qt/qt-platform-theme-gtk.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + qt = { + enable = true; + platformTheme = "gtk"; + }; + + nmt.script = '' + assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \ + 'QT_QPA_PLATFORMTHEME="gtk2"' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/misc/xdg/default.nix b/third_party/home-manager/tests/modules/misc/xdg/default.nix index 813a25202f..b637cd1bf5 100644 --- a/third_party/home-manager/tests/modules/misc/xdg/default.nix +++ b/third_party/home-manager/tests/modules/misc/xdg/default.nix @@ -1,4 +1,6 @@ { xdg-mime-apps-basics = ./mime-apps-basics.nix; xdg-file-attr-names = ./file-attr-names.nix; + xdg-system-dirs = ./system-dirs.nix; + xdg-desktop-entries = ./desktop-entries.nix; } diff --git a/third_party/home-manager/tests/modules/misc/xdg/desktop-entries.nix b/third_party/home-manager/tests/modules/misc/xdg/desktop-entries.nix new file mode 100644 index 0000000000..098aa7eeed --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/xdg/desktop-entries.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + xdg.desktopEntries = { + full = { # full definition + type = "Application"; + exec = "test --option"; + icon = "test"; + comment = "My Application"; + terminal = true; + name = "Test"; + genericName = "Web Browser"; + mimeType = [ "text/html" "text/xml" ]; + categories = [ "Network" "WebBrowser" ]; + startupNotify = false; + extraConfig = '' + [X-ExtraSection] + Exec=foo -o + ''; + settings = { + Keywords = "calc;math"; + DBusActivatable = "false"; + }; + fileValidation = true; + }; + min = { # minimal definition + exec = "test --option"; + name = "Test"; + }; + }; + + #testing that preexisting entries in the store are overridden + home.packages = [ + (pkgs.makeDesktopItem { + name = "full"; + desktopName = "We don't want this"; + exec = "no"; + }) + (pkgs.makeDesktopItem { + name = "min"; + desktopName = "We don't want this"; + exec = "no"; + }) + ]; + + nmt.script = '' + assertFileExists home-path/share/applications/full.desktop + assertFileExists home-path/share/applications/min.desktop + assertFileContent home-path/share/applications/full.desktop \ + ${./desktop-full-expected.desktop} + assertFileContent home-path/share/applications/min.desktop \ + ${./desktop-min-expected.desktop} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/misc/xdg/desktop-full-expected.desktop b/third_party/home-manager/tests/modules/misc/xdg/desktop-full-expected.desktop new file mode 100644 index 0000000000..fd5ace1b92 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/xdg/desktop-full-expected.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Categories=Network;WebBrowser; +Comment=My Application +DBusActivatable=false +Exec=test --option +GenericName=Web Browser +Icon=test +Keywords=calc;math +MimeType=text/html;text/xml; +Name=Test +StartupNotify=false +Terminal=true +Type=Application +[X-ExtraSection] +Exec=foo -o + diff --git a/third_party/home-manager/tests/modules/misc/xdg/desktop-min-expected.desktop b/third_party/home-manager/tests/modules/misc/xdg/desktop-min-expected.desktop new file mode 100644 index 0000000000..9475024ae9 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/xdg/desktop-min-expected.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Exec=test --option +Name=Test +Terminal=false +Type=Application diff --git a/third_party/home-manager/tests/modules/misc/xdg/system-dirs.nix b/third_party/home-manager/tests/modules/misc/xdg/system-dirs.nix new file mode 100644 index 0000000000..9bfa2ae446 --- /dev/null +++ b/third_party/home-manager/tests/modules/misc/xdg/system-dirs.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + xdg.systemDirs.config = [ "/etc/xdg" "/foo/bar" ]; + xdg.systemDirs.data = [ "/usr/local/share" "/usr/share" "/baz/quux" ]; + + nmt.script = '' + envFile=home-files/.config/environment.d/10-home-manager.conf + assertFileExists $envFile + assertFileContent $envFile ${ + pkgs.writeText "expected" '' + LOCALE_ARCHIVE_2_27=${pkgs.glibcLocales}/lib/locale/locale-archive + XDG_CONFIG_DIRS=/etc/xdg:/foo/bar''${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS} + XDG_DATA_DIRS=/usr/local/share:/usr/share:/baz/quux''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS} + '' + } + + sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $sessionVarsFile + assertFileContains $sessionVarsFile \ + 'export XDG_CONFIG_DIRS="/etc/xdg:/foo/bar''${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}"' + assertFileContains $sessionVarsFile \ + 'export XDG_DATA_DIRS="/usr/local/share:/usr/share:/baz/quux''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/misc/xsession/basic-xsession-expected.txt b/third_party/home-manager/tests/modules/misc/xsession/basic-xsession-expected.txt index c11b7c3304..423e7779c1 100644 --- a/third_party/home-manager/tests/modules/misc/xsession/basic-xsession-expected.txt +++ b/third_party/home-manager/tests/modules/misc/xsession/basic-xsession-expected.txt @@ -1,5 +1,5 @@ if [ -z "$HM_XPROFILE_SOURCED" ]; then - . ~/.xprofile + . "/home/hm-user/.xprofile" fi unset HM_XPROFILE_SOURCED diff --git a/third_party/home-manager/tests/modules/programs/alacritty/default.nix b/third_party/home-manager/tests/modules/programs/alacritty/default.nix index f63e033d84..3ccd9a91f3 100644 --- a/third_party/home-manager/tests/modules/programs/alacritty/default.nix +++ b/third_party/home-manager/tests/modules/programs/alacritty/default.nix @@ -1,4 +1,5 @@ { alacritty-example-settings = ./example-settings.nix; alacritty-empty-settings = ./empty-settings.nix; + alacritty-merging-settings = ./settings-merging.nix; } diff --git a/third_party/home-manager/tests/modules/programs/alacritty/settings-merging-expected.yml b/third_party/home-manager/tests/modules/programs/alacritty/settings-merging-expected.yml new file mode 100644 index 0000000000..49d92a614e --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/alacritty/settings-merging-expected.yml @@ -0,0 +1 @@ +{"font":{"bold":{"family":"SFMono"},"normal":{"family":"SFMono"}},"key_bindings":[{"chars":"\x0c","key":"K","mods":"Control"}],"window":{"dimensions":{"columns":200,"lines":3}}} \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/programs/alacritty/settings-merging.nix b/third_party/home-manager/tests/modules/programs/alacritty/settings-merging.nix new file mode 100644 index 0000000000..1b8559d69d --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/alacritty/settings-merging.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.alacritty = { + enable = true; + package = pkgs.writeScriptBin "dummy-alacritty" ""; + + settings = { + window.dimensions = { + lines = 3; + columns = 200; + }; + + key_bindings = [{ + key = "K"; + mods = "Control"; + chars = "\\x0c"; + }]; + + font = let + defaultFont = + lib.mkMerge [ (lib.mkIf true "SFMono") (lib.mkIf false "Iosevka") ]; + in { + normal.family = defaultFont; + bold.family = defaultFont; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/alacritty/alacritty.yml \ + ${./settings-merging-expected.yml} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/alot/alot.nix b/third_party/home-manager/tests/modules/programs/alot/alot.nix index 40028b7aac..3f74ef21c0 100644 --- a/third_party/home-manager/tests/modules/programs/alot/alot.nix +++ b/third_party/home-manager/tests/modules/programs/alot/alot.nix @@ -8,7 +8,6 @@ with lib; config = { accounts.email.accounts = { "hm@example.com" = { - primary = true; notmuch.enable = true; alot = { contactCompletion = { }; diff --git a/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.conf b/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.conf deleted file mode 100644 index 681574cf20..0000000000 --- a/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.conf +++ /dev/null @@ -1,10 +0,0 @@ -output DP1 -off - -output DP2 -pos 0x0 -crtc 0 -primary -mode 1920x1080 -transform 0.600000,0.000000,0.000000,0.000000,0.600000,0.000000,0.000000,0.000000,1.000000 -scale 2x4 \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.nix b/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.nix index 190511016f..fad18f7542 100644 --- a/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.nix +++ b/third_party/home-manager/tests/modules/programs/autorandr/basic-configuration.nix @@ -17,10 +17,6 @@ primary = true; position = "0x0"; mode = "1920x1080"; - scale = { - x = 2; - y = 4; - }; transform = [ [ 0.6 0.0 0.0 ] # a b c [ 0.0 0.6 0.0 ] # d e f @@ -42,7 +38,18 @@ assertFileExists $config assertFileContent $config \ - ${./basic-configuration.conf} + ${ + pkgs.writeText "basic-configuration.conf" '' + output DP1 + off + + output DP2 + pos 0x0 + crtc 0 + primary + mode 1920x1080 + transform 0.600000,0.000000,0.000000,0.000000,0.600000,0.000000,0.000000,0.000000,1.000000'' + } ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/autorandr/default.nix b/third_party/home-manager/tests/modules/programs/autorandr/default.nix index 5f12d40938..bb7b279ee2 100644 --- a/third_party/home-manager/tests/modules/programs/autorandr/default.nix +++ b/third_party/home-manager/tests/modules/programs/autorandr/default.nix @@ -1 +1,4 @@ -{ autorandr-basic-configuration = ./basic-configuration.nix; } +{ + autorandr-basic-configuration = ./basic-configuration.nix; + autorandr-scale = ./scale.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/autorandr/scale.nix b/third_party/home-manager/tests/modules/programs/autorandr/scale.nix new file mode 100644 index 0000000000..9092e61dcd --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/autorandr/scale.nix @@ -0,0 +1,32 @@ +{ config, pkgs, ... }: + +{ + config = { + programs.autorandr = { + enable = true; + profiles = { + default = { + fingerprint.DP1 = "XXX"; + config.DP1 = { + scale = { + x = 2; + y = 4; + }; + }; + }; + }; + }; + + nmt.script = '' + config=home-files/.config/autorandr/default/config + + assertFileExists $config + assertFileContent $config \ + ${ + pkgs.writeText "scale-expected.conf" '' + output DP1 + scale 2x4'' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/bash/logout-expected.txt b/third_party/home-manager/tests/modules/programs/bash/logout-expected.txt deleted file mode 100644 index 9462f58f73..0000000000 --- a/third_party/home-manager/tests/modules/programs/bash/logout-expected.txt +++ /dev/null @@ -1,4 +0,0 @@ -# -*- mode: sh -*- - -clear-console - diff --git a/third_party/home-manager/tests/modules/programs/bash/logout.nix b/third_party/home-manager/tests/modules/programs/bash/logout.nix index 8f96dc7e1a..7b7f738ab2 100644 --- a/third_party/home-manager/tests/modules/programs/bash/logout.nix +++ b/third_party/home-manager/tests/modules/programs/bash/logout.nix @@ -16,7 +16,11 @@ with lib; assertFileExists home-files/.bash_logout assertFileContent \ home-files/.bash_logout \ - ${./logout-expected.txt} + ${ + pkgs.writeShellScript "logout-expected" '' + clear-console + '' + } ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/bash/session-variables-expected.txt b/third_party/home-manager/tests/modules/programs/bash/session-variables-expected.txt deleted file mode 100644 index 0d93217a91..0000000000 --- a/third_party/home-manager/tests/modules/programs/bash/session-variables-expected.txt +++ /dev/null @@ -1,8 +0,0 @@ -# -*- mode: sh -*- - -. "/home/hm-user/.nix-profile/etc/profile.d/hm-session-vars.sh" - -export V1="v1" -export V2="v2-v1" - - diff --git a/third_party/home-manager/tests/modules/programs/bash/session-variables.nix b/third_party/home-manager/tests/modules/programs/bash/session-variables.nix index 1ef65a3444..47ed2130d7 100644 --- a/third_party/home-manager/tests/modules/programs/bash/session-variables.nix +++ b/third_party/home-manager/tests/modules/programs/bash/session-variables.nix @@ -17,7 +17,16 @@ with lib; assertFileExists home-files/.profile assertFileContent \ home-files/.profile \ - ${./session-variables-expected.txt} + ${ + pkgs.writeShellScript "session-variables-expected" '' + . "/home/hm-user/.nix-profile/etc/profile.d/hm-session-vars.sh" + + export V1="v1" + export V2="v2-v1" + + + '' + } ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/dircolors/settings-expected.conf b/third_party/home-manager/tests/modules/programs/dircolors/settings-expected.conf index 17bc247c0c..d490081b37 100644 --- a/third_party/home-manager/tests/modules/programs/dircolors/settings-expected.conf +++ b/third_party/home-manager/tests/modules/programs/dircolors/settings-expected.conf @@ -1,5 +1,3 @@ -# Extra dircolors configuration. - .7z 01;31 .aac 00;36 .ace 01;31 @@ -131,3 +129,5 @@ SETUID 37;41 SOCK 01;35 STICKY 37;44 STICKY_OTHER_WRITABLE 30;42 + +# Extra dircolors configuration. diff --git a/third_party/home-manager/tests/modules/programs/direnv/nix-direnv.nix b/third_party/home-manager/tests/modules/programs/direnv/nix-direnv.nix index 57b3907dda..4c17309773 100644 --- a/third_party/home-manager/tests/modules/programs/direnv/nix-direnv.nix +++ b/third_party/home-manager/tests/modules/programs/direnv/nix-direnv.nix @@ -6,7 +6,7 @@ with lib; config = { programs.bash.enable = true; programs.direnv.enable = true; - programs.direnv.enableNixDirenvIntegration = true; + programs.direnv.nix-direnv.enable = true; nmt.script = '' assertFileExists home-files/.bashrc diff --git a/third_party/home-manager/tests/modules/programs/direnv/stdlib-and-nix-direnv.nix b/third_party/home-manager/tests/modules/programs/direnv/stdlib-and-nix-direnv.nix index 1dc224317a..4e5efb8732 100644 --- a/third_party/home-manager/tests/modules/programs/direnv/stdlib-and-nix-direnv.nix +++ b/third_party/home-manager/tests/modules/programs/direnv/stdlib-and-nix-direnv.nix @@ -7,7 +7,7 @@ in { config = { programs.bash.enable = true; programs.direnv.enable = true; - programs.direnv.enableNixDirenvIntegration = true; + programs.direnv.nix-direnv.enable = true; programs.direnv.stdlib = expectedContent; nmt.script = '' diff --git a/third_party/home-manager/tests/modules/programs/firefox/default.nix b/third_party/home-manager/tests/modules/programs/firefox/default.nix index 6612a9ac97..cc8e2fc466 100644 --- a/third_party/home-manager/tests/modules/programs/firefox/default.nix +++ b/third_party/home-manager/tests/modules/programs/firefox/default.nix @@ -1,4 +1,5 @@ { firefox-profile-settings = ./profile-settings.nix; firefox-state-version-19_09 = ./state-version-19_09.nix; + firefox-deprecated-native-messenger = ./deprecated-native-messenger.nix; } diff --git a/third_party/home-manager/tests/modules/programs/firefox/deprecated-native-messenger.nix b/third_party/home-manager/tests/modules/programs/firefox/deprecated-native-messenger.nix new file mode 100644 index 0000000000..95e9d31827 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/firefox/deprecated-native-messenger.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.firefox = { + enable = true; + enableGnomeExtensions = true; + }; + + nixpkgs.overlays = [ + (self: super: { + firefox-unwrapped = pkgs.runCommandLocal "firefox-0" { + meta.description = "I pretend to be Firefox"; + } '' + mkdir -p "$out/bin" + touch "$out/bin/firefox" + chmod 755 "$out/bin/firefox" + ''; + + chrome-gnome-shell = + pkgs.runCommandLocal "dummy-chrome-gnome-shell" { } '' + mkdir -p $out/lib/mozilla/native-messaging-hosts + touch $out/lib/mozilla/native-messaging-hosts/dummy + ''; + }) + ]; + + test.asserts.warnings.expected = ['' + Using 'programs.firefox.enableGnomeExtensions' has been deprecated and + will be removed in the future. Please change to overriding the package + configuration using 'programs.firefox.package' instead. You can refer to + its example for how to do this. + '']; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/firefox/profile-settings.nix b/third_party/home-manager/tests/modules/programs/firefox/profile-settings.nix index 8c5fb4ec1f..b90fd9192d 100644 --- a/third_party/home-manager/tests/modules/programs/firefox/profile-settings.nix +++ b/third_party/home-manager/tests/modules/programs/firefox/profile-settings.nix @@ -6,7 +6,12 @@ with lib; config = { programs.firefox = { enable = true; - profiles.test.settings = { "general.smoothScroll" = false; }; + profiles.basic.isDefault = true; + + profiles.test = { + id = 1; + settings = { "general.smoothScroll" = false; }; + }; }; nixpkgs.overlays = [ @@ -28,6 +33,8 @@ with lib; home-path/bin/firefox \ MOZ_APP_LAUNCHER + assertDirectoryExists home-files/.mozilla/firefox/basic + assertFileContent \ home-files/.mozilla/firefox/test/user.js \ ${./profile-settings-expected-user.js} diff --git a/third_party/home-manager/tests/modules/programs/foot/default.nix b/third_party/home-manager/tests/modules/programs/foot/default.nix new file mode 100644 index 0000000000..329e0f1f22 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/foot/default.nix @@ -0,0 +1,5 @@ +{ + foot-example-settings = ./example-settings.nix; + foot-empty-settings = ./empty-settings.nix; + foot-systemd-user-service = ./systemd-user-service.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/foot/empty-settings.nix b/third_party/home-manager/tests/modules/programs/foot/empty-settings.nix new file mode 100644 index 0000000000..3935fd9dcd --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/foot/empty-settings.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.foot.enable = true; + + nixpkgs.overlays = + [ (self: super: { foot = pkgs.writeScriptBin "dummy-foot" ""; }) ]; + + nmt.script = '' + assertPathNotExists home-files/.config/foot + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/foot/example-settings-expected.ini b/third_party/home-manager/tests/modules/programs/foot/example-settings-expected.ini new file mode 100644 index 0000000000..f5e12d80b4 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/foot/example-settings-expected.ini @@ -0,0 +1,7 @@ +[main] +dpi-aware=yes +font=Fira Code:size=11 +term=xterm-256color + +[mouse] +hide-when-typing=yes diff --git a/third_party/home-manager/tests/modules/programs/foot/example-settings.nix b/third_party/home-manager/tests/modules/programs/foot/example-settings.nix new file mode 100644 index 0000000000..c230638233 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/foot/example-settings.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.foot = { + enable = true; + package = pkgs.writeShellScriptBin "dummy-foot" ""; + + settings = { + main = { + term = "xterm-256color"; + + font = "Fira Code:size=11"; + dpi-aware = "yes"; + }; + + mouse = { hide-when-typing = "yes"; }; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/foot/foot.ini \ + ${./example-settings-expected.ini} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/foot/systemd-user-service-expected.service b/third_party/home-manager/tests/modules/programs/foot/systemd-user-service-expected.service new file mode 100644 index 0000000000..ff0f8a61b4 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/foot/systemd-user-service-expected.service @@ -0,0 +1,12 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +ExecStart=@foot@/bin/foot --server +Restart=on-failure + +[Unit] +After=graphical-session.target +Description=Fast, lightweight and minimalistic Wayland terminal emulator. +Documentation=man:foot(1) +PartOf=graphical-session.target diff --git a/third_party/home-manager/tests/modules/programs/foot/systemd-user-service.nix b/third_party/home-manager/tests/modules/programs/foot/systemd-user-service.nix new file mode 100644 index 0000000000..1eff14f9fd --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/foot/systemd-user-service.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +let + package = pkgs.writeShellScriptBin "dummy-foot" "" // { outPath = "@foot@"; }; +in { + config = { + programs.foot = { + inherit package; + enable = true; + server.enable = true; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/foot/foot.ini + + assertFileContent \ + home-files/.config/systemd/user/foot.service \ + ${./systemd-user-service-expected.service} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/getmail/getmail-expected.conf b/third_party/home-manager/tests/modules/programs/getmail/getmail-expected.conf index 90dc963e57..a91522a5de 100644 --- a/third_party/home-manager/tests/modules/programs/getmail/getmail-expected.conf +++ b/third_party/home-manager/tests/modules/programs/getmail/getmail-expected.conf @@ -5,7 +5,7 @@ server = imap.example.com port = 993 username = home.manager password_command = ('password-command') -mailboxes = ( 'INBOX', 'Sent', 'Work' ) +mailboxes = ( 'INBOX', 'Sent', 'Work', ) [destination] type = MDA_external diff --git a/third_party/home-manager/tests/modules/programs/getmail/getmail.nix b/third_party/home-manager/tests/modules/programs/getmail/getmail.nix index b0d979c467..c460a37e76 100644 --- a/third_party/home-manager/tests/modules/programs/getmail/getmail.nix +++ b/third_party/home-manager/tests/modules/programs/getmail/getmail.nix @@ -19,10 +19,8 @@ with lib; }; nmt.script = '' - assertFileExists home-files/.getmail/getmailhm@example.com - assertFileContent home-files/.getmail/getmailhm@example.com ${ - ./getmail-expected.conf - } + assertFileExists home-files/.getmail/getmailrc + assertFileContent home-files/.getmail/getmailrc ${./getmail-expected.conf} ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/gh/config-file.nix b/third_party/home-manager/tests/modules/programs/gh/config-file.nix index 0c01869420..71fd74d32e 100644 --- a/third_party/home-manager/tests/modules/programs/gh/config-file.nix +++ b/third_party/home-manager/tests/modules/programs/gh/config-file.nix @@ -8,19 +8,14 @@ editor = "vim"; }; - nixpkgs.overlays = [ - (self: super: { - gitAndTools = super.gitAndTools // { - gh = pkgs.writeScriptBin "dummy-gh" ""; - }; - }) - ]; + nixpkgs.overlays = + [ (self: super: { gh = pkgs.writeScriptBin "dummy-gh" ""; }) ]; nmt.script = '' assertFileExists home-files/.config/gh/config.yml assertFileContent home-files/.config/gh/config.yml ${ builtins.toFile "config-file.yml" '' - {"aliases":{"co":"pr checkout"},"editor":"vim","gitProtocol":"https"}'' + {"aliases":{"co":"pr checkout"},"editor":"vim","git_protocol":"https"}'' } ''; }; diff --git a/third_party/home-manager/tests/modules/programs/git/default.nix b/third_party/home-manager/tests/modules/programs/git/default.nix index 45aface8d2..3d401d8fc2 100644 --- a/third_party/home-manager/tests/modules/programs/git/default.nix +++ b/third_party/home-manager/tests/modules/programs/git/default.nix @@ -1,5 +1,8 @@ { git-with-email = ./git-with-email.nix; git-with-most-options = ./git.nix; + git-with-msmtp = ./git-with-msmtp.nix; git-with-str-extra-config = ./git-with-str-extra-config.nix; + git-with-signing-key-id = ./git-with-signing-key-id.nix; + git-without-signing-key-id = ./git-without-signing-key-id.nix; } diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-email-expected.conf b/third_party/home-manager/tests/modules/programs/git/git-with-email-expected.conf index f48b7c3333..c34ab1d79e 100644 --- a/third_party/home-manager/tests/modules/programs/git/git-with-email-expected.conf +++ b/third_party/home-manager/tests/modules/programs/git/git-with-email-expected.conf @@ -2,12 +2,14 @@ from = "hm@example.org" smtpEncryption = "tls" smtpServer = "smtp.example.org" + smtpSslCertPath = "/etc/test/certificates.crt" smtpUser = "home.manager.jr" [sendemail "hm@example.com"] from = "hm@example.com" smtpEncryption = "ssl" smtpServer = "smtp.example.com" + smtpSslCertPath = "/etc/ssl/certs/ca-certificates.crt" smtpUser = "home.manager" [user] diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-email.nix b/third_party/home-manager/tests/modules/programs/git/git-with-email.nix index d7ed7e185d..ec18ecb92e 100644 --- a/third_party/home-manager/tests/modules/programs/git/git-with-email.nix +++ b/third_party/home-manager/tests/modules/programs/git/git-with-email.nix @@ -6,6 +6,8 @@ with lib; imports = [ ../../accounts/email-test-accounts.nix ]; config = { + accounts.email.accounts.hm-account.smtp.tls.certificatesFile = + "/etc/test/certificates.crt"; programs.git = { enable = true; package = pkgs.gitMinimal; @@ -18,7 +20,7 @@ with lib; nmt.script = '' function assertGitConfig() { local value - value=$(${pkgs.git}/bin/git config \ + value=$(${pkgs.gitMinimal}/bin/git config \ --file $TESTED/home-files/.config/git/config \ --get $1) if [[ $value != $2 ]]; then diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-msmtp-expected.conf b/third_party/home-manager/tests/modules/programs/git/git-with-msmtp-expected.conf new file mode 100644 index 0000000000..1f2c7b794b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/git/git-with-msmtp-expected.conf @@ -0,0 +1,15 @@ +[sendemail "hm-account"] + from = "hm@example.org" + smtpEncryption = "tls" + smtpServer = "smtp.example.org" + smtpSslCertPath = "/etc/ssl/certs/ca-certificates.crt" + smtpUser = "home.manager.jr" + +[sendemail "hm@example.com"] + envelopeSender = "auto" + from = "hm@example.com" + smtpServer = "@msmtp@/bin/msmtp" + +[user] + email = "hm@example.com" + name = "H. M. Test" diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-msmtp.nix b/third_party/home-manager/tests/modules/programs/git/git-with-msmtp.nix new file mode 100644 index 0000000000..abe32af8ec --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/git/git-with-msmtp.nix @@ -0,0 +1,45 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts."hm@example.com".msmtp.enable = true; + programs.git = { + enable = true; + package = pkgs.gitMinimal; + userEmail = "hm@example.com"; + userName = "H. M. Test"; + }; + + home.stateVersion = "20.09"; + + nmt.script = '' + function assertGitConfig() { + local value + value=$(${pkgs.gitMinimal}/bin/git config \ + --file $TESTED/home-files/.config/git/config \ + --get $1) + if [[ $value != $2 ]]; then + fail "Expected option '$1' to have value '$2' but it was '$value'" + fi + } + + assertFileExists home-files/.config/git/config + assertFileContent home-files/.config/git/config \ + ${ + pkgs.substituteAll { + inherit (pkgs) msmtp; + src = ./git-with-msmtp-expected.conf; + } + } + + assertGitConfig "sendemail.hm@example.com.from" "hm@example.com" + assertGitConfig "sendemail.hm-account.from" "hm@example.org" + assertGitConfig "sendemail.hm@example.com.smtpServer" "${pkgs.msmtp}/bin/msmtp" + assertGitConfig "sendemail.hm@example.com.envelopeSender" "auto" + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id-expected.conf b/third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id-expected.conf new file mode 100644 index 0000000000..4a42899020 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id-expected.conf @@ -0,0 +1,10 @@ +[commit] + gpgSign = true + +[gpg] + program = "path-to-gpg" + +[user] + email = "user@example.org" + name = "John Doe" + signingKey = "00112233445566778899AABBCCDDEEFF" diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id.nix b/third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id.nix new file mode 100644 index 0000000000..8d182505fb --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/git/git-with-signing-key-id.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: { + config = { + programs.git = { + enable = true; + userName = "John Doe"; + userEmail = "user@example.org"; + + signing = { + gpgPath = "path-to-gpg"; + key = "00112233445566778899AABBCCDDEEFF"; + signByDefault = true; + }; + }; + + nmt.script = '' + assertFileExists home-files/.config/git/config + assertFileContent home-files/.config/git/config ${ + ./git-with-signing-key-id-expected.conf + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/git/git-with-str-extra-config.nix b/third_party/home-manager/tests/modules/programs/git/git-with-str-extra-config.nix index 3dbc497a5e..b2294c65b2 100644 --- a/third_party/home-manager/tests/modules/programs/git/git-with-str-extra-config.nix +++ b/third_party/home-manager/tests/modules/programs/git/git-with-str-extra-config.nix @@ -14,6 +14,12 @@ with lib; userName = "John Doe"; }; + test.asserts.warnings.expected = ['' + Using programs.git.extraConfig as a string option is + deprecated and will be removed in the future. Please + change to using it as an attribute set instead. + '']; + nmt.script = '' assertFileExists home-files/.config/git/config assertFileContent home-files/.config/git/config \ diff --git a/third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id-expected.conf b/third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id-expected.conf new file mode 100644 index 0000000000..7564b35021 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id-expected.conf @@ -0,0 +1,9 @@ +[commit] + gpgSign = true + +[gpg] + program = "path-to-gpg" + +[user] + email = "user@example.org" + name = "John Doe" diff --git a/third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id.nix b/third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id.nix new file mode 100644 index 0000000000..3428c40d79 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/git/git-without-signing-key-id.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: { + config = { + programs.git = { + enable = true; + userName = "John Doe"; + userEmail = "user@example.org"; + + signing = { + gpgPath = "path-to-gpg"; + key = null; + signByDefault = true; + }; + }; + + nmt.script = '' + assertFileExists home-files/.config/git/config + assertFileContent home-files/.config/git/config ${ + ./git-without-signing-key-id-expected.conf + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/git/git.nix b/third_party/home-manager/tests/modules/programs/git/git.nix index 981d193482..5417f7ea09 100644 --- a/third_party/home-manager/tests/modules/programs/git/git.nix +++ b/third_party/home-manager/tests/modules/programs/git/git.nix @@ -82,10 +82,8 @@ in { nixpkgs.overlays = [ (self: super: { git-lfs = pkgs.writeScriptBin "dummy-git-lfs" ""; - gitAndTools = super.gitAndTools // { - delta = pkgs.writeScriptBin "dummy-delta" "" // { - outPath = "@delta@"; - }; + delta = pkgs.writeScriptBin "dummy-delta" "" // { + outPath = "@delta@"; }; }) ]; diff --git a/third_party/home-manager/tests/modules/programs/gnome-terminal/default.nix b/third_party/home-manager/tests/modules/programs/gnome-terminal/default.nix new file mode 100644 index 0000000000..2cfb492361 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/gnome-terminal/default.nix @@ -0,0 +1 @@ +{ gnome-terminal-1 = ./gnome-terminal-1.nix; } diff --git a/third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.conf b/third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.conf new file mode 100644 index 0000000000..d44376449f --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.conf @@ -0,0 +1,34 @@ +[org/gnome/terminal/legacy] +default-show-menubar=false +schema-version=3 +theme-variant='default' + +[org/gnome/terminal/legacy/profiles:] +default='e0b782ed-6aca-44eb-8c75-62b3706b6220' +list=@as ['e0b782ed-6aca-44eb-8c75-62b3706b6220'] + +[org/gnome/terminal/legacy/profiles:/:e0b782ed-6aca-44eb-8c75-62b3706b6220] +allow-bold=true +audible-bell=true +background-color='#2E3436' +background-transparency-percent=5 +backspace-binding='ascii-delete' +bold-color-same-as-fg=true +bold-is-bright=true +cursor-blink-mode='off' +cursor-colors-set=false +cursor-shape='underline' +delete-binding='delete-sequence' +foreground-color='#D3D7C1' +highlight-colors-set=false +login-shell=false +palette=@as ['#000000','#AA0000','#00AA00','#AA5500','#0000AA','#AA00AA','#00AAAA','#AAAAAA','#555555','#FF5555','#55FF55','#FFFF55','#5555FF','#FF55FF','#55FFFF','#FFFFFF'] +scroll-on-output=false +scrollback-lines=1000000 +scrollbar-policy='never' +use-custom-command=false +use-system-font=true +use-theme-colors=false +use-theme-transparency=false +use-transparent-background=true +visible-name='kamadorueda' diff --git a/third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.nix b/third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.nix new file mode 100644 index 0000000000..44d95cb3b1 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/gnome-terminal/gnome-terminal-1.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + nixpkgs.overlays = [ + (self: super: { + gnome.gnome-terminal = + pkgs.writeScriptBin "dummy-gnome3-gnome-terminal" ""; + }) + ]; + + programs.gnome-terminal = { + enable = true; + profile = { + "e0b782ed-6aca-44eb-8c75-62b3706b6220" = { + allowBold = true; + audibleBell = true; + backspaceBinding = "ascii-delete"; + boldIsBright = true; + colors = { + backgroundColor = "#2E3436"; + foregroundColor = "#D3D7C1"; + palette = [ + "#000000" + "#AA0000" + "#00AA00" + "#AA5500" + "#0000AA" + "#AA00AA" + "#00AAAA" + "#AAAAAA" + "#555555" + "#FF5555" + "#55FF55" + "#FFFF55" + "#5555FF" + "#FF55FF" + "#55FFFF" + "#FFFFFF" + ]; + }; + cursorBlinkMode = "off"; + cursorShape = "underline"; + default = true; + deleteBinding = "delete-sequence"; + scrollbackLines = 1000000; + scrollOnOutput = false; + showScrollbar = false; + transparencyPercent = 5; + visibleName = "kamadorueda"; + }; + }; + showMenubar = false; + }; + + nmt.script = '' + dconfIni=$(grep -oPm 1 '/nix/store/[a-z0-9]*?-hm-dconf.ini' $TESTED/activate) + assertFileContent $dconfIni ${./gnome-terminal-1.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/gpg/override-defaults-expected.conf b/third_party/home-manager/tests/modules/programs/gpg/override-defaults-expected.conf index 3198183f72..4b4f132d00 100644 --- a/third_party/home-manager/tests/modules/programs/gpg/override-defaults-expected.conf +++ b/third_party/home-manager/tests/modules/programs/gpg/override-defaults-expected.conf @@ -14,6 +14,8 @@ require-cross-certification s2k-cipher-algo AES128 s2k-digest-algo SHA512 throw-keyids +trusted-key 0xXXXXXXXXXXXXX +trusted-key 0xYYYYYYYYYYYYY use-agent verify-options show-uid-validity -with-fingerprint \ No newline at end of file +with-fingerprint diff --git a/third_party/home-manager/tests/modules/programs/gpg/override-defaults.nix b/third_party/home-manager/tests/modules/programs/gpg/override-defaults.nix index 850334dc58..3b00e451bc 100644 --- a/third_party/home-manager/tests/modules/programs/gpg/override-defaults.nix +++ b/third_party/home-manager/tests/modules/programs/gpg/override-defaults.nix @@ -11,12 +11,18 @@ with lib; no-comments = false; s2k-cipher-algo = "AES128"; throw-keyids = true; + trusted-key = [ + "0xXXXXXXXXXXXXX" + "0xYYYYYYYYYYYYY" + ]; }; + + homedir = "${config.home.homeDirectory}/bar/foopg"; }; nmt.script = '' - assertFileExists home-files/.gnupg/gpg.conf - assertFileContent home-files/.gnupg/gpg.conf ${./override-defaults-expected.conf} + assertFileExists home-files/bar/foopg/gpg.conf + assertFileContent home-files/bar/foopg/gpg.conf ${./override-defaults-expected.conf} ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/himalaya/default.nix b/third_party/home-manager/tests/modules/programs/himalaya/default.nix new file mode 100644 index 0000000000..54c3978d8a --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/himalaya/default.nix @@ -0,0 +1 @@ +{ himalaya = ./himalaya.nix; } diff --git a/third_party/home-manager/tests/modules/programs/himalaya/himalaya-expected.toml b/third_party/home-manager/tests/modules/programs/himalaya/himalaya-expected.toml new file mode 100644 index 0000000000..db94d42a8a --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/himalaya/himalaya-expected.toml @@ -0,0 +1,18 @@ +downloads-dir = "/data/download" +name = "" + +["hm@example.com"] +default = true +default-page-size = 50 +email = "hm@example.com" +imap-host = "imap.example.com" +imap-login = "home.manager" +imap-passwd-cmd = "'password-command'" +imap-port = 995 +imap-starttls = false +name = "H. M. Test" +smtp-host = "smtp.example.com" +smtp-login = "home.manager" +smtp-passwd-cmd = "'password-command'" +smtp-port = 465 +smtp-starttls = false diff --git a/third_party/home-manager/tests/modules/programs/himalaya/himalaya.nix b/third_party/home-manager/tests/modules/programs/himalaya/himalaya.nix new file mode 100644 index 0000000000..ce5385d14e --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/himalaya/himalaya.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com" = { + himalaya = { + enable = true; + + settings = { default-page-size = 50; }; + }; + + imap.port = 995; + smtp.port = 465; + }; + }; + + programs.himalaya = { + enable = true; + settings = { downloads-dir = "/data/download"; }; + }; + + nixpkgs.overlays = + [ (self: super: { himalaya = pkgs.writeScriptBin "dummy-alot" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/himalaya/config.toml + assertFileContent home-files/.config/himalaya/config.toml ${ + ./himalaya-expected.toml + } + ''; + }; +} + diff --git a/third_party/home-manager/tests/modules/programs/htop/default-settings.nix b/third_party/home-manager/tests/modules/programs/htop/default-settings.nix new file mode 100644 index 0000000000..f67e58276c --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/htop/default-settings.nix @@ -0,0 +1,13 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.htop.enable = true; + + nmt.script = '' + assertFileExists home-files/.config/htop/htoprc + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/htop/default.nix b/third_party/home-manager/tests/modules/programs/htop/default.nix new file mode 100644 index 0000000000..53653285ea --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/htop/default.nix @@ -0,0 +1,4 @@ +{ + htop-default-settings = ./default-settings.nix; + htop-example-settings = ./example-settings.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/htop/example-settings.nix b/third_party/home-manager/tests/modules/programs/htop/example-settings.nix new file mode 100644 index 0000000000..66698c844e --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/htop/example-settings.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.htop.enable = true; + programs.htop.settings = { + color_scheme = 6; + cpu_count_from_one = 0; + delay = 15; + fields = with config.lib.htop.fields; [ + PID + USER + PRIORITY + NICE + M_SIZE + M_RESIDENT + M_SHARE + STATE + PERCENT_CPU + PERCENT_MEM + TIME + COMM + ]; + highlight_base_name = 1; + highlight_megabytes = 1; + highlight_threads = 1; + } // (with config.lib.htop; + leftMeters [ (bar "AllCPUs2") (bar "Memory") (bar "Swap") (text "Zram") ]) + // (with config.lib.htop; + rightMeters [ + (text "Tasks") + (text "LoadAverage") + (text "Uptime") + (text "Systemd") + ]); + + nmt.script = '' + assertFileExists home-files/.config/htop/htoprc + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/i3status-rust/default.nix b/third_party/home-manager/tests/modules/programs/i3status-rust/default.nix new file mode 100644 index 0000000000..50d8c7b853 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/i3status-rust/default.nix @@ -0,0 +1,6 @@ +{ + i3status-rust-with-default = ./with-default.nix; + i3status-rust-with-custom = ./with-custom.nix; + i3status-rust-with-extra-settings = ./with-extra-settings.nix; + i3status-rust-with-multiple-bars = ./with-multiple-bars.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/i3status-rust/with-custom.nix b/third_party/home-manager/tests/modules/programs/i3status-rust/with-custom.nix new file mode 100644 index 0000000000..4ced6add57 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/i3status-rust/with-custom.nix @@ -0,0 +1,186 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.i3status-rust = { + enable = true; + bars = { + custom = { + blocks = [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "memory"; + display_type = "memory"; + format_mem = "{Mug}GB ({Mup}%)"; + format_swap = "{SUp}%"; + } + { + block = "cpu"; + interval = 1; + format = "{barchart}"; + } + { + block = "load"; + interval = 1; + format = "{1m} {5m}"; + } + { + block = "temperature"; + collapsed = true; + interval = 10; + format = "{min}° min, {max}° max, {average}° avg"; + chip = "*-isa-*"; + } + { + block = "networkmanager"; + ap_format = "{ssid} @ {strength}%"; + on_click = "kcmshell5 kcm_networkmanagement"; + } + { + block = "net"; + device = "enp9s0u2u1u2c2"; + speed_up = true; + interval = 5; + } + { + block = "speedtest"; + bytes = true; + } + { + block = "xrandr"; + interval = + 6000; # Because running the commands causes screen lag, see https://github.com/greshake/i3status-rust/issues/668 + } + { + block = "sound"; + format = "{output_name} {volume}%"; + on_click = "pavucontrol --tab=3"; + mappings = { + "alsa_output.pci-0000_00_1f.3.analog-stereo" = ""; + "bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = ""; + }; + } + { + block = "music"; + player = "spotify"; + buttons = [ "play" "prev" "next" ]; + on_collapsed_click = "i3-msg '[class=Spotify] focus'"; + } + { + block = "time"; + interval = 60; + format = "%a %d.%m %R"; + } + { block = "battery"; } + ]; + + icons = "awesome5"; + + theme = "gruvbox-dark"; + }; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + i3status-rust = pkgs.writeScriptBin "dummy-i3status-rust" ""; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/i3status-rust/config-custom.toml + assertFileContent home-files/.config/i3status-rust/config-custom.toml \ + ${ + pkgs.writeText "i3status-rust-expected-config" '' + icons = "awesome5" + theme = "gruvbox-dark" + [[block]] + alert = 10 + alias = "/" + block = "disk_space" + info_type = "available" + interval = 60 + path = "/" + unit = "GB" + warning = 20 + + [[block]] + block = "memory" + display_type = "memory" + format_mem = "{Mug}GB ({Mup}%)" + format_swap = "{SUp}%" + + [[block]] + block = "cpu" + format = "{barchart}" + interval = 1 + + [[block]] + block = "load" + format = "{1m} {5m}" + interval = 1 + + [[block]] + block = "temperature" + chip = "*-isa-*" + collapsed = true + format = "{min}° min, {max}° max, {average}° avg" + interval = 10 + + [[block]] + ap_format = "{ssid} @ {strength}%" + block = "networkmanager" + on_click = "kcmshell5 kcm_networkmanagement" + + [[block]] + block = "net" + device = "enp9s0u2u1u2c2" + interval = 5 + speed_up = true + + [[block]] + block = "speedtest" + bytes = true + + [[block]] + block = "xrandr" + interval = 6000 + + [[block]] + block = "sound" + format = "{output_name} {volume}%" + on_click = "pavucontrol --tab=3" + + [block.mappings] + "alsa_output.pci-0000_00_1f.3.analog-stereo" = "" + "bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = "" + + [[block]] + block = "music" + buttons = ["play", "prev", "next"] + on_collapsed_click = "i3-msg '[class=Spotify] focus'" + player = "spotify" + + [[block]] + block = "time" + format = "%a %d.%m %R" + interval = 60 + + [[block]] + block = "battery" + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/i3status-rust/with-default.nix b/third_party/home-manager/tests/modules/programs/i3status-rust/with-default.nix new file mode 100644 index 0000000000..b62c248c8a --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/i3status-rust/with-default.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.i3status-rust = { enable = true; }; + + nixpkgs.overlays = [ + (self: super: { + i3status-rust = pkgs.writeScriptBin "dummy-i3status-rust" ""; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/i3status-rust/config-default.toml + assertFileContent home-files/.config/i3status-rust/config-default.toml \ + ${ + pkgs.writeText "i3status-rust-expected-config" '' + icons = "none" + theme = "plain" + [[block]] + alert = 10 + alias = "/" + block = "disk_space" + info_type = "available" + interval = 60 + path = "/" + unit = "GB" + warning = 20 + + [[block]] + block = "memory" + display_type = "memory" + format_mem = "{Mup}%" + format_swap = "{SUp}%" + + [[block]] + block = "cpu" + interval = 1 + + [[block]] + block = "load" + format = "{1m}" + interval = 1 + + [[block]] + block = "sound" + + [[block]] + block = "time" + format = "%a %d/%m %R" + interval = 60 + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/i3status-rust/with-extra-settings.nix b/third_party/home-manager/tests/modules/programs/i3status-rust/with-extra-settings.nix new file mode 100644 index 0000000000..16f3428a0f --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/i3status-rust/with-extra-settings.nix @@ -0,0 +1,202 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.i3status-rust = { + enable = true; + bars = { + extra-settings = { + blocks = [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "memory"; + display_type = "memory"; + format_mem = "{Mug}GB ({Mup}%)"; + format_swap = "{SUp}%"; + } + { + block = "cpu"; + interval = 1; + format = "{barchart}"; + } + { + block = "load"; + interval = 1; + format = "{1m} {5m}"; + } + { + block = "temperature"; + collapsed = true; + interval = 10; + format = "{min}° min, {max}° max, {average}° avg"; + chip = "*-isa-*"; + } + { + block = "networkmanager"; + ap_format = "{ssid} @ {strength}%"; + on_click = "kcmshell5 kcm_networkmanagement"; + } + { + block = "net"; + device = "enp9s0u2u1u2c2"; + speed_up = true; + interval = 5; + } + { + block = "speedtest"; + bytes = true; + } + { + block = "xrandr"; + interval = + 6000; # Because running the commands causes screen lag, see https://github.com/greshake/i3status-rust/issues/668 + } + { + block = "sound"; + format = "{output_name} {volume}%"; + on_click = "pavucontrol --tab=3"; + mappings = { + "alsa_output.pci-0000_00_1f.3.analog-stereo" = ""; + "bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = ""; + }; + } + { + block = "music"; + player = "spotify"; + buttons = [ "play" "prev" "next" ]; + on_collapsed_click = "i3-msg '[class=Spotify] focus'"; + } + { + block = "time"; + interval = 60; + format = "%a %d.%m %R"; + } + { block = "battery"; } + ]; + + icons = "awesome5"; + + settings = { + theme = { + name = "solarized-dark"; + overrides = { + idle_bg = "#123456"; + idle_fg = "#abcdef"; + }; + }; + }; + + theme = "gruvbox-dark"; + }; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + i3status-rust = pkgs.writeScriptBin "dummy-i3status-rust" ""; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/i3status-rust/config-extra-settings.toml + assertFileContent home-files/.config/i3status-rust/config-extra-settings.toml \ + ${ + pkgs.writeText "i3status-rust-expected-config" '' + icons = "awesome5" + [[block]] + alert = 10 + alias = "/" + block = "disk_space" + info_type = "available" + interval = 60 + path = "/" + unit = "GB" + warning = 20 + + [[block]] + block = "memory" + display_type = "memory" + format_mem = "{Mug}GB ({Mup}%)" + format_swap = "{SUp}%" + + [[block]] + block = "cpu" + format = "{barchart}" + interval = 1 + + [[block]] + block = "load" + format = "{1m} {5m}" + interval = 1 + + [[block]] + block = "temperature" + chip = "*-isa-*" + collapsed = true + format = "{min}° min, {max}° max, {average}° avg" + interval = 10 + + [[block]] + ap_format = "{ssid} @ {strength}%" + block = "networkmanager" + on_click = "kcmshell5 kcm_networkmanagement" + + [[block]] + block = "net" + device = "enp9s0u2u1u2c2" + interval = 5 + speed_up = true + + [[block]] + block = "speedtest" + bytes = true + + [[block]] + block = "xrandr" + interval = 6000 + + [[block]] + block = "sound" + format = "{output_name} {volume}%" + on_click = "pavucontrol --tab=3" + + [block.mappings] + "alsa_output.pci-0000_00_1f.3.analog-stereo" = "" + "bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = "" + + [[block]] + block = "music" + buttons = ["play", "prev", "next"] + on_collapsed_click = "i3-msg '[class=Spotify] focus'" + player = "spotify" + + [[block]] + block = "time" + format = "%a %d.%m %R" + interval = 60 + + [[block]] + block = "battery" + + [theme] + name = "solarized-dark" + + [theme.overrides] + idle_bg = "#123456" + idle_fg = "#abcdef" + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/i3status-rust/with-multiple-bars.nix b/third_party/home-manager/tests/modules/programs/i3status-rust/with-multiple-bars.nix new file mode 100644 index 0000000000..9cbbe2854a --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/i3status-rust/with-multiple-bars.nix @@ -0,0 +1,106 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.i3status-rust = { + enable = true; + + bars = { + + top = { + blocks = [ + { + block = "disk_space"; + path = "/"; + alias = "/"; + info_type = "available"; + unit = "GB"; + interval = 60; + warning = 20.0; + alert = 10.0; + } + { + block = "memory"; + display_type = "memory"; + format_mem = "{Mug}GB ({Mup}%)"; + format_swap = "{SUp}%"; + } + ]; + }; + + bottom = { + blocks = [ + { + block = "cpu"; + interval = 1; + format = "{barchart}"; + } + { + block = "load"; + interval = 1; + format = "{1m} {5m}"; + } + ]; + icons = "awesome5"; + + theme = "gruvbox-dark"; + }; + + }; + + }; + + nixpkgs.overlays = [ + (self: super: { + i3status-rust = pkgs.writeScriptBin "dummy-i3status-rust" ""; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/i3status-rust/config-top.toml + assertFileContent home-files/.config/i3status-rust/config-top.toml \ + ${ + pkgs.writeText "i3status-rust-expected-config" '' + icons = "none" + theme = "plain" + [[block]] + alert = 10 + alias = "/" + block = "disk_space" + info_type = "available" + interval = 60 + path = "/" + unit = "GB" + warning = 20 + + [[block]] + block = "memory" + display_type = "memory" + format_mem = "{Mug}GB ({Mup}%)" + format_swap = "{SUp}%" + '' + } + + assertFileExists home-files/.config/i3status-rust/config-bottom.toml + assertFileContent \ + home-files/.config/i3status-rust/config-bottom.toml \ + ${ + pkgs.writeText "i3status-rust-expected-config" '' + icons = "awesome5" + theme = "gruvbox-dark" + [[block]] + block = "cpu" + format = "{barchart}" + interval = 1 + + [[block]] + block = "load" + format = "{1m} {5m}" + interval = 1 + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/irsii/default.nix b/third_party/home-manager/tests/modules/programs/irsii/default.nix new file mode 100644 index 0000000000..ff8fe12a7c --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/irsii/default.nix @@ -0,0 +1 @@ +{ irsii-example-settings = ./example-settings.nix; } diff --git a/third_party/home-manager/tests/modules/programs/irsii/example-settings-expected.config b/third_party/home-manager/tests/modules/programs/irsii/example-settings-expected.config new file mode 100644 index 0000000000..8c54243bc3 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/irsii/example-settings-expected.config @@ -0,0 +1,43 @@ +settings = { + core = { + settings_autosave = "no"; + }; +}; + +aliases = { + +}; + +chatnets = { +oftc = { + type = "IRC"; + nick = "nick"; + autosendcmd = ""; +}; + +}; + +servers = ( +{ + chatnet = "oftc"; + address = "irc.oftc.net"; + port = "6697"; + use_ssl = "yes"; + ssl_verify = "yes"; + autoconnect = "yes"; + ssl_cert = "/home/hm-user/.irssi/certs/nick.pem"; + +} + +); + +channels = ( +{ + chatnet = "oftc"; + name = "home-manager"; + autojoin = "yes"; +} + +); + + diff --git a/third_party/home-manager/tests/modules/programs/irsii/example-settings.nix b/third_party/home-manager/tests/modules/programs/irsii/example-settings.nix new file mode 100644 index 0000000000..d7b9ff1e67 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/irsii/example-settings.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.irssi = { + enable = true; + networks.oftc = { + nick = "nick"; + server = { + address = "irc.oftc.net"; + port = 6697; + autoConnect = true; + ssl.certificateFile = + "${config.home.homeDirectory}/.irssi/certs/nick.pem"; + }; + channels.home-manager.autoJoin = true; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.irssi/config \ + ${./example-settings-expected.config} + ''; + + nixpkgs.overlays = + [ (self: super: { irsii = pkgs.writeScriptBin "dummy-irsii" ""; }) ]; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/kakoune/default.nix b/third_party/home-manager/tests/modules/programs/kakoune/default.nix index 1e6e077df1..cb9f05afda 100644 --- a/third_party/home-manager/tests/modules/programs/kakoune/default.nix +++ b/third_party/home-manager/tests/modules/programs/kakoune/default.nix @@ -1,6 +1,8 @@ { kakoune-no-plugins = ./no-plugins.nix; - kakoune-use-plugins = ./use-plugins.nix; + # Temporarily disabled until https://github.com/NixOS/nixpkgs/pull/110196 + # reaches the unstable channel. + # kakoune-use-plugins = ./use-plugins.nix; kakoune-whitespace-highlighter = ./whitespace-highlighter.nix; kakoune-whitespace-highlighter-corner-cases = ./whitespace-highlighter-corner-cases.nix; diff --git a/third_party/home-manager/tests/modules/programs/kakoune/no-plugins.nix b/third_party/home-manager/tests/modules/programs/kakoune/no-plugins.nix index 76dea5440a..67a7f30f52 100644 --- a/third_party/home-manager/tests/modules/programs/kakoune/no-plugins.nix +++ b/third_party/home-manager/tests/modules/programs/kakoune/no-plugins.nix @@ -7,7 +7,7 @@ with lib; programs.kakoune = { enable = true; }; nmt.script = '' - assertFileNotRegex home-path/share/kak/plugins.kak . # file is empty + assertPathNotExists home-path/share/kak/autoload/plugins ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/kakoune/use-plugins.nix b/third_party/home-manager/tests/modules/programs/kakoune/use-plugins.nix index 7b23627dbb..9d44483276 100644 --- a/third_party/home-manager/tests/modules/programs/kakoune/use-plugins.nix +++ b/third_party/home-manager/tests/modules/programs/kakoune/use-plugins.nix @@ -6,13 +6,11 @@ with lib; config = { programs.kakoune = { enable = true; - plugins = [ pkgs.kakounePlugins.kak-powerline ]; + plugins = [ pkgs.kakounePlugins.kak-prelude ]; }; - nmt.script = let plugins_kak = "home-path/share/kak/plugins.kak"; - in '' - assertFileRegex ${plugins_kak} \ - '^source "/nix/store/.*-kak-powerline/share/kak/autoload/plugins/powerline/.*.kak"$' + nmt.script = '' + assertDirectoryNotEmpty home-path/share/kak/autoload/plugins ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/kitty/default.nix b/third_party/home-manager/tests/modules/programs/kitty/default.nix new file mode 100644 index 0000000000..694c43cd87 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/kitty/default.nix @@ -0,0 +1 @@ +{ kitty-example-settings = ./example-settings.nix; } diff --git a/third_party/home-manager/tests/modules/programs/kitty/example-settings-expected.conf b/third_party/home-manager/tests/modules/programs/kitty/example-settings-expected.conf new file mode 100644 index 0000000000..23cd3a85a8 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/kitty/example-settings-expected.conf @@ -0,0 +1,17 @@ +# Generated by Home Manager. +# See https://sw.kovidgoyal.net/kitty/conf.html + +font_family DejaVu Sans +font_size 8 + + +enable_audio_bell no +scrollback_lines 10000 +update_check_interval 0 + + +map ctrl+c copy_or_interrupt +map ctrl+f>2 set_font_size 20 + + + diff --git a/third_party/home-manager/tests/modules/programs/kitty/example-settings.nix b/third_party/home-manager/tests/modules/programs/kitty/example-settings.nix new file mode 100644 index 0000000000..8b5c0c330b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/kitty/example-settings.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.kitty = { + enable = true; + settings = { + scrollback_lines = 10000; + enable_audio_bell = false; + update_check_interval = 0; + }; + + font.name = "DejaVu Sans"; + font.size = 8; + + keybindings = { + "ctrl+c" = "copy_or_interrupt"; + "ctrl+f>2" = "set_font_size 20"; + }; + }; + + nixpkgs.overlays = + [ (self: super: { kitty = pkgs.writeScriptBin "dummy-kitty" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/kitty/kitty.conf + assertFileContent \ + home-files/.config/kitty/kitty.conf \ + ${./example-settings-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/lieer/lieer.nix b/third_party/home-manager/tests/modules/programs/lieer/lieer.nix index 2ce4fb4e03..c5771b67d0 100644 --- a/third_party/home-manager/tests/modules/programs/lieer/lieer.nix +++ b/third_party/home-manager/tests/modules/programs/lieer/lieer.nix @@ -8,7 +8,11 @@ with lib; config = { programs.lieer.enable = true; - accounts.email.accounts = { "hm@example.com".lieer.enable = true; }; + accounts.email.accounts."hm@example.com" = { + flavor = "gmail.com"; + lieer.enable = true; + notmuch.enable = true; + }; nixpkgs.overlays = [ (self: super: { gmailieer = pkgs.writeScriptBin "dummy-gmailieer" ""; }) diff --git a/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration-mpv.conf b/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration-mpv.conf new file mode 100644 index 0000000000..9cf2f34ef8 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration-mpv.conf @@ -0,0 +1,2 @@ +no_display +output_folder=/home/user/Documents/mpv-mangohud diff --git a/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.conf b/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.conf new file mode 100644 index 0000000000..8ded2dbc01 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.conf @@ -0,0 +1,13 @@ +cpu_load_change +cpu_load_value +cpu_mhz +cpu_power +cpu_stats +cpu_temp +cpu_text=CPU +fps_limit=30,60 +legacy_layout=false +media_player_name=spotify +media_player_order=title,artist,album +output_folder=/home/user/Documents/mangohud +vsync=0 diff --git a/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.nix b/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.nix new file mode 100644 index 0000000000..7ff4a89018 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mangohud/basic-configuration.nix @@ -0,0 +1,40 @@ +{ config, pkgs, ... }: + +{ + config = { + programs.mangohud = { + enable = true; + package = pkgs.writeScriptBin "dummy-mangohud" ""; + settings = { + output_folder = /home/user/Documents/mangohud; + fps_limit = [ 30 60 ]; + vsync = 0; + legacy_layout = false; + cpu_stats = true; + cpu_temp = true; + cpu_power = true; + cpu_text = "CPU"; + cpu_mhz = true; + cpu_load_change = true; + cpu_load_value = true; + media_player_name = "spotify"; + media_player_order = [ "title" "artist" "album" ]; + }; + settingsPerApplication = { + mpv = { + output_folder = /home/user/Documents/mpv-mangohud; + no_display = true; + }; + }; + }; + + nmt.script = '' + assertFileExists home-files/.config/MangoHud/MangoHud.conf + assertFileContent home-files/.config/MangoHud/MangoHud.conf \ + ${./basic-configuration.conf} + assertFileExists home-files/.config/MangoHud/mpv.conf + assertFileContent home-files/.config/MangoHud/mpv.conf \ + ${./basic-configuration-mpv.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/mangohud/default.nix b/third_party/home-manager/tests/modules/programs/mangohud/default.nix new file mode 100644 index 0000000000..87db32ed7b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mangohud/default.nix @@ -0,0 +1 @@ +{ mangohud-basic-configuration = ./basic-configuration.nix; } diff --git a/third_party/home-manager/tests/modules/programs/mbsync/mbsync-expected.conf b/third_party/home-manager/tests/modules/programs/mbsync/mbsync-expected.conf index 6722960476..c1ca921ac1 100644 --- a/third_party/home-manager/tests/modules/programs/mbsync/mbsync-expected.conf +++ b/third_party/home-manager/tests/modules/programs/mbsync/mbsync-expected.conf @@ -16,30 +16,30 @@ Path /home/hm-user/Mail/hm-account/ SubFolders Verbatim Channel emptyChannels-empty1 -Master :hm-account-remote: -Slave :hm-account-local: +Far :hm-account-remote: +Near :hm-account-local: Channel emptyChannels-empty2 -Master :hm-account-remote: -Slave :hm-account-local: +Far :hm-account-remote: +Near :hm-account-local: Channel hm-account-earlierPatternMatch -Master :hm-account-remote:Label -Slave :hm-account-local:SomethingUnderLabel +Far :hm-account-remote:Label +Near :hm-account-local:SomethingUnderLabel Pattern ThingUnderLabel !NotThisMaildirThough "[Weird] Label?" Channel hm-account-inbox -Master :hm-account-remote:Inbox -Slave :hm-account-local:Inbox +Far :hm-account-remote:Inbox +Near :hm-account-local:Inbox Channel hm-account-patternMatch -Master :hm-account-remote:Label -Slave :hm-account-local:SomethingUnderLabel +Far :hm-account-remote:Label +Near :hm-account-local:SomethingUnderLabel Pattern ThingUnderLabel !NotThisMaildirThough "[Weird] Label?" Channel hm-account-strangeHostBoxName -Master ":hm-account-remote:[Weird]/Label Mess" -Slave :hm-account-local:[AnotherWeird]/Label +Far ":hm-account-remote:[Weird]/Label Mess" +Near :hm-account-local:[AnotherWeird]/Label Group emptyChannels Channel emptyChannels-empty1 @@ -68,12 +68,12 @@ Path /home/hm-user/Mail/hm@example.com/ SubFolders Verbatim Channel inboxes-inbox1 -Master :hm@example.com-remote:Inbox1 -Slave :hm@example.com-local:Inboxes +Far :hm@example.com-remote:Inbox1 +Near :hm@example.com-local:Inboxes Channel inboxes-inbox2 -Master :hm@example.com-remote:Inbox2 -Slave :hm@example.com-local:Inboxes +Far :hm@example.com-remote:Inbox2 +Near :hm@example.com-local:Inboxes Group inboxes Channel inboxes-inbox1 diff --git a/third_party/home-manager/tests/modules/programs/mbsync/mbsync-master-slave-change.nix b/third_party/home-manager/tests/modules/programs/mbsync/mbsync-master-slave-change.nix new file mode 100644 index 0000000000..96f02d9068 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mbsync/mbsync-master-slave-change.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + test.asserts.warnings.expected = [ + "mbsync channels no longer use masterPattern. Use farPattern in its place." + "mbsync channels no longer use slavePattern. Use nearPattern in its place." + ]; + + config = { + programs.mbsync = { + enable = true; + # 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. + groups.inboxes = { + "hm@example.com" = [ "Inbox1" "Inbox2" ]; + hm-account = [ "Inbox" ]; + }; + }; + + accounts.email.accounts = { + "hm@example.com".mbsync = { + enable = true; + groups.inboxes = { + channels = { + inbox1 = { + farPattern = "Inbox1"; + nearPattern = "Inboxes"; + }; + inbox2 = { + farPattern = "Inbox2"; + nearPattern = "Inboxes"; + }; + }; + }; + }; + + hm-account.mbsync = { + enable = true; + groups.hm-account = { + channels.earlierPatternMatch = { + farPattern = "Label"; + nearPattern = "SomethingUnderLabel"; + patterns = [ + "ThingUnderLabel" + "!NotThisMaildirThough" + ''"[Weird] Label?"'' + ]; + }; + channels.inbox = { + farPattern = "Inbox"; + nearPattern = "Inbox"; + }; + channels.strangeHostBoxName = { + farPattern = "[Weird]/Label Mess"; + nearPattern = "[AnotherWeird]/Label"; + }; + channels.patternMatch = { + farPattern = "Label"; + nearPattern = "SomethingUnderLabel"; + patterns = [ + "ThingUnderLabel" + "!NotThisMaildirThough" + ''"[Weird] Label?"'' + ]; + }; + }; + # No group should be printed. + groups.emptyGroup = { }; + # Group should be printed, but left with default channels. + groups.emptyChannels = { + channels.empty1 = { }; + channels.empty2 = { }; + }; + }; + }; + + test.asserts.warnings.expected = [ + "mbsync channels no longer use masterPattern. use farPattern in its place." + "mbsync channels no longer use slavePattern. Use nearPattern in its place." + ]; + + nmt.script = '' + assertFileExists home-files/.mbsyncrc + assertFileContent home-files/.mbsyncrc ${./mbsync-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/mbsync/mbsync.nix b/third_party/home-manager/tests/modules/programs/mbsync/mbsync.nix index a6e555cd4c..d80421d6da 100644 --- a/third_party/home-manager/tests/modules/programs/mbsync/mbsync.nix +++ b/third_party/home-manager/tests/modules/programs/mbsync/mbsync.nix @@ -24,12 +24,12 @@ with lib; groups.inboxes = { channels = { inbox1 = { - masterPattern = "Inbox1"; - slavePattern = "Inboxes"; + farPattern = "Inbox1"; + nearPattern = "Inboxes"; }; inbox2 = { - masterPattern = "Inbox2"; - slavePattern = "Inboxes"; + farPattern = "Inbox2"; + nearPattern = "Inboxes"; }; }; }; @@ -39,8 +39,8 @@ with lib; enable = true; groups.hm-account = { channels.earlierPatternMatch = { - masterPattern = "Label"; - slavePattern = "SomethingUnderLabel"; + farPattern = "Label"; + nearPattern = "SomethingUnderLabel"; patterns = [ "ThingUnderLabel" "!NotThisMaildirThough" @@ -48,16 +48,16 @@ with lib; ]; }; channels.inbox = { - masterPattern = "Inbox"; - slavePattern = "Inbox"; + farPattern = "Inbox"; + nearPattern = "Inbox"; }; channels.strangeHostBoxName = { - masterPattern = "[Weird]/Label Mess"; - slavePattern = "[AnotherWeird]/Label"; + farPattern = "[Weird]/Label Mess"; + nearPattern = "[AnotherWeird]/Label"; }; channels.patternMatch = { - masterPattern = "Label"; - slavePattern = "SomethingUnderLabel"; + farPattern = "Label"; + nearPattern = "SomethingUnderLabel"; patterns = [ "ThingUnderLabel" "!NotThisMaildirThough" diff --git a/third_party/home-manager/tests/modules/programs/mpv/default.nix b/third_party/home-manager/tests/modules/programs/mpv/default.nix new file mode 100644 index 0000000000..c2785ed3ea --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mpv/default.nix @@ -0,0 +1,4 @@ +{ + mpv-example-settings = ./mpv-example-settings.nix; + mpv-invalid-settings = ./mpv-invalid-settings.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-bindings b/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-bindings new file mode 100644 index 0000000000..7a2ee13b03 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-bindings @@ -0,0 +1,3 @@ +Alt+0 set window-scale 0.5 +WHEEL_DOWN seek -10 +WHEEL_UP seek 10 \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-config b/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-config new file mode 100644 index 0000000000..e44239096a --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings-expected-config @@ -0,0 +1,13 @@ +profile=%6%gpu-hq + +cache-default=%7%4000000 +force-window=%3%yes +ytdl-format=%19%bestvideo+bestaudio + +[fast] +vo=%5%vdpau + +[protocol.dvd] +alang=%2%en +profile-desc=%26%profile for dvd:// streams + diff --git a/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings.nix b/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings.nix new file mode 100644 index 0000000000..5701d9eaba --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mpv/mpv-example-settings.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + programs.mpv = { + enable = true; + package = pkgs.mpvDummy; + + bindings = { + WHEEL_UP = "seek 10"; + WHEEL_DOWN = "seek -10"; + "Alt+0" = "set window-scale 0.5"; + }; + + config = { + force-window = true; + ytdl-format = "bestvideo+bestaudio"; + cache-default = 4000000; + }; + + profiles = { + fast = { vo = "vdpau"; }; + "protocol.dvd" = { + profile-desc = "profile for dvd:// streams"; + alang = "en"; + }; + }; + + defaultProfiles = [ "gpu-hq" ]; + }; + + nixpkgs.overlays = [ + (self: super: { mpvDummy = pkgs.runCommandLocal "mpv" { } "mkdir $out"; }) + ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/mpv/mpv.conf \ + ${./mpv-example-settings-expected-config} + assertFileContent \ + home-files/.config/mpv/input.conf \ + ${./mpv-example-settings-expected-bindings} + ''; + }; + +} diff --git a/third_party/home-manager/tests/modules/programs/mpv/mpv-invalid-settings.nix b/third_party/home-manager/tests/modules/programs/mpv/mpv-invalid-settings.nix new file mode 100644 index 0000000000..f7fd390a98 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/mpv/mpv-invalid-settings.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + programs.mpv = { + enable = true; + package = pkgs.mpvDummy; + scripts = [ pkgs.mpvScript ]; + }; + + nixpkgs.overlays = [ + (self: super: { + mpv-unwrapped = pkgs.runCommandLocal "mpv" { + version = "0"; + passthru = { + lua.luaversion = "0"; + luaEnv = "/dummy"; + vapoursynthSupport = false; + }; + } '' + mkdir -p $out/bin $out/Applications/mpv.app/Contents/MacOS + touch $out/bin/{,u}mpv $out/Applications/mpv.app/Contents/MacOS/mpv + chmod 755 $out/bin/{,u}mpv $out/Applications/mpv.app/Contents/MacOS/mpv + ''; + mpvDummy = pkgs.runCommandLocal "mpv" { } "mkdir $out"; + mpvScript = + pkgs.runCommandLocal "mpvScript" { scriptName = "something"; } + "mkdir $out"; + }) + ]; + + test.asserts.assertions.expected = [ + '' + The programs.mpv "package" option is mutually exclusive with "scripts" option.'' + ]; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/default.nix b/third_party/home-manager/tests/modules/programs/neomutt/default.nix index aef9f37e02..d24813545c 100644 --- a/third_party/home-manager/tests/modules/programs/neomutt/default.nix +++ b/third_party/home-manager/tests/modules/programs/neomutt/default.nix @@ -1,4 +1,11 @@ { neomutt-simple = ./neomutt.nix; neomutt-with-msmtp = ./neomutt-with-msmtp.nix; + neomutt-not-primary = ./neomutt-not-primary.nix; + neomutt-with-binds = ./neomutt-with-binds.nix; + neomutt-with-binds-with-warning = ./neomutt-with-binds-with-warning.nix; + neomutt-with-binds-invalid-settings = + ./neomutt-with-binds-invalid-settings.nix; + neomutt-with-gpg = ./neomutt-with-gpg.nix; + neomutt-no-folder-change = ./neomutt-no-folder-change.nix; } diff --git a/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-expected b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-expected index fceae5dc1f..6c96f61f41 100644 --- a/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-expected +++ b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-expected @@ -5,12 +5,13 @@ set certificate_file=/etc/ssl/certs/ca-certificates.crt # GPG section set crypt_use_gpgme = yes set crypt_autosign = no +set crypt_opportunistic_encrypt = no set pgp_use_gpg_agent = yes set mbox_type = Maildir set sort = "threads" # MTA section -set smtp_pass='`password-command`' +set smtp_pass="`password-command`" set smtp_url='smtps://home.manager@smtp.example.com' diff --git a/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-gpg-expected.conf b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-gpg-expected.conf new file mode 100644 index 0000000000..f7763dbe66 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-gpg-expected.conf @@ -0,0 +1,32 @@ +# Generated by Home Manager. +set ssl_force_tls = yes +set certificate_file=/etc/ssl/certs/ca-certificates.crt + +# GPG section +set crypt_use_gpgme = yes +set crypt_autosign = yes +set crypt_opportunistic_encrypt = yes +set pgp_use_gpg_agent = yes +set mbox_type = Maildir +set sort = "threads" + +# MTA section +set smtp_pass="`password-command`" +set smtp_url='smtps://home.manager@smtp.example.com' + + + + + +# MRA section +set folder='/home/hm-user/Mail/hm@example.com' +set from='hm@example.com' +set postponed='+Drafts' +set realname='H. M. Test' +set record='+Sent' +set spoolfile='+Inbox' +set trash='+Trash' + + +# Extra configuration + diff --git a/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-msmtp-expected.conf b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-msmtp-expected.conf index 925c70636a..d2e2f3eeec 100644 --- a/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-msmtp-expected.conf +++ b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-msmtp-expected.conf @@ -5,6 +5,7 @@ set certificate_file=/etc/ssl/certs/ca-certificates.crt # GPG section set crypt_use_gpgme = yes set crypt_autosign = no +set crypt_opportunistic_encrypt = no set pgp_use_gpg_agent = yes set mbox_type = Maildir set sort = "threads" diff --git a/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-no-folder-change-expected.conf b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-no-folder-change-expected.conf new file mode 100644 index 0000000000..03ea3b31af --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/hm-example.com-no-folder-change-expected.conf @@ -0,0 +1,30 @@ +# Generated by Home Manager. +set ssl_force_tls = yes +set certificate_file=/etc/ssl/certs/ca-certificates.crt + +# GPG section +set crypt_use_gpgme = yes +set crypt_autosign = no +set crypt_opportunistic_encrypt = no +set pgp_use_gpg_agent = yes +set mbox_type = Maildir +set sort = "threads" + +# MTA section +set sendmail='msmtpq --read-envelope-from --read-recipients' + + + + + +# MRA section +set from='hm@example.com' +set postponed='+Drafts' +set realname='H. M. Test' +set record='+Sent' +set spoolfile='+Inbox' +set trash='+Trash' + + +# Extra configuration + diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-expected.conf b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-expected.conf index 7711aa5a65..6d51da816f 100644 --- a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-expected.conf +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-expected.conf @@ -16,12 +16,17 @@ set delete = yes -# Extra configuration - - - +# Register accounts # register account hm@example.com mailboxes "/home/hm-user/Mail/hm@example.com/Inbox" folder-hook /home/hm-user/Mail/hm@example.com/ " \ source /home/hm-user/.config/neomutt/hm@example.com " -source /home/hm-user/.config/neomutt/hm@example.com \ No newline at end of file + + +# Source primary account +source /home/hm-user/.config/neomutt/hm@example.com + +# Extra configuration + + + diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-no-folder-change.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-no-folder-change.nix new file mode 100644 index 0000000000..db7246604f --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-no-folder-change.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com" = { + msmtp.enable = true; + neomutt.enable = true; + imap.port = 993; + }; + }; + + programs.neomutt.enable = true; + programs.neomutt.changeFolderWhenSourcingAccount = false; + + nixpkgs.overlays = + [ (self: super: { neomutt = pkgs.writeScriptBin "dummy-neomutt" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/neomutt/hm@example.com + assertFileContent home-files/.config/neomutt/hm@example.com ${ + ./hm-example.com-no-folder-change-expected.conf + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary-expected.conf b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary-expected.conf new file mode 100644 index 0000000000..ed64124d99 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary-expected.conf @@ -0,0 +1,32 @@ +# Generated by Home Manager. +set header_cache = "/home/hm-user/.cache/neomutt/headers/" +set message_cachedir = "/home/hm-user/.cache/neomutt/messages/" +set editor = "$EDITOR" +set implicit_autoview = yes + +alternative_order text/enriched text/plain text + +set delete = yes + +# Binds + + +# Macros + + + + +# Register accounts +# register account hm-account +mailboxes "/home/hm-user/Mail/hm-account/Inbox" +folder-hook /home/hm-user/Mail/hm-account/ " \ + source /home/hm-user/.config/neomutt/hm-account " + + +# Source primary account +source /home/hm-user/.config/neomutt/hm-account + +# Extra configuration + + + diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary.nix new file mode 100644 index 0000000000..10e9791de5 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-not-primary.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com".maildir = null; + hm-account.neomutt.enable = true; + }; + + programs.neomutt.enable = true; + + nixpkgs.overlays = + [ (self: super: { neomutt = pkgs.writeScriptBin "dummy-neomutt" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/neomutt/neomuttrc + assertFileContent home-files/.config/neomutt/neomuttrc ${ + ./neomutt-not-primary-expected.conf + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-expected.conf b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-expected.conf new file mode 100644 index 0000000000..7f89c3178a --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-expected.conf @@ -0,0 +1,34 @@ +# Generated by Home Manager. +set header_cache = "/home/hm-user/.cache/neomutt/headers/" +set message_cachedir = "/home/hm-user/.cache/neomutt/messages/" +set editor = "$EDITOR" +set implicit_autoview = yes + +alternative_order text/enriched text/plain text + +set delete = yes + +# Binds +bind editor "complete-query" +bind index,pager \Cp "sidebar-prev" + +# Macros +macro index s "?" +macro index,pager c "?^K=" + + + +# Register accounts +# register account hm@example.com +mailboxes "/home/hm-user/Mail/hm@example.com/Inbox" +folder-hook /home/hm-user/Mail/hm@example.com/ " \ + source /home/hm-user/.config/neomutt/hm@example.com " + + +# Source primary account +source /home/hm-user/.config/neomutt/hm@example.com + +# Extra configuration + + + diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-invalid-settings.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-invalid-settings.nix new file mode 100644 index 0000000000..deaf021f7b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-invalid-settings.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.neomutt = { + enable = true; + + binds = [{ + action = "complete-query"; + key = ""; + map = [ ]; + }]; + + macros = [{ + action = "?^K="; + key = "c"; + map = [ ]; + }]; + }; + + test.asserts.assertions.expected = [ + "The 'programs.neomutt.(binds|macros).map' list must contain at least one element." + ]; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-with-warning.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-with-warning.nix new file mode 100644 index 0000000000..529d284758 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds-with-warning.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com" = { + notmuch.enable = true; + neomutt = { + enable = true; + extraConfig = '' + color status cyan default + ''; + }; + imap.port = 993; + }; + }; + + programs.neomutt = { + enable = true; + vimKeys = false; + + binds = [ + { + action = "complete-query"; + key = ""; + map = "editor"; + } + { + action = "sidebar-prev"; + key = "\\Cp"; + map = [ "index" "pager" ]; + } + ]; + + macros = [ + { + action = "?"; + key = "s"; + map = "index"; + } + { + action = "?^K="; + key = "c"; + map = [ "index" "pager" ]; + } + ]; + }; + + nixpkgs.overlays = + [ (self: super: { neomutt = pkgs.writeScriptBin "dummy-neomutt" ""; }) ]; + + test.asserts.warnings.expected = [ + "Specifying 'programs.neomutt.(binds|macros).map' as a string is deprecated, use a list of strings instead. See https://github.com/nix-community/home-manager/pull/1885." + ]; + + nmt.script = '' + assertFileExists home-files/.config/neomutt/neomuttrc + assertFileExists home-files/.config/neomutt/hm@example.com + assertFileContent home-files/.config/neomutt/neomuttrc ${ + ./neomutt-with-binds-expected.conf + } + assertFileContent home-files/.config/neomutt/hm@example.com ${ + ./hm-example.com-expected + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds.nix new file mode 100644 index 0000000000..bd40cd8934 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-binds.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com" = { + notmuch.enable = true; + neomutt = { + enable = true; + extraConfig = '' + color status cyan default + ''; + }; + imap.port = 993; + }; + }; + + programs.neomutt = { + enable = true; + vimKeys = false; + + binds = [ + { + action = "complete-query"; + key = ""; + map = [ "editor" ]; + } + { + action = "sidebar-prev"; + key = "\\Cp"; + map = [ "index" "pager" ]; + } + ]; + + macros = [ + { + action = "?"; + key = "s"; + map = [ "index" ]; + } + { + action = "?^K="; + key = "c"; + map = [ "index" "pager" ]; + } + ]; + }; + + nixpkgs.overlays = + [ (self: super: { neomutt = pkgs.writeScriptBin "dummy-neomutt" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/neomutt/neomuttrc + assertFileExists home-files/.config/neomutt/hm@example.com + assertFileContent home-files/.config/neomutt/neomuttrc ${ + ./neomutt-with-binds-expected.conf + } + assertFileContent home-files/.config/neomutt/hm@example.com ${ + ./hm-example.com-expected + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-gpg.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-gpg.nix new file mode 100644 index 0000000000..164e4b58cd --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-gpg.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: +with lib; { + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com" = { + gpg = { + encryptByDefault = true; + signByDefault = true; + }; + neomutt.enable = true; + imap.port = 993; + }; + }; + + programs.neomutt.enable = true; + + nixpkgs.overlays = + [ (self: super: { neomutt = pkgs.writeScriptBin "dummy-neomutt" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/neomutt/neomuttrc + assertFileExists home-files/.config/neomutt/hm@example.com + assertFileContent home-files/.config/neomutt/neomuttrc ${ + ./neomutt-expected.conf + } + assertFileContent home-files/.config/neomutt/hm@example.com ${ + ./hm-example.com-gpg-expected.conf + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-msmtp.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-msmtp.nix index 22f65599cf..1d5db5f908 100644 --- a/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-msmtp.nix +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt-with-msmtp.nix @@ -8,7 +8,6 @@ with lib; config = { accounts.email.accounts = { "hm@example.com" = { - primary = true; msmtp.enable = true; neomutt = { enable = true; diff --git a/third_party/home-manager/tests/modules/programs/neomutt/neomutt.nix b/third_party/home-manager/tests/modules/programs/neomutt/neomutt.nix index c0caa44af4..d4419d93ec 100644 --- a/third_party/home-manager/tests/modules/programs/neomutt/neomutt.nix +++ b/third_party/home-manager/tests/modules/programs/neomutt/neomutt.nix @@ -8,7 +8,6 @@ with lib; config = { accounts.email.accounts = { "hm@example.com" = { - primary = true; notmuch.enable = true; neomutt = { enable = true; diff --git a/third_party/home-manager/tests/modules/programs/neovim/default.nix b/third_party/home-manager/tests/modules/programs/neovim/default.nix index 7d6e53aae3..13efac9b68 100644 --- a/third_party/home-manager/tests/modules/programs/neovim/default.nix +++ b/third_party/home-manager/tests/modules/programs/neovim/default.nix @@ -1 +1,5 @@ -{ neovim-plugin-config = ./plugin-config.nix; } +{ + neovim-plugin-config = ./plugin-config.nix; + # waiting for a nixpkgs patch + # neovim-no-init = ./no-init.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/neovim/no-init.nix b/third_party/home-manager/tests/modules/programs/neovim/no-init.nix new file mode 100644 index 0000000000..1156529d3e --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/neovim/no-init.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.neovim = { + enable = true; + package = pkgs.neovim-unwrapped; + vimAlias = true; + withNodeJs = false; + withPython3 = true; + withRuby = false; + + extraPython3Packages = (ps: with ps; [ jedi pynvim ]); + }; + nmt.script = '' + vimrc="home-files/.config/nvim/init.vim" + assertPathNotExists "$vimrc" + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/neovim/plugin-config.nix b/third_party/home-manager/tests/modules/programs/neovim/plugin-config.nix index 60edaee82c..f4f81d8d32 100644 --- a/third_party/home-manager/tests/modules/programs/neovim/plugin-config.nix +++ b/third_party/home-manager/tests/modules/programs/neovim/plugin-config.nix @@ -23,14 +23,11 @@ with lib; }; nmt.script = '' - vimrc=$(grep -Po "(?<=-u )[^ ]*" < "${ - builtins.toJSON config.programs.neovim.finalPackage - }/bin/nvim") - # We need to remove the unkown store paths in the config - TESTED="" assertFileContent \ - <( ${pkgs.perl}/bin/perl -pe "s|\Q$NIX_STORE\E/[a-z0-9]{32}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" < "$vimrc" - ) \ - "${./plugin-config.vim}" + vimrc="$TESTED/home-files/.config/nvim/init.vim" + vimrcNormalized="$(normalizeStorePaths "$vimrc")" + + assertFileExists "$vimrc" + assertFileContent "$vimrcNormalized" "${./plugin-config.vim}" ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/neovim/plugin-config.vim b/third_party/home-manager/tests/modules/programs/neovim/plugin-config.vim index a8d833f4e0..89278a0a94 100644 --- a/third_party/home-manager/tests/modules/programs/neovim/plugin-config.vim +++ b/third_party/home-manager/tests/modules/programs/neovim/plugin-config.vim @@ -1,22 +1,10 @@ -" configuration generated by NIX -set nocompatible +set packpath^=/nix/store/00000000000000000000000000000000-vim-pack-dir +set runtimepath^=/nix/store/00000000000000000000000000000000-vim-pack-dir - - - - - -set packpath^=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-vim-pack-dir -set runtimepath^=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-vim-pack-dir - -filetype indent plugin on | syn on - - -" This should be present in vimrc " vim-commentary {{{ " This should be present too autocmd FileType c setlocal commentstring=//\ %s autocmd FileType c setlocal comments=:// " }}} - +" This should be present in vimrc diff --git a/third_party/home-manager/tests/modules/programs/newsboat/default.nix b/third_party/home-manager/tests/modules/programs/newsboat/default.nix index f12f640ef2..b40751c0eb 100644 --- a/third_party/home-manager/tests/modules/programs/newsboat/default.nix +++ b/third_party/home-manager/tests/modules/programs/newsboat/default.nix @@ -1,4 +1,5 @@ { newsboat-basics = ./newsboat-basics.nix; newsboat-basics-2003 = ./newsboat-basics-2003.nix; + newsboat-basics-2105 = ./newsboat-basics-2105.nix; } diff --git a/third_party/home-manager/tests/modules/programs/newsboat/newsboat-basics-2105.nix b/third_party/home-manager/tests/modules/programs/newsboat/newsboat-basics-2105.nix new file mode 100644 index 0000000000..e7a17c5d7f --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/newsboat/newsboat-basics-2105.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + home.stateVersion = "21.05"; + + programs.newsboat = { + enable = true; + + urls = [ + { + url = "http://example.org/feed.xml"; + tags = [ "tag1" "tag2" ]; + title = "Cool feed"; + } + + { url = "http://example.org/feed2.xml"; } + ]; + + queries = { "foo" = ''rssurl =~ "example.com"''; }; + }; + + nixpkgs.overlays = [ + (self: super: { newsboat = pkgs.writeScriptBin "dummy-newsboat" ""; }) + ]; + + # The format didn't change since 20.03, just the location. + nmt.script = '' + assertFileContent \ + home-files/.config/newsboat/urls \ + ${./newsboat-basics-urls-2003.txt} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/nix-index/assert-on-command-not-found.nix b/third_party/home-manager/tests/modules/programs/nix-index/assert-on-command-not-found.nix new file mode 100644 index 0000000000..757ac65b5d --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/nix-index/assert-on-command-not-found.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: { + config = { + programs.bash.enable = true; + programs.fish.enable = true; + programs.zsh.enable = true; + + programs.command-not-found.enable = true; + + nixpkgs.overlays = + [ (self: super: { zsh = pkgs.writeScriptBin "dummy-zsh" ""; }) ]; + + programs.nix-index.enable = true; + + # 'command-not-found' does not have a 'fish' integration + test.asserts.assertions.expected = [ + '' + The 'programs.command-not-found.enable' option is mutually exclusive + with the 'programs.nix-index.enableBashIntegration' option. + '' + '' + The 'programs.command-not-found.enable' option is mutually exclusive + with the 'programs.nix-index.enableZshIntegration' option. + '' + ]; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/nix-index/default.nix b/third_party/home-manager/tests/modules/programs/nix-index/default.nix new file mode 100644 index 0000000000..eaebd7311e --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/nix-index/default.nix @@ -0,0 +1,4 @@ +{ + nix-index-integrations = ./integrations.nix; + nix-index-assert-on-command-not-found = ./assert-on-command-not-found.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/nix-index/integrations.nix b/third_party/home-manager/tests/modules/programs/nix-index/integrations.nix new file mode 100644 index 0000000000..6da5fd0490 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/nix-index/integrations.nix @@ -0,0 +1,38 @@ +{ pkgs, ... }: +let + fishRegex = '' + function __fish_command_not_found_handler --on-event fish_command_not_found + /nix/store/.*command-not-found $argv + end + ''; +in { + config = { + programs.bash.enable = true; + programs.fish.enable = true; + programs.zsh.enable = true; + + nixpkgs.overlays = + [ (self: super: { zsh = pkgs.writeScriptBin "dummy-zsh" ""; }) ]; + + programs.nix-index.enable = true; + + nmt.script = '' + # Bash integration + assertFileExists home-files/.bashrc + assertFileRegex \ + home-files/.bashrc \ + 'source /nix/store/.*nix-index.*/etc/profile.d/command-not-found.sh' + + # Zsh integration + assertFileExists home-files/.zshrc + assertFileRegex \ + home-files/.zshrc \ + 'source /nix/store/.*nix-index.*/etc/profile.d/command-not-found.sh' + + # Fish integration + assertFileExists home-files/.config/fish/config.fish + assertFileRegex \ + home-files/.config/fish/config.fish '${fishRegex}' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/pet/default.nix b/third_party/home-manager/tests/modules/programs/pet/default.nix new file mode 100644 index 0000000000..553b8392c5 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/pet/default.nix @@ -0,0 +1 @@ +{ pet-snippets = ./snippets.nix; } diff --git a/third_party/home-manager/tests/modules/programs/pet/snippet.toml b/third_party/home-manager/tests/modules/programs/pet/snippet.toml new file mode 100644 index 0000000000..a7ad0e2763 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/pet/snippet.toml @@ -0,0 +1,5 @@ +[[snippets]] +command = "git log -p -G " +description = "git: search full history for regex" +output = "" +tag = ["git", "regex"] diff --git a/third_party/home-manager/tests/modules/programs/pet/snippets.nix b/third_party/home-manager/tests/modules/programs/pet/snippets.nix new file mode 100644 index 0000000000..6713b4f163 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/pet/snippets.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.pet = { + enable = true; + selectcmdPackage = pkgs.writeScriptBin "pet-cmd" "" // { + outPath = "@pet-cmd@"; + }; + snippets = [{ + description = "git: search full history for regex"; + command = "git log -p -G "; + tag = [ "git" "regex" ]; + }]; + }; + + nixpkgs.overlays = [ + (self: super: { + pet = pkgs.writeScriptBin "pet" "" // { outPath = "@pet@"; }; + }) + ]; + + nmt.script = '' + assertFileContent home-files/.config/pet/snippet.toml ${./snippet.toml} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/powerline-go/standard.nix b/third_party/home-manager/tests/modules/programs/powerline-go/bash.nix similarity index 86% rename from third_party/home-manager/tests/modules/programs/powerline-go/standard.nix rename to third_party/home-manager/tests/modules/programs/powerline-go/bash.nix index b01fcb1a75..945bde7312 100644 --- a/third_party/home-manager/tests/modules/programs/powerline-go/standard.nix +++ b/third_party/home-manager/tests/modules/programs/powerline-go/bash.nix @@ -18,6 +18,9 @@ with lib; }; }; + nixpkgs.overlays = + [ (self: super: { powerline-go = pkgs.writeScriptBin "dummy-pkg" ""; }) ]; + nmt.script = '' assertFileExists home-files/.bashrc assertFileContains \ diff --git a/third_party/home-manager/tests/modules/programs/powerline-go/default.nix b/third_party/home-manager/tests/modules/programs/powerline-go/default.nix index 50febefbcc..e89d7c6cde 100644 --- a/third_party/home-manager/tests/modules/programs/powerline-go/default.nix +++ b/third_party/home-manager/tests/modules/programs/powerline-go/default.nix @@ -1 +1,4 @@ -{ powerline-go-standard = ./standard.nix; } +{ + powerline-go-bash = ./bash.nix; + powerline-go-zsh = ./zsh.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/powerline-go/zsh.nix b/third_party/home-manager/tests/modules/programs/powerline-go/zsh.nix new file mode 100644 index 0000000000..0ed88215d2 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/powerline-go/zsh.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs = { + zsh.enable = true; + + powerline-go = { + enable = true; + newline = true; + modules = [ "nix-shell" ]; + pathAliases = { "\\~/project/foo" = "prj-foo"; }; + settings = { + ignore-repos = [ "/home/me/project1" "/home/me/project2" ]; + }; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + powerline-go = pkgs.writeScriptBin "dummy-pkg" ""; + zsh = pkgs.writeScriptBin "dummy-pkg" ""; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.zshrc + assertFileContains \ + home-files/.zshrc \ + '/bin/powerline-go -error $? -shell zsh -modules nix-shell -newline -path-aliases \~/project/foo=prj-foo -ignore-repos /home/me/project1,/home/me/project2' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/qutebrowser/default.nix b/third_party/home-manager/tests/modules/programs/qutebrowser/default.nix index 581b4a5834..8c23515c0b 100644 --- a/third_party/home-manager/tests/modules/programs/qutebrowser/default.nix +++ b/third_party/home-manager/tests/modules/programs/qutebrowser/default.nix @@ -1,4 +1,5 @@ { qutebrowser-settings = ./settings.nix; qutebrowser-keybindings = ./keybindings.nix; + qutebrowser-quickmarks = ./quickmarks.nix; } diff --git a/third_party/home-manager/tests/modules/programs/qutebrowser/keybindings.nix b/third_party/home-manager/tests/modules/programs/qutebrowser/keybindings.nix index e89e44b46d..1236c058dc 100644 --- a/third_party/home-manager/tests/modules/programs/qutebrowser/keybindings.nix +++ b/third_party/home-manager/tests/modules/programs/qutebrowser/keybindings.nix @@ -24,11 +24,17 @@ with lib; }) ]; - nmt.script = '' + nmt.script = let + qutebrowserConfig = if pkgs.stdenv.hostPlatform.isDarwin then + ".qutebrowser/config.py" + else + ".config/qutebrowser/config.py"; + in '' assertFileContent \ - home-files/.config/qutebrowser/config.py \ + home-files/${qutebrowserConfig} \ ${ pkgs.writeText "qutebrowser-expected-config.py" '' + config.load_autoconfig(False) c.bindings.default = {} config.bind(",l", "config-cycle spellcheck.languages [\"en-GB\"] [\"en-US\"]", mode="normal") config.bind("", "spawn mpv {url}", mode="normal") diff --git a/third_party/home-manager/tests/modules/programs/qutebrowser/quickmarks.nix b/third_party/home-manager/tests/modules/programs/qutebrowser/quickmarks.nix new file mode 100644 index 0000000000..30d1856c82 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/qutebrowser/quickmarks.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.qutebrowser = { + enable = true; + + quickmarks = { + nixpkgs = "https://github.com/NixOS/nixpkgs"; + home-manager = "https://github.com/nix-community/home-manager"; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + qutebrowser = pkgs.writeScriptBin "dummy-qutebrowser" ""; + }) + ]; + + nmt.script = let + quickmarksFile = if pkgs.stdenv.hostPlatform.isDarwin then + ".qutebrowser/quickmarks" + else + ".config/qutebrowser/quickmarks"; + in '' + assertFileContent \ + home-files/${quickmarksFile} \ + ${ + pkgs.writeText "qutebrowser-expected-quickmarks" '' + home-manager https://github.com/nix-community/home-manager + nixpkgs https://github.com/NixOS/nixpkgs'' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/qutebrowser/settings.nix b/third_party/home-manager/tests/modules/programs/qutebrowser/settings.nix index 1f0f5db049..e9bedcaa3d 100644 --- a/third_party/home-manager/tests/modules/programs/qutebrowser/settings.nix +++ b/third_party/home-manager/tests/modules/programs/qutebrowser/settings.nix @@ -30,11 +30,17 @@ with lib; }) ]; - nmt.script = '' + nmt.script = let + qutebrowserConfig = if pkgs.stdenv.hostPlatform.isDarwin then + ".qutebrowser/config.py" + else + ".config/qutebrowser/config.py"; + in '' assertFileContent \ - home-files/.config/qutebrowser/config.py \ + home-files/${qutebrowserConfig} \ ${ pkgs.writeText "qutebrowser-expected-config.py" '' + config.load_autoconfig(False) c.colors.hints.bg = "#000000" c.colors.hints.fg = "#ffffff" c.colors.tabs.bar.bg = "#000000" diff --git a/third_party/home-manager/tests/modules/programs/rbw/default.nix b/third_party/home-manager/tests/modules/programs/rbw/default.nix new file mode 100644 index 0000000000..99f36f314b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rbw/default.nix @@ -0,0 +1,5 @@ +{ + rbw-empty-settings = ./empty-settings.nix; + rbw-simple-settings = ./simple-settings.nix; + rbw-settings = ./settings.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/rbw/empty-settings.nix b/third_party/home-manager/tests/modules/programs/rbw/empty-settings.nix new file mode 100644 index 0000000000..3e4c821d84 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rbw/empty-settings.nix @@ -0,0 +1,19 @@ +{ pkgs, ... }: +let + inherit (pkgs.stdenv.hostPlatform) isDarwin; + + path = if isDarwin then + "Library/Application Support/rbw/config.json" + else + ".config/rbw/config.json"; +in { + config = { + programs.rbw.enable = true; + + nixpkgs.overlays = [ (import ./overlay.nix) ]; + + nmt.script = '' + assertPathNotExists home-files/${path} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rbw/overlay.nix b/third_party/home-manager/tests/modules/programs/rbw/overlay.nix new file mode 100644 index 0000000000..f10b1955fb --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rbw/overlay.nix @@ -0,0 +1,12 @@ +self: super: { + rbw = self.writeScriptBin "dummy-rbw" ""; + pinentry = { + gnome3 = self.writeScriptBin "pinentry-gnome3" "" // { + outPath = "@pinentry-gnome3@"; + }; + gtk2 = self.writeScriptBin "pinentry-gtk2" "" // { + outPath = "@pinentry-gtk2@"; + }; + flavors = [ "gnome3" "gtk2" ]; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rbw/settings.nix b/third_party/home-manager/tests/modules/programs/rbw/settings.nix new file mode 100644 index 0000000000..de08ec830f --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rbw/settings.nix @@ -0,0 +1,39 @@ +{ pkgs, ... }: +let + inherit (pkgs.stdenv.hostPlatform) isDarwin; + + path = if isDarwin then + "Library/Application Support/rbw/config.json" + else + ".config/rbw/config.json"; + + expected = pkgs.writeText "rbw-expected.json" '' + { + "base_url": "bitwarden.example.com", + "email": "name@example.com", + "identity_url": "identity.example.com", + "lock_timeout": 300, + "pinentry": "@pinentry-gnome3@/bin/pinentry" + } + ''; +in { + config = { + programs.rbw = { + enable = true; + settings = { + email = "name@example.com"; + base_url = "bitwarden.example.com"; + identity_url = "identity.example.com"; + lock_timeout = 300; + pinentry = "gnome3"; + }; + }; + + nixpkgs.overlays = [ (import ./overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/${path} + assertFileContent home-files/${path} '${expected}' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rbw/simple-settings.nix b/third_party/home-manager/tests/modules/programs/rbw/simple-settings.nix new file mode 100644 index 0000000000..4e05b69fe3 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rbw/simple-settings.nix @@ -0,0 +1,33 @@ +{ pkgs, ... }: +let + inherit (pkgs.stdenv.hostPlatform) isDarwin; + + path = if isDarwin then + "Library/Application Support/rbw/config.json" + else + ".config/rbw/config.json"; + + expected = pkgs.writeText "rbw-expected.json" '' + { + "base_url": null, + "email": "name@example.com", + "identity_url": null, + "lock_timeout": 3600, + "pinentry": "@pinentry-gtk2@/bin/pinentry" + } + ''; +in { + config = { + programs.rbw = { + enable = true; + settings = { email = "name@example.com"; }; + }; + + nixpkgs.overlays = [ (import ./overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/${path} + assertFileContent home-files/${path} '${expected}' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi-pass/default.nix b/third_party/home-manager/tests/modules/programs/rofi-pass/default.nix new file mode 100644 index 0000000000..181aef4e12 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi-pass/default.nix @@ -0,0 +1,4 @@ +{ + rofi-pass-root = ./rofi-pass-root.nix; + rofi-pass-config = ./rofi-pass-config.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-config.nix b/third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-config.nix new file mode 100644 index 0000000000..e70ad9ab16 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-config.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.rofi = { + enable = true; + + pass = { + enable = true; + extraConfig = '' + # Extra config for rofi-pass + xdotool_delay=12 + ''; + }; + }; + + nixpkgs.overlays = [ + (self: super: { rofi-pass = pkgs.writeScriptBin "dummy-rofi-pass" ""; }) + ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/rofi-pass/config \ + ${ + pkgs.writeText "rofi-pass-expected-config" '' + # Extra config for rofi-pass + xdotool_delay=12 + + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-root.nix b/third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-root.nix new file mode 100644 index 0000000000..15c86ef629 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi-pass/rofi-pass-root.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.rofi = { + enable = true; + + pass = { + enable = true; + stores = [ "~/.local/share/password-store" ]; + }; + }; + + nixpkgs.overlays = [ + (self: super: { rofi-pass = pkgs.writeScriptBin "dummy-rofi-pass" ""; }) + ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/rofi-pass/config \ + ${ + pkgs.writeText "rofi-pass-expected-config" '' + root=~/.local/share/password-store + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors-expected.json b/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors-expected.json deleted file mode 100644 index 808288f419..0000000000 --- a/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors-expected.json +++ /dev/null @@ -1 +0,0 @@ -["Cannot use the rofi options 'theme' and 'colors' simultaneously.\n"] \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors.nix b/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors.nix index f162a486b8..087ca472a6 100644 --- a/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors.nix +++ b/third_party/home-manager/tests/modules/programs/rofi/assert-on-both-theme-and-colors.nix @@ -17,16 +17,11 @@ with lib; }; }; - home.file.result.text = builtins.toJSON - (map (a: a.message) (filter (a: !a.assertion) config.assertions)); - nixpkgs.overlays = [ (self: super: { rofi = pkgs.writeScriptBin "dummy-rofi" ""; }) ]; - nmt.script = '' - assertFileContent \ - home-files/result \ - ${./assert-on-both-theme-and-colors-expected.json} - ''; + test.asserts.assertions.expected = ['' + Cannot use the rofi options 'theme' and 'colors' simultaneously. + '']; }; } diff --git a/third_party/home-manager/tests/modules/programs/rofi/custom-theme-config.rasi b/third_party/home-manager/tests/modules/programs/rofi/custom-theme-config.rasi new file mode 100644 index 0000000000..639336d983 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi/custom-theme-config.rasi @@ -0,0 +1,6 @@ +configuration { +location: 0; +theme: "custom"; +xoffset: 0; +yoffset: 0; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi/custom-theme.nix b/third_party/home-manager/tests/modules/programs/rofi/custom-theme.nix new file mode 100644 index 0000000000..2d318a4e42 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi/custom-theme.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.rofi = { + enable = true; + + theme = let inherit (config.lib.formats.rasi) mkLiteral; + in { + "@import" = "~/.cache/wal/colors-rofi-dark"; + + "*" = { + background-color = mkLiteral "#000000"; + foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )"; + border-color = mkLiteral "#FFFFFF"; + width = 512; + }; + + "#inputbar" = { children = map mkLiteral [ "prompt" "entry" ]; }; + + "#textbox-prompt-colon" = { + expand = false; + str = ":"; + margin = mkLiteral "0px 0.3em 0em 0em"; + text-color = mkLiteral "@foreground-color"; + }; + }; + }; + + nixpkgs.overlays = + [ (self: super: { rofi = pkgs.writeScriptBin "dummy-rofi" ""; }) ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/rofi/config.rasi \ + ${./custom-theme-config.rasi} + assertFileContent \ + home-files/.local/share/rofi/themes/custom.rasi \ + ${./custom-theme.rasi} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi/custom-theme.rasi b/third_party/home-manager/tests/modules/programs/rofi/custom-theme.rasi new file mode 100644 index 0000000000..b018843feb --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi/custom-theme.rasi @@ -0,0 +1,19 @@ +#inputbar { +children: [ prompt,entry ]; +} + +#textbox-prompt-colon { +expand: false; +margin: 0px 0.3em 0em 0em; +str: ":"; +text-color: @foreground-color; +} + +* { +background-color: #000000; +border-color: #FFFFFF; +foreground-color: rgba ( 250, 251, 252, 100 % ); +width: 512; +} + +@import "~/.cache/wal/colors-rofi-dark" \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/programs/rofi/default.nix b/third_party/home-manager/tests/modules/programs/rofi/default.nix index c18c3b0ed6..057ef0039d 100644 --- a/third_party/home-manager/tests/modules/programs/rofi/default.nix +++ b/third_party/home-manager/tests/modules/programs/rofi/default.nix @@ -1,3 +1,5 @@ { + rofi-valid-config = ./valid-config.nix; + rofi-custom-theme = ./custom-theme.nix; rofi-assert-on-both-theme-and-colors = ./assert-on-both-theme-and-colors.nix; } diff --git a/third_party/home-manager/tests/modules/programs/rofi/valid-config-expected.rasi b/third_party/home-manager/tests/modules/programs/rofi/valid-config-expected.rasi new file mode 100644 index 0000000000..23cf246067 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi/valid-config-expected.rasi @@ -0,0 +1,20 @@ +configuration { +bw: 1; +color-normal: "argb:58455a64, #fafbfc, argb:58455a64, #00bcd4, #fafbfc"; +color-window: "argb:583a4c54, argb:582a373e, #c3c6c8"; +cycle: false; +eh: 1; +font: "Droid Sans Mono 14"; +hide-scrollbar: false; +kb-primary-paste: "Control+V,Shift+Insert"; +kb-secondary-paste: "Control+v,Insert"; +lines: 10; +location: 0; +modi: "drun,emoji,ssh"; +padding: 400; +separator-style: "solid"; +terminal: "/some/path"; +width: 100; +xoffset: 0; +yoffset: 0; +} diff --git a/third_party/home-manager/tests/modules/programs/rofi/valid-config.nix b/third_party/home-manager/tests/modules/programs/rofi/valid-config.nix new file mode 100644 index 0000000000..efcb1acdc5 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/rofi/valid-config.nix @@ -0,0 +1,60 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.rofi = { + enable = true; + width = 100; + lines = 10; + borderWidth = 1; + rowHeight = 1; + padding = 400; + font = "Droid Sans Mono 14"; + scrollbar = true; + terminal = "/some/path"; + separator = "solid"; + cycle = false; + fullscren = true; + colors = { + window = { + background = "argb:583a4c54"; + border = "argb:582a373e"; + separator = "#c3c6c8"; + }; + + rows = { + normal = { + background = "argb:58455a64"; + foreground = "#fafbfc"; + backgroundAlt = "argb:58455a64"; + highlight = { + background = "#00bcd4"; + foreground = "#fafbfc"; + }; + }; + }; + }; + window = { + background = "background"; + border = "border"; + separator = "separator"; + }; + extraConfig = { + modi = "drun,emoji,ssh"; + kb-primary-paste = "Control+V,Shift+Insert"; + kb-secondary-paste = "Control+v,Insert"; + }; + }; + + nixpkgs.overlays = + [ (self: super: { rofi = pkgs.writeScriptBin "dummy-rofi" ""; }) ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/rofi/config.rasi \ + ${./valid-config-expected.rasi} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/sbt/credentials.nix b/third_party/home-manager/tests/modules/programs/sbt/credentials.nix new file mode 100644 index 0000000000..5aa4c2f776 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/sbt/credentials.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + credentials = [ + { + realm = "Sonatype Nexus Repository Manager"; + host = "example.com"; + user = "user"; + passwordCommand = "echo password"; + } + { + realm = "Sonatype Nexus Repository Manager X"; + host = "v2.example.com"; + user = "user1"; + passwordCommand = "echo password1"; + } + ]; + expectedCredentialsSbt = pkgs.writeText "credentials.sbt" '' + import scala.sys.process._ + credentials += Credentials("Sonatype Nexus Repository Manager", "example.com", "user", "echo password".!!) + credentials += Credentials("Sonatype Nexus Repository Manager X", "v2.example.com", "user1", "echo password1".!!) + ''; + credentialsSbtPath = ".sbt/1.0/credentials.sbt"; +in { + config = { + programs.sbt = { + enable = true; + credentials = credentials; + package = pkgs.writeScriptBin "sbt" ""; + }; + + nmt.script = '' + assertFileExists "home-files/${credentialsSbtPath}" + assertFileContent "home-files/${credentialsSbtPath}" "${expectedCredentialsSbt}" + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/sbt/default.nix b/third_party/home-manager/tests/modules/programs/sbt/default.nix new file mode 100644 index 0000000000..59ad89dae7 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/sbt/default.nix @@ -0,0 +1,4 @@ +{ + sbt-plugins = ./plugins.nix; + sbt-credentials = ./credentials.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/sbt/plugins.nix b/third_party/home-manager/tests/modules/programs/sbt/plugins.nix new file mode 100644 index 0000000000..b413de80e7 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/sbt/plugins.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + dependencyGraph = { + org = "net.virtual-void"; + artifact = "sbt-dependency-graph"; + version = "0.10.0-RC1"; + }; + projectGraph = { + org = "com.dwijnand"; + artifact = "sbt-project-graph"; + version = "0.4.0"; + }; + + plugins = [ dependencyGraph projectGraph ]; + + pluginsSbtPath = ".sbt/1.0/plugins/plugins.sbt"; + + expectedPluginsSbt = pkgs.writeText "plugins.sbt" '' + addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.10.0-RC1") + addSbtPlugin("com.dwijnand" % "sbt-project-graph" % "0.4.0") + ''; + +in { + config = { + programs.sbt = { + enable = true; + plugins = plugins; + package = pkgs.writeScriptBin "sbt" ""; + }; + + nmt.script = '' + assertFileExists "home-files/${pluginsSbtPath}" + assertFileContent "home-files/${pluginsSbtPath}" "${expectedPluginsSbt}" + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/scmpuff/bash.nix b/third_party/home-manager/tests/modules/programs/scmpuff/bash.nix new file mode 100644 index 0000000000..ea34373b9c --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/scmpuff/bash.nix @@ -0,0 +1,15 @@ +{ 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)"' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/scmpuff/default.nix b/third_party/home-manager/tests/modules/programs/scmpuff/default.nix new file mode 100644 index 0000000000..5852c5b69f --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/scmpuff/default.nix @@ -0,0 +1,7 @@ +{ + scmpuff-bash = ./bash.nix; + scmpuff-no-bash = ./no-bash.nix; + scmpuff-no-shell = ./no-shell.nix; + scmpuff-no-zsh = ./no-zsh.nix; + scmpuff-zsh = ./zsh.nix; +} diff --git a/third_party/home-manager/tests/modules/programs/scmpuff/no-bash.nix b/third_party/home-manager/tests/modules/programs/scmpuff/no-bash.nix new file mode 100644 index 0000000000..e3852b84a0 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/scmpuff/no-bash.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: { + config = { + programs = { + scmpuff = { + enable = true; + enableBashIntegration = false; + }; + bash.enable = true; + }; + + nmt.script = '' + assertFileNotRegex home-files/.bashrc '${pkgs.scmpuff}/bin/scmpuff' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/scmpuff/no-shell.nix b/third_party/home-manager/tests/modules/programs/scmpuff/no-shell.nix new file mode 100644 index 0000000000..df85176716 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/scmpuff/no-shell.nix @@ -0,0 +1,18 @@ +{ pkgs, ... }: { + config = { + 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' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/scmpuff/no-zsh.nix b/third_party/home-manager/tests/modules/programs/scmpuff/no-zsh.nix new file mode 100644 index 0000000000..18480add15 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/scmpuff/no-zsh.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: { + config = { + programs = { + scmpuff = { + enable = true; + enableZshIntegration = false; + }; + zsh.enable = true; + }; + + nmt.script = '' + assertFileNotRegex home-files/.zshrc '${pkgs.scmpuff} init -s' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/scmpuff/zsh.nix b/third_party/home-manager/tests/modules/programs/scmpuff/zsh.nix new file mode 100644 index 0000000000..d6f7cc5edf --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/scmpuff/zsh.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: { + config = { + programs = { + scmpuff.enable = true; + zsh.enable = true; + }; + + nmt.script = '' + assertFileExists home-files/.zshrc + assertFileContains \ + home-files/.zshrc \ + 'eval "$(${pkgs.scmpuff}/bin/scmpuff init -s)"' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/ssh/forwards-dynamic-bind-path-with-port-asserts.nix b/third_party/home-manager/tests/modules/programs/ssh/forwards-dynamic-bind-path-with-port-asserts.nix index cf2efe5a5a..e841b5bcde 100644 --- a/third_party/home-manager/tests/modules/programs/ssh/forwards-dynamic-bind-path-with-port-asserts.nix +++ b/third_party/home-manager/tests/modules/programs/ssh/forwards-dynamic-bind-path-with-port-asserts.nix @@ -17,13 +17,6 @@ with lib; }; }; - home.file.result.text = builtins.toJSON - (map (a: a.message) (filter (a: !a.assertion) config.assertions)); - - nmt.script = '' - assertFileContent home-files/result ${ - ./forwards-paths-with-ports-error.json - } - ''; + test.asserts.assertions.expected = [ "Forwarded paths cannot have ports." ]; }; } diff --git a/third_party/home-manager/tests/modules/programs/ssh/forwards-local-bind-path-with-port-asserts.nix b/third_party/home-manager/tests/modules/programs/ssh/forwards-local-bind-path-with-port-asserts.nix index f9d8e2daf8..e7ac454e88 100644 --- a/third_party/home-manager/tests/modules/programs/ssh/forwards-local-bind-path-with-port-asserts.nix +++ b/third_party/home-manager/tests/modules/programs/ssh/forwards-local-bind-path-with-port-asserts.nix @@ -21,13 +21,6 @@ with lib; }; }; - home.file.result.text = builtins.toJSON - (map (a: a.message) (filter (a: !a.assertion) config.assertions)); - - nmt.script = '' - assertFileContent home-files/result ${ - ./forwards-paths-with-ports-error.json - } - ''; + test.asserts.assertions.expected = [ "Forwarded paths cannot have ports." ]; }; } diff --git a/third_party/home-manager/tests/modules/programs/ssh/forwards-local-host-path-with-port-asserts.nix b/third_party/home-manager/tests/modules/programs/ssh/forwards-local-host-path-with-port-asserts.nix index 02a7e5b168..890459c8ab 100644 --- a/third_party/home-manager/tests/modules/programs/ssh/forwards-local-host-path-with-port-asserts.nix +++ b/third_party/home-manager/tests/modules/programs/ssh/forwards-local-host-path-with-port-asserts.nix @@ -21,13 +21,6 @@ with lib; }; }; - home.file.result.text = builtins.toJSON - (map (a: a.message) (filter (a: !a.assertion) config.assertions)); - - nmt.script = '' - assertFileContent home-files/result ${ - ./forwards-paths-with-ports-error.json - } - ''; + test.asserts.assertions.expected = [ "Forwarded paths cannot have ports." ]; }; } diff --git a/third_party/home-manager/tests/modules/programs/ssh/forwards-paths-with-ports-error.json b/third_party/home-manager/tests/modules/programs/ssh/forwards-paths-with-ports-error.json deleted file mode 100644 index e7e3a374ec..0000000000 --- a/third_party/home-manager/tests/modules/programs/ssh/forwards-paths-with-ports-error.json +++ /dev/null @@ -1 +0,0 @@ -["Forwarded paths cannot have ports."] \ No newline at end of file diff --git a/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-bind-path-with-port-asserts.nix b/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-bind-path-with-port-asserts.nix index 61ce9ae038..ece7d7953a 100644 --- a/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-bind-path-with-port-asserts.nix +++ b/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-bind-path-with-port-asserts.nix @@ -21,13 +21,6 @@ with lib; }; }; - home.file.result.text = builtins.toJSON - (map (a: a.message) (filter (a: !a.assertion) config.assertions)); - - nmt.script = '' - assertFileContent home-files/result ${ - ./forwards-paths-with-ports-error.json - } - ''; + test.asserts.assertions.expected = [ "Forwarded paths cannot have ports." ]; }; } diff --git a/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-host-path-with-port-asserts.nix b/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-host-path-with-port-asserts.nix index 71bdbcb70f..b1228f4efe 100644 --- a/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-host-path-with-port-asserts.nix +++ b/third_party/home-manager/tests/modules/programs/ssh/forwards-remote-host-path-with-port-asserts.nix @@ -21,13 +21,6 @@ with lib; }; }; - home.file.result.text = builtins.toJSON - (map (a: a.message) (filter (a: !a.assertion) config.assertions)); - - nmt.script = '' - assertFileContent home-files/result ${ - ./forwards-paths-with-ports-error.json - } - ''; + test.asserts.assertions.expected = [ "Forwarded paths cannot have ports." ]; }; } diff --git a/third_party/home-manager/tests/modules/programs/starship/settings-expected.toml b/third_party/home-manager/tests/modules/programs/starship/settings-expected.toml index a4fb0ee55d..ee07a02e6d 100644 --- a/third_party/home-manager/tests/modules/programs/starship/settings-expected.toml +++ b/third_party/home-manager/tests/modules/programs/starship/settings-expected.toml @@ -1,5 +1,5 @@ add_newline = false -prompt_order = ["line_break", "package", "line_break", "character"] +format = "$line_break$package$line_break$character" scan_timeout = 10 [aws] @@ -18,7 +18,8 @@ style = "bold yellow" threshold = 30 [character] -symbol = "➜" +error_symbol = "➜" +success_symbol = "➜" [memory_usage] threshold = -1 diff --git a/third_party/home-manager/tests/modules/programs/starship/settings.nix b/third_party/home-manager/tests/modules/programs/starship/settings.nix index e7a27733d9..4c506c9e81 100644 --- a/third_party/home-manager/tests/modules/programs/starship/settings.nix +++ b/third_party/home-manager/tests/modules/programs/starship/settings.nix @@ -10,9 +10,17 @@ with lib; settings = mkMerge [ { add_newline = false; - prompt_order = [ "line_break" "package" "line_break" "character" ]; + format = concatStrings [ + "$line_break" + "$package" + "$line_break" + "$character" + ]; scan_timeout = 10; - character.symbol = "➜"; + character = { + success_symbol = "➜"; + error_symbol = "➜"; + }; package.disabled = true; memory_usage.threshold = -1; aws.style = "bold blue"; diff --git a/third_party/home-manager/tests/modules/programs/terminator/config-file.nix b/third_party/home-manager/tests/modules/programs/terminator/config-file.nix new file mode 100644 index 0000000000..1ae06fdc93 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/terminator/config-file.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: { + config = { + programs.terminator = { + enable = true; + config = { + global_config.borderless = true; + profiles.default.background_color = "#002b36"; + }; + }; + + nixpkgs.overlays = + [ (self: super: { terminator = pkgs.writeScriptBin "dummy" ""; }) ]; + + nmt.script = '' + assertFileContent home-files/.config/terminator/config ${ + pkgs.writeText "expected" '' + [global_config] + borderless = True + [profiles] + [[default]] + background_color = "#002b36"'' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/terminator/default.nix b/third_party/home-manager/tests/modules/programs/terminator/default.nix new file mode 100644 index 0000000000..4d53e534c6 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/terminator/default.nix @@ -0,0 +1 @@ +{ terminator-config-file = ./config-file.nix; } diff --git a/third_party/home-manager/tests/modules/programs/tmux/default-shell.conf b/third_party/home-manager/tests/modules/programs/tmux/default-shell.conf new file mode 100644 index 0000000000..a336236307 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/tmux/default-shell.conf @@ -0,0 +1,30 @@ +# ============================================= # +# 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 +# We need to set default-shell before calling new-session +set -g default-shell "/usr/bin/myshell" + + + + + +set -g status-keys emacs +set -g mode-keys emacs + + + + + + + +setw -g aggressive-resize off +setw -g clock-mode-style 12 +set -s escape-time 500 +set -g history-limit 2000 + diff --git a/third_party/home-manager/tests/modules/programs/tmux/default-shell.nix b/third_party/home-manager/tests/modules/programs/tmux/default-shell.nix new file mode 100644 index 0000000000..af05eb0e70 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/tmux/default-shell.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + substituteExpected = path: + pkgs.substituteAll { + src = path; + + sensible_rtp = pkgs.tmuxPlugins.sensible.rtp; + }; + +in { + config = { + programs.tmux = { + enable = true; + shell = "/usr/bin/myshell"; + }; + + nmt.script = '' + assertFileExists home-files/.config/tmux/tmux.conf + assertFileContent home-files/.config/tmux/tmux.conf \ + ${substituteExpected ./default-shell.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/tmux/default.nix b/third_party/home-manager/tests/modules/programs/tmux/default.nix index d4501c6098..be78c2620a 100644 --- a/third_party/home-manager/tests/modules/programs/tmux/default.nix +++ b/third_party/home-manager/tests/modules/programs/tmux/default.nix @@ -4,4 +4,7 @@ tmux-vi-all-true = ./vi-all-true.nix; tmux-secure-socket-enabled = ./secure-socket-enabled.nix; tmux-disable-confirmation-prompt = ./disable-confirmation-prompt.nix; + tmux-default-shell = ./default-shell.nix; + tmux-shortcut-without-prefix = ./shortcut-without-prefix.nix; + tmux-prefix = ./prefix.nix; } diff --git a/third_party/home-manager/tests/modules/programs/tmux/disable-confirmation-prompt.nix b/third_party/home-manager/tests/modules/programs/tmux/disable-confirmation-prompt.nix index 9c65ad6eee..aec1f66cf5 100644 --- a/third_party/home-manager/tests/modules/programs/tmux/disable-confirmation-prompt.nix +++ b/third_party/home-manager/tests/modules/programs/tmux/disable-confirmation-prompt.nix @@ -18,8 +18,8 @@ with lib; ]; nmt.script = '' - assertFileExists home-files/.tmux.conf - assertFileContent home-files/.tmux.conf \ + assertFileExists home-files/.config/tmux/tmux.conf + assertFileContent home-files/.config/tmux/tmux.conf \ ${./disable-confirmation-prompt.conf} ''; }; diff --git a/third_party/home-manager/tests/modules/programs/tmux/emacs-with-plugins.nix b/third_party/home-manager/tests/modules/programs/tmux/emacs-with-plugins.nix index f9bccaa2ce..4a0382d8df 100644 --- a/third_party/home-manager/tests/modules/programs/tmux/emacs-with-plugins.nix +++ b/third_party/home-manager/tests/modules/programs/tmux/emacs-with-plugins.nix @@ -42,8 +42,10 @@ with lib; ]; nmt.script = '' - assertFileExists home-files/.tmux.conf - assertFileContent home-files/.tmux.conf ${./emacs-with-plugins.conf} + assertFileExists home-files/.config/tmux/tmux.conf + assertFileContent home-files/.config/tmux/tmux.conf ${ + ./emacs-with-plugins.conf + } ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/tmux/not-enabled.nix b/third_party/home-manager/tests/modules/programs/tmux/not-enabled.nix index b7c675a83a..d5f08b36f7 100644 --- a/third_party/home-manager/tests/modules/programs/tmux/not-enabled.nix +++ b/third_party/home-manager/tests/modules/programs/tmux/not-enabled.nix @@ -7,7 +7,7 @@ with lib; programs.tmux = { enable = false; }; nmt.script = '' - assertPathNotExists home-files/.tmux.conf + assertPathNotExists home-files/.config/tmux/tmux.conf ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/tmux/prefix.conf b/third_party/home-manager/tests/modules/programs/tmux/prefix.conf new file mode 100644 index 0000000000..3188030023 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/tmux/prefix.conf @@ -0,0 +1,32 @@ +# ============================================= # +# 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 + + + +# rebind main key: C-a +unbind C-b +set -g prefix C-a +bind C-a send-prefix + + + + +setw -g aggressive-resize off +setw -g clock-mode-style 12 +set -s escape-time 500 +set -g history-limit 2000 + diff --git a/third_party/home-manager/tests/modules/programs/tmux/prefix.nix b/third_party/home-manager/tests/modules/programs/tmux/prefix.nix new file mode 100644 index 0000000000..9f97940e7b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/tmux/prefix.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.tmux = { + enable = true; + prefix = "C-a"; + }; + + 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 \ + ${./prefix.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.conf b/third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.conf new file mode 100644 index 0000000000..a8bc59cbb8 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.conf @@ -0,0 +1,33 @@ +# ============================================= # +# 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 + + + +# rebind main key: C-a +unbind C-b +set -g prefix C-a +bind a send-prefix +bind C-a last-window + + + + +setw -g aggressive-resize off +setw -g clock-mode-style 12 +set -s escape-time 500 +set -g history-limit 2000 + diff --git a/third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.nix b/third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.nix new file mode 100644 index 0000000000..5c294ef97b --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/tmux/shortcut-without-prefix.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.tmux = { + enable = true; + shortcut = "a"; + prefix = null; + }; + + 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 \ + ${./shortcut-without-prefix.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/tmux/vi-all-true.nix b/third_party/home-manager/tests/modules/programs/tmux/vi-all-true.nix index bce032fd65..8b9cf1a368 100644 --- a/third_party/home-manager/tests/modules/programs/tmux/vi-all-true.nix +++ b/third_party/home-manager/tests/modules/programs/tmux/vi-all-true.nix @@ -22,8 +22,8 @@ with lib; ]; nmt.script = '' - assertFileExists home-files/.tmux.conf - assertFileContent home-files/.tmux.conf ${./vi-all-true.conf} + assertFileExists home-files/.config/tmux/tmux.conf + assertFileContent home-files/.config/tmux/tmux.conf ${./vi-all-true.conf} ''; }; } diff --git a/third_party/home-manager/tests/modules/programs/topgrade/default.nix b/third_party/home-manager/tests/modules/programs/topgrade/default.nix new file mode 100644 index 0000000000..46b0384a07 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/topgrade/default.nix @@ -0,0 +1 @@ +{ topgrade-settings = ./settings.nix; } diff --git a/third_party/home-manager/tests/modules/programs/topgrade/settings-expected.toml b/third_party/home-manager/tests/modules/programs/topgrade/settings-expected.toml new file mode 100644 index 0000000000..aeed3d14b0 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/topgrade/settings-expected.toml @@ -0,0 +1,8 @@ +cleanup = true +disable = ["sdkman", "flutter", "node", "nix", "home_manager"] +remote_topgrade_path = "bin/topgrade" +remote_topgrades = ["backup", "ci"] +set_title = false + +[commands] +"Purge unused APT packages" = "sudo apt autoremove" diff --git a/third_party/home-manager/tests/modules/programs/topgrade/settings.nix b/third_party/home-manager/tests/modules/programs/topgrade/settings.nix new file mode 100644 index 0000000000..a7436b5efc --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/topgrade/settings.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.topgrade = { + enable = true; + + settings = mkMerge [ + { + disable = [ "sdkman" "flutter" "node" "nix" "home_manager" ]; + + remote_topgrades = [ "backup" "ci" ]; + + remote_topgrade_path = "bin/topgrade"; + } + + { + set_title = false; + cleanup = true; + + commands = { "Purge unused APT packages" = "sudo apt autoremove"; }; + } + ]; + }; + + nixpkgs.overlays = [ + (self: super: { topgrade = pkgs.writeScriptBin "dummy-topgrade" ""; }) + ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/topgrade.toml \ + ${./settings-expected.toml} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/vscode/keybindings.nix b/third_party/home-manager/tests/modules/programs/vscode/keybindings.nix index 420b212dce..57931c43f4 100644 --- a/third_party/home-manager/tests/modules/programs/vscode/keybindings.nix +++ b/third_party/home-manager/tests/modules/programs/vscode/keybindings.nix @@ -1,4 +1,4 @@ -# Test that keybdinings.json is created correctly. +# Test that keybindings.json is created correctly. { config, lib, pkgs, ... }: with lib; @@ -20,6 +20,11 @@ let command = "deleteFile"; when = "explorerViewletVisible"; } + { + key = "ctrl+r"; + command = "run"; + args = { command = "echo file"; }; + } ]; targetPath = if pkgs.stdenv.hostPlatform.isDarwin then @@ -27,24 +32,40 @@ let else ".config/Code/User/keybindings.json"; - expectedJson = pkgs.writeText "expected.json" (builtins.toJSON bindings); + expectedJson = pkgs.writeText "expected.json" '' + [ + { + "command": "editor.action.clipboardCopyAction", + "key": "ctrl+c", + "when": "textInputFocus && false" + }, + { + "command": "deleteFile", + "key": "ctrl+c", + "when": "" + }, + { + "command": "deleteFile", + "key": "d", + "when": "explorerViewletVisible" + }, + { + "args": { + "command": "echo file" + }, + "command": "run", + "key": "ctrl+r" + } + ] + ''; in { config = { programs.vscode = { enable = true; keybindings = bindings; + package = pkgs.writeScriptBin "vscode" "" // { pname = "vscode"; }; }; - nixpkgs.overlays = [ - (self: super: { - vscode = pkgs.runCommandLocal "vscode" { pname = "vscode"; } '' - mkdir -p $out/bin - touch $out/bin/code - chmod +x $out/bin/code; - ''; - }) - ]; - nmt.script = '' assertFileExists "home-files/${targetPath}" assertFileContent "home-files/${targetPath}" "${expectedJson}" diff --git a/third_party/home-manager/tests/modules/programs/waybar/broken-settings.nix b/third_party/home-manager/tests/modules/programs/waybar/broken-settings.nix deleted file mode 100644 index f5ac39468e..0000000000 --- a/third_party/home-manager/tests/modules/programs/waybar/broken-settings.nix +++ /dev/null @@ -1,80 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - package = pkgs.writeScriptBin "dummy-waybar" "" // { outPath = "@waybar@"; }; - expected = pkgs.writeText "expected-json" '' - [ - { - "height": 26, - "layer": "top", - "modules-center": [ - "sway/window" - ], - "modules-left": [ - "sway/workspaces", - "sway/mode" - ], - "modules-right": [ - "idle_inhibitor", - "pulseaudio", - "network", - "cpu", - "memory", - "backlight", - "tray", - "clock" - ], - "output": [ - "DP-1", - "eDP-1", - "HEADLESS-1" - ], - "position": "top", - "sway/workspaces": { - "all-outputs": true - } - } - ] - ''; -in { - config = { - programs.waybar = { - inherit package; - enable = true; - systemd.enable = true; - settings = [{ - layer = "top"; - position = "top"; - height = 26; - output = [ "DP-1" "eDP-1" "HEADLESS-1" ]; - modules-left = [ "sway/workspaces" "sway/mode" ]; - modules-center = [ "sway/window" ]; - modules-right = [ - "idle_inhibitor" - "pulseaudio" - "network" - "cpu" - "memory" - "backlight" - "tray" - "clock" - ]; - - modules = { "sway/workspaces".all-outputs = true; }; - }]; - }; - - nmt.description = '' - Test for the broken configuration - https://github.com/nix-community/home-manager/pull/1329#issuecomment-653253069 - ''; - nmt.script = '' - assertPathNotExists home-files/.config/waybar/style.css - assertFileContent \ - home-files/.config/waybar/config \ - ${expected} - ''; - }; -} diff --git a/third_party/home-manager/tests/modules/programs/waybar/default.nix b/third_party/home-manager/tests/modules/programs/waybar/default.nix index cac5de664c..9ffebe2423 100644 --- a/third_party/home-manager/tests/modules/programs/waybar/default.nix +++ b/third_party/home-manager/tests/modules/programs/waybar/default.nix @@ -3,6 +3,5 @@ ./systemd-with-graphical-session-target.nix; waybar-styling = ./styling.nix; waybar-settings-complex = ./settings-complex.nix; - # Broken configuration from https://github.com/nix-community/home-manager/pull/1329#issuecomment-653253069 - waybar-broken-settings = ./broken-settings.nix; + waybar-warnings = ./warnings-tests.nix; } diff --git a/third_party/home-manager/tests/modules/programs/waybar/settings-complex-expected.json b/third_party/home-manager/tests/modules/programs/waybar/settings-complex-expected.json index 0d020c19c9..c5c21a6e44 100644 --- a/third_party/home-manager/tests/modules/programs/waybar/settings-complex-expected.json +++ b/third_party/home-manager/tests/modules/programs/waybar/settings-complex-expected.json @@ -25,7 +25,8 @@ "memory", "backlight", "tray", - "battery", + "battery#bat1", + "battery#bat2", "clock" ], "output": [ diff --git a/third_party/home-manager/tests/modules/programs/waybar/settings-complex.nix b/third_party/home-manager/tests/modules/programs/waybar/settings-complex.nix index 750e52f458..1756ae120a 100644 --- a/third_party/home-manager/tests/modules/programs/waybar/settings-complex.nix +++ b/third_party/home-manager/tests/modules/programs/waybar/settings-complex.nix @@ -24,7 +24,8 @@ in { "memory" "backlight" "tray" - "battery" + "battery#bat1" + "battery#bat2" "clock" ]; diff --git a/third_party/home-manager/tests/modules/programs/waybar/systemd-with-graphical-session-target.service b/third_party/home-manager/tests/modules/programs/waybar/systemd-with-graphical-session-target.service index 7d4c65214e..e03326e6e7 100644 --- a/third_party/home-manager/tests/modules/programs/waybar/systemd-with-graphical-session-target.service +++ b/third_party/home-manager/tests/modules/programs/waybar/systemd-with-graphical-session-target.service @@ -2,15 +2,13 @@ WantedBy=graphical-session.target [Service] -BusName=fr.arouillard.waybar +ExecReload=kill -SIGUSR2 $MAINPID ExecStart=@waybar@/bin/waybar -Restart=always -RestartSec=1sec -Type=dbus +KillMode=mixed +Restart=on-failure [Unit] -After=dbus.service +After=graphical-session.target Description=Highly customizable Wayland bar for Sway and Wlroots based compositors. Documentation=https://github.com/Alexays/Waybar/wiki PartOf=graphical-session.target -Requisite=dbus.service diff --git a/third_party/home-manager/tests/modules/programs/waybar/warnings-tests.nix b/third_party/home-manager/tests/modules/programs/waybar/warnings-tests.nix new file mode 100644 index 0000000000..f7912dba73 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/waybar/warnings-tests.nix @@ -0,0 +1,64 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + package = pkgs.writeScriptBin "dummy-waybar" "" // { outPath = "@waybar@"; }; +in { + config = { + programs.waybar = { + inherit package; + enable = true; + settings = [{ + modules-left = [ "custom/my-module" ]; + modules-center = + [ "this_module_is_not_a_valid_default_module_nor_custom_module" ]; + modules-right = [ + "battery#bat1" # CSS identifier is allowed + "custom/this_custom_module_doesn't_have_a_definition_in_modules" + ]; + + modules = { + "custom/this_module_is_not_referenced" = { }; + "battery#bat1" = { }; + "custom/my-module" = { }; + }; + }]; + }; + + test.asserts.warnings.expected = [ + "The module 'this_module_is_not_a_valid_default_module_nor_custom_module' defined in 'programs.waybar.settings.[].modules-center' is neither a default module or a custom module declared in 'programs.waybar.settings.[].modules'" + + "The module 'custom/this_custom_module_doesn't_have_a_definition_in_modules' defined in 'programs.waybar.settings.[].modules-right' is neither a default module or a custom module declared in 'programs.waybar.settings.[].modules'" + + "The module 'custom/this_module_is_not_referenced' defined in 'programs.waybar.settings.[].modules' is not referenced in either `modules-left`, `modules-center` or `modules-right` of Waybar's options" + ]; + + nmt.script = '' + assertPathNotExists home-files/.config/waybar/style.css + assertFileContent \ + home-files/.config/waybar/config \ + ${ + pkgs.writeText "expected-json" '' + [ + { + "battery#bat1": {}, + "custom/my-module": {}, + "custom/this_module_is_not_referenced": {}, + "modules-center": [ + "this_module_is_not_a_valid_default_module_nor_custom_module" + ], + "modules-left": [ + "custom/my-module" + ], + "modules-right": [ + "battery#bat1", + "custom/this_custom_module_doesn't_have_a_definition_in_modules" + ] + } + ] + '' + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.expected b/third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.expected new file mode 100644 index 0000000000..51b06a7efc --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.expected @@ -0,0 +1,19 @@ +Config + { font = "Fira Code" + , borderColor = "#d0d0d0" + , border = FullB + , borderWidth = 3 + , bgColor = "#222" + , fgColor = "grey" + , position = TopSize C 99 30 + , commands = + [ Run Cpu ["-t", "cpu: %"] 10 + , Run Network "enp3s0" ["-S", "True", "-t", "eth: /"] 10 + , Run Memory ["-t","mem: %"] 10 + , Run Date "date: %a %d %b %Y %H:%M:%S " "date" 10 + , Run StdinReader + ] + , sepChar = "%" + , alignSep = "}{" + , template = " %StdinReader% | %cpu% | %memory% | %enp3s0% }{%date% " + } diff --git a/third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.nix b/third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.nix new file mode 100644 index 0000000000..360cc4c3dc --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/xmobar/basic-configuration.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.xmobar = { + enable = true; + extraConfig = '' + Config + { font = "Fira Code" + , borderColor = "#d0d0d0" + , border = FullB + , borderWidth = 3 + , bgColor = "#222" + , fgColor = "grey" + , position = TopSize C 99 30 + , commands = + [ Run Cpu ["-t", "cpu: %"] 10 + , Run Network "enp3s0" ["-S", "True", "-t", "eth: /"] 10 + , Run Memory ["-t","mem: %"] 10 + , Run Date "date: %a %d %b %Y %H:%M:%S " "date" 10 + , Run StdinReader + ] + , sepChar = "%" + , alignSep = "}{" + , template = " %StdinReader% | %cpu% | %memory% | %enp3s0% }{%date% " + } + ''; + }; + + nmt.script = '' + assertFileExists home-files/.config/xmobar/.xmobarrc + assertFileContent \ + home-files/.config/xmobar/.xmobarrc \ + ${./basic-configuration.expected} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/xmobar/default.nix b/third_party/home-manager/tests/modules/programs/xmobar/default.nix new file mode 100644 index 0000000000..f1a3148908 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/xmobar/default.nix @@ -0,0 +1 @@ +{ xmobar-basic-configuration = ./basic-configuration.nix; } diff --git a/third_party/home-manager/tests/modules/programs/zsh/default.nix b/third_party/home-manager/tests/modules/programs/zsh/default.nix index 274ba0942e..81e0d2d415 100644 --- a/third_party/home-manager/tests/modules/programs/zsh/default.nix +++ b/third_party/home-manager/tests/modules/programs/zsh/default.nix @@ -4,5 +4,6 @@ zsh-history-path-new-custom = ./history-path-new-custom.nix; zsh-history-path-old-default = ./history-path-old-default.nix; zsh-history-path-old-custom = ./history-path-old-custom.nix; + zsh-history-ignore-pattern = ./history-ignore-pattern.nix; zsh-prezto = ./prezto.nix; } diff --git a/third_party/home-manager/tests/modules/programs/zsh/history-ignore-pattern.nix b/third_party/home-manager/tests/modules/programs/zsh/history-ignore-pattern.nix new file mode 100644 index 0000000000..ba423efe23 --- /dev/null +++ b/third_party/home-manager/tests/modules/programs/zsh/history-ignore-pattern.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ + ({ ... }: { config.programs.zsh.history.ignorePatterns = [ "echo *" ]; }) + ({ ... }: { config.programs.zsh.history.ignorePatterns = [ "rm *" ]; }) + ]; + + config = { + programs.zsh.enable = true; + + nixpkgs.overlays = + [ (self: super: { zsh = pkgs.writeScriptBin "dummy-zsh" ""; }) ]; + + nmt.script = '' + assertFileContains home-files/.zshrc "HISTORY_IGNORE='(echo *|rm *)'" + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/programs/zsh/prezto.nix b/third_party/home-manager/tests/modules/programs/zsh/prezto.nix index 118c2e7266..5bc95510d4 100644 --- a/third_party/home-manager/tests/modules/programs/zsh/prezto.nix +++ b/third_party/home-manager/tests/modules/programs/zsh/prezto.nix @@ -6,6 +6,18 @@ with lib; config = { programs.zsh.prezto.enable = true; + nixpkgs.overlays = [ + (self: super: { + zsh-prezto = super.runCommandLocal "dummy-zsh-prezto" { } '' + mkdir -p $out/share/zsh-prezto/runcoms + echo '# zprofile' > $out/share/zsh-prezto/runcoms/zprofile + echo '# zlogin' > $out/share/zsh-prezto/runcoms/zlogin + echo '# zlogout' > $out/share/zsh-prezto/runcoms/zlogout + echo '# zshenv' > $out/share/zsh-prezto/runcoms/zshenv + ''; + }) + ]; + nmt.script = '' assertFileExists home-files/.zpreztorc ''; diff --git a/third_party/home-manager/tests/modules/services/barrier/basic-configuration.nix b/third_party/home-manager/tests/modules/services/barrier/basic-configuration.nix new file mode 100644 index 0000000000..83a9365e4e --- /dev/null +++ b/third_party/home-manager/tests/modules/services/barrier/basic-configuration.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +{ + config = { + services.barrier.client = { + enable = true; + server = "testServer"; + }; + + nixpkgs.overlays = + [ (self: super: { barrier = pkgs.writeScriptBin "dummy-barrier" ""; }) ]; + + nmt.script = '' + clientServiceFile=home-files/.config/systemd/user/barrierc.service + + assertFileExists $clientServiceFile + assertFileRegex $clientServiceFile 'ExecStart=.*/bin/barrierc --enable-crypto -f testServer' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/barrier/default.nix b/third_party/home-manager/tests/modules/services/barrier/default.nix new file mode 100644 index 0000000000..d36f79532a --- /dev/null +++ b/third_party/home-manager/tests/modules/services/barrier/default.nix @@ -0,0 +1 @@ +{ barrier-basic-configuration = ./basic-configuration.nix; } diff --git a/third_party/home-manager/tests/modules/services/emacs/default.nix b/third_party/home-manager/tests/modules/services/emacs/default.nix index af27538d99..86f68c4c87 100644 --- a/third_party/home-manager/tests/modules/services/emacs/default.nix +++ b/third_party/home-manager/tests/modules/services/emacs/default.nix @@ -1,5 +1,6 @@ { - emacs-service = ./emacs-service.nix; - emacs-socket-26 = ./emacs-socket-26.nix; + emacs-service-27 = ./emacs-service-27.nix; + emacs-service-28 = ./emacs-service-28.nix; emacs-socket-27 = ./emacs-socket-27.nix; + emacs-socket-28 = ./emacs-socket-28.nix; } diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-emacsclient.desktop b/third_party/home-manager/tests/modules/services/emacs/emacs-27-emacsclient.desktop similarity index 87% rename from third_party/home-manager/tests/modules/services/emacs/emacs-emacsclient.desktop rename to third_party/home-manager/tests/modules/services/emacs/emacs-27-emacsclient.desktop index 1dafb4e0f1..89503c7902 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-emacsclient.desktop +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-27-emacsclient.desktop @@ -1,9 +1,10 @@ [Desktop Entry] -Categories=Utility;TextEditor; +Categories=Development;TextEditor; Comment=Edit text Exec=@emacs@/bin/emacsclient -c %F GenericName=Text Editor Icon=emacs +Keywords=Text;Editor; MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; Name=Emacs Client StartupWMClass=Emacs diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-28-emacsclient.desktop b/third_party/home-manager/tests/modules/services/emacs/emacs-28-emacsclient.desktop new file mode 100644 index 0000000000..96b7275255 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-28-emacsclient.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Categories=Development;TextEditor; +Comment=Edit text +Exec=@emacs@/bin/emacsclient -c %F +GenericName=Text Editor +Icon=emacs +Keywords=Text;Editor; +MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; +Name=Emacs Client +StartupWMClass=Emacsd +Terminal=false +Type=Application diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-service.nix b/third_party/home-manager/tests/modules/services/emacs/emacs-service-27.nix similarity index 89% rename from third_party/home-manager/tests/modules/services/emacs/emacs-service.nix rename to third_party/home-manager/tests/modules/services/emacs/emacs-service-27.nix index be27e9ab33..fa5f9f62bb 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-service.nix +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-service-27.nix @@ -6,7 +6,7 @@ with lib; config = { nixpkgs.overlays = [ (self: super: rec { - emacs = pkgs.writeShellScriptBin "dummy-emacs" "" // { + emacs = pkgs.writeShellScriptBin "dummy-emacs-27.2" "" // { outPath = "@emacs@"; }; emacsPackagesFor = _: @@ -31,7 +31,7 @@ with lib; } } assertFileContent home-path/share/applications/emacsclient.desktop \ - ${./emacs-emacsclient.desktop} + ${./emacs-27-emacsclient.desktop} ''; }; } diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-service-28.nix b/third_party/home-manager/tests/modules/services/emacs/emacs-service-28.nix new file mode 100644 index 0000000000..092cd14533 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-service-28.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + nixpkgs.overlays = [ + (self: super: rec { + emacs = pkgs.writeShellScriptBin "dummy-emacs-28.0.5" "" // { + outPath = "@emacs@"; + }; + emacsPackagesFor = _: + makeScope super.newScope (_: { emacsWithPackages = _: emacs; }); + }) + ]; + + programs.emacs.enable = true; + services.emacs.enable = true; + services.emacs.client.enable = true; + + nmt.script = '' + assertPathNotExists home-files/.config/systemd/user/emacs.socket + assertFileExists home-files/.config/systemd/user/emacs.service + assertFileExists home-path/share/applications/emacsclient.desktop + + assertFileContent home-files/.config/systemd/user/emacs.service \ + ${ + pkgs.substituteAll { + inherit (pkgs) runtimeShell; + src = ./emacs-service-emacs.service; + } + } + assertFileContent home-path/share/applications/emacsclient.desktop \ + ${./emacs-28-emacsclient.desktop} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-service-emacs.service b/third_party/home-manager/tests/modules/services/emacs/emacs-service-emacs.service index d8a618a267..00b0c8eb2f 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-service-emacs.service +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-service-emacs.service @@ -3,10 +3,11 @@ WantedBy=default.target [Service] ExecStart=@runtimeShell@ -l -c "@emacs@/bin/emacs --fg-daemon" -ExecStop=@emacs@/bin/emacsclient --eval '(kill-emacs 0)' Restart=on-failure +SuccessExitStatus=15 +Type=notify [Unit] -Description=Emacs: the extensible, self-documenting text editor +Description=Emacs text editor Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ X-RestartIfChanged=false diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.service b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.service deleted file mode 100644 index 2d731c7ee1..0000000000 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.service +++ /dev/null @@ -1,9 +0,0 @@ -[Service] -ExecStart=@runtimeShell@ -l -c "@emacs@/bin/emacs --fg-daemon='%T/emacs%U/server'" -ExecStop=@emacs@/bin/emacsclient --eval '(kill-emacs 0)' -Restart=on-failure - -[Unit] -Description=Emacs: the extensible, self-documenting text editor -Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ -X-RestartIfChanged=false diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.socket b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.socket deleted file mode 100644 index d2fa78e226..0000000000 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26-emacs.socket +++ /dev/null @@ -1,12 +0,0 @@ -[Install] -WantedBy=sockets.target - -[Socket] -DirectoryMode=0700 -FileDescriptorName=server -ListenStream=%T/emacs%U/server -SocketMode=0600 - -[Unit] -Description=Emacs: the extensible, self-documenting text editor -Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27.nix b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27.nix index 213dedca51..0fd1be1be7 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27.nix +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27.nix @@ -8,7 +8,7 @@ in { config = { nixpkgs.overlays = [ (self: super: rec { - emacs = pkgs.writeShellScriptBin "dummy-emacs-27.0.91" "" // { + emacs = pkgs.writeShellScriptBin "dummy-emacs-27.2" "" // { outPath = "@emacs@"; }; emacsPackagesFor = _: @@ -27,16 +27,16 @@ in { assertFileExists home-path/share/applications/emacsclient.desktop assertFileContent home-files/.config/systemd/user/emacs.socket \ - ${./emacs-socket-27-emacs.socket} + ${./emacs-socket-emacs.socket} assertFileContent home-files/.config/systemd/user/emacs.service \ ${ pkgs.substituteAll { - inherit (pkgs) runtimeShell; - src = ./emacs-socket-27-emacs.service; + inherit (pkgs) runtimeShell coreutils; + src = ./emacs-socket-emacs.service; } } assertFileContent home-path/share/applications/emacsclient.desktop \ - ${./emacs-emacsclient.desktop} + ${./emacs-27-emacsclient.desktop} ''; }; } diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26.nix b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-28.nix similarity index 75% rename from third_party/home-manager/tests/modules/services/emacs/emacs-socket-26.nix rename to third_party/home-manager/tests/modules/services/emacs/emacs-socket-28.nix index 65f06159e4..d2c04239c7 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-26.nix +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-28.nix @@ -2,11 +2,13 @@ with lib; -{ +let + +in { config = { nixpkgs.overlays = [ (self: super: rec { - emacs = pkgs.writeShellScriptBin "dummy-emacs-26.3" "" // { + emacs = pkgs.writeShellScriptBin "dummy-emacs-28.0.5" "" // { outPath = "@emacs@"; }; emacsPackagesFor = _: @@ -25,16 +27,16 @@ with lib; assertFileExists home-path/share/applications/emacsclient.desktop assertFileContent home-files/.config/systemd/user/emacs.socket \ - ${./emacs-socket-26-emacs.socket} + ${./emacs-socket-emacs.socket} assertFileContent home-files/.config/systemd/user/emacs.service \ ${ pkgs.substituteAll { - inherit (pkgs) runtimeShell; - src = ./emacs-socket-26-emacs.service; + inherit (pkgs) runtimeShell coreutils; + src = ./emacs-socket-emacs.service; } } assertFileContent home-path/share/applications/emacsclient.desktop \ - ${./emacs-emacsclient.desktop} + ${./emacs-28-emacsclient.desktop} ''; }; } diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27-emacs.service b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-emacs.service similarity index 51% rename from third_party/home-manager/tests/modules/services/emacs/emacs-socket-27-emacs.service rename to third_party/home-manager/tests/modules/services/emacs/emacs-socket-emacs.service index 408a5d24b5..a3687ead3e 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27-emacs.service +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-emacs.service @@ -1,9 +1,13 @@ [Service] ExecStart=@runtimeShell@ -l -c "@emacs@/bin/emacs --fg-daemon='%t/emacs/server'" -ExecStop=@emacs@/bin/emacsclient --eval '(kill-emacs 0)' +ExecStartPost=@coreutils@/bin/chmod --changes -w %t/emacs +ExecStopPost=@coreutils@/bin/chmod --changes +w %t/emacs Restart=on-failure +SuccessExitStatus=15 +Type=notify [Unit] -Description=Emacs: the extensible, self-documenting text editor +Description=Emacs text editor Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ +RefuseManualStart=true X-RestartIfChanged=false diff --git a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27-emacs.socket b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-emacs.socket similarity index 76% rename from third_party/home-manager/tests/modules/services/emacs/emacs-socket-27-emacs.socket rename to third_party/home-manager/tests/modules/services/emacs/emacs-socket-emacs.socket index 8fa68bf591..7fffcb0d00 100644 --- a/third_party/home-manager/tests/modules/services/emacs/emacs-socket-27-emacs.socket +++ b/third_party/home-manager/tests/modules/services/emacs/emacs-socket-emacs.socket @@ -8,5 +8,5 @@ ListenStream=%t/emacs/server SocketMode=0600 [Unit] -Description=Emacs: the extensible, self-documenting text editor +Description=Emacs text editor Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ diff --git a/third_party/home-manager/tests/modules/services/gpg-agent/default-homedir.nix b/third_party/home-manager/tests/modules/services/gpg-agent/default-homedir.nix new file mode 100644 index 0000000000..f7ebf5739e --- /dev/null +++ b/third_party/home-manager/tests/modules/services/gpg-agent/default-homedir.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + services.gpg-agent.enable = true; + programs.gpg.enable = true; + + nixpkgs.overlays = + [ (self: super: { gnupg = pkgs.writeScriptBin "dummy-gnupg" ""; }) ]; + + nmt.script = '' + in="${config.systemd.user.sockets.gpg-agent.Socket.ListenStream}" + if [[ $in != "%t/gnupg/S.gpg-agent" ]] + then + echo $in + fail "gpg-agent socket directory not set to default value" + fi + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/gpg-agent/default.nix b/third_party/home-manager/tests/modules/services/gpg-agent/default.nix new file mode 100644 index 0000000000..cf34517b28 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/gpg-agent/default.nix @@ -0,0 +1,4 @@ +{ + gpg-agent-default-homedir = ./default-homedir.nix; + gpg-agent-override-homedir = ./override-homedir.nix; +} diff --git a/third_party/home-manager/tests/modules/services/gpg-agent/override-homedir.nix b/third_party/home-manager/tests/modules/services/gpg-agent/override-homedir.nix new file mode 100644 index 0000000000..6705a0014a --- /dev/null +++ b/third_party/home-manager/tests/modules/services/gpg-agent/override-homedir.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + services.gpg-agent.enable = true; + programs.gpg = { + enable = true; + homedir = "${config.home.homeDirectory}/foo/bar"; + }; + + nixpkgs.overlays = + [ (self: super: { gnupg = pkgs.writeScriptBin "dummy-gnupg" ""; }) ]; + + nmt.script = '' + in="${config.systemd.user.sockets.gpg-agent.Socket.ListenStream}" + if [[ $in != "%t/gnupg/d."????????????????????????"/S.gpg-agent" ]] + then + echo $in + fail "gpg-agent socket directory is malformed" + fi + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/lieer/lieer-service-expected.service b/third_party/home-manager/tests/modules/services/lieer/lieer-service-expected.service index 1110e85c47..8437b9895b 100644 --- a/third_party/home-manager/tests/modules/services/lieer/lieer-service-expected.service +++ b/third_party/home-manager/tests/modules/services/lieer/lieer-service-expected.service @@ -1,4 +1,5 @@ [Service] +Environment=NOTMUCH_CONFIG=/home/hm-user/.config/notmuch/notmuchrc ExecStart=@lieer@/bin/gmi sync Type=oneshot WorkingDirectory=/home/hm-user/Mail/hm@example.com diff --git a/third_party/home-manager/tests/modules/services/lieer/lieer-service.nix b/third_party/home-manager/tests/modules/services/lieer/lieer-service.nix index 03dcdc749b..af3074b0f3 100644 --- a/third_party/home-manager/tests/modules/services/lieer/lieer-service.nix +++ b/third_party/home-manager/tests/modules/services/lieer/lieer-service.nix @@ -9,8 +9,14 @@ with lib; services.lieer.enable = true; accounts.email.accounts = { - "hm@example.com".lieer.enable = true; - "hm@example.com".lieer.sync.enable = true; + "hm@example.com" = { + flavor = "gmail.com"; + lieer = { + enable = true; + sync.enable = true; + }; + notmuch.enable = true; + }; }; nixpkgs.overlays = [ diff --git a/third_party/home-manager/tests/modules/services/pantalaimon/basic-configuration.nix b/third_party/home-manager/tests/modules/services/pantalaimon/basic-configuration.nix new file mode 100644 index 0000000000..f04101c052 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/pantalaimon/basic-configuration.nix @@ -0,0 +1,29 @@ +{ config, pkgs, ... }: + +{ + config = { + services.pantalaimon = { + enable = true; + package = pkgs.writeScriptBin "dummy-pantalaimon" "" // { + outPath = "@pantalaimon@"; + }; + settings = { + Default = { + LogLevel = "Debug"; + SSL = true; + }; + local-matrix = { + Homeserver = "https://matrix.org"; + ListenAddress = "127.0.0.1"; + ListenPort = 8008; + }; + }; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/pantalaimon.service + assertFileExists $serviceFile + assertFileRegex $serviceFile 'ExecStart=@pantalaimon@/bin/pantalaimon -c /nix/store/.*-pantalaimon.conf' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/pantalaimon/default.nix b/third_party/home-manager/tests/modules/services/pantalaimon/default.nix new file mode 100644 index 0000000000..8c29efb406 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/pantalaimon/default.nix @@ -0,0 +1 @@ +{ pantalaimon-basic-configuration = ./basic-configuration.nix; } diff --git a/third_party/home-manager/tests/modules/services/pbgopy/default.nix b/third_party/home-manager/tests/modules/services/pbgopy/default.nix new file mode 100644 index 0000000000..c2c9d485dd --- /dev/null +++ b/third_party/home-manager/tests/modules/services/pbgopy/default.nix @@ -0,0 +1 @@ +{ pbgopy = import ./service.nix; } diff --git a/third_party/home-manager/tests/modules/services/pbgopy/service.nix b/third_party/home-manager/tests/modules/services/pbgopy/service.nix new file mode 100644 index 0000000000..fb03c355cd --- /dev/null +++ b/third_party/home-manager/tests/modules/services/pbgopy/service.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: { + config = { + services.pbgopy.enable = true; + + nixpkgs.overlays = [ + (self: super: { + pbgopy = pkgs.writeScriptBin "dummy-pbgopy" "" // { + outPath = "@pbgopy@"; + }; + }) + ]; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/pbgopy.service + + assertFileExists $serviceFile + + assertFileContains $serviceFile \ + 'ExecStart=@pbgopy@/bin/pbgopy serve --port 9090 --ttl 24h' + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/playerctld/basic.nix b/third_party/home-manager/tests/modules/services/playerctld/basic.nix new file mode 100644 index 0000000000..3c10a99f1b --- /dev/null +++ b/third_party/home-manager/tests/modules/services/playerctld/basic.nix @@ -0,0 +1,31 @@ +{ config, pkgs, ... }: + +{ + config = { + services.playerctld.enable = true; + services.playerctld.package = pkgs.writeScriptBin "playerctld" "" // { + outPath = "@playerctld@"; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/playerctld.service + + assertFileExists "$serviceFile" + + assertFileContent "$serviceFile" "${ + pkgs.writeText "playerctld-test" '' + [Install] + WantedBy=default.target + + [Service] + BusName=org.mpris.MediaPlayer2.playerctld + ExecStart=@playerctld@/bin/playerctld + Type=dbus + + [Unit] + Description=MPRIS media player daemon + '' + }" + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/playerctld/default.nix b/third_party/home-manager/tests/modules/services/playerctld/default.nix new file mode 100644 index 0000000000..93ed10aaf4 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/playerctld/default.nix @@ -0,0 +1 @@ +{ playerctld-basic = ./basic.nix; } diff --git a/third_party/home-manager/tests/modules/services/polybar/basic-configuration.conf b/third_party/home-manager/tests/modules/services/polybar/basic-configuration.conf index 54448a705f..10ea0f076e 100644 --- a/third_party/home-manager/tests/modules/services/polybar/basic-configuration.conf +++ b/third_party/home-manager/tests/modules/services/polybar/basic-configuration.conf @@ -12,6 +12,16 @@ label=%time% %date% time=%H:%M type=internal/date +[module/volume] +click-right=pavucontrol & +format-volume= +label-muted=🔇 +label-muted-foreground=#666 +ramp-volume-0=🔈 +ramp-volume-1=🔉 +ramp-volume-2=🔊 +type=internal/pulseaudio + [module/date] type = internal/date interval = 5 @@ -19,3 +29,4 @@ date = "%d.%m.%y" time = %H:%M format-prefix-foreground = ${colors.foreground-alt} label = %time% %date% + diff --git a/third_party/home-manager/tests/modules/services/polybar/basic-configuration.nix b/third_party/home-manager/tests/modules/services/polybar/basic-configuration.nix index a8886dab6d..fd23256c3d 100644 --- a/third_party/home-manager/tests/modules/services/polybar/basic-configuration.nix +++ b/third_party/home-manager/tests/modules/services/polybar/basic-configuration.nix @@ -22,6 +22,16 @@ label = "%time% %date%"; }; }; + settings = { + "module/volume" = { + type = "internal/pulseaudio"; + format.volume = " "; + label.muted.text = "🔇"; + label.muted.foreground = "#666"; + ramp.volume = [ "🔈" "🔉" "🔊" ]; + click.right = "pavucontrol &"; + }; + }; extraConfig = '' [module/date] type = internal/date diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/default.nix b/third_party/home-manager/tests/modules/services/redshift-gammastep/default.nix new file mode 100644 index 0000000000..78251059ac --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/default.nix @@ -0,0 +1,4 @@ +{ + gammastep-basic-configuration = ./gammastep-basic-configuration.nix; + redshift-basic-configuration = ./redshift-basic-configuration.nix; +} diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-expected.service b/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-expected.service new file mode 100644 index 0000000000..8d0e7a5fbc --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-expected.service @@ -0,0 +1,13 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +ExecStart=@gammastep@/bin/gammastep -v -c /home/hm-user/.config/gammastep/config.ini +Restart=on-failure +RestartSec=3 + +[Unit] +After=graphical-session-pre.target +Description=Gammastep colour temperature adjuster +Documentation=https://gitlab.com/chinstrap/gammastep/ +PartOf=graphical-session.target diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-file-expected.conf b/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-file-expected.conf new file mode 100644 index 0000000000..a33230a681 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration-file-expected.conf @@ -0,0 +1,13 @@ +[general] +adjustment-method=randr +dawn-time=6:00-7:45 +dusk-time=18:35-20:15 +gamma=0.800000 +location-provider=manual +temp-day=5500 +temp-night=3700 + +[manual] + +[randr] +screen=0 diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration.nix b/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration.nix new file mode 100644 index 0000000000..9ccf38528c --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/gammastep-basic-configuration.nix @@ -0,0 +1,36 @@ +{ config, pkgs, ... }: + +{ + config = { + services.gammastep = { + enable = true; + provider = "manual"; + dawnTime = "6:00-7:45"; + duskTime = "18:35-20:15"; + settings = { + general = { + adjustment-method = "randr"; + gamma = 0.8; + }; + randr = { screen = 0; }; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + gammastep = pkgs.writeScriptBin "dummy-gammastep" "" // { + outPath = "@gammastep@"; + }; + }) + ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/gammastep/config.ini \ + ${./gammastep-basic-configuration-file-expected.conf} + assertFileContent \ + home-files/.config/systemd/user/gammastep.service \ + ${./gammastep-basic-configuration-expected.service} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-expected.service b/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-expected.service new file mode 100644 index 0000000000..07ffbf06d8 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-expected.service @@ -0,0 +1,13 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +ExecStart=@redshift@/bin/redshift -v -c /home/hm-user/.config/redshift/redshift.conf +Restart=on-failure +RestartSec=3 + +[Unit] +After=graphical-session-pre.target +Description=Redshift colour temperature adjuster +Documentation=http://jonls.dk/redshift/ +PartOf=graphical-session.target diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-file-expected.conf b/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-file-expected.conf new file mode 100644 index 0000000000..f2aab6a530 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration-file-expected.conf @@ -0,0 +1,13 @@ +[manual] +lat=0.000000 +lon=0.0 + +[randr] +screen=0 + +[redshift] +adjustment-method=randr +gamma=0.800000 +location-provider=manual +temp-day=5500 +temp-night=3700 diff --git a/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration.nix b/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration.nix new file mode 100644 index 0000000000..5e2fe40e0e --- /dev/null +++ b/third_party/home-manager/tests/modules/services/redshift-gammastep/redshift-basic-configuration.nix @@ -0,0 +1,36 @@ +{ config, pkgs, ... }: + +{ + config = { + services.redshift = { + enable = true; + provider = "manual"; + latitude = 0.0; + longitude = "0.0"; + settings = { + redshift = { + adjustment-method = "randr"; + gamma = 0.8; + }; + randr = { screen = 0; }; + }; + }; + + nixpkgs.overlays = [ + (self: super: { + redshift = pkgs.writeScriptBin "dummy-redshift" "" // { + outPath = "@redshift@"; + }; + }) + ]; + + nmt.script = '' + assertFileContent \ + home-files/.config/redshift/redshift.conf \ + ${./redshift-basic-configuration-file-expected.conf} + assertFileContent \ + home-files/.config/systemd/user/redshift.service \ + ${./redshift-basic-configuration-expected.service} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/sxhkd/configuration.nix b/third_party/home-manager/tests/modules/services/sxhkd/configuration.nix index 03206a8d52..e9d85477b0 100644 --- a/third_party/home-manager/tests/modules/services/sxhkd/configuration.nix +++ b/third_party/home-manager/tests/modules/services/sxhkd/configuration.nix @@ -3,6 +3,10 @@ services.sxhkd = { enable = true; + package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out" // { + outPath = "@sxhkd@"; + }; + keybindings = { "super + a" = "run command a"; "super + b" = null; @@ -19,9 +23,6 @@ ''; }; - nixpkgs.overlays = - [ (self: super: { sxhkd = pkgs.writeScriptBin "dummy-sxhkd" ""; }) ]; - nmt.script = '' sxhkdrc=home-files/.config/sxhkd/sxhkdrc diff --git a/third_party/home-manager/tests/modules/services/sxhkd/service.nix b/third_party/home-manager/tests/modules/services/sxhkd/service.nix index 9b4fd70cc5..be51f544c5 100644 --- a/third_party/home-manager/tests/modules/services/sxhkd/service.nix +++ b/third_party/home-manager/tests/modules/services/sxhkd/service.nix @@ -1,20 +1,28 @@ -{ config, ... }: +{ config, pkgs, ... }: + { config = { + xsession = { + enable = true; + windowManager.command = ""; + }; + services.sxhkd = { enable = true; - extraPath = "/home/the-user/bin:/extra/path/bin"; + package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out" // { outPath = "@sxhkd@"; }; + extraOptions = [ "-m 1" ]; }; nmt.script = '' - serviceFile=home-files/.config/systemd/user/sxhkd.service + xsessionFile=home-files/.xsession - assertFileExists $serviceFile + assertFileExists $xsessionFile - assertFileRegex $serviceFile 'ExecStart=.*/bin/sxhkd' + assertFileContains $xsessionFile \ + 'systemctl --user stop sxhkd.scope 2> /dev/null || true' - assertFileRegex $serviceFile \ - 'Environment=PATH=.*\.nix-profile/bin:/home/the-user/bin:/extra/path/bin' + assertFileContains $xsessionFile \ + 'systemd-cat -t sxhkd systemd-run --user --scope -u sxhkd @sxhkd@/bin/sxhkd -m 1 &' ''; }; } diff --git a/third_party/home-manager/tests/modules/services/syncthing/default.nix b/third_party/home-manager/tests/modules/services/syncthing/default.nix new file mode 100644 index 0000000000..14136fe637 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/syncthing/default.nix @@ -0,0 +1,4 @@ +{ + syncthing-tray = ./tray.nix; + syncthing-tray-as-bool-triggers-warning = ./tray-as-bool-triggers-warning.nix; +} diff --git a/third_party/home-manager/tests/modules/services/syncthing/tray-as-bool-triggers-warning.nix b/third_party/home-manager/tests/modules/services/syncthing/tray-as-bool-triggers-warning.nix new file mode 100644 index 0000000000..9f9dc2ba90 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/syncthing/tray-as-bool-triggers-warning.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + services.syncthing.tray = true; + + nixpkgs.overlays = [ + (self: super: { syncthingtray-minimal = pkgs.writeScriptBin "dummy" ""; }) + ]; + + test.asserts.warnings.expected = [ + "Specifying 'services.syncthing.tray' as a boolean is deprecated, set 'services.syncthing.tray.enable' instead. See https://github.com/nix-community/home-manager/pull/1257." + ]; + + nmt.script = '' + assertFileExists home-files/.config/systemd/user/syncthingtray.service + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/syncthing/tray.nix b/third_party/home-manager/tests/modules/services/syncthing/tray.nix new file mode 100644 index 0000000000..5ff3c2841f --- /dev/null +++ b/third_party/home-manager/tests/modules/services/syncthing/tray.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + services.syncthing.tray.enable = true; + + nixpkgs.overlays = [ + (self: super: { + syncthingtray-minimal = + pkgs.runCommandLocal "syncthingtray" { pname = "syncthingtray"; } + "mkdir $out"; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/systemd/user/syncthingtray.service + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/bspwm/bspwmrc b/third_party/home-manager/tests/modules/services/window-managers/bspwm/bspwmrc new file mode 100755 index 0000000000..7ebb64aca3 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/bspwm/bspwmrc @@ -0,0 +1,19 @@ +bspc monitor 'focused' -d 'desktop 1' 'd'\''esk top' + +bspc config 'border_width' '2' +bspc config 'external_rules_command' '/path/to/external rules command' +bspc config 'gapless_monocle' 'on' +bspc config 'ignore_ewmh_fullscreen' 'enter,exit' +bspc config 'split_ratio' '0.520000' + +bspc rule -r '*' +bspc rule -a '*' 'center=off' 'desktop=d'\''esk top#next' 'split_dir=north' 'sticky=on' + +# java gui fixes +export _JAVA_AWT_WM_NONREPARENTING=1 +bspc rule -a sun-awt-X11-XDialogPeer state=floating + +extra config + +foo & +bar || qux & diff --git a/third_party/home-manager/tests/modules/services/window-managers/bspwm/configuration.nix b/third_party/home-manager/tests/modules/services/window-managers/bspwm/configuration.nix new file mode 100644 index 0000000000..6c1effb628 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/bspwm/configuration.nix @@ -0,0 +1,40 @@ +{ lib, pkgs, ... }: + +with lib; + +{ + config = { + xsession.windowManager.bspwm = { + enable = true; + monitors.focused = + [ "desktop 1" "d'esk top" ]; # pathological desktop names + settings = { + border_width = 2; + split_ratio = 0.52; + gapless_monocle = true; + external_rules_command = "/path/to/external rules command"; + ignore_ewmh_fullscreen = [ "enter" "exit" ]; + }; + rules."*" = { + sticky = true; + center = false; + desktop = "d'esk top#next"; + splitDir = "north"; + border = null; + }; + extraConfig = '' + extra config + ''; + startupPrograms = [ "foo" "bar || qux" ]; + }; + + nmt.script = '' + bspwmrc=home-files/.config/bspwm/bspwmrc + assertFileExists "$bspwmrc" + assertFileIsExecutable "$bspwmrc" + assertFileContent "$bspwmrc" ${ + pkgs.writeShellScript "bspwmrc-expected" (readFile ./bspwmrc) + } + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/bspwm/default.nix b/third_party/home-manager/tests/modules/services/window-managers/bspwm/default.nix new file mode 100644 index 0000000000..45b5e2ae8a --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/bspwm/default.nix @@ -0,0 +1 @@ +{ bspwm-configuration = ./configuration.nix; } diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/default.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/default.nix index c523dfcd04..28631a1a5a 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/i3/default.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/default.nix @@ -1,4 +1,10 @@ { + i3-bar-focused-colors = ./i3-bar-focused-colors.nix; i3-followmouse = ./i3-followmouse.nix; + i3-fonts = ./i3-fonts.nix; + i3-fonts-deprecated = ./i3-fonts-deprecated.nix; i3-keybindings = ./i3-keybindings.nix; + i3-null-config = ./i3-null-config.nix; + i3-workspace-default = ./i3-workspace-default.nix; + i3-workspace-output = ./i3-workspace-output.nix; } diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf new file mode 100644 index 0000000000..c50f317ad9 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors-expected.conf @@ -0,0 +1,110 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border normal 2 +default_floating_border normal 2 +hide_edge_borders none +force_focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+0 workspace number 10 +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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 i3-sensible-terminal +bindsym Mod1+Right focus right +bindsym Mod1+Shift+0 move container to workspace number 10 +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit' +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+r restart +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h split h +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v split v +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px or 10 ppt +bindsym Escape mode default +bindsym Left resize shrink width 10 px or 10 ppt +bindsym Return mode default +bindsym Right resize grow width 10 px or 10 ppt +bindsym Up resize shrink height 10 px or 10 ppt +} + + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + i3bar_command @i3@/bin/i3bar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + focused_background #ffffff + focused_statusline #000000 + focused_separator #999999 + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + + + + + + diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors.nix new file mode 100644 index 0000000000..aaa6809f5b --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-bar-focused-colors.nix @@ -0,0 +1,25 @@ +{ config, lib, ... }: + +with lib; + +{ + config = { + xsession.windowManager.i3 = { + enable = true; + + config.bars = [{ + colors.focusedBackground = "#ffffff"; + colors.focusedStatusline = "#000000"; + colors.focusedSeparator = "#999999"; + }]; + }; + + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/i3/config + assertFileContent home-files/.config/i3/config \ + ${./i3-bar-focused-colors-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf index 729605be46..3d8ad0d21d 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse-expected.conf @@ -1,7 +1,7 @@ -font pango:monospace 8 +font pango:monospace 8.000000 floating_modifier Mod1 -new_window normal 2 -new_float normal 2 +default_border normal 2 +default_floating_border normal 2 hide_edge_borders none force_focus_wrapping no focus_follows_mouse no @@ -17,6 +17,7 @@ client.urgent #2f343a #900000 #ffffff #900000 #900000 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c client.background #ffffff + bindsym Mod1+0 workspace number 10 bindsym Mod1+1 workspace number 1 bindsym Mod1+2 workspace number 2 @@ -76,7 +77,7 @@ bindsym Up resize shrink height 10 px or 10 ppt bar { - font pango:monospace 8 + font pango:monospace 8.000000 mode dock hidden_state hide position bottom @@ -89,6 +90,9 @@ bar { background #000000 statusline #ffffff separator #666666 + + + focused_workspace #4c7899 #285577 #ffffff active_workspace #333333 #5f676a #ffffff inactive_workspace #333333 #222222 #888888 @@ -103,3 +107,4 @@ bar { + diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse.nix index 8d51e34887..43e15cda39 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-followmouse.nix @@ -14,7 +14,9 @@ with lib; (self: super: { dmenu = super.dmenu // { outPath = "@dmenu@"; }; - i3 = super.i3 // { outPath = "@i3@"; }; + i3 = super.writeScriptBin "i3" "" // { outPath = "@i3@"; }; + + i3-gaps = super.writeScriptBin "i3" "" // { outPath = "@i3-gaps@"; }; i3status = super.i3status // { outPath = "@i3status@"; }; }) diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-deprecated.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-deprecated.nix new file mode 100644 index 0000000000..c5142ed457 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-deprecated.nix @@ -0,0 +1,29 @@ +{ config, lib, ... }: + +with lib; + +{ + config = { + xsession.windowManager.i3 = { + enable = true; + + config = { + bars = [{ fonts = [ "FontAwesome" "Iosevka 11.500000" ]; }]; + fonts = [ "DejaVuSansMono" "Terminus Bold Semi-Condensed 13.500000" ]; + }; + }; + + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/i3/config + assertFileContent home-files/.config/i3/config \ + ${./i3-fonts-expected.conf} + ''; + + test.asserts.warnings.expected = [ + "Specifying i3.config.fonts as a list is deprecated. Use the attrset version instead." + "Specifying i3.config.bars[].fonts as a list is deprecated. Use the attrset version instead." + ]; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-expected.conf new file mode 100644 index 0000000000..8a565bc3fc --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts-expected.conf @@ -0,0 +1,110 @@ +font pango:DejaVuSansMono, Terminus Bold Semi-Condensed 13.500000 +floating_modifier Mod1 +default_border normal 2 +default_floating_border normal 2 +hide_edge_borders none +force_focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+0 workspace number 10 +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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 i3-sensible-terminal +bindsym Mod1+Right focus right +bindsym Mod1+Shift+0 move container to workspace number 10 +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit' +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+r restart +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h split h +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v split v +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px or 10 ppt +bindsym Escape mode default +bindsym Left resize shrink width 10 px or 10 ppt +bindsym Return mode default +bindsym Right resize grow width 10 px or 10 ppt +bindsym Up resize shrink height 10 px or 10 ppt +} + + +bar { + + font pango:FontAwesome, Iosevka 11.500000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + i3bar_command @i3@/bin/i3bar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + + + + + + diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts.nix new file mode 100644 index 0000000000..20ea5cabe3 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-fonts.nix @@ -0,0 +1,33 @@ +{ config, lib, ... }: + +with lib; + +{ + config = { + xsession.windowManager.i3 = { + enable = true; + + config = { + bars = [{ + fonts = { + names = [ "FontAwesome" "Iosevka" ]; + size = 11.5; + }; + }]; + fonts = { + names = [ "DejaVuSansMono" "Terminus" ]; + style = "Bold Semi-Condensed"; + size = 13.5; + }; + }; + }; + + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/i3/config + assertFileContent home-files/.config/i3/config \ + ${./i3-fonts-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf index 1e385e8c73..6c310baac9 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings-expected.conf @@ -1,7 +1,7 @@ -font pango:monospace 8 +font pango:monospace 8.000000 floating_modifier Mod1 -new_window normal 2 -new_float normal 2 +default_border normal 2 +default_floating_border normal 2 hide_edge_borders none force_focus_wrapping no focus_follows_mouse yes @@ -17,6 +17,7 @@ client.urgent #2f343a #900000 #ffffff #900000 #900000 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c client.background #ffffff + bindsym Mod1+0 workspace number 10 bindsym Mod1+1 workspace number 1 bindsym Mod1+2 workspace number 2 @@ -77,7 +78,7 @@ bindsym Up resize shrink height 10 px or 10 ppt bar { - font pango:monospace 8 + font pango:monospace 8.000000 mode dock hidden_state hide position bottom @@ -90,6 +91,9 @@ bar { background #000000 statusline #ffffff separator #666666 + + + focused_workspace #4c7899 #285577 #ffffff active_workspace #333333 #5f676a #ffffff inactive_workspace #333333 #222222 #888888 @@ -104,3 +108,4 @@ bar { + diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings.nix index 4f8515e61f..bc3cae6e0f 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-keybindings.nix @@ -16,15 +16,7 @@ with lib; }; }; - nixpkgs.overlays = [ - (self: super: { - dmenu = super.dmenu // { outPath = "@dmenu@"; }; - - i3 = super.i3 // { outPath = "@i3@"; }; - - i3status = super.i3status // { outPath = "@i3status@"; }; - }) - ]; + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; nmt.script = '' assertFileExists home-files/.config/i3/config diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-null-config.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-null-config.nix new file mode 100644 index 0000000000..a9b3788245 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-null-config.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + xsession.windowManager.i3 = { + enable = true; + config = null; + }; + + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/i3/config + assertFileContent home-files/.config/i3/config \ + ${pkgs.writeText "expected" "\n"} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-overlay.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-overlay.nix new file mode 100644 index 0000000000..fead262f47 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-overlay.nix @@ -0,0 +1,12 @@ +self: super: +# Avoid unnecessary downloads in CI jobs and/or make out paths +# constant, i.e., not containing hashes, version numbers etc. +{ + dmenu = super.dmenu // { outPath = "@dmenu@"; }; + + i3 = super.writeScriptBin "i3" "" // { outPath = "@i3@"; }; + + i3-gaps = super.writeScriptBin "i3" "" // { outPath = "@i3-gaps@"; }; + + i3status = super.i3status // { outPath = "@i3status@"; }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf new file mode 100644 index 0000000000..d214a96b48 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default-expected.conf @@ -0,0 +1,109 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border normal 2 +default_floating_border normal 2 +hide_edge_borders none +force_focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + +bindsym Mod1+1 workspace number 1 +bindsym Mod1+0 workspace number 10 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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 i3-sensible-terminal +bindsym Mod1+Right focus right +bindsym Mod1+Shift+0 move container to workspace number 10 +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit' +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+r restart +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h split h +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v split v +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px or 10 ppt +bindsym Escape mode default +bindsym Left resize shrink width 10 px or 10 ppt +bindsym Return mode default +bindsym Right resize grow width 10 px or 10 ppt +bindsym Up resize shrink height 10 px or 10 ppt +} + + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + i3bar_command @i3@/bin/i3bar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + + + + + + diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default.nix new file mode 100644 index 0000000000..0a825b1e86 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-default.nix @@ -0,0 +1,21 @@ +{ config, lib, ... }: + +with lib; + +{ + config = { + xsession.windowManager.i3 = { + enable = true; + + config.defaultWorkspace = "workspace number 1"; + }; + + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/i3/config + assertFileContent home-files/.config/i3/config \ + ${./i3-workspace-default-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf new file mode 100644 index 0000000000..9166cf9bbe --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output-expected.conf @@ -0,0 +1,113 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border normal 2 +default_floating_border normal 2 +hide_edge_borders none +force_focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+0 workspace number 10 +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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 i3-sensible-terminal +bindsym Mod1+Right focus right +bindsym Mod1+Shift+0 move container to workspace number 10 +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit' +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+r restart +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h split h +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v split v +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px or 10 ppt +bindsym Escape mode default +bindsym Left resize shrink width 10 px or 10 ppt +bindsym Return mode default +bindsym Right resize grow width 10 px or 10 ppt +bindsym Up resize shrink height 10 px or 10 ppt +} + + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + i3bar_command @i3@/bin/i3bar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + + + + +workspace "1" output eDP +workspace "ABC" output DP +workspace "3: Test" output HDMI +workspace "!"§$%&/(){}[]=?\*#<>-_.:,;²³" output DVI + diff --git a/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output.nix b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output.nix new file mode 100644 index 0000000000..b2ff90e028 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/i3/i3-workspace-output.nix @@ -0,0 +1,46 @@ +{ config, lib, ... }: + +with lib; + +{ + config = let + i3 = { + ws1 = "1"; + ws2 = "ABC"; + ws3 = "3: Test"; + ws4 = ''!"§$%&/(){}[]=?\*#<>-_.:,;²³''; + }; + + in { + xsession.windowManager.i3 = { + enable = true; + + config.workspaceOutputAssign = [ + { + workspace = "${i3.ws1}"; + output = "eDP"; + } + { + workspace = "${i3.ws2}"; + output = "DP"; + } + { + workspace = "${i3.ws3}"; + output = "HDMI"; + } + { + workspace = "${i3.ws4}"; + output = "DVI"; + } + ]; + }; + + nixpkgs.overlays = [ (import ./i3-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/i3/config + assertFileContent home-files/.config/i3/config \ + ${./i3-workspace-output-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/default.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/default.nix index b9c0ab5e09..16f7751cb0 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/default.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/default.nix @@ -1,6 +1,12 @@ { + sway-bar-focused-colors = ./sway-bar-focused-colors.nix; sway-default = ./sway-default.nix; sway-post-2003 = ./sway-post-2003.nix; sway-followmouse = ./sway-followmouse.nix; sway-followmouse-legacy = ./sway-followmouse-legacy.nix; + sway-null-config = ./sway-null-config.nix; + sway-null-package = ./sway-null-package.nix; + sway-modules = ./sway-modules.nix; + sway-workspace-default = ./sway-workspace-default.nix; + sway-workspace-output = ./sway-workspace-output.nix; } diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf new file mode 100644 index 0000000000..dc8319d6b8 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.conf @@ -0,0 +1,114 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border pixel 2 +default_floating_border pixel 2 +hide_edge_borders none +focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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+Right focus right +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' +bindsym Mod1+Shift+h move left +bindsym Mod1+Shift+j move down +bindsym Mod1+Shift+k move up +bindsym Mod1+Shift+l move right +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+b splith +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h focus left +bindsym Mod1+j focus down +bindsym Mod1+k focus up +bindsym Mod1+l focus right +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v splitv +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px +bindsym Escape mode default +bindsym Left resize shrink width 10 px +bindsym Return mode default +bindsym Right resize grow width 10 px +bindsym Up resize shrink height 10 px +bindsym h resize shrink width 10 px +bindsym j resize grow height 10 px +bindsym k resize shrink height 10 px +bindsym l resize grow width 10 px +} + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + swaybar_command @sway/bin/swaybar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + focused_background #ffffff + focused_statusline #000000 + focused_separator #999999 + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + +exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.nix new file mode 100644 index 0000000000..8b3df36ef1 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-bar-focused-colors.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { + config = { + wayland.windowManager.sway = { + enable = true; + package = dummy-package // { outPath = "@sway"; }; + # overriding findutils causes issues + config.menu = "${pkgs.dmenu}/bin/dmenu_run"; + + config.bars = [{ + colors.focusedBackground = "#ffffff"; + colors.focusedStatusline = "#000000"; + colors.focusedSeparator = "#999999"; + }]; + }; + + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-bar-focused-colors.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.conf index da5b1f47ee..cbcd2d8320 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.conf +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.conf @@ -1,4 +1,4 @@ -font pango:monospace 8 +font pango:monospace 8.000000 floating_modifier Mod1 default_border pixel 2 default_floating_border pixel 2 @@ -17,6 +17,7 @@ client.urgent #2f343a #900000 #ffffff #900000 #900000 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c client.background #ffffff + bindsym Mod1+1 workspace number 1 bindsym Mod1+2 workspace number 2 bindsym Mod1+3 workspace number 3 @@ -69,8 +70,6 @@ bindsym Mod1+space focus mode_toggle bindsym Mod1+v splitv bindsym Mod1+w layout tabbed - - mode "resize" { bindsym Down resize grow height 10 px bindsym Escape mode default @@ -84,10 +83,9 @@ bindsym k resize shrink height 10 px bindsym l resize grow width 10 px } - bar { - font pango:monospace 8 + font pango:monospace 8.000000 mode dock hidden_state hide position bottom @@ -100,6 +98,9 @@ bar { background #000000 statusline #ffffff separator #666666 + + + focused_workspace #4c7899 #285577 #ffffff active_workspace #333333 #5f676a #ffffff inactive_workspace #333333 #222222 #888888 @@ -110,8 +111,4 @@ bar { } - - - - exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.nix index 09c388c1c5..141f6303e2 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-default.nix @@ -2,27 +2,20 @@ with lib; -{ +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { config = { wayland.windowManager.sway = { enable = true; - package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out" // { - outPath = "@sway"; - }; + package = dummy-package // { outPath = "@sway"; }; # overriding findutils causes issues config.menu = "${pkgs.dmenu}/bin/dmenu_run"; }; - nixpkgs.overlays = [ - (self: super: { - dummy-package = super.runCommandLocal "dummy-package" { } "mkdir $out"; - dmenu = self.dummy-package // { outPath = "@dmenu@"; }; - rxvt-unicode-unwrapped = self.dummy-package // { - outPath = "@rxvt-unicode-unwrapped@"; - }; - i3status = self.dummy-package // { outPath = "@i3status@"; }; - }) - ]; + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; nmt.script = '' assertFileExists home-files/.config/sway/config diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf index 198ce4bd37..4eae367946 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-expected.conf @@ -1,4 +1,4 @@ -font pango:monospace 8 +font pango:monospace 8.000000 floating_modifier Mod1 default_border pixel 2 default_floating_border pixel 2 @@ -17,6 +17,7 @@ client.urgent #2f343a #900000 #ffffff #900000 #900000 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c client.background #ffffff + bindsym Mod1+1 workspace number 1 bindsym Mod1+2 workspace number 2 bindsym Mod1+3 workspace number 3 @@ -69,8 +70,6 @@ bindsym Mod1+space focus mode_toggle bindsym Mod1+v splitv bindsym Mod1+w layout tabbed - - mode "resize" { bindsym Down resize grow height 10 px bindsym Escape mode default @@ -85,10 +84,4 @@ bindsym l resize grow width 10 px } - - - - - - exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf index cbc55722a0..c6497eb6dd 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy-expected.conf @@ -1,4 +1,4 @@ -font pango:monospace 8 +font pango:monospace 8.000000 floating_modifier Mod1 default_border pixel 2 default_floating_border pixel 2 @@ -17,6 +17,7 @@ client.urgent #2f343a #900000 #ffffff #900000 #900000 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c client.background #ffffff + bindsym Mod1+1 workspace number 1 bindsym Mod1+2 workspace number 2 bindsym Mod1+3 workspace number 3 @@ -69,8 +70,6 @@ bindsym Mod1+space focus mode_toggle bindsym Mod1+v splitv bindsym Mod1+w layout tabbed - - mode "resize" { bindsym Down resize grow height 10 px bindsym Escape mode default @@ -85,10 +84,4 @@ bindsym l resize grow width 10 px } - - - - - - exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy.nix index 9b80a63bc5..b83c8d1ba2 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse-legacy.nix @@ -2,10 +2,15 @@ with lib; -{ +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { config = { wayland.windowManager.sway = { enable = true; + package = dummy-package // { outPath = "@sway"; }; config = { focus.followMouse = false; @@ -14,19 +19,7 @@ with lib; }; }; - nixpkgs.overlays = [ - (self: super: { - dmenu = super.dmenu // { outPath = "@dmenu@"; }; - rxvt-unicode-unwrapped = super.rxvt-unicode-unwrapped // { - outPath = "@rxvt-unicode-unwrapped@"; - }; - sway-unwrapped = - pkgs.runCommandLocal "dummy-sway-unwrapped" { version = "1"; } - "mkdir $out"; - swaybg = pkgs.writeScriptBin "dummy-swaybg" ""; - xwayland = pkgs.writeScriptBin "xwayland" ""; - }) - ]; + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; nmt.script = '' assertFileExists home-files/.config/sway/config diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse.nix index e05b4e56fc..9d18b6913e 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-followmouse.nix @@ -2,10 +2,15 @@ with lib; -{ +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { config = { wayland.windowManager.sway = { enable = true; + package = dummy-package // { outPath = "@sway"; }; config = { focus.followMouse = "always"; @@ -14,19 +19,7 @@ with lib; }; }; - nixpkgs.overlays = [ - (self: super: { - dmenu = super.dmenu // { outPath = "@dmenu@"; }; - rxvt-unicode-unwrapped = super.rxvt-unicode-unwrapped // { - outPath = "@rxvt-unicode-unwrapped@"; - }; - sway-unwrapped = - pkgs.runCommandLocal "dummy-sway-unwrapped" { version = "1"; } - "mkdir $out"; - swaybg = pkgs.writeScriptBin "dummy-swaybg" ""; - xwayland = pkgs.writeScriptBin "xwayland" ""; - }) - ]; + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; nmt.script = '' assertFileExists home-files/.config/sway/config diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.conf new file mode 100644 index 0000000000..ee63330544 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.conf @@ -0,0 +1,126 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border pixel 2 +default_floating_border pixel 2 +hide_edge_borders none +focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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+Right focus right +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' +bindsym Mod1+Shift+h move left +bindsym Mod1+Shift+j move down +bindsym Mod1+Shift+k move up +bindsym Mod1+Shift+l move right +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+b splith +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h focus left +bindsym Mod1+j focus down +bindsym Mod1+k focus up +bindsym Mod1+l focus right +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v splitv +bindsym Mod1+w layout tabbed + +input "*" { +xkb_variant dvorak +} + +output "HDMI-A-2" { +bg ~/path/to/background.png fill +} + +seat "*" { +hide_cursor when-typing enable +} + +mode "resize" { +bindsym Down resize grow height 10 px +bindsym Escape mode default +bindsym Left resize shrink width 10 px +bindsym Return mode default +bindsym Right resize grow width 10 px +bindsym Up resize shrink height 10 px +bindsym h resize shrink width 10 px +bindsym j resize grow height 10 px +bindsym k resize shrink height 10 px +bindsym l resize grow width 10 px +} + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + swaybar_command @sway/bin/swaybar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + +exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.nix new file mode 100644 index 0000000000..fbe927f35b --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-modules.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { + config = { + wayland.windowManager.sway = { + enable = true; + package = dummy-package // { outPath = "@sway"; }; + # overriding findutils causes issues + config = { + menu = "${pkgs.dmenu}/bin/dmenu_run"; + + input = { "*" = { xkb_variant = "dvorak"; }; }; + output = { "HDMI-A-2" = { bg = "~/path/to/background.png fill"; }; }; + seat = { "*" = { hide_cursor = "when-typing enable"; }; }; + }; + }; + + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-modules.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-config.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-config.nix new file mode 100644 index 0000000000..fc01660cbd --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-config.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + wayland.windowManager.sway = { + enable = true; + config = null; + systemdIntegration = false; + package = pkgs.sway; + }; + + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${pkgs.writeText "expected" "\n"} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.conf new file mode 100644 index 0000000000..1cd75fd522 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.conf @@ -0,0 +1,114 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border pixel 2 +default_floating_border pixel 2 +hide_edge_borders none +focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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+Right focus right +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' +bindsym Mod1+Shift+h move left +bindsym Mod1+Shift+j move down +bindsym Mod1+Shift+k move up +bindsym Mod1+Shift+l move right +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+b splith +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h focus left +bindsym Mod1+j focus down +bindsym Mod1+k focus up +bindsym Mod1+l focus right +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v splitv +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px +bindsym Escape mode default +bindsym Left resize shrink width 10 px +bindsym Return mode default +bindsym Right resize grow width 10 px +bindsym Up resize shrink height 10 px +bindsym h resize shrink width 10 px +bindsym j resize grow height 10 px +bindsym k resize shrink height 10 px +bindsym l resize grow width 10 px +} + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + swaybar_command @sway@/bin/swaybar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + +exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.nix new file mode 100644 index 0000000000..3993d6389e --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-null-package.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { + config = { + # Enables the default bar configuration + home.stateVersion = "20.09"; + + wayland.windowManager.sway = { + enable = true; + package = null; + config.menu = "${pkgs.dmenu}/bin/dmenu_run"; + }; + + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; + + assertions = [{ + assertion = + !elem config.wayland.windowManager.sway.config.bars [ [ { } ] [ ] ]; + message = + "The default Sway bars configuration should be set for this test (sway-null-package) to work."; + }]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-null-package.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-overlay.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-overlay.nix new file mode 100644 index 0000000000..4edfb20557 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-overlay.nix @@ -0,0 +1,17 @@ +self: super: +# Avoid unnecessary downloads in CI jobs. +let dummy-package = super.runCommandLocal "dummy-package" { } "mkdir $out"; +in { + dmenu = dummy-package // { outPath = "@dmenu@"; }; + rxvt-unicode-unwrapped = dummy-package // { + outPath = "@rxvt-unicode-unwrapped@"; + }; + i3status = dummy-package // { outPath = "@i3status@"; }; + sway = dummy-package // { outPath = "@sway@"; }; + sway-unwrapped = dummy-package // { + outPath = "@sway-unwrapped@"; + version = "1"; + }; + swaybg = dummy-package // { outPath = "@swaybg@"; }; + xwayland = dummy-package // { outPath = "@xwayland@"; }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-post-2003.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-post-2003.nix index 3eab6538e4..ddcf2b234f 100644 --- a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-post-2003.nix +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-post-2003.nix @@ -2,29 +2,22 @@ with lib; -{ +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { config = { home.stateVersion = "20.09"; wayland.windowManager.sway = { enable = true; - package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out" // { - outPath = "@sway"; - }; + package = dummy-package // { outPath = "@sway"; }; # overriding findutils causes issues config.menu = "${pkgs.dmenu}/bin/dmenu_run"; }; - nixpkgs.overlays = [ - (self: super: { - dummy-package = super.runCommandLocal "dummy-package" { } "mkdir $out"; - dmenu = self.dummy-package // { outPath = "@dmenu@"; }; - rxvt-unicode-unwrapped = self.dummy-package // { - outPath = "@rxvt-unicode-unwrapped@"; - }; - i3status = self.dummy-package // { outPath = "@i3status@"; }; - }) - ]; + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; nmt.script = '' assertFileExists home-files/.config/sway/config diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf new file mode 100644 index 0000000000..9441bf5cfd --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default-expected.conf @@ -0,0 +1,113 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border pixel 2 +default_floating_border pixel 2 +hide_edge_borders none +focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + +bindsym Mod1+9 workspace number 9 +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +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+Right focus right +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' +bindsym Mod1+Shift+h move left +bindsym Mod1+Shift+j move down +bindsym Mod1+Shift+k move up +bindsym Mod1+Shift+l move right +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+b splith +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h focus left +bindsym Mod1+j focus down +bindsym Mod1+k focus up +bindsym Mod1+l focus right +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v splitv +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px +bindsym Escape mode default +bindsym Left resize shrink width 10 px +bindsym Return mode default +bindsym Right resize grow width 10 px +bindsym Up resize shrink height 10 px +bindsym h resize shrink width 10 px +bindsym j resize grow height 10 px +bindsym k resize shrink height 10 px +bindsym l resize grow width 10 px +} + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + swaybar_command @sway/bin/swaybar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + + +exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default.nix new file mode 100644 index 0000000000..52f4f3ec18 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-default.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { + config = { + wayland.windowManager.sway = { + enable = true; + package = dummy-package // { outPath = "@sway"; }; + # overriding findutils causes issues + config.menu = "${pkgs.dmenu}/bin/dmenu_run"; + config.defaultWorkspace = "workspace number 9"; + }; + + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-workspace-default-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf new file mode 100644 index 0000000000..6ef9f6d134 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output-expected.conf @@ -0,0 +1,118 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border pixel 2 +default_floating_border pixel 2 +hide_edge_borders none +focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no + +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + + +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 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+Right focus right +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' +bindsym Mod1+Shift+h move left +bindsym Mod1+Shift+j move down +bindsym Mod1+Shift+k move up +bindsym Mod1+Shift+l move right +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+b splith +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h focus left +bindsym Mod1+j focus down +bindsym Mod1+k focus up +bindsym Mod1+l focus right +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v splitv +bindsym Mod1+w layout tabbed + +mode "resize" { +bindsym Down resize grow height 10 px +bindsym Escape mode default +bindsym Left resize shrink width 10 px +bindsym Return mode default +bindsym Right resize grow width 10 px +bindsym Up resize shrink height 10 px +bindsym h resize shrink width 10 px +bindsym j resize grow height 10 px +bindsym k resize shrink height 10 px +bindsym l resize grow width 10 px +} + +bar { + + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + swaybar_command @sway/bin/swaybar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + + + + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} + +workspace "1" output eDP +workspace "ABC" output DP +workspace "3: Test" output HDMI +workspace "!"§$%&/(){}[]=?\*#<>-_.:,;²³" output DVI + +exec "systemctl --user import-environment; systemctl --user start sway-session.target" diff --git a/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output.nix b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output.nix new file mode 100644 index 0000000000..5791a3da43 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/window-managers/sway/sway-workspace-output.nix @@ -0,0 +1,53 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dummy-package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out"; + +in { + config = let + i3 = { + ws1 = "1"; + ws2 = "ABC"; + ws3 = "3: Test"; + ws4 = ''!"§$%&/(){}[]=?\*#<>-_.:,;²³''; + }; + + in { + wayland.windowManager.sway = { + enable = true; + package = dummy-package // { outPath = "@sway"; }; + # overriding findutils causes issues + config.menu = "${pkgs.dmenu}/bin/dmenu_run"; + + config.workspaceOutputAssign = [ + { + workspace = "${i3.ws1}"; + output = "eDP"; + } + { + workspace = "${i3.ws2}"; + output = "DP"; + } + { + workspace = "${i3.ws3}"; + output = "HDMI"; + } + { + workspace = "${i3.ws4}"; + output = "DVI"; + } + ]; + }; + + nixpkgs.overlays = [ (import ./sway-overlay.nix) ]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-workspace-output-expected.conf} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/services/wlsunset/default.nix b/third_party/home-manager/tests/modules/services/wlsunset/default.nix new file mode 100644 index 0000000000..d59af70153 --- /dev/null +++ b/third_party/home-manager/tests/modules/services/wlsunset/default.nix @@ -0,0 +1 @@ +{ wlsunset-service = ./wlsunset-service.nix; } diff --git a/third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service-expected.service b/third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service-expected.service new file mode 100644 index 0000000000..f0cf96f3ad --- /dev/null +++ b/third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service-expected.service @@ -0,0 +1,9 @@ +[Install] +WantedBy=test.target + +[Service] +ExecStart=@wlsunset@/bin/wlsunset -l 12.3 -L 128.8 -t 3500 -T 6000 -g 0.6 + +[Unit] +Description=Day/night gamma adjustments for Wayland compositors. +PartOf=graphical-session.target diff --git a/third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service.nix b/third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service.nix new file mode 100644 index 0000000000..de32a8270b --- /dev/null +++ b/third_party/home-manager/tests/modules/services/wlsunset/wlsunset-service.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +{ + config = { + services.wlsunset = { + enable = true; + package = pkgs.writeScriptBin "dummy-wlsunset" "" // { + outPath = "@wlsunset@"; + }; + latitude = "12.3"; + longitude = "128.8"; + temperature.day = 6000; + temperature.night = 3500; + gamma = "0.6"; + systemdTarget = "test.target"; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/wlsunset.service + + assertFileExists $serviceFile + assertFileContent $serviceFile ${./wlsunset-service-expected.service} + ''; + }; +} diff --git a/third_party/home-manager/tests/modules/systemd/services-expected.conf b/third_party/home-manager/tests/modules/systemd/services-expected.conf deleted file mode 100644 index 34b9618d6d..0000000000 --- a/third_party/home-manager/tests/modules/systemd/services-expected.conf +++ /dev/null @@ -1,5 +0,0 @@ -[Service] -ExecStart=/some/exec/start/command --with-arguments "%i" - -[Unit] -Description=A basic test service diff --git a/third_party/home-manager/tests/modules/systemd/services.nix b/third_party/home-manager/tests/modules/systemd/services.nix index ea9b2b4fb8..4f73c5568f 100644 --- a/third_party/home-manager/tests/modules/systemd/services.nix +++ b/third_party/home-manager/tests/modules/systemd/services.nix @@ -10,6 +10,7 @@ with lib; }; Service = { + Environment = [ "VAR1=1" "VAR2=2" ]; ExecStart = ''/some/exec/start/command --with-arguments "%i"''; }; }; @@ -17,7 +18,16 @@ with lib; nmt.script = '' serviceFile=home-files/.config/systemd/user/test-service@.service assertFileExists $serviceFile - assertFileContent $serviceFile ${./services-expected.conf} + assertFileContent $serviceFile \ + ${builtins.toFile "services-expected.conf" '' + [Service] + Environment=VAR1=1 + Environment=VAR2=2 + ExecStart=/some/exec/start/command --with-arguments "%i" + + [Unit] + Description=A basic test service + ''} ''; }; } diff --git a/third_party/home-manager/tests/modules/systemd/session-variables-expected.conf b/third_party/home-manager/tests/modules/systemd/session-variables-expected.conf index 5b6e80bc32..65ced43ea6 100644 --- a/third_party/home-manager/tests/modules/systemd/session-variables-expected.conf +++ b/third_party/home-manager/tests/modules/systemd/session-variables-expected.conf @@ -1,2 +1,3 @@ +LOCALE_ARCHIVE_2_27=@glibcLocales@/lib/locale/locale-archive V_int=1 V_str=2 diff --git a/third_party/home-manager/tests/modules/systemd/session-variables.nix b/third_party/home-manager/tests/modules/systemd/session-variables.nix index b725827ce6..59d1a4d3aa 100644 --- a/third_party/home-manager/tests/modules/systemd/session-variables.nix +++ b/third_party/home-manager/tests/modules/systemd/session-variables.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, ... }: -with lib; - { config = { systemd.user.sessionVariables = { @@ -12,7 +10,11 @@ with lib; nmt.script = '' envFile=home-files/.config/environment.d/10-home-manager.conf assertFileExists $envFile - assertFileContent $envFile ${./session-variables-expected.conf} + assertFileContent $envFile ${pkgs.writeText "expected" '' + LOCALE_ARCHIVE_2_27=${pkgs.glibcLocales}/lib/locale/locale-archive + V_int=1 + V_str=2 + ''} ''; }; } diff --git a/third_party/home-manager/tests/modules/targets-linux/generic-linux.nix b/third_party/home-manager/tests/modules/targets-linux/generic-linux.nix index 10481b5e98..88cec8a005 100644 --- a/third_party/home-manager/tests/modules/targets-linux/generic-linux.nix +++ b/third_party/home-manager/tests/modules/targets-linux/generic-linux.nix @@ -2,21 +2,39 @@ with lib; -{ +let + expectedXdgDataDirs = concatStringsSep ":" [ + "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share" + "/home/hm-user/.nix-profile/share" + "/usr/share/ubuntu" + "/usr/local/share" + "/usr/share" + "/var/lib/snapd/desktop" + "/foo" + ]; + +in { config = { - targets.genericLinux = { - enable = true; - extraXdgDataDirs = [ "/foo" ]; - }; + targets.genericLinux.enable = true; + + xdg.systemDirs.data = [ "/foo" ]; nmt.script = '' - assertFileExists home-path/etc/profile.d/hm-session-vars.sh - assertFileContains \ - home-path/etc/profile.d/hm-session-vars.sh \ - 'export XDG_DATA_DIRS="''${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share:/home/hm-user/.nix-profile/share:/foo''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS"' - assertFileContains \ - home-path/etc/profile.d/hm-session-vars.sh \ + envFile=home-files/.config/environment.d/10-home-manager.conf + assertFileExists $envFile + assertFileContains $envFile \ + 'XDG_DATA_DIRS=${expectedXdgDataDirs}''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}' + assertFileContains $envFile \ + 'TERMINFO_DIRS=/home/hm-user/.nix-profile/share/terminfo:$TERMINFO_DIRS''${TERMINFO_DIRS:+:}/etc/terminfo:/lib/terminfo:/usr/share/terminfo' + + sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $sessionVarsFile + assertFileContains $sessionVarsFile \ '. "${pkgs.nix}/etc/profile.d/nix.sh"' + + assertFileContains \ + home-path/etc/profile.d/hm-session-vars.sh \ + 'export TERM="$TERM"' ''; }; }