Merge commit '46a69810cb95d2e7286089830dc535d6719eaa6f'

main
Katharina Fey 3 years ago
commit 3d4704b0b4
Signed by: kookie
GPG Key ID: 90734A9E619C8A6C
  1. 129
      infra/libkookie/home-manager/.github/CODEOWNERS
  2. 38
      infra/libkookie/home-manager/.github/ISSUE_TEMPLATE.md
  3. 15
      infra/libkookie/home-manager/.github/ISSUE_TEMPLATE/feature-request.md
  4. 46
      infra/libkookie/home-manager/.github/ISSUE_TEMPLATE/issue.yaml
  5. 4
      infra/libkookie/home-manager/.github/PULL_REQUEST_TEMPLATE.md
  6. 2
      infra/libkookie/home-manager/.github/dependabot.yml
  7. 75
      infra/libkookie/home-manager/.github/stale.yml
  8. 4
      infra/libkookie/home-manager/.github/workflows/github_pages.yml
  9. 7
      infra/libkookie/home-manager/.github/workflows/test.yml
  10. 1
      infra/libkookie/home-manager/.release
  11. 1
      infra/libkookie/home-manager/CONTRIBUTING.adoc
  12. 1
      infra/libkookie/home-manager/FAQ.adoc
  13. 17
      infra/libkookie/home-manager/Makefile
  14. 60
      infra/libkookie/home-manager/README.md
  15. 2
      infra/libkookie/home-manager/default.nix
  16. 4
      infra/libkookie/home-manager/docs/contributing.adoc
  17. 4
      infra/libkookie/home-manager/docs/default.nix
  18. 14
      infra/libkookie/home-manager/docs/faq.adoc
  19. 25
      infra/libkookie/home-manager/docs/installation.adoc
  20. 0
      infra/libkookie/home-manager/docs/man-configuration.xml
  21. 147
      infra/libkookie/home-manager/docs/man-home-manager.xml
  22. 0
      infra/libkookie/home-manager/docs/man-pages.xml
  23. 8
      infra/libkookie/home-manager/docs/manual.xml
  24. 2
      infra/libkookie/home-manager/docs/release-notes/release-notes.adoc
  25. 0
      infra/libkookie/home-manager/docs/release-notes/rl-1809.adoc
  26. 0
      infra/libkookie/home-manager/docs/release-notes/rl-1903.adoc
  27. 0
      infra/libkookie/home-manager/docs/release-notes/rl-1909.adoc
  28. 0
      infra/libkookie/home-manager/docs/release-notes/rl-2003.adoc
  29. 0
      infra/libkookie/home-manager/docs/release-notes/rl-2009.adoc
  30. 38
      infra/libkookie/home-manager/docs/release-notes/rl-2105.adoc
  31. 47
      infra/libkookie/home-manager/docs/release-notes/rl-2111.adoc
  32. 0
      infra/libkookie/home-manager/docs/writing-modules.adoc
  33. 63
      infra/libkookie/home-manager/flake.nix
  34. 19
      infra/libkookie/home-manager/format
  35. 15
      infra/libkookie/home-manager/home-manager/completion.bash
  36. 65
      infra/libkookie/home-manager/home-manager/completion.fish
  37. 12
      infra/libkookie/home-manager/home-manager/completion.zsh
  38. 68
      infra/libkookie/home-manager/home-manager/default.nix
  39. 162
      infra/libkookie/home-manager/home-manager/home-manager
  40. 2
      infra/libkookie/home-manager/home-manager/install.nix
  41. 9
      infra/libkookie/home-manager/modules/accounts/email.nix
  42. 2
      infra/libkookie/home-manager/modules/config/i18n.nix
  43. 104
      infra/libkookie/home-manager/modules/files.nix
  44. 106
      infra/libkookie/home-manager/modules/home-environment.nix
  45. 106
      infra/libkookie/home-manager/modules/i18n/input-method/default.nix
  46. 50
      infra/libkookie/home-manager/modules/i18n/input-method/fcitx.nix
  47. 42
      infra/libkookie/home-manager/modules/i18n/input-method/fcitx5.nix
  48. 23
      infra/libkookie/home-manager/modules/i18n/input-method/hime.nix
  49. 58
      infra/libkookie/home-manager/modules/i18n/input-method/kime.nix
  50. 23
      infra/libkookie/home-manager/modules/i18n/input-method/nabi.nix
  51. 45
      infra/libkookie/home-manager/modules/i18n/input-method/uim.nix
  52. 13
      infra/libkookie/home-manager/modules/lib-bash/activation-init.sh
  53. 14
      infra/libkookie/home-manager/modules/lib/assertions.nix
  54. 2
      infra/libkookie/home-manager/modules/lib/default.nix
  55. 5
      infra/libkookie/home-manager/modules/lib/file-type.nix
  56. 7
      infra/libkookie/home-manager/modules/lib/gvariant.nix
  57. 80
      infra/libkookie/home-manager/modules/lib/maintainers.nix
  58. 8
      infra/libkookie/home-manager/modules/lib/stdlib-extended.nix
  59. 27
      infra/libkookie/home-manager/modules/lib/types.nix
  60. 2
      infra/libkookie/home-manager/modules/manual.nix
  61. 2
      infra/libkookie/home-manager/modules/misc/dconf.nix
  62. 26
      infra/libkookie/home-manager/modules/misc/fontconfig.nix
  63. 38
      infra/libkookie/home-manager/modules/misc/gtk.nix
  64. 387
      infra/libkookie/home-manager/modules/misc/news.nix
  65. 73
      infra/libkookie/home-manager/modules/misc/nixpkgs-disabled.nix
  66. 63
      infra/libkookie/home-manager/modules/misc/nixpkgs.nix
  67. 4
      infra/libkookie/home-manager/modules/misc/numlock.nix
  68. 2
      infra/libkookie/home-manager/modules/misc/qt.nix
  69. 5
      infra/libkookie/home-manager/modules/misc/tmpfiles.nix
  70. 12
      infra/libkookie/home-manager/modules/misc/version.nix
  71. 183
      infra/libkookie/home-manager/modules/misc/xdg-desktop-entries.nix
  72. 7
      infra/libkookie/home-manager/modules/misc/xdg-mime-apps.nix
  73. 7
      infra/libkookie/home-manager/modules/misc/xdg-mime.nix
  74. 61
      infra/libkookie/home-manager/modules/misc/xdg-system-dirs.nix
  75. 40
      infra/libkookie/home-manager/modules/misc/xdg-user-dirs.nix
  76. 37
      infra/libkookie/home-manager/modules/misc/xdg.nix
  77. 450
      infra/libkookie/home-manager/modules/modules.nix
  78. 4
      infra/libkookie/home-manager/modules/programs/abook.nix
  79. 4
      infra/libkookie/home-manager/modules/programs/afew.nix
  80. 4
      infra/libkookie/home-manager/modules/programs/alacritty.nix
  81. 2
      infra/libkookie/home-manager/modules/programs/alot-accounts.nix
  82. 2
      infra/libkookie/home-manager/modules/programs/alot.nix
  83. 2
      infra/libkookie/home-manager/modules/programs/aria2.nix
  84. 6
      infra/libkookie/home-manager/modules/programs/astroid.nix
  85. 90
      infra/libkookie/home-manager/modules/programs/atuin.nix
  86. 8
      infra/libkookie/home-manager/modules/programs/autorandr.nix
  87. 73
      infra/libkookie/home-manager/modules/programs/bash.nix
  88. 16
      infra/libkookie/home-manager/modules/programs/bat.nix
  89. 4
      infra/libkookie/home-manager/modules/programs/beets.nix
  90. 66
      infra/libkookie/home-manager/modules/programs/bottom.nix
  91. 23
      infra/libkookie/home-manager/modules/programs/broot.nix
  92. 29
      infra/libkookie/home-manager/modules/programs/chromium.nix
  93. 7
      infra/libkookie/home-manager/modules/programs/command-not-found/command-not-found.nix
  94. 13
      infra/libkookie/home-manager/modules/programs/command-not-found/command-not-found.pl
  95. 6
      infra/libkookie/home-manager/modules/programs/dircolors.nix
  96. 35
      infra/libkookie/home-manager/modules/programs/direnv.nix
  97. 4
      infra/libkookie/home-manager/modules/programs/eclipse.nix
  98. 37
      infra/libkookie/home-manager/modules/programs/emacs.nix
  99. 36
      infra/libkookie/home-manager/modules/programs/exa.nix
  100. 327
      infra/libkookie/home-manager/modules/programs/firefox.nix
  101. Some files were not shown because too many files have changed in this diff Show More

@ -4,6 +4,9 @@
/modules/home-environment.nix @rycee /modules/home-environment.nix @rycee
/modules/i18n/input-method @Kranzes
/tests/modules/i18n/input-method @Kranzes
/modules/misc/dconf.nix @gnidorah @rycee /modules/misc/dconf.nix @gnidorah @rycee
/modules/misc/fontconfig.nix @rycee /modules/misc/fontconfig.nix @rycee
@ -16,6 +19,8 @@
/modules/misc/news.nix @rycee /modules/misc/news.nix @rycee
/modules/misc/nixpkgs-disabled.nix @thiagokokada
/modules/misc/numlock.nix @evanjs /modules/misc/numlock.nix @evanjs
/tests/modules/misc/numlock @evanjs /tests/modules/misc/numlock @evanjs
@ -34,11 +39,22 @@
/modules/misc/xdg-user-dirs.nix @pacien /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/aria2.nix @JustinLovinger
/modules/programs/autojump.nix @evanjs /modules/programs/autojump.nix @evanjs
/tests/modules/programs/autojump @evanjs /tests/modules/programs/autojump @evanjs
/modules/programs/atuin.nix @hawkw
/tests/modules/programs/atuin @hawkw
/modules/programs/autorandr.nix @uvNikita /modules/programs/autorandr.nix @uvNikita
/modules/programs/bash.nix @rycee /modules/programs/bash.nix @rycee
@ -47,6 +63,9 @@
/modules/programs/beets.nix @rycee /modules/programs/beets.nix @rycee
/modules/programs/bottom.nix @polykernel
/tests/modules/programs/bottom @polykernel
/modules/programs/broot.nix @aheaume /modules/programs/broot.nix @aheaume
/modules/programs/dircolors.nix @JustinLovinger /modules/programs/dircolors.nix @JustinLovinger
@ -57,25 +76,43 @@
/modules/programs/emacs.nix @rycee /modules/programs/emacs.nix @rycee
/modules/programs/exa.nix @kalhauge
/modules/programs/firefox.nix @rycee /modules/programs/firefox.nix @rycee
/modules/programs/gh.nix @Gerschtli /modules/programs/foot.nix @plabadens
/tests/modules/programs/gh @Gerschtli /tests/modules/programs/foot @plabadens
/modules/programs/gh.nix @Gerschtli @berbiche
/tests/modules/programs/gh @Gerschtli @berbiche
/modules/programs/git.nix @rycee /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/go.nix @rvolosatovs
/modules/programs/hexchat.nix @superherointj @thiagokokada
/tests/modules/programs/hexchat @thiagokokada
/modules/programs/himalaya.nix @ambroisie
/tests/modules/programs/himalaya @ambroisie
/modules/programs/home-manager.nix @rycee /modules/programs/home-manager.nix @rycee
/modules/programs/htop.nix @bjpbakker
/tests/modules/htop @bjpbakker
/modules/programs/i3status.nix @JustinLovinger /modules/programs/i3status.nix @JustinLovinger
/modules/programs/i3status-rust.nix @workflow /modules/programs/i3status-rust.nix @workflow
/modules/programs/java.nix @ShamrockLee
/modules/programs/keychain.nix @marsam /modules/programs/keychain.nix @marsam
/modules/programs/lazygit.nix @kalhauge
/modules/programs/lesspipe.nix @rycee /modules/programs/lesspipe.nix @rycee
/modules/programs/lf.nix @owm111 /modules/programs/lf.nix @owm111
@ -87,6 +124,9 @@
/modules/programs/matplotlib.nix @rprospero /modules/programs/matplotlib.nix @rprospero
/modules/programs/mangohud.nix @ZerataX
/tests/modules/programs/mangohud @ZerataX
/modules/programs/mbsync.nix @KarlJoad /modules/programs/mbsync.nix @KarlJoad
/tests/modules/programs/mbsync @KarlJoad /tests/modules/programs/mbsync @KarlJoad
@ -101,9 +141,20 @@
/tests/modules/programs/ncmpcpp @olmokramer /tests/modules/programs/ncmpcpp @olmokramer
/tests/modules/programs/ncmpcpp-linux @olmokramer /tests/modules/programs/ncmpcpp-linux @olmokramer
/modules/programs/ncspot.nix @marsam
/modules/programs/ne.nix @cwyc /modules/programs/ne.nix @cwyc
/tests/modules/programs/ne @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/nnn.nix @thiagokokada
/tests/modules/programs/nnn @thiagokokada
/modules/programs/noti.nix @marsam /modules/programs/noti.nix @marsam
/modules/programs/nushell.nix @Philipp-M /modules/programs/nushell.nix @Philipp-M
@ -123,8 +174,13 @@
/modules/programs/pidgin.nix @rycee /modules/programs/pidgin.nix @rycee
/modules/programs/piston-cli.nix @ethancedwards8
/modules/programs/powerline-go.nix @DamienCassou /modules/programs/powerline-go.nix @DamienCassou
/modules/programs/rbw.nix @ambroisie
/tests/modules/programs/rbw @ambroisie
/modules/programs/rofi.nix @thiagokokada /modules/programs/rofi.nix @thiagokokada
/tests/modules/programs/rofi @thiagokokada /tests/modules/programs/rofi @thiagokokada
@ -136,15 +192,31 @@
/modules/programs/sbt.nix @kubukoz /modules/programs/sbt.nix @kubukoz
/tests/modules/programs/sbt @kubukoz /tests/modules/programs/sbt @kubukoz
/modules/programs/scmpuff.nix @cpcloud
/tests/modules/programs/scmpuff @cpcloud
/modules/programs/senpai.nix @malte-v
/modules/programs/sm64ex.nix @ivarwithoutbones
/tests/modules/programs/sm64ex @ivarwithoutbones
/modules/programs/ssh.nix @rycee /modules/programs/ssh.nix @rycee
/modules/programs/starship.nix @marsam /modules/programs/starship.nix @marsam
/modules/programs/terminator.nix @chisui
/modules/programs/texlive.nix @rycee /modules/programs/texlive.nix @rycee
/modules/programs/topgrade.nix @msfjarvis
/tests/modules/programs/topgrade @msfjarvis
/modules/programs/waybar.nix @berbiche /modules/programs/waybar.nix @berbiche
/tests/modules/programs/waybar @berbiche /tests/modules/programs/waybar @berbiche
/modules/programs/xmobar.nix @t4ccer
/tests/modules/programs/xmobar @t4ccer
/modules/programs/z-lua.nix @marsam /modules/programs/z-lua.nix @marsam
/modules/programs/zathura.nix @rprospero /modules/programs/zathura.nix @rprospero
@ -153,23 +225,40 @@
/modules/programs/zsh/prezto.nix @NickHu /modules/programs/zsh/prezto.nix @NickHu
/modules/services/barrier.nix @Kritnich
/tests/modules/services/barrier @Kritnich
/modules/services/betterlockscreen.nix @SebTM
/modules/services/caffeine.nix @uvNikita /modules/services/caffeine.nix @uvNikita
/modules/services/cbatticon.nix @pmiddend /modules/services/cbatticon.nix @pmiddend
/modules/services/clipmenu.nix @DamienCassou /modules/services/clipmenu.nix @DamienCassou
/modules/services/devilspie2.nix @dawidsowa
/tests/modules/services/devilspie2 @dawidsowa
/modules/services/dropbox.nix @eyJhb /modules/services/dropbox.nix @eyJhb
/tests/modules/services/dropbox @eyJhb /tests/modules/services/dropbox @eyJhb
/modules/services/dunst.nix @rycee /modules/services/dunst.nix @rycee
/modules/services/easyeffects.nix @fufexan
/modules/services/emacs.nix @tadfisher /modules/services/emacs.nix @tadfisher
/modules/services/etesync-dav.nix @Valodim
/modules/services/flameshot.nix @moredhel /modules/services/flameshot.nix @moredhel
/modules/services/fluidsynth.nix @Valodim /modules/services/fluidsynth.nix @Valodim
/modules/services/fnott.nix @polykernel
/tests/modules/services/fnott @polykernel
/modules/services/git-sync.nix @IvanMalison
/modules/services/gnome-keyring.nix @rycee /modules/services/gnome-keyring.nix @rycee
/modules/services/gpg-agent.nix @rycee /modules/services/gpg-agent.nix @rycee
@ -197,12 +286,21 @@
/modules/services/mpdris2.nix @pjones /modules/services/mpdris2.nix @pjones
/modules/services/mpris-proxy.nix @ThibautMarty
/modules/services/muchsync.nix @pacien /modules/services/muchsync.nix @pacien
/modules/services/network-manager-applet.nix @rycee /modules/services/network-manager-applet.nix @rycee
/modules/services/notify-osd.nix @imalison
/modules/services/pantalaimon.nix @jojosch
/tests/modules/services/pantalaimon @jojosch
/modules/services/parcellite.nix @gleber /modules/services/parcellite.nix @gleber
/modules/services/pass-secret-service.nix @cab404
/modules/services/password-store-sync.nix @pacien /modules/services/password-store-sync.nix @pacien
/modules/services/pasystray.nix @pltanton /modules/services/pasystray.nix @pltanton
@ -215,6 +313,8 @@
/modules/services/playerctld.nix @fendse /modules/services/playerctld.nix @fendse
/tests/modules/playerctld @fendse /tests/modules/playerctld @fendse
/modules/services/poweralertd.nix @ThibautMarty
/modules/services/pulseeffects.nix @jonringer /modules/services/pulseeffects.nix @jonringer
/modules/services/random-background.nix @rycee /modules/services/random-background.nix @rycee
@ -222,6 +322,9 @@
/modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada /modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada
/tests/modules/redshift-gammastep @thiagokokada /tests/modules/redshift-gammastep @thiagokokada
/modules/services/screen-locker.nix @jrobsonchase
/tests/modules/services/screen-locker @jrobsonchase
/modules/services/status-notifier-watcher.nix @pltanton /modules/services/status-notifier-watcher.nix @pltanton
/modules/services/syncthing.nix @rycee /modules/services/syncthing.nix @rycee
@ -232,11 +335,23 @@
/modules/services/taskwarrior-sync.nix @minijackson @pacien /modules/services/taskwarrior-sync.nix @minijackson @pacien
/modules/services/trayer.nix @AndreasMager
/tests/modules/services/trayer @AndreasMager
/modules/services/udiskie.nix @rycee /modules/services/udiskie.nix @rycee
/modules/services/unison.nix @pacien /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 /modules/services/wlsunset.nix @matrss
/tests/modules/services/wlsunset @matrss /tests/modules/services/wlsunset @matrss
@ -245,6 +360,8 @@
/modules/services/xembed-sni-proxy.nix @rycee /modules/services/xembed-sni-proxy.nix @rycee
/modules/services/xidlehook.nix @dschrempf
/modules/services/xscreensaver.nix @rycee /modules/services/xscreensaver.nix @rycee
/modules/services/xsuspender.nix @offlinehacker /modules/services/xsuspender.nix @offlinehacker
@ -256,3 +373,7 @@
/modules/xresources.nix @rycee /modules/xresources.nix @rycee
/modules/xsession.nix @rycee /modules/xsession.nix @rycee
/modules/services/volnoti.nix @IvanMalison
Makefile @thiagokokada

@ -1,38 +0,0 @@
<!--
If you are encountering the error
element xref: validity error : IDREF attribute linkend references an unknown ID "opt-home.file._name__.source"
then it means that you are using an old version of Home Manager, such
as the release-20.03 branch, with a recent version of Nixpkgs, such as
version 20.09 or master. See https://git.io/JTb6K for more.
In general, please check if there already exists a relevant issue
before creating a new one.
-->
### Issue description
<!--
Please describe the issue. For support and help please use the IRC
channel #home-manager @ freenode.net instead.
-->
### Meta
#### Maintainer CC
<!--
Please @ people who are in the `meta.maintainers` list of the
offending module. If in doubt, check `git blame` for whoever last
touched something.
-->
#### Technical details
<!--
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the
result.
-->

@ -0,0 +1,15 @@
---
name: Feature request
about: Ask for a new feature to be added (module, program, etc.)
title: ''
labels: feature request
assignees: rycee, berbiche, sumnerevans
---
<!--
Note: Please search to see if the feature has already been requested
-->
### Description

@ -0,0 +1,46 @@
name: Bug Report
description: File a bug/issue
title: 'bug: '
labels: [bug, triage]
# We cannot use nix-community/home-manager
# See https://github.com/dear-github/dear-github/issues/170
assignees: [rycee, berbiche, sumnerevans]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: |
Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Issue description
description: |
Please describe the issue.
For support and help please use the IRC channel #home-manager at irc.oftc.net or
Matrix room <https://matrix.to/#/#hm:rycee.net> instead.
validations:
required: false
- type: textarea
attributes:
label: Maintainer CC
description: |
Please @ people who are in the `meta.maintainers` list of the offending module.
If in doubt, check `git blame` for whoever last touched something.
validations:
required: false
- type: textarea
id: system
attributes:
label: System information
description: |
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.
render: markdown
validations:
required: true

@ -15,7 +15,7 @@ pull-request.
Also make sure to read the guidelines found at Also make sure to read the guidelines found at
https://github.com/nix-community/home-manager/blob/master/doc/contributing.adoc#sec-guidelines https://github.com/nix-community/home-manager/blob/master/docs/contributing.adoc#sec-guidelines
--> -->
@ -35,7 +35,7 @@ Also make sure to read the guidelines found at
{long description} {long description}
``` ```
See [CONTRIBUTING](https://github.com/nix-community/home-manager/blob/master/doc/contributing.adoc#sec-commit-style) for more information and [recent commit messages](https://github.com/nix-community/home-manager/commits/master) for examples. See [CONTRIBUTING](https://github.com/nix-community/home-manager/blob/master/docs/contributing.adoc#sec-commit-style) for more information and [recent commit messages](https://github.com/nix-community/home-manager/commits/master) for examples.
- If this PR adds a new module - If this PR adds a new module

@ -10,7 +10,7 @@ updates:
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
target-branch: "release-20.09" target-branch: "release-21.05"
schedule: schedule:
interval: "weekly" interval: "weekly"
commit-message: commit-message:

@ -0,0 +1,75 @@
# Configuration for probot-stale - https://github.com/probot/stale
daysUntilStale: 90
daysUntilClose: 7
staleLabel: "status: stale"
closeComment: false
issues:
markComment: |
<p>
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.
<b>Please read the relevant sections below before commenting.</b>
</p>
<details>
<summary><b>If you are the original author of the issue</b></summary>
<p>
* 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.
</p>
</details>
<details>
<summary><b>If you are <i>not</i> the original author of the issue</b></summary>
<p>
* 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.
</p>
</details>
<details>
<summary><b>Memorandum on closing issues</b></summary>
<p>
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.
</p>
<p>
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.
</p>
</details>
pulls:
markComment: |
<p>
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.
<b>Please read the relevant sections below before commenting.</b>
</p>
<details>
<summary><b>If you are the original author of the PR</b></summary>
<p>
* 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.
</p>
</details>
<details>
<summary><b>If you are <i>not</i> the original author of the issue</b></summary>
<p>
* 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.
</p>
</details>

@ -11,10 +11,10 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: cachix/install-nix-action@v12 - uses: cachix/install-nix-action@v14
with: with:
nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v8 - uses: cachix/cachix-action@v10
with: with:
name: nix-community name: nix-community
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'

@ -6,18 +6,19 @@ on:
jobs: jobs:
tests: tests:
strategy: strategy:
fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest] os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: cachix/install-nix-action@v12 - uses: cachix/install-nix-action@v14.1
with: with:
nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v8 - uses: cachix/cachix-action@v10
with: with:
name: nix-community name: nix-community
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- run: ./format -c - run: ./format -c
- run: nix-shell . -A install - run: nix-shell . -A install
- run: nix-shell --pure tests -A run.all - run: nix-shell --arg enableBig false --pure tests -A run.all

@ -1 +0,0 @@
doc/contributing.adoc

@ -1 +0,0 @@
doc/faq.adoc

@ -0,0 +1,17 @@
.PHONY: all all-tests test format
NIXPKGS_REV := nixpkgs-unstable
NIX_PATH := nixpkgs=https://github.com/NixOS/nixpkgs/archive/${NIXPKGS_REV}.tar.gz
all: all-tests
all-tests:
$(MAKE) test TEST=all
test:
ifndef TEST
$(error Use 'make test TEST=<test_name>' to run desired test)
endif
nix-shell --pure tests -I ${NIX_PATH} -A run.${TEST}
format:
./format

@ -29,10 +29,10 @@ learn.
In some cases Home Manager cannot detect whether it will overwrite a In some cases Home Manager cannot detect whether it will overwrite a
previous manual configuration. For example, the Gnome Terminal module previous manual configuration. For example, the Gnome Terminal module
will write to your dconf store and cannot tell whether a configuration 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. generation or from manual configuration.
Home Manager targets [NixOS][] unstable and NixOS version 20.09 (the Home Manager targets [NixOS][] unstable and NixOS version 21.05 (the
current stable version), it may or may not work on other Linux current stable version), it may or may not work on other Linux
distributions and NixOS versions. distributions and NixOS versions.
@ -48,8 +48,7 @@ Contact
------- -------
You can chat with us on IRC in the channel [#home-manager][] on You can chat with us on IRC in the channel [#home-manager][] on
[freenode][]. The [channel logs][] are hosted courtesy of [OFTC][].
[samueldr][].
Installation Installation
------------ ------------
@ -71,16 +70,16 @@ Currently the easiest way to install Home Manager is as follows:
2. Add the appropriate Home Manager channel. If you are following 2. Add the appropriate Home Manager channel. If you are following
Nixpkgs master or an unstable channel you can run Nixpkgs master or an unstable channel you can run
```console ```shell
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
$ nix-channel --update nix-channel --update
``` ```
and if you follow a Nixpkgs version 20.09 channel you can run and if you follow a Nixpkgs version 21.05 channel you can run
```console ```shell
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.09.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 nix-channel --update
``` ```
On NixOS you may need to log out and back in for the channel to On NixOS you may need to log out and back in for the channel to
@ -94,8 +93,8 @@ Currently the easiest way to install Home Manager is as follows:
3. Install Home Manager and create the first Home Manager generation: 3. Install Home Manager and create the first Home Manager generation:
```console ```shell
$ nix-shell '<home-manager>' -A install nix-shell '<home-manager>' -A install
``` ```
Once finished, Home Manager should be active and available in your Once finished, Home Manager should be active and available in your
@ -104,13 +103,14 @@ Currently the easiest way to install Home Manager is as follows:
3. If you do not plan on having Home Manager manage your shell 3. If you do not plan on having Home Manager manage your shell
configuration then you must source the configuration then you must source the
``` ```shell
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
``` ```
file in your shell configuration. Unfortunately, in this specific file in your shell configuration. This file can be sourced
case we currently only support POSIX.2-like shells such as directly by POSIX.2-like shells such as [Bash][] or [Z shell][].
[Bash][] or [Z shell][]. [Fish][] users can use utilities such as [foreign-env][] or
[babelfish][].
For example, if you use Bash then add For example, if you use Bash then add
@ -143,7 +143,7 @@ configuration generations.
As an example, let us expand the initial configuration file from the As an example, let us expand the initial configuration file from the
installation above to install the htop and fortune packages, install installation above to install the htop and fortune packages, install
Emacs with a few extra packages enabled, install Firefox with Emacs with a few extra packages enabled, install Firefox with
smooth scrolling enabled, and enable the user gpg-agent service. smooth scrolling disabled, and enable the user gpg-agent service.
To satisfy the above setup we should elaborate the To satisfy the above setup we should elaborate the
`~/.config/nixpkgs/home.nix` file as follows: `~/.config/nixpkgs/home.nix` file as follows:
@ -191,14 +191,14 @@ To satisfy the above setup we should elaborate the
To activate this configuration you can then run To activate this configuration you can then run
```console ```shell
$ home-manager switch home-manager switch
``` ```
or if you are not feeling so lucky, or if you are not feeling so lucky,
```console ```shell
$ home-manager build home-manager build
``` ```
which will create a `result` link to a directory containing an which will create a `result` link to a directory containing an
@ -208,8 +208,8 @@ Documentation of available configuration options, including
descriptions and usage examples, is available in the [Home Manager descriptions and usage examples, is available in the [Home Manager
manual][configuration options] or offline by running manual][configuration options] or offline by running
```console ```shell
$ man home-configuration.nix man home-configuration.nix
``` ```
Rollbacks Rollbacks
@ -280,7 +280,7 @@ then result in
$ home-manager switch $ home-manager switch
Activating checkLinkTargets 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 Please move the above files and try again
``` ```
@ -367,7 +367,7 @@ Home Manager is developed against `nixpkgs-unstable` branch, which
often causes it to contain tweaks for changes/packages not yet often causes it to contain tweaks for changes/packages not yet
released in stable NixOS. To avoid breaking users' configurations, released in stable NixOS. To avoid breaking users' configurations,
Home Manager is released in branches corresponding to NixOS releases Home Manager is released in branches corresponding to NixOS releases
(e.g. `release-20.09`). 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 modules. If you need a module to be backported, then feel free to open
an issue. an issue.
@ -380,9 +380,11 @@ an issue.
[Z shell]: http://zsh.sourceforge.net/ [Z shell]: http://zsh.sourceforge.net/
[manual]: https://nix-community.github.io/home-manager/ [manual]: https://nix-community.github.io/home-manager/
[configuration options]: https://nix-community.github.io/home-manager/options.html [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 [#home-manager]: https://webchat.oftc.net/?channels=home-manager
[freenode]: https://freenode.net/ [OFTC]: https://oftc.net/
[channel logs]: https://logs.nix.samueldr.com/home-manager/
[samueldr]: https://github.com/samueldr/ [samueldr]: https://github.com/samueldr/
[Nix Pills]: https://nixos.org/nixos/nix-pills/ [Nix Pills]: https://nixos.org/nixos/nix-pills/
[Nix Flakes]: https://nixos.wiki/wiki/Flakes [Nix Flakes]: https://nixos.wiki/wiki/Flakes
[Fish]: https://fishshell.com
[foreign-env]: https://github.com/oh-my-fish/plugin-foreign-env
[babelfish]: https://github.com/bouk/babelfish

@ -1,7 +1,7 @@
{ pkgs ? import <nixpkgs> { } }: { pkgs ? import <nixpkgs> { } }:
rec { rec {
docs = with import ./doc { inherit pkgs; }; { docs = with import ./docs { inherit pkgs; }; {
html = manual.html; html = manual.html;
manPages = manPages; manPages = manPages;
json = options.json; json = options.json;

@ -44,7 +44,7 @@ The first option is good if you only temporarily want to use your clone.
[[sec-guidelines]] [[sec-guidelines]]
=== 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 :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 :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 :assertions: https://nixos.org/manual/nixos/stable/index.html#sec-assertions
@ -163,7 +163,7 @@ The commit messages should follow the {seven-rules}[seven rules]. We also ask yo
{long description} {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 <<ex-commit-message>> 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 <<ex-commit-message>> for a commit message that fulfills these requirements.
[[ex-commit-message]] [[ex-commit-message]]
.Compliant commit message .Compliant commit message

@ -9,8 +9,8 @@ let
name = "nmd"; name = "nmd";
owner = "rycee"; owner = "rycee";
repo = "nmd"; repo = "nmd";
rev = "2398aa79ab12aa7aba14bc3b08a6efd38ebabdc5"; rev = "12bc57594e12525d2e4422fa7034b2d54e9ea09a";
sha256 = "0yxb48afvccn8vvpkykzcr4q1rgv8jsijqncia7a5ffzshcrwrnh"; sha256 = "0fpankfx2c99x4n1mhdy730yxy2b03qcw4zvjxyk4b1v60h8057n";
}; };
nmd = import nmdSrc { inherit lib pkgs; }; nmd = import nmdSrc { inherit lib pkgs; };

@ -40,16 +40,24 @@ 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. 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? === Why are the session variables not set?
:foreign-env: https://github.com/oh-my-fish/plugin-foreign-env
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 Home Manager is only able to set session variables automatically if it manages your Bash, Z shell, or fish 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
[source,bash] [source,bash]
---- ----
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
---- ----
to your `.profile` and `.zshrc` files, respectively. The `hm-session-vars.sh` file should work in most Bourne-like shells. to your `.profile` and `.zshrc` files, respectively. The `hm-session-vars.sh` file should work in most Bourne-like shells. For fish shell, it is possible to source it using {foreign-env}[the foreign-env plugin]
[source,bash]
----
fenv source "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" > /dev/null
----
=== How to 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/ :post-your-homenix: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/
@ -92,7 +100,7 @@ error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt.
The solution on NixOS is to add The solution on NixOS is to add
[source,nix] [source,nix]
services.dbus.packages = with pkgs; [ gnome3.dconf ]; programs.dconf.enable = true;
to your system configuration. to your system configuration.

@ -47,11 +47,11 @@ $ nix-channel --add https://github.com/nix-community/home-manager/archive/master
$ nix-channel --update $ nix-channel --update
---- ----
+ +
and if you follow a Nixpkgs version 20.09 channel, you can run and if you follow a Nixpkgs version 21.05 channel, you can run
+ +
[source,console] [source,console]
---- ----
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.09.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 $ nix-channel --update
---- ----
+ +
@ -86,9 +86,12 @@ file in your shell configuration. Alternatively source
+ +
when managing home configuration together with system configuration. when managing home configuration together with system configuration.
+ +
Unfortunately, we currently only support POSIX.2-like shells such as This file can be sourced directly by POSIX.2-like shells such as
https://www.gnu.org/software/bash/[Bash] or https://www.gnu.org/software/bash/[Bash] or
http://zsh.sourceforge.net/[Z shell]. http://zsh.sourceforge.net/[Z shell]. https://fishshell.com[Fish]
users can use utilities such as
https://github.com/oh-my-fish/plugin-foreign-env[foreign-env] or
https://github.com/bouk/babelfish[babelfish].
+ +
For example, if you use Bash then add For example, if you use Bash then add
+ +
@ -125,11 +128,11 @@ or an unstable channel, you can run
# nix-channel --update # nix-channel --update
---- ----
and if you follow a Nixpkgs version 20.09 channel, you can run and if you follow a Nixpkgs version 21.05 channel, you can run
[source,console] [source,console]
---- ----
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.09.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 # nix-channel --update
---- ----
@ -203,11 +206,11 @@ or an unstable channel, you can run
# nix-channel --update # nix-channel --update
---- ----
and if you follow a Nixpkgs version 20.09 channel, you can run and if you follow a Nixpkgs version 21.05 channel, you can run
[source,console] [source,console]
---- ----
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.09.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 # nix-channel --update
---- ----
@ -224,13 +227,17 @@ For example, a nix-darwin configuration may include the lines
[source,nix] [source,nix]
---- ----
users.users.eve = {
name = "eve";
home = "/Users/eve";
}
home-manager.users.eve = { pkgs, ... }: { home-manager.users.eve = { pkgs, ... }: {
home.packages = [ pkgs.atool pkgs.httpie ]; home.packages = [ pkgs.atool pkgs.httpie ];
programs.bash.enable = true; programs.bash.enable = true;
}; };
---- ----
and after a `darwin-rebuild --switch` the user eve's environment and after a `darwin-rebuild switch` the user eve's environment
should include a basic Bash configuration and the packages atool and should include a basic Bash configuration and the packages atool and
httpie. httpie.

@ -12,47 +12,51 @@
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<cmdsynopsis> <cmdsynopsis>
<command>home-manager</command> <group choice="req"> <command>home-manager</command> <group choice="req">
<arg choice="plain"> <arg choice="plain">
build build
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
instantiate instantiate
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
edit edit
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
expire-generations <replaceable>timestamp</replaceable> expire-generations <replaceable>timestamp</replaceable>
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
generations generations
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
help help
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
news news
</arg> </arg>
<arg choice="plain">
option <replaceable>option.name</replaceable>
</arg>
<arg choice="plain"> <arg choice="plain">
packages packages
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
remove-generations <replaceable>ID …</replaceable> remove-generations <replaceable>ID …</replaceable>
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
switch switch
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
uninstall uninstall
</arg> </arg>
@ -61,59 +65,63 @@
<arg> <arg>
-A <replaceable>attrPath</replaceable> -A <replaceable>attrPath</replaceable>
</arg> </arg>
<arg> <arg>
-I <replaceable>path</replaceable> -I <replaceable>path</replaceable>
</arg> </arg>
<arg>
--flake <replaceable>flake-uri</replaceable>
</arg>
<arg> <arg>
-b <replaceable>ext</replaceable> -b <replaceable>ext</replaceable>
</arg> </arg>
<arg> <arg>
<group choice="req"> <group choice="req">
<arg choice="plain"> <arg choice="plain">
-f -f
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
--file --file
</arg> </arg>
</group> <replaceable>path</replaceable> </group> <replaceable>path</replaceable>
</arg> </arg>
<arg> <arg>
<group choice="req"> <group choice="req">
<arg choice="plain"> <arg choice="plain">
-h -h
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
--help --help
</arg> </arg>
</group> </group>
</arg> </arg>
<arg> <arg>
<group choice="req"> <group choice="req">
<arg choice="plain"> <arg choice="plain">
-n -n
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
--dry-run --dry-run
</arg> </arg>
</group> </group>
</arg> </arg>
<arg> <arg>
--option <replaceable>name</replaceable> <replaceable>value</replaceable> --option <replaceable>name</replaceable> <replaceable>value</replaceable>
</arg> </arg>
<arg> <arg>
--cores <replaceable>number</replaceable> --cores <replaceable>number</replaceable>
</arg> </arg>
<arg> <arg>
<group choice="req"> <group choice="req">
<arg choice="plain"> <arg choice="plain">
@ -126,29 +134,41 @@
</group> </group>
<replaceable>number</replaceable> <replaceable>number</replaceable>
</arg> </arg>
<arg>
--debug
</arg>
<arg>
--impure
</arg>
<arg> <arg>
--keep-failed --keep-failed
</arg> </arg>
<arg> <arg>
--keep-going --keep-going
</arg> </arg>
<arg> <arg>
--show-trace --show-trace
</arg> </arg>
<arg> <arg>
--(no-)substitute --(no-)substitute
</arg> </arg>
<arg> <arg>
<group choice="req"> --no-out-link
</arg>
<arg>
<group choice="req">
<arg choice="plain"> <arg choice="plain">
-v -v
</arg> </arg>
<arg choice="plain"> <arg choice="plain">
--verbose --verbose
</arg> </arg>
@ -160,7 +180,7 @@
<title>Description</title> <title>Description</title>
<para> <para>
This command updates the user environment so that it corresponds to the This command updates the user environment so that it corresponds to the
configuration specified in <filename>~/.config/nixpkgs/home.nix</filename>. configuration specified in <filename>~/.config/nixpkgs/home.nix</filename> or <filename>~/.config/nixpkgs/flake.nix</filename>.
</para> </para>
<para> <para>
All operations using this tool expects a sub-command that indicates the All operations using this tool expects a sub-command that indicates the
@ -242,6 +262,18 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>option <replaceable>option.name</replaceable></option>
</term>
<listitem>
<para>
Inspect the given option name in the home configuration, like <citerefentry>
<refentrytitle>nixos-option</refentrytitle>
<manvolnum>8</manvolnum> </citerefentry>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>packages</option> <option>packages</option>
@ -343,6 +375,18 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--flake <replaceable>flake-uri[#name]</replaceable></option>
</term>
<listitem>
<para>
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.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>-b <replaceable>extension</replaceable></option> <option>-b <replaceable>extension</replaceable></option>
@ -440,6 +484,30 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--debug</option>
</term>
<listitem>
<para>
Passed on to <citerefentry>
<refentrytitle>nix-build</refentrytitle>
<manvolnum>1</manvolnum> </citerefentry>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--impure</option>
</term>
<listitem>
<para>
Passed on to <citerefentry>
<refentrytitle>nix-build</refentrytitle>
<manvolnum>1</manvolnum> </citerefentry>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>--keep-failed</option> <option>--keep-failed</option>
@ -488,6 +556,19 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--no-out-link</option>
</term>
<listitem>
<para>
Passed on to <citerefentry>
<refentrytitle>nix-build</refentrytitle>
<manvolnum>1</manvolnum> </citerefentry>
when running <command>home-manager build</command>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>-v</option> <option>-v</option>

@ -9,15 +9,13 @@
<preface> <preface>
<title>Preface</title> <title>Preface</title>
<para> <para>
This manual will eventually describes how to install, use, and extend Home This manual will eventually describe how to install, use, and extend Home
Manager. Manager.
</para> </para>
<para> <para>
If you encounter problems then please reach out on the IRC channel If you encounter problems then please reach out on the IRC channel
<link xlink:href="https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager">#home-manager</link> <link xlink:href="https://webchat.oftc.net/?channels=home-manager">#home-manager</link>
hosted by <link xlink:href="https://freenode.net/">freenode</link>. hosted by <link xlink:href="https://oftc.net/">OFTC</link>.
The <link xlink:href="https://logs.nix.samueldr.com/home-manager/">channel logs</link>
are hosted courtesy of <link xlink:href="https://github.com/samueldr/">samueldr</link>.
If your problem is caused by a bug in Home Manager then it should If your problem is caused by a bug in Home Manager then it should
be reported on the be reported on the
<link xlink:href="https://github.com/nix-community/home-manager/issues">Home Manager issue tracker</link>. <link xlink:href="https://github.com/nix-community/home-manager/issues">Home Manager issue tracker</link>.

@ -6,6 +6,8 @@ This section lists the release notes for stable versions of Home Manager and the
:leveloffset: 1 :leveloffset: 1
include::rl-2111.adoc[]
include::rl-2105.adoc[] include::rl-2105.adoc[]
include::rl-2009.adoc[] include::rl-2009.adoc[]

@ -1,8 +1,7 @@
[[sec-release-21.05]] [[sec-release-21.05]]
== Release 21.05 == Release 21.05
This is the current unstable branch and the information in this The 21.05 release branch became the stable branch in May, 2021.
section is therefore not final.
[[sec-release-21.05-highlights]] [[sec-release-21.05-highlights]]
=== Highlights === Highlights
@ -129,6 +128,10 @@ https://github.com/jonls/redshift/blob/master/redshift.conf.sample[redshift.conf
https://gitlab.com/chinstrap/gammastep/-/blob/master/gammastep.conf.sample[gammastep.conf.sample] https://gitlab.com/chinstrap/gammastep/-/blob/master/gammastep.conf.sample[gammastep.conf.sample]
for the available additional options in each program. 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; * The `programs.neovim.configure` is deprecated in favor of other `programs.neovim` options;
please use the other options at your disposal: please use the other options at your disposal:
+ +
@ -158,6 +161,34 @@ 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 <<opt-programs.htop.settings>> option is introduced to replace individual
options in `programs.htop`. To migrate, set the htop options directly in
<<opt-programs.htop.settings>>. 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]] [[sec-release-21.05-state-version-changes]]
=== State Version Changes === State Version Changes
@ -165,4 +196,5 @@ The state version in this release includes the changes below. These
changes are only active if the `home.stateVersion` option is set to changes are only active if the `home.stateVersion` option is set to
"21.05" or later. "21.05" or later.
* Nothing has happened. * The `newsboat` module now stores generated configuration in
`$XDG_CONFIG_HOME/newsboat`.

@ -0,0 +1,47 @@
[[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:
* All Home Manager modules are now loaded on all platforms. With this
change you will get a more descriptive error message if you attempt to
enable a module that is incompatible with the host platform.
+
Previously, modules that were platform specific would only be loaded
on that particular platform. For example, a module defining a
https://systemd.io/[systemd] service would only be loaded when the
host platform was Linux. This reduced evaluation times, simplified the
generated documentation, and made it impossible to accidentally use
modules that do not support the host platform.
+
While the above benefits are quite nice, avoiding module loads also
brings a few problems. For example, the
https://nix-community.github.io/home-manager/[public documentation]
will only show the options available for Linux hosts and the
documentation cannot make references to options within modules that
are unavailable on some hosts. Finally, users who wish to use the same
configuration file for different platforms cannot do so, even if the
platform incompatible options are unused.
+
Ultimately, the benefits of loading all modules won and the behavior
has now changed. For associated discussion see
https://github.com/nix-community/home-manager/issues/1906[issue #1906].
* Rofi version 1.7.0 removed many options that were used by the module and replaced them with custom themes, which are more flexible and powerful.
+
You can replicate your old configuration by moving those options to <<opt-programs.rofi.theme>>. Keep in mind that the syntax is different so you may need to do some changes.
[[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.

@ -1,24 +1,51 @@
{ {
description = "Home Manager for Nix"; description = "Home Manager for Nix";
outputs = { self, nixpkgs }: rec { outputs = { self, nixpkgs }:
nixosModules.home-manager = import ./nixos; let
# List of systems supported by home-manager binary
darwinModules.home-manager = import ./nix-darwin; supportedSystems = nixpkgs.lib.platforms.unix;
lib = { # Function to generate a set based on supported systems
hm = import ./modules/lib { lib = nixpkgs.lib; }; forAllSystems = f:
homeManagerConfiguration = { configuration, system, homeDirectory nixpkgs.lib.genAttrs supportedSystems (system: f system);
, username, extraSpecialArgs ? { }
, pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
, check ? true }@args: in rec {
import ./modules { nixosModules.home-manager = import ./nixos;
inherit pkgs check extraSpecialArgs; nixosModule = self.nixosModules.home-manager;
configuration = { ... }: {
imports = [ configuration ]; darwinModules.home-manager = import ./nix-darwin;
home = { inherit homeDirectory username; }; darwinModule = self.darwinModules.home-manager;
packages = forAllSystems (system:
let docs = import ./docs { pkgs = nixpkgsFor.${system}; };
in {
home-manager = nixpkgsFor.${system}.callPackage ./home-manager { };
docs-html = docs.manual.html;
docs-manpages = docs.manPages;
docs-json = docs.options.json;
});
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; };
};
}; };
}; };
}; };
};
} }

@ -1,5 +1,5 @@
#! /usr/bin/env nix-shell #! /usr/bin/env nix-shell
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/05f0934825c2a0750d4888c4735f9420c906b388.tar.gz -i bash -p findutils nixfmt #! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/5edf5b60c3d8f82b5fc5e73e822b6f7460584945.tar.gz -i bash -p findutils nixfmt
CHECK_ARG= CHECK_ARG=
@ -18,7 +18,6 @@ esac
find . -name '*.nix' \ find . -name '*.nix' \
! -path ./modules/programs/irssi.nix \ ! -path ./modules/programs/irssi.nix \
\ \
! -path ./home-manager/default.nix \
! -path ./home-manager/home-manager.nix \ ! -path ./home-manager/home-manager.nix \
! -path ./modules/default.nix \ ! -path ./modules/default.nix \
! -path ./modules/files.nix \ ! -path ./modules/files.nix \
@ -27,31 +26,15 @@ find . -name '*.nix' \
! -path ./modules/lib/file-type.nix \ ! -path ./modules/lib/file-type.nix \
! -path ./modules/manual.nix \ ! -path ./modules/manual.nix \
! -path ./modules/misc/news.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/bash.nix \
! -path ./modules/programs/firefox.nix \
! -path ./modules/programs/gpg.nix \ ! -path ./modules/programs/gpg.nix \
! -path ./modules/programs/lesspipe.nix \
! -path ./modules/programs/ssh.nix \ ! -path ./modules/programs/ssh.nix \
! -path ./modules/programs/tmux.nix \ ! -path ./modules/programs/tmux.nix \
! -path ./modules/programs/zsh.nix \ ! -path ./modules/programs/zsh.nix \
! -path ./modules/services/gpg-agent.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/mpd.nix \
! -path ./modules/services/sxhkd.nix \
! -path ./modules/services/window-managers/i3.nix \
! -path ./modules/systemd.nix \
! -path ./nix-darwin/default.nix \ ! -path ./nix-darwin/default.nix \
! -path ./tests/default.nix \ ! -path ./tests/default.nix \
! -path ./tests/modules/home-environment/default.nix \
! -path ./tests/modules/home-environment/session-variables.nix \ ! -path ./tests/modules/home-environment/session-variables.nix \
! -path ./tests/modules/programs/gpg/override-defaults.nix \ ! -path ./tests/modules/programs/gpg/override-defaults.nix \
! -path ./tests/modules/programs/zsh/session-variables.nix \
! -path ./tests/modules/services/sxhkd/service.nix \
! -path ./tests/modules/systemd/services.nix \
! -path ./tests/modules/systemd/session-variables.nix \
-exec nixfmt $CHECK_ARG {} + -exec nixfmt $CHECK_ARG {} +

@ -62,6 +62,7 @@
# generations # generations
# help # help
# news # news
# option
# packages # packages
# remove-generations # remove-generations
# switch # switch
@ -86,6 +87,7 @@
# #
# help # help
# edit # edit
# option
# build # build
# switch # switch
# generations # generations
@ -131,6 +133,9 @@
# #
# edit Open the home configuration in $EDITOR # edit Open the home configuration in $EDITOR
# #
# option OPTION.NAME
# Inspect configuration option named OPTION.NAME.
#
# build Build configuration into result directory # build Build configuration into result directory
# #
# switch Build and activate configuration # switch Build and activate configuration
@ -278,15 +283,17 @@ _home-manager_completions ()
#--------------------------# #--------------------------#
local Subcommands 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. # ^ « home-manager »'s subcommands.
#--------------------------# #--------------------------#
local Options 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" \
"-j" "--max-jobs" ) "--verbose" "--cores" "--debug" "--impure" "--keep-failed" \
"--keep-going" "-j" "--max-jobs" "--no-substitute" "--no-out-link" \
"--show-trace" "--substitute" "--builders")
# ^ « home-manager »'s options. # ^ « home-manager »'s options.
@ -354,4 +361,4 @@ _home-manager_completions ()
complete -F _home-manager_completions -o default home-manager 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

@ -0,0 +1,65 @@
#!/bin/env fish
##################################################
# « home-manager » command-line fish completion
#
# © 2021 "Ariel AxionL" <i at axionl dot me>
#
# MIT License
#
##################################################
### Functions
function __home_manager_generations --description "Get all generations"
for i in (home-manager generations)
set -l split (string split " " $i)
set -l gen_id $split[5]
set -l gen_datetime $split[1..2]
set -l gen_hash (string match -r '\w{32}' $i)
echo $gen_id\t$gen_datetime $gen_hash
end
end
### SubCommands
complete -c home-manager -n "__fish_use_subcommand" -f -a "help" -d "Print home-manager help"
complete -c home-manager -n "__fish_use_subcommand" -f -a "edit" -d "Open the home configuration in $EDITOR"
complete -c home-manager -n "__fish_use_subcommand" -f -a "option" -d "Inspect configuration option"
complete -c home-manager -n "__fish_use_subcommand" -f -a "build" -d "Build configuration into result directory"
complete -c home-manager -n "__fish_use_subcommand" -f -a "instantiate" -d "Instantiate the configuration and print the resulting derivation"
complete -c home-manager -n "__fish_use_subcommand" -f -a "switch" -d "Build and activate configuration"
complete -c home-manager -n "__fish_use_subcommand" -f -a "generations" -d "List all home environment generations"
complete -c home-manager -n "__fish_use_subcommand" -f -a "packages" -d "List all packages installed in home-manager-path"
complete -c home-manager -n "__fish_use_subcommand" -f -a "news" -d "Show news entries in a pager"
complete -c home-manager -n "__fish_use_subcommand" -f -a "uninstall" -d "Remove Home Manager"
complete -c home-manager -n "__fish_use_subcommand" -x -a "remove-generations" -d "Remove indicated generations"
complete -c home-manager -n "__fish_seen_subcommand_from remove-generations" -f -ka '(__home_manager_generations)'
complete -c home-manager -n "__fish_use_subcommand" -x -a "expire-generations" -d "Remove generations older than TIMESTAMP"
### Options
complete -c home-manager -F -s f -l "file" -d "The home configuration file"
complete -c home-manager -x -s A -d "Select an expression in the configuration file"
complete -c home-manager -F -s I -d "Add a path to the Nix expression search path"
complete -c home-manager -F -l "flake" -d "Use home-manager configuration at specified flake-uri"
complete -c home-manager -F -s b -d "Move existing files to new path rather than fail"
complete -c home-manager -f -s v -l "verbose" -d "Verbose output"
complete -c home-manager -f -s n -l "dry-run" -d "Do a dry run, only prints what actions would be taken"
complete -c home-manager -f -s h -l "help" -d "Print this help"
complete -c home-manager -x -l "arg" -d "Override inputs passed to home-manager.nix"
complete -c home-manager -x -l "argstr" -d "Like --arg but the value is a string"
complete -c home-manager -x -l "cores" -d "Threads per job (e.g. -j argument to make)"
complete -c home-manager -x -l "debug"
complete -c home-manager -x -l "impure"
complete -c home-manager -f -l "keep-failed" -d "Keep temporary directory used by failed builds"
complete -c home-manager -f -l "keep-going" -d "Keep going in case of failed builds"
complete -c home-manager -x -s j -l "max-jobs" -d "Max number of build jobs in parallel"
complete -c home-manager -x -l "option" -d "Set Nix configuration option"
complete -c home-manager -x -l "builders" -d "Remote builders"
complete -c home-manager -f -l "show-trace" -d "Print stack trace of evaluation errors"
complete -c home-manager -f -l "substitute"
complete -c home-manager -f -l "no-substitute"
complete -c home-manager -f -l "no-out-link"

@ -7,6 +7,8 @@ _arguments \
'-I[search path]:PATH:_files -/' \ '-I[search path]:PATH:_files -/' \
'-b[backup files]:EXT:()' \ '-b[backup files]:EXT:()' \
'--cores[cores]:NUM:()' \ '--cores[cores]:NUM:()' \
'--debug[debug]' \
'--impure[impure]' \
'--keep-failed[keep failed]' \ '--keep-failed[keep failed]' \
'--keep-going[keep going]' \ '--keep-going[keep going]' \
'(-h --help)'{--help,-h}'[help]' \ '(-h --help)'{--help,-h}'[help]' \
@ -15,6 +17,7 @@ _arguments \
'(-f --file)'{--file,-f}'[configuration file]:FILE:_files' \ '(-f --file)'{--file,-f}'[configuration file]:FILE:_files' \
'(-j --max-jobs)'{--max-jobs,-j}'[max jobs]:NUM:()' \ '(-j --max-jobs)'{--max-jobs,-j}'[max jobs]:NUM:()' \
'--option[option]:NAME VALUE:()' \ '--option[option]:NAME VALUE:()' \
'--builders[builders]:SPEC:()' \
'--show-trace[show trace]' \ '--show-trace[show trace]' \
'1: :->cmds' \ '1: :->cmds' \
'*:: :->args' && ret=0 '*:: :->args' && ret=0
@ -24,6 +27,7 @@ case "$state" in
_values 'command' \ _values 'command' \
'help[help]' \ 'help[help]' \
'edit[edit]' \ 'edit[edit]' \
'option[inspect option]' \
'build[build]' \ 'build[build]' \
'switch[switch]' \ 'switch[switch]' \
'generations[list generations]' \ 'generations[list generations]' \
@ -42,11 +46,17 @@ case "$state" in
build|switch) build|switch)
_arguments \ _arguments \
'--cores[cores]:NUM:()' \ '--cores[cores]:NUM:()' \
'--debug[debug]' \
'--impure[impure]' \
'--keep-failed[keep failed]' \ '--keep-failed[keep failed]' \
'--keep-going[keep going]' \ '--keep-going[keep going]' \
'--max-jobs[max jobs]:NUM:()' \ '--max-jobs[max jobs]:NUM:()' \
'--no-out-link[no out link]' \
'--no-substitute[no substitute]' \
'--option[option]:NAME VALUE:()' \ '--option[option]:NAME VALUE:()' \
'--show-trace[show trace]' '--show-trace[show trace]' \
'--substitute[substitute]' \
'--builders[builders]:SPEC:()'
;; ;;
esac esac
esac esac

@ -1,42 +1,44 @@
{ 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 # Extra path to Home Manager. If set then this path will be tried
# before `$HOME/.config/nixpkgs/home-manager` and # before `$HOME/.config/nixpkgs/home-manager` and
# `$HOME/.nixpkgs/home-manager`. # `$HOME/.nixpkgs/home-manager`.
, path ? null , path ? null }:
}:
let let
pathStr = if path == null then "" else path; pathStr = if path == null then "" else path;
in nixos-option = pkgs.nixos-option or (callPackage
(pkgs.path + "/nixos/modules/installer/tools/nixos-option") { });
runCommand in runCommand "home-manager" {
"home-manager" preferLocalBuild = true;
{ allowSubstitutes = false;
preferLocalBuild = true; meta = with lib; {
allowSubstitutes = false; description = "A user environment configurator";
meta = with lib; { maintainers = [ maintainers.rycee ];
description = "A user environment configurator"; platforms = platforms.unix;
maintainers = [ maintainers.rycee ]; license = licenses.mit;
platforms = platforms.unix; };
license = licenses.mit; } ''
}; install -v -D -m755 ${./home-manager} $out/bin/home-manager
}
''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
substituteInPlace $out/bin/home-manager \ substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${bash}" \ --subst-var-by bash "${bash}" \
--subst-var-by coreutils "${coreutils}" \ --subst-var-by coreutils "${coreutils}" \
--subst-var-by findutils "${findutils}" \ --subst-var-by findutils "${findutils}" \
--subst-var-by gnused "${gnused}" \ --subst-var-by gnused "${gnused}" \
--subst-var-by less "${less}" \ --subst-var-by less "${less}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}' --subst-var-by nixos-option "${nixos-option}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
install -D -m755 ${./completion.bash} \ install -D -m755 ${./completion.bash} \
$out/share/bash-completion/completions/home-manager $out/share/bash-completion/completions/home-manager
install -D -m755 ${./completion.zsh} \ install -D -m755 ${./completion.zsh} \
$out/share/zsh/site-functions/_home-manager $out/share/zsh/site-functions/_home-manager
'' install -D -m755 ${./completion.fish} \
$out/share/fish/vendor_completions.d/home-manager.fish
''

@ -1,7 +1,7 @@
#!@bash@/bin/bash #!@bash@/bin/bash
# Prepare to use tools from Nixpkgs. # 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 set -euo pipefail
@ -74,7 +74,75 @@ function setHomeManagerNixPath() {
done 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 <home-manager/modules> {"
modulesExpr+=" configuration = if confAttr == \"\" then confPath else (import confPath).\${confAttr};"
modulesExpr+=" pkgs = import <nixpkgs> {}; check = true; })"
nixos-option \
--options_expr "$modulesExpr.options" \
--config_expr "$modulesExpr.config" \
"${extraArgs[@]}" \
"${PASSTHROUGH_OPTS[@]}"
}
function doInstantiate() { function doInstantiate() {
setFlakeAttribute
if [[ -v FLAKE_CONFIG_URI ]]; then
errorEcho "Can't instantiate a flake configuration"
exit 1
fi
setConfigFile setConfigFile
setHomeManagerNixPath setHomeManagerNixPath
@ -178,14 +246,27 @@ function doBuild() {
return 1 return 1
fi fi
setFlakeAttribute
if [[ -v FLAKE_CONFIG_URI ]]; then
local exitCode=0
nix build \
"${PASSTHROUGH_OPTS[@]}" \
${DRY_RUN+--dry-run} \
${NO_OUT_LINK+--no-out-link} \
"$FLAKE_CONFIG_URI.activationPackage" \
|| exitCode=1
return $exitCode
fi
setWorkDir setWorkDir
local newsInfo local newsInfo
newsInfo=$(buildNews) newsInfo=$(buildNews)
local exitCode local exitCode
doBuildAttr \
doBuildAttr --attr activationPackage \ ${NO_OUT_LINK+--no-out-link} \
--attr activationPackage \
&& exitCode=0 || exitCode=1 && exitCode=0 || exitCode=1
presentNews "$newsInfo" presentNews "$newsInfo"
@ -194,6 +275,16 @@ function doBuild() {
} }
function doSwitch() { 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 setWorkDir
local newsInfo local newsInfo
@ -409,25 +500,31 @@ function doHelp() {
echo echo
echo "Options" echo "Options"
echo echo
echo " -f FILE The home configuration file." echo " -f FILE The home configuration file."
echo " Default is '~/.config/nixpkgs/home.nix'." echo " Default is '~/.config/nixpkgs/home.nix'."
echo " -A ATTRIBUTE Optional attribute that selects a configuration" echo " -A ATTRIBUTE Optional attribute that selects a configuration"
echo " expression in the configuration file." echo " expression in the configuration file."
echo " -I PATH Add a path to the Nix expression search path." 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 " --flake flake-uri Use home-manager configuration at flake-uri"
echo " -v Verbose output" echo " -b EXT Move existing files to new path rather than fail."
echo " -n Do a dry run, only prints what actions would be taken" echo " -v Verbose output"
echo " -h Print this help" echo " -n Do a dry run, only prints what actions would be taken"
echo " -h Print this help"
echo echo
echo "Options passed on to nix-build(1)" echo "Options passed on to nix-build(1)"
echo echo
echo " --arg(str) NAME VALUE Override inputs passed to home-manager.nix"
echo " --cores NUM" echo " --cores NUM"
echo " --debug"
echo " --impure"
echo " --keep-failed" echo " --keep-failed"
echo " --keep-going" echo " --keep-going"
echo " -j, --max-jobs NUM" echo " -j, --max-jobs NUM"
echo " --option NAME VALUE" echo " --option NAME VALUE"
echo " --show-trace" echo " --show-trace"
echo " --(no-)substitute" echo " --(no-)substitute"
echo " --no-out-link Do not create a symlink to the output path"
echo " --builders VALUE"
echo echo
echo "Commands" echo "Commands"
echo echo
@ -435,6 +532,9 @@ function doHelp() {
echo echo
echo " edit Open the home configuration in \$EDITOR" echo " edit Open the home configuration in \$EDITOR"
echo echo
echo " option OPTION.NAME"
echo " Inspect configuration option named OPTION.NAME."
echo
echo " build Build configuration into result directory" echo " build Build configuration into result directory"
echo echo
echo " instantiate Instantiate the configuration and print the resulting derivation" echo " instantiate Instantiate the configuration and print the resulting derivation"
@ -466,12 +566,13 @@ HOME_MANAGER_CONFIG_ATTRIBUTE=""
PASSTHROUGH_OPTS=() PASSTHROUGH_OPTS=()
COMMAND="" COMMAND=""
COMMAND_ARGS=() COMMAND_ARGS=()
FLAKE_ARG=""
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
opt="$1" opt="$1"
shift shift
case $opt in 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" COMMAND="$opt"
;; ;;
-A) -A)
@ -490,6 +591,24 @@ while [[ $# -gt 0 ]]; do
HOME_MANAGER_CONFIG="$1" HOME_MANAGER_CONFIG="$1"
shift 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
;;
--no-out-link)
NO_OUT_LINK=1
;;
-h|--help) -h|--help)
doHelp doHelp
exit 0 exit 0
@ -497,28 +616,28 @@ while [[ $# -gt 0 ]]; do
-n|--dry-run) -n|--dry-run)
export DRY_RUN=1 export DRY_RUN=1
;; ;;
--option) --option|--arg|--argstr)
PASSTHROUGH_OPTS+=("$opt" "$1" "$2") PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
shift 2 shift 2
;; ;;
-j|--max-jobs|--cores) -j|--max-jobs|--cores|--builders)
PASSTHROUGH_OPTS+=("$opt" "$1") PASSTHROUGH_OPTS+=("$opt" "$1")
shift shift
;; ;;
--keep-failed|--keep-going|--show-trace\ --debug|--keep-failed|--keep-going|--show-trace\
|--substitute|--no-substitute) |--substitute|--no-substitute|--impure)
PASSTHROUGH_OPTS+=("$opt") PASSTHROUGH_OPTS+=("$opt")
;; ;;
-v|--verbose) -v|--verbose)
export VERBOSE=1 export VERBOSE=1
;; ;;
--version) --version)
echo 21.05 echo 21.11
exit 0 exit 0
;; ;;
*) *)
case $COMMAND in case $COMMAND in
expire-generations|remove-generations) expire-generations|remove-generations|option)
COMMAND_ARGS+=("$opt") COMMAND_ARGS+=("$opt")
;; ;;
*) *)
@ -563,6 +682,9 @@ case $COMMAND in
doExpireGenerations "${COMMAND_ARGS[@]}" doExpireGenerations "${COMMAND_ARGS[@]}"
fi fi
;; ;;
option)
doInspectOption "${COMMAND_ARGS[@]}"
;;
packages) packages)
doListPackages doListPackages
;; ;;
@ -581,3 +703,5 @@ case $COMMAND in
exit 1 exit 1
;; ;;
esac esac
# vim: ft=bash

@ -45,7 +45,7 @@ runCommand "home-manager-install" {
# You can update Home Manager without changing this value. See # You can update Home Manager without changing this value. See
# the Home Manager release notes for a list of state version # the Home Manager release notes for a list of state version
# changes in each release. # changes in each release.
home.stateVersion = "21.05"; home.stateVersion = "21.11";
} }
EOF EOF
fi fi

@ -71,7 +71,7 @@ let
}; };
certificatesFile = mkOption { certificatesFile = mkOption {
type = types.path; type = types.nullOr types.path;
default = config.accounts.email.certificatesFile; default = config.accounts.email.certificatesFile;
defaultText = "config.accounts.email.certificatesFile"; defaultText = "config.accounts.email.certificatesFile";
description = '' description = ''
@ -332,7 +332,10 @@ let
(mkIf (config.flavor == "gmail.com") { (mkIf (config.flavor == "gmail.com") {
userName = mkDefault config.address; userName = mkDefault config.address;
imap = { host = "imap.gmail.com"; }; imap = {
host = "imap.gmail.com";
port = 993;
};
smtp = { smtp = {
host = "smtp.gmail.com"; host = "smtp.gmail.com";
@ -351,7 +354,7 @@ let
in { in {
options.accounts.email = { options.accounts.email = {
certificatesFile = mkOption { certificatesFile = mkOption {
type = types.path; type = types.nullOr types.path;
default = "/etc/ssl/certs/ca-certificates.crt"; default = "/etc/ssl/certs/ca-certificates.crt";
description = '' description = ''
Path to default file containing certificate authorities that Path to default file containing certificate authorities that

@ -36,7 +36,7 @@ let
in { in {
meta.maintainers = with maintainers; [ midchildan ]; meta.maintainers = with maintainers; [ midchildan ];
config = { config = mkIf pkgs.hostPlatform.isLinux {
# For shell sessions. # For shell sessions.
home.sessionVariables = localeVars; home.sessionVariables = localeVars;

@ -39,6 +39,28 @@ in
}; };
config = { 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: lib.file.mkOutOfStoreSymlink = path:
let let
pathStr = toString path; pathStr = toString path;
@ -53,7 +75,7 @@ in
# Paths that should be forcibly overwritten by Home Manager. # Paths that should be forcibly overwritten by Home Manager.
# Caveat emptor! # Caveat emptor!
forcedPaths = forcedPaths =
concatMapStringsSep " " (p: ''"$HOME/${p}"'') concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'')
(mapAttrsToList (n: v: v.target) (mapAttrsToList (n: v: v.target)
(filterAttrs (n: v: v.force) cfg)); (filterAttrs (n: v: v.force) cfg));
@ -62,7 +84,7 @@ in
# A symbolic link whose target path matches this pattern will be # A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation. # 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}) forcedPaths=(${forcedPaths})
@ -84,7 +106,12 @@ in
$VERBOSE_ECHO "Skipping collision check for $targetPath" $VERBOSE_ECHO "Skipping collision check for $targetPath"
elif [[ -e "$targetPath" \ elif [[ -e "$targetPath" \
&& ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then && ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
if [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then # The target file already exists and it isn't a symlink owned by Home Manager.
if cmp -s $sourcePath $targetPath; then
# First compare the files' content. If they're equal, we're fine.
warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be skipped since they are the same"
elif [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
# Next, try to move the file to a backup location if configured and possible
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT" backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
if [[ -e "$backup" ]]; then if [[ -e "$backup" ]]; then
errorEcho "Existing file '$backup' would be clobbered by backing up '$targetPath'" errorEcho "Existing file '$backup' would be clobbered by backing up '$targetPath'"
@ -93,6 +120,7 @@ in
warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be moved to '$backup'" warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be moved to '$backup'"
fi fi
else else
# Fail if nothing else works
errorEcho "Existing file '$targetPath' is in the way of '$sourcePath'" errorEcho "Existing file '$targetPath' is in the way of '$sourcePath'"
collision=1 collision=1
fi fi
@ -100,7 +128,7 @@ in
done done
if [[ -v collision ]] ; then if [[ -v collision ]] ; then
errorEcho "Please move the above files and try again or use -b <ext> to move automatically." errorEcho "Please move the above files and try again or use 'home-manager switch -b backup' to back up existing files automatically."
exit 1 exit 1
fi fi
''; '';
@ -140,27 +168,35 @@ in
# source and target generation. # source and target generation.
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] ( home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
let let
link = pkgs.writeText "link" '' link = pkgs.writeShellScript "link" ''
newGenFiles="$1" newGenFiles="$1"
shift shift
for sourcePath in "$@" ; do for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}" relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath" targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
# The target exists, back it up
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT" backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
$DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!" $DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
fi fi
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath" if [[ -e "$targetPath" && ! -L "$targetPath" ]] && cmp -s $sourcePath $targetPath ; then
# The target exists but is identical – don't do anything.
$VERBOSE_ECHO "Skipping '$targetPath' as it is identical to '$sourcePath'"
else
# Place that symlink, --force
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath"
fi
done done
''; '';
cleanup = pkgs.writeText "cleanup" '' cleanup = pkgs.writeShellScript "cleanup" ''
. ${./lib-bash/color-echo.sh} . ${./lib-bash/color-echo.sh}
# A symbolic link whose target path matches this pattern will be # A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation. # 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" newGenFiles="$1"
shift 1 shift 1
@ -235,31 +271,50 @@ in
); );
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] ( 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 declare -A changedFiles
'' + concatMapStrings (v: '' '' + concatMapStrings (v:
cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \ let
&& changedFiles["${v.target}"]=0 \ sourceArg = escapeShellArg (sourceStorePath v);
|| changedFiles["${v.target}"]=1 targetArg = escapeShellArg v.target;
'') (filter (v: v.onChange != "") (attrValues cfg)) 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"] ( home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
concatMapStrings (v: '' concatMapStrings (v: ''
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then if (( ''${changedFiles[${escapeShellArg v.target}]} == 1 )); then
${v.onChange} if [[ -v DRY_RUN || -v VERBOSE ]]; then
echo "Running onChange hook for" ${escapeShellArg v.target}
fi
if [[ ! -v DRY_RUN ]]; then
${v.onChange}
fi
fi fi
'') (filter (v: v.onChange != "") (attrValues cfg)) '') (filter (v: v.onChange != "") (attrValues cfg))
); );
# Symlink directories and files that have the right execute bit. # Symlink directories and files that have the right execute bit.
# Copy files that need their execute bit changed. # Copy files that need their execute bit changed.
home-files = pkgs.runCommand home-files = pkgs.runCommandLocal
"home-manager-files" "home-manager-files"
{ {
nativeBuildInputs = [ pkgs.xorg.lndir ]; nativeBuildInputs = [ pkgs.xorg.lndir ];
preferLocalBuild = true;
allowSubstitutes = false;
} }
('' (''
mkdir -p $out mkdir -p $out
@ -273,6 +328,15 @@ in
local executable="$3" local executable="$3"
local recursive="$4" 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. # Figure out the real absolute path to the target.
local target local target
target="$(realpath -m "$realOut/$relTarget")" target="$(realpath -m "$realOut/$relTarget")"

@ -115,7 +115,7 @@ let
if versionAtLeast config.home.stateVersion "19.09" if versionAtLeast config.home.stateVersion "19.09"
then null then null
else "us"; else "us";
defaultText = literalExample "null"; defaultText = literalExpression "null";
description = '' description = ''
Keyboard layout. If <literal>null</literal>, then the system Keyboard layout. If <literal>null</literal>, then the system
configuration will be used. configuration will be used.
@ -149,7 +149,7 @@ let
if versionAtLeast config.home.stateVersion "19.09" if versionAtLeast config.home.stateVersion "19.09"
then null then null
else ""; else "";
defaultText = literalExample "null"; defaultText = literalExpression "null";
example = "colemak"; example = "colemak";
description = '' description = ''
X keyboard variant. If <literal>null</literal>, then the X keyboard variant. If <literal>null</literal>, then the
@ -182,7 +182,7 @@ in
options = { options = {
home.username = mkOption { home.username = mkOption {
type = types.str; type = types.str;
defaultText = literalExample '' defaultText = literalExpression ''
"$USER" for state version < 20.09, "$USER" for state version < 20.09,
undefined for state version 20.09 undefined for state version 20.09
''; '';
@ -192,7 +192,7 @@ in
home.homeDirectory = mkOption { home.homeDirectory = mkOption {
type = types.path; type = types.path;
defaultText = literalExample '' defaultText = literalExpression ''
"$HOME" for state version < 20.09, "$HOME" for state version < 20.09,
undefined for state version 20.09 undefined for state version 20.09
''; '';
@ -321,7 +321,7 @@ in
home.activation = mkOption { home.activation = mkOption {
type = hm.types.dagOf types.str; type = hm.types.dagOf types.str;
default = {}; default = {};
example = literalExample '' example = literalExpression ''
{ {
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] ''' myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
$DRY_RUN_CMD ln -s $VERBOSE_ARG \ $DRY_RUN_CMD ln -s $VERBOSE_ARG \
@ -373,6 +373,16 @@ in
description = "The package containing the complete activation script."; description = "The package containing the complete activation script.";
}; };
home.extraActivationPath = mkOption {
internal = true;
type = types.listOf types.package;
default = [ ];
description = ''
Extra packages to add to <envar>PATH</envar> within the activation
script.
'';
};
home.extraBuilderCommands = mkOption { home.extraBuilderCommands = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
@ -390,6 +400,21 @@ in
Extra commands to run in the Home Manager profile builder. 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.
</para><para>
When this option is enabled and a mismatch is detected then a warning
will be printed when the user configuration is being built.
'';
};
}; };
config = { config = {
@ -404,6 +429,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 = home.username =
mkIf (versionOlder config.home.stateVersion "20.09") mkIf (versionOlder config.home.stateVersion "20.09")
(mkDefault (builtins.getEnv "USER")); (mkDefault (builtins.getEnv "USER"));
@ -493,7 +543,24 @@ in
'' ''
else else
'' ''
$DRY_RUN_CMD nix-env -i ${cfg.path} if ! $DRY_RUN_CMD nix-env -i ${cfg.path} ; then
cat <<EOF
Oops, nix-env failed to install your new Home Manager profile!
Perhaps there is a conflict with a package that was installed using
'nix-env -i'? Try running
nix-env -q
and if there is a conflicting package you can remove it with
nix-env -e {package name}
Then try activating your Home Manager configuration again.
EOF
exit 1
fi
'' ''
); );
@ -513,20 +580,20 @@ in
# Programs that always should be available on the activation # Programs that always should be available on the activation
# script's PATH. # script's PATH.
activationBinPaths = lib.makeBinPath [ activationBinPaths = lib.makeBinPath (
pkgs.bash [
pkgs.coreutils pkgs.bash
pkgs.diffutils # For `cmp` and `diff`. pkgs.coreutils
pkgs.findutils pkgs.diffutils # For `cmp` and `diff`.
pkgs.gnugrep pkgs.findutils
pkgs.gnused pkgs.gnugrep
pkgs.ncurses # For `tput`. pkgs.gnused
] pkgs.ncurses # For `tput`.
] ++ config.home.extraActivationPath
)
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH"; + optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
activationScript = pkgs.writeScript "activation-script" '' activationScript = pkgs.writeShellScript "activation-script" ''
#!${pkgs.runtimeShell}
set -eu set -eu
set -o pipefail set -o pipefail
@ -552,6 +619,9 @@ in
cp ${activationScript} $out/activate cp ${activationScript} $out/activate
mkdir $out/bin
ln -s $out/activate $out/bin/home-manager-generation
substituteInPlace $out/activate \ substituteInPlace $out/activate \
--subst-var-by GENERATION_DIR $out --subst-var-by GENERATION_DIR $out

@ -0,0 +1,106 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.i18n.inputMethod;
gtk2Cache = pkgs.runCommandLocal "gtk2-immodule.cache" {
buildInputs = [ pkgs.gtk2 cfg.package ];
} ''
mkdir -p $out/etc/gtk-2.0/
GTK_PATH=${cfg.package}/lib/gtk-2.0/ \
gtk-query-immodules-2.0 > $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.
</para><para>
Input methods are specially used to input Chinese, Japanese and Korean
characters.
</para><para>
Currently the following input methods are available in Home Manager:
<variablelist>
<varlistentry>
<term><literal>fcitx</literal></term>
<listitem><para>
A customizable lightweight input method
extra input engines can be added using
<literal>i18n.inputMethod.fcitx.engines</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>fcitx5</literal></term>
<listitem><para>
The next generation of fcitx,
addons (including engines, dictionaries, skins) can be added using
<literal>i18n.inputMethod.fcitx5.addons</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>nabi</literal></term>
<listitem><para>
A Korean input method based on XIM. Nabi doesn't support Qt 5.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>uim</literal></term>
<listitem><para>
The universal input method, is a library with a XIM bridge.
uim mainly support Chinese, Japanese and Korean.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>hime</literal></term>
<listitem><para>An extremely easy-to-use input method framework.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>kime</literal></term>
<listitem><para>A Korean IME.</para></listitem>
</varlistentry>
</variablelist>
'';
};
package = mkOption {
internal = true;
type = types.nullOr types.path;
default = null;
description = ''
The input method method package.
'';
};
};
};
config = mkIf (cfg.enabled != null) {
assertions = [
(hm.assertions.assertPlatform "i18n.inputMethod" pkgs platforms.linux)
];
home.packages = [ cfg.package gtk2Cache gtk3Cache ];
};
meta.maintainers = with lib; [ hm.maintainers.kranzes ];
}

@ -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 = literalExpression "with pkgs.fcitx-engines; [ mozc hangul ]";
description = let
enginesDrv = filterAttrs (const isDerivation) pkgs.fcitx-engines;
engines = concatStringsSep ", "
(map (name: "<literal>${name}</literal>") (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" ];
};
};
}

@ -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 = literalExpression "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" ];
};
};
}

@ -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" ];
};
};
}

@ -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 = literalExpression ''
{
daemon = {
modules = ["Xim" "Indicator"];
};
indicator = {
icon_color = "White";
};
engine = {
hangul = {
layout = "dubeolsik";
};
};
}
'';
description = ''
kime configuration. Refer to
<link xlink:href="https://github.com/Riey/kime/blob/develop/docs/CONFIGURATION.md"/>
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" ];
};
};
}

@ -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" ];
};
};
}

@ -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" ];
};
};
}

@ -5,9 +5,9 @@ function setupVars() {
local profilesPath="$nixStateDir/profiles/per-user/$USER" local profilesPath="$nixStateDir/profiles/per-user/$USER"
local gcPath="$nixStateDir/gcroots/per-user/$USER" local gcPath="$nixStateDir/gcroots/per-user/$USER"
genProfilePath="$profilesPath/home-manager" declare -gr genProfilePath="$profilesPath/home-manager"
newGenPath="@GENERATION_DIR@"; declare -gr newGenPath="@GENERATION_DIR@";
newGenGcPath="$gcPath/current-home" declare -gr newGenGcPath="$gcPath/current-home"
local greatestGenNum local greatestGenNum
greatestGenNum=$( \ greatestGenNum=$( \
@ -16,14 +16,15 @@ function setupVars() {
| sed -E 's/ *([[:digit:]]+) .*/\1/') | sed -E 's/ *([[:digit:]]+) .*/\1/')
if [[ -n $greatestGenNum ]] ; then if [[ -n $greatestGenNum ]] ; then
oldGenNum=$greatestGenNum declare -gr oldGenNum=$greatestGenNum
newGenNum=$((oldGenNum + 1)) declare -gr newGenNum=$((oldGenNum + 1))
else else
newGenNum=1 declare -gr newGenNum=1
fi fi
if [[ -e $profilesPath/home-manager ]] ; then if [[ -e $profilesPath/home-manager ]] ; then
oldGenPath="$(readlink -e "$profilesPath/home-manager")" oldGenPath="$(readlink -e "$profilesPath/home-manager")"
declare -gr oldGenPath
fi fi
$VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath" $VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath"

@ -0,0 +1,14 @@
{ lib }:
{
assertPlatform = module: pkgs: platforms: {
assertion = lib.elem pkgs.stdenv.hostPlatform.system platforms;
message = let
platformsStr = lib.concatStringsSep "\n"
(map (p: " - ${p}") (lib.sort (a: b: a < b) platforms));
in ''
The module ${module} does not support your platform. It only supports
${platformsStr}'';
};
}

@ -16,6 +16,8 @@ rec {
entryBefore = d.dagEntryBefore; entryBefore = d.dagEntryBefore;
}; };
assertions = import ./assertions.nix { inherit lib; };
gvariant = import ./gvariant.nix { inherit lib; }; gvariant = import ./gvariant.nix { inherit lib; };
maintainers = import ./maintainers.nix; maintainers = import ./maintainers.nix;
strings = import ./strings.nix { inherit lib; }; strings = import ./strings.nix { inherit lib; };

@ -21,7 +21,7 @@ with lib;
absPath = if hasPrefix "/" p then p else "${basePath}/${p}"; absPath = if hasPrefix "/" p then p else "${basePath}/${p}";
in in
removePrefix (homeDirectory + "/") absPath; removePrefix (homeDirectory + "/") absPath;
defaultText = literalExample "<name>"; defaultText = literalExpression "<name>";
description = '' description = ''
Path to target file relative to ${basePathDesc}. Path to target file relative to ${basePathDesc}.
''; '';
@ -82,6 +82,9 @@ with lib;
generations. The script will be run generations. The script will be run
<emphasis>after</emphasis> the new files have been linked <emphasis>after</emphasis> the new files have been linked
into place. into place.
</para><para>
Note, this code is always run when <literal>recursive</literal> is
enabled.
''; '';
}; };

@ -71,6 +71,8 @@ in rec {
inherit type typeOf; inherit type typeOf;
isGVariant = v: v._type or "" == "gvariant";
isArray = hasPrefix "a"; isArray = hasPrefix "a";
isMaybe = hasPrefix "m"; isMaybe = hasPrefix "m";
isTuple = hasPrefix "("; isTuple = hasPrefix "(";
@ -122,8 +124,9 @@ in rec {
}; };
mkString = v: mkString = v:
mkPrimitive type.string v // { let sanitize = s: replaceStrings [ "\n" ] [ "\\n" ] (escape [ "'" "\\" ] s);
__toString = self: "'${escape [ "'" "\\" ] self.value}'"; in mkPrimitive type.string v // {
__toString = self: "'${sanitize self.value}'";
}; };
mkObjectpath = v: mkObjectpath = v:

@ -25,12 +25,34 @@
github = "cwyc"; github = "cwyc";
githubId = 16950437; githubId = 16950437;
}; };
chisui = {
name = "Philipp Dargel";
email = "chisui@users.noreply.github.com";
github = "chisui";
githubId = 4526429;
};
olmokramer = { olmokramer = {
name = "Olmo Kramer"; name = "Olmo Kramer";
email = "olmokramer@users.noreply.github.com"; email = "olmokramer@users.noreply.github.com";
github = "olmokramer"; github = "olmokramer";
githubId = 3612514; 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 = { kubukoz = {
name = "Jakub Kozłowski"; name = "Jakub Kozłowski";
email = "kubukoz@users.noreply.github.com"; email = "kubukoz@users.noreply.github.com";
@ -53,16 +75,62 @@
fingerprint = "F0E0 0311 126A CD72 4392 25E6 68BF 2EAE 6D91 CAFF"; 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 = { fendse = {
email = "46252070+Fendse@users.noreply.github.com"; email = "46252070+Fendse@users.noreply.github.com";
github = "Fendse"; github = "Fendse";
githubId = 46252070; githubId = 46252070;
name = "Sara Johnsson"; 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";
};
mager = {
email = "andreas@mager.eu";
github = "AndreasMager";
githubId = 5646732;
name = "Andreas Mager";
};
bjpbakker = {
email = "bart@thesoftwarecraft.com";
github = "bjpbakker";
githubId = 605641;
name = "Bart Bakker";
};
jrobsonchase = {
email = "josh@robsonchase.com";
github = "jrobsonchase";
githubId = 1553581;
name = "Josh Robson Chase";
};
hawkw = {
name = "Eliza Weisman";
email = "eliza@elizas.website";
github = "hawkw";
githubId = 2796466;
};
} }

@ -4,4 +4,10 @@
nixpkgsLib: nixpkgsLib:
let mkHmLib = import ./.; let mkHmLib = import ./.;
in nixpkgsLib.extend (self: super: { hm = mkHmLib { lib = super; }; }) in nixpkgsLib.extend (self: super: {
hm = mkHmLib { lib = self; };
# For forward compatibility.
literalExpression = super.literalExpression or super.literalExample;
literalDocBook = super.literalDocBook or super.literalExample;
})

@ -37,7 +37,7 @@ in rec {
package = mkOption { package = mkOption {
type = types.nullOr types.package; type = types.nullOr types.package;
default = null; default = null;
example = literalExample "pkgs.dejavu_fonts"; example = literalExpression "pkgs.dejavu_fonts";
description = '' description = ''
Package providing the font. This package will be installed Package providing the font. This package will be installed
to your profile. If <literal>null</literal> then the font to your profile. If <literal>null</literal> then the font
@ -47,9 +47,18 @@ in rec {
name = mkOption { name = mkOption {
type = types.str; type = types.str;
example = "DejaVu Sans 8"; example = "DejaVu Sans";
description = '' 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.
''; '';
}; };
}; };
@ -61,7 +70,11 @@ in rec {
check = v: gvar.mkValue v != null; check = v: gvar.mkValue v != null;
merge = loc: defs: merge = loc: defs:
let let
vdefs = map (d: d // { value = gvar.mkValue d.value; }) defs; vdefs = map (d:
d // {
value =
if gvar.isGVariant d.value then d.value else gvar.mkValue d.value;
}) defs;
vals = map (d: d.value) vdefs; vals = map (d: d.value) vdefs;
defTypes = map (x: x.type) vals; defTypes = map (x: x.type) vals;
sameOrNull = x: y: if x == y then y else null; sameOrNull = x: y: if x == y then y else null;
@ -73,8 +86,10 @@ in rec {
+ " mismatched GVariant types given in" + " mismatched GVariant types given in"
+ " ${showFiles (getFiles defs)}.") + " ${showFiles (getFiles defs)}.")
else if gvar.isArray sharedDefType && allChecked then else if gvar.isArray sharedDefType && allChecked then
(types.listOf gvariant).merge loc gvar.mkValue ((types.listOf gvariant).merge loc
(map (d: d // { value = d.value.value; }) vdefs) (map (d: d // { value = d.value.value; }) vdefs)) // {
type = sharedDefType;
}
else if gvar.isTuple sharedDefType && allChecked then else if gvar.isTuple sharedDefType && allChecked then
mergeOneOption loc defs mergeOneOption loc defs
else if gvar.isMaybe sharedDefType && allChecked then else if gvar.isMaybe sharedDefType && allChecked then

@ -6,7 +6,7 @@ let
cfg = config.manual; cfg = config.manual;
docs = import ../doc { inherit lib pkgs; }; docs = import ../docs { inherit lib pkgs; };
in in

@ -27,7 +27,7 @@ in {
settings = mkOption { settings = mkOption {
type = with types; attrsOf (attrsOf hm.types.gvariant); type = with types; attrsOf (attrsOf hm.types.gvariant);
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
"org/gnome/calculator" = { "org/gnome/calculator" = {
button-mode = "programming"; button-mode = "programming";

@ -36,22 +36,11 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
# Create two dummy files in /lib/fontconfig to make sure that
# buildEnv creates a real directory path. These files are removed
# in home.extraProfileCommands below so the packages will not
# become "runtime" dependencies.
home.packages = [ home.packages = [
(pkgs.writeTextFile { # Make sure that buildEnv creates a real directory path so that we avoid
name = "hm-dummy1"; # trying to write to a read-only location.
destination = "/lib/fontconfig/hm-dummy1"; (pkgs.runCommandLocal "dummy-fc-dir1" { } "mkdir -p $out/lib/fontconfig")
text = "dummy"; (pkgs.runCommandLocal "dummy-fc-dir2" { } "mkdir -p $out/lib/fontconfig")
})
(pkgs.writeTextFile {
name = "hm-dummy2";
destination = "/lib/fontconfig/hm-dummy2";
text = "dummy";
})
]; ];
home.extraProfileCommands = '' home.extraProfileCommands = ''
@ -76,9 +65,10 @@ in {
unset FONTCONFIG_FILE unset FONTCONFIG_FILE
fi fi
# Remove hacky dummy files. # Remove the fontconfig directory if no files were available.
rm $out/lib/fontconfig/hm-dummy? if [[ -d $out/lib/fontconfig ]] ; then
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
fi
''; '';
xdg.configFile = { xdg.configFile = {

@ -33,7 +33,7 @@ let
package = mkOption { package = mkOption {
type = types.nullOr types.package; type = types.nullOr types.package;
default = null; default = null;
example = literalExample "pkgs.gnome3.gnome_themes_standard"; example = literalExpression "pkgs.gnome.gnome_themes_standard";
description = '' description = ''
Package providing the theme. This package will be installed Package providing the theme. This package will be installed
to your profile. If <literal>null</literal> then the theme to your profile. If <literal>null</literal> then the theme
@ -92,6 +92,18 @@ in {
<filename>~/.gtkrc-2.0</filename>. <filename>~/.gtkrc-2.0</filename>.
''; '';
}; };
configLocation = mkOption {
type = types.path;
default = "${config.home.homeDirectory}/.gtkrc-2.0";
defaultText =
literalExpression ''"''${config.home.homeDirectory}/.gtkrc-2.0"'';
example =
literalExpression ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"'';
description = ''
The location to put the GTK configuration file.
'';
};
}; };
gtk3 = { gtk3 = {
@ -128,14 +140,22 @@ in {
}; };
config = mkIf cfg.enable (let config = mkIf cfg.enable (let
ini = optionalAttrs (cfg.font != null) { gtk-font-name = cfg.font.name; } ini = optionalAttrs (cfg.font != null) {
// optionalAttrs (cfg.theme != null) { gtk-theme-name = cfg.theme.name; } 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) { // optionalAttrs (cfg.iconTheme != null) {
gtk-icon-theme-name = cfg.iconTheme.name; gtk-icon-theme-name = cfg.iconTheme.name;
}; };
dconfIni = optionalAttrs (cfg.font != null) { font-name = cfg.font.name; } dconfIni = optionalAttrs (cfg.font != null) {
// optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; } 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) { // optionalAttrs (cfg.iconTheme != null) {
icon-theme = cfg.iconTheme.name; icon-theme = cfg.iconTheme.name;
}; };
@ -146,17 +166,19 @@ in {
home.packages = optionalPackage cfg.font ++ optionalPackage cfg.theme home.packages = optionalPackage cfg.font ++ optionalPackage cfg.theme
++ optionalPackage cfg.iconTheme; ++ optionalPackage cfg.iconTheme;
home.file.".gtkrc-2.0".text = home.file.${cfg2.configLocation}.text =
concatStringsSep "\n" (mapAttrsToList formatGtk2Option ini) + "\n" concatMapStrings (l: l + "\n") (mapAttrsToList formatGtk2Option ini)
+ cfg2.extraConfig; + cfg2.extraConfig;
home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation;
xdg.configFile."gtk-3.0/settings.ini".text = xdg.configFile."gtk-3.0/settings.ini".text =
toGtk3Ini { Settings = ini // cfg3.extraConfig; }; toGtk3Ini { Settings = ini // cfg3.extraConfig; };
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss; xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
xdg.configFile."gtk-3.0/bookmarks" = mkIf (cfg3.bookmarks != [ ]) { xdg.configFile."gtk-3.0/bookmarks" = mkIf (cfg3.bookmarks != [ ]) {
text = concatStringsSep "\n" cfg3.bookmarks; text = concatMapStrings (l: l + "\n") cfg3.bookmarks;
}; };
dconf.settings."org/gnome/desktop/interface" = dconfIni; dconf.settings."org/gnome/desktop/interface" = dconfIni;

@ -116,6 +116,9 @@ in
# #
# date --iso-8601=second --universal # date --iso-8601=second --universal
# #
# On darwin (or BSD like systems) use
#
# date -u +'%Y-%m-%dT%H:%M:%S+00:00'
news.entries = [ news.entries = [
{ {
time = "2017-09-01T10:56:28+00:00"; time = "2017-09-01T10:56:28+00:00";
@ -533,23 +536,6 @@ in
''; '';
} }
{
time = "2018-02-09T21:14:42+00:00";
condition = with config.programs.rofi; enable && colors != null;
message = ''
The new and preferred way to configure the rofi theme is
using rasi themes through the 'programs.rofi.theme' option.
This option can take as value either the name of a
pre-installed theme or the path to a theme file.
A rasi theme can be generated from an Xresources config
using 'rofi -dump-theme'.
The option 'programs.rofi.colors' is still supported but may
become deprecated and removed in the future.
'';
}
{ {
time = "2018-02-19T21:45:26+00:00"; time = "2018-02-19T21:45:26+00:00";
message = '' message = ''
@ -1863,6 +1849,7 @@ in
lists to polybar-style 'foo-0, foo-1, ...' lists. lists to polybar-style 'foo-0, foo-1, ...' lists.
''; '';
} }
{ {
time = "2021-02-25T22:36:43+00:00"; time = "2021-02-25T22:36:43+00:00";
condition = config.programs.git.enable && any (msmtp: msmtp.enable) condition = config.programs.git.enable && any (msmtp: msmtp.enable)
@ -1873,6 +1860,7 @@ in
'accounts.email.accounts.<name>.msmtp.enable' is true. 'accounts.email.accounts.<name>.msmtp.enable' is true.
''; '';
} }
{ {
time = "2021-03-03T22:16:05+00:00"; time = "2021-03-03T22:16:05+00:00";
message = '' message = ''
@ -1880,6 +1868,371 @@ in
https://no-color.org/. 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'.
'';
}
{
time = "2021-07-11T17:45:56+00:00";
message = ''
A new module is available: 'programs.sm64ex'.
'';
}
{
time = "2021-07-15T13:38:32+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.xsettingsd'.
'';
}
{
time = "2021-07-14T20:06:18+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.volnoti'.
'';
}
{
time = "2021-07-23T22:22:31+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.trayer'.
'';
}
{
time = "2021-07-19T01:30:46+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.notify-osd'.
'';
}
{
time = "2021-08-10T21:28:40+00:00";
message = ''
A new module is available: 'programs.java'.
'';
}
{
time = "2021-08-11T13:55:51+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.easyeffects'.
'';
}
{
time = "2021-08-16T21:59:02+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.git-sync'.
'';
}
{
time = "2021-08-26T06:40:59+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.fnott'.
'';
}
{
time = "2021-08-31T18:44:26+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.betterlockscreen'.
'';
}
{
time = "2021-09-14T21:31:03+00:00";
message = ''
A new module is available: 'programs.bottom'.
'';
}
{
time = "2021-09-23T17:04:48+00:00";
condition = hostPlatform.isLinux && config.services.screen-locker.enable;
message = ''
'xautolock' is now optional in 'services.screen-locker', and the
'services.screen-locker' options have been reorganized for clarity.
See the 'xautolock' and 'xss-lock' options modules in
'services.screen-locker'.
'';
}
{
time = "2021-10-05T20:55:07+00:00";
message = ''
A new module is available: 'programs.atuin'.
'';
}
{
time = "2021-10-05T22:15:00+00:00";
message = ''
A new module is available: 'programs.nnn'.
'';
}
{
time = "2021-10-08T22:16:50+00:00";
condition = hostPlatform.isLinux && config.programs.rofi.enable;
message = ''
Rofi version '1.7.0' removed many options that were used by the module
and replaced them with custom themes, which are more flexible and
powerful.
You can replicate your old configuration by moving those options to
'programs.rofi.theme'. Keep in mind that the syntax is different so
you may need to do some changes.
'';
}
{
time = "2021-10-23T17:12:22+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'programs.hexchat'.
'';
}
]; ];
}; };
} }

@ -0,0 +1,73 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.nixpkgs;
# Copied from nixpkgs.nix.
isConfig = x: builtins.isAttrs x || builtins.isFunction x;
# Copied from nixpkgs.nix.
optCall = f: x: if builtins.isFunction f then f x else f;
# Copied from nixpkgs.nix.
mergeConfig = lhs_: rhs_:
let
lhs = optCall lhs_ { inherit pkgs; };
rhs = optCall rhs_ { inherit pkgs; };
in lhs // rhs // optionalAttrs (lhs ? packageOverrides) {
packageOverrides = pkgs:
optCall lhs.packageOverrides pkgs
// optCall (attrByPath [ "packageOverrides" ] ({ }) rhs) pkgs;
} // optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides = pkgs:
optCall lhs.perlPackageOverrides pkgs
// optCall (attrByPath [ "perlPackageOverrides" ] ({ }) rhs) pkgs;
};
# Copied from nixpkgs.nix.
configType = mkOptionType {
name = "nixpkgs-config";
description = "nixpkgs config";
check = x:
let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
in traceXIfNot isConfig;
merge = args: fold (def: mergeConfig def.value) { };
};
# Copied from nixpkgs.nix.
overlayType = mkOptionType {
name = "nixpkgs-overlay";
description = "nixpkgs overlay";
check = builtins.isFunction;
merge = lib.mergeOneOption;
};
in {
meta.maintainers = with maintainers; [ thiagokokada ];
options.nixpkgs = {
config = mkOption {
default = null;
type = types.nullOr configType;
visible = false;
};
overlays = mkOption {
default = null;
type = types.nullOr (types.listOf overlayType);
visible = false;
};
};
config = {
assertions = [{
assertion = cfg.config == null || cfg.overlays == null;
message = ''
`nixpkgs` options are disabled when `home-manager.useGlobalPkgs` is enabled.
'';
}];
};
}

@ -6,40 +6,31 @@ with lib;
let let
isConfig = x: isConfig = x: builtins.isAttrs x || builtins.isFunction x;
builtins.isAttrs x || builtins.isFunction x;
optCall = f: x: optCall = f: x: if builtins.isFunction f then f x else f;
if builtins.isFunction f
then f x
else f;
mergeConfig = lhs_: rhs_: mergeConfig = lhs_: rhs_:
let let
lhs = optCall lhs_ { inherit pkgs; }; lhs = optCall lhs_ { inherit pkgs; };
rhs = optCall rhs_ { inherit pkgs; }; rhs = optCall rhs_ { inherit pkgs; };
in in lhs // rhs // optionalAttrs (lhs ? packageOverrides) {
lhs // rhs //
optionalAttrs (lhs ? packageOverrides) {
packageOverrides = pkgs: packageOverrides = pkgs:
optCall lhs.packageOverrides pkgs // optCall lhs.packageOverrides pkgs
optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs; // optCall (attrByPath [ "packageOverrides" ] ({ }) rhs) pkgs;
} // } // optionalAttrs (lhs ? perlPackageOverrides) {
optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides = pkgs: perlPackageOverrides = pkgs:
optCall lhs.perlPackageOverrides pkgs // optCall lhs.perlPackageOverrides pkgs
optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs; // optCall (attrByPath [ "perlPackageOverrides" ] ({ }) rhs) pkgs;
}; };
configType = mkOptionType { configType = mkOptionType {
name = "nixpkgs-config"; name = "nixpkgs-config";
description = "nixpkgs config"; description = "nixpkgs config";
check = x: check = x:
let traceXIfNot = c: let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
if c x then true
else lib.traceSeqN 1 x false;
in traceXIfNot isConfig; in traceXIfNot isConfig;
merge = args: fold (def: mergeConfig def.value) {}; merge = args: fold (def: mergeConfig def.value) { };
}; };
overlayType = mkOptionType { overlayType = mkOptionType {
@ -49,13 +40,9 @@ let
merge = lib.mergeOneOption; merge = lib.mergeOneOption;
}; };
_pkgs = import pkgsPath ( _pkgs = import pkgsPath (filterAttrs (n: v: v != null) config.nixpkgs);
filterAttrs (n: v: v != null) config.nixpkgs
);
in in {
{
options.nixpkgs = { options.nixpkgs = {
config = mkOption { config = mkOption {
default = null; default = null;
@ -91,17 +78,16 @@ in
overlays = mkOption { overlays = mkOption {
default = null; default = null;
example = literalExample example = literalExpression ''
'' [ (self: super: {
[ (self: super: { openssh = super.openssh.override {
openssh = super.openssh.override { hpnSupport = true;
hpnSupport = true; withKerberos = true;
withKerberos = true; kerberos = self.libkrb5;
kerberos = self.libkrb5;
};
}; };
) ] };
''; ) ]
'';
type = types.nullOr (types.listOf overlayType); type = types.nullOr (types.listOf overlayType);
description = '' description = ''
List of overlays to use with the Nix Packages collection. (For List of overlays to use with the Nix Packages collection. (For
@ -144,9 +130,10 @@ in
_module.args = { _module.args = {
pkgs = mkOverride modules.defaultPriority _pkgs; pkgs = mkOverride modules.defaultPriority _pkgs;
pkgs_i686 = pkgs_i686 =
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 then
then _pkgs.pkgsi686Linux _pkgs.pkgsi686Linux
else { }; else
{ };
}; };
}; };
} }

@ -12,6 +12,10 @@ in {
options = { xsession.numlock.enable = mkEnableOption "Num Lock"; }; options = { xsession.numlock.enable = mkEnableOption "Num Lock"; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [
(hm.assertions.assertPlatform "xsession.numlock" pkgs platforms.linux)
];
systemd.user.services.numlockx = { systemd.user.services.numlockx = {
Unit = { Unit = {
Description = "NumLockX"; Description = "NumLockX";

@ -78,7 +78,7 @@ in {
package = mkOption { package = mkOption {
type = types.nullOr types.package; type = types.nullOr types.package;
default = null; default = null;
example = literalExample "pkgs.adwaita-qt"; example = literalExpression "pkgs.adwaita-qt";
description = "Theme package to be used in Qt5 applications."; description = "Theme package to be used in Qt5 applications.";
}; };
}; };

@ -25,6 +25,11 @@ in {
}; };
config = mkIf (cfg.rules != [ ]) { config = mkIf (cfg.rules != [ ]) {
assertions = [
(hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs
platforms.linux)
];
xdg = { xdg = {
dataFile."user-tmpfiles.d/home-manager.conf" = { dataFile."user-tmpfiles.d/home-manager.conf" = {
text = '' text = ''

@ -5,8 +5,16 @@ with lib;
{ {
options = { options = {
home.stateVersion = mkOption { home.stateVersion = mkOption {
type = type = types.enum [
types.enum [ "18.09" "19.03" "19.09" "20.03" "20.09" "21.03" "21.05" ]; "18.09"
"19.03"
"19.09"
"20.03"
"20.09"
"21.03"
"21.05"
"21.11"
];
default = "18.09"; default = "18.09";
description = '' description = ''
It is occasionally necessary for Home Manager to change It is occasionally necessary for Home Manager to change

@ -0,0 +1,183 @@
{ 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 <literal>DESKTOP_STARTUP_ID</literal>
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 <literal>[Desktop Entry]</literal> section.
This may override other values.
'';
default = { };
example = literalExpression ''
{
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. </para><para>
You can define entries for programs without entries or override existing entries. </para><para>
See <link xlink:href="https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys" /> for more information on options.
'';
default = { };
type = types.attrsOf (types.submodule desktopEntry);
example = literalExpression ''
{
firefox = {
name = "Firefox";
genericName = "Web Browser";
exec = "firefox %U";
terminal = false;
categories = [ "Application" "Network" "WebBrowser" ];
mimeType = [ "text/html" "text/xml" ];
};
}
'';
};
config = mkIf (config.xdg.desktopEntries != { }) {
assertions = [
(hm.assertions.assertPlatform "xdg.desktopEntries" pkgs platforms.linux)
];
home.packages = (map hiPrio # we need hiPrio to override existing entries
(attrsets.mapAttrsToList makeFile config.xdg.desktopEntries));
};
}

@ -30,7 +30,7 @@ in {
associations.added = mkOption { associations.added = mkOption {
type = types.attrsOf strListOrSingleton; type = types.attrsOf strListOrSingleton;
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
"mimetype1" = [ "foo1.desktop" "foo2.desktop" "foo3.desktop" ]; "mimetype1" = [ "foo1.desktop" "foo2.desktop" "foo3.desktop" ];
"mimetype2" = "foo4.desktop"; "mimetype2" = "foo4.desktop";
@ -57,7 +57,7 @@ in {
defaultApplications = mkOption { defaultApplications = mkOption {
type = types.attrsOf strListOrSingleton; type = types.attrsOf strListOrSingleton;
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
"mimetype1" = [ "default1.desktop" "default2.desktop" ]; "mimetype1" = [ "default1.desktop" "default2.desktop" ];
} }
@ -73,6 +73,9 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions =
[ (hm.assertions.assertPlatform "xdg.mimeApps" pkgs platforms.linux) ];
# Deprecated but still used by some applications. # Deprecated but still used by some applications.
xdg.dataFile."applications/mimeapps.list".source = xdg.dataFile."applications/mimeapps.list".source =
config.xdg.configFile."mimeapps.list".source; config.xdg.configFile."mimeapps.list".source;

@ -10,7 +10,9 @@ in {
options = { options = {
xdg.mime.enable = mkOption { xdg.mime.enable = mkOption {
type = types.bool; type = types.bool;
default = true; default = pkgs.hostPlatform.isLinux;
defaultText =
literalExpression "true if host platform is Linux, false otherwise";
description = '' description = ''
Whether to install programs and files to support the Whether to install programs and files to support the
XDG Shared MIME-info specification and XDG MIME Applications XDG Shared MIME-info specification and XDG MIME Applications
@ -24,6 +26,9 @@ in {
}; };
config = mkIf config.xdg.mime.enable { config = mkIf config.xdg.mime.enable {
assertions =
[ (hm.assertions.assertPlatform "xdg.mime" pkgs platforms.linux) ];
home.packages = [ home.packages = [
# Explicitly install package to provide basic mime types. # Explicitly install package to provide basic mime types.
pkgs.shared-mime-info pkgs.shared-mime-info

@ -0,0 +1,61 @@
{ 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 = literalExpression ''[ "/etc/xdg" ]'';
description = ''
Directory names to add to <envar>XDG_CONFIG_DIRS</envar>
in the user session.
'';
};
data = mkOption {
type = types.listOf types.str;
default = [ ];
example = literalExpression ''[ "/usr/share" "/usr/local/share" ]'';
description = ''
Directory names to add to <envar>XDG_DATA_DIRS</envar>
in the user session.
'';
};
};
config = mkMerge [
(mkIf (cfg.config != [ ] || cfg.data != [ ]) {
assertions = [
(hm.assertions.assertPlatform "xdg.systemDirs" pkgs platforms.linux)
];
})
(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}";
})
];
}

@ -86,25 +86,39 @@ in {
example = { XDG_MISC_DIR = "$HOME/Misc"; }; example = { XDG_MISC_DIR = "$HOME/Misc"; };
description = "Other user directories."; description = "Other user directories.";
}; };
createDirectories =
mkEnableOption "automatic creation of the XDG user directories";
}; };
config = mkIf cfg.enable { config = let
xdg.configFile."user-dirs.dirs".text = let directories = {
options = { XDG_DESKTOP_DIR = cfg.desktop;
XDG_DESKTOP_DIR = cfg.desktop; XDG_DOCUMENTS_DIR = cfg.documents;
XDG_DOCUMENTS_DIR = cfg.documents; XDG_DOWNLOAD_DIR = cfg.download;
XDG_DOWNLOAD_DIR = cfg.download; XDG_MUSIC_DIR = cfg.music;
XDG_MUSIC_DIR = cfg.music; XDG_PICTURES_DIR = cfg.pictures;
XDG_PICTURES_DIR = cfg.pictures; XDG_PUBLICSHARE_DIR = cfg.publicShare;
XDG_PUBLICSHARE_DIR = cfg.publicShare; XDG_TEMPLATES_DIR = cfg.templates;
XDG_TEMPLATES_DIR = cfg.templates; XDG_VIDEOS_DIR = cfg.videos;
XDG_VIDEOS_DIR = cfg.videos; } // cfg.extraConfig;
} // cfg.extraConfig; in mkIf cfg.enable {
assertions =
[ (hm.assertions.assertPlatform "xdg.userDirs" pkgs platforms.linux) ];
xdg.configFile."user-dirs.dirs".text = let
# For some reason, these need to be wrapped with quotes to be valid. # 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; in generators.toKeyValue { } wrapped;
xdg.configFile."user-dirs.conf".text = "enabled=False"; 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);
};
}; };
} }

@ -6,8 +6,6 @@ let
cfg = config.xdg; cfg = config.xdg;
dag = config.lib.dag;
fileType = (import ../lib/file-type.nix { fileType = (import ../lib/file-type.nix {
inherit (config.home) homeDirectory; inherit (config.home) homeDirectory;
inherit lib pkgs; inherit lib pkgs;
@ -17,21 +15,18 @@ let
defaultConfigHome = "${config.home.homeDirectory}/.config"; defaultConfigHome = "${config.home.homeDirectory}/.config";
defaultDataHome = "${config.home.homeDirectory}/.local/share"; defaultDataHome = "${config.home.homeDirectory}/.local/share";
getXdgDir = name: fallback: getEnvFallback = name: fallback:
let let value = builtins.getEnv name;
value = builtins.getEnv name; in if value != "" then value else fallback;
in
if value != "" then value else fallback;
in
{ in {
options.xdg = { options.xdg = {
enable = mkEnableOption "management of XDG base directories"; enable = mkEnableOption "management of XDG base directories";
cacheHome = mkOption { cacheHome = mkOption {
type = types.path; type = types.path;
defaultText = "~/.cache"; defaultText = "~/.cache";
apply = toString;
description = '' description = ''
Absolute path to directory holding application caches. Absolute path to directory holding application caches.
''; '';
@ -39,7 +34,7 @@ in
configFile = mkOption { configFile = mkOption {
type = fileType "<varname>xdg.configHome</varname>" cfg.configHome; type = fileType "<varname>xdg.configHome</varname>" cfg.configHome;
default = {}; default = { };
description = '' description = ''
Attribute set of files to link into the user's XDG Attribute set of files to link into the user's XDG
configuration home. configuration home.
@ -49,6 +44,7 @@ in
configHome = mkOption { configHome = mkOption {
type = types.path; type = types.path;
defaultText = "~/.config"; defaultText = "~/.config";
apply = toString;
description = '' description = ''
Absolute path to directory holding application configurations. Absolute path to directory holding application configurations.
''; '';
@ -56,7 +52,7 @@ in
dataFile = mkOption { dataFile = mkOption {
type = fileType "<varname>xdg.dataHome</varname>" cfg.dataHome; type = fileType "<varname>xdg.dataHome</varname>" cfg.dataHome;
default = {}; default = { };
description = '' description = ''
Attribute set of files to link into the user's XDG Attribute set of files to link into the user's XDG
data home. data home.
@ -66,6 +62,7 @@ in
dataHome = mkOption { dataHome = mkOption {
type = types.path; type = types.path;
defaultText = "~/.local/share"; defaultText = "~/.local/share";
apply = toString;
description = '' description = ''
Absolute path to directory holding application data. Absolute path to directory holding application data.
''; '';
@ -87,9 +84,11 @@ in
# Legacy non-deterministic setup. # Legacy non-deterministic setup.
(mkIf (!cfg.enable && versionOlder config.home.stateVersion "20.09") { (mkIf (!cfg.enable && versionOlder config.home.stateVersion "20.09") {
xdg.cacheHome = getXdgDir "XDG_CACHE_HOME" defaultCacheHome; xdg.cacheHome =
xdg.configHome = getXdgDir "XDG_CONFIG_HOME" defaultConfigHome; mkDefault (getEnvFallback "XDG_CACHE_HOME" defaultCacheHome);
xdg.dataHome = getXdgDir "XDG_DATA_HOME" defaultDataHome; xdg.configHome =
mkDefault (getEnvFallback "XDG_CONFIG_HOME" defaultConfigHome);
xdg.dataHome = mkDefault (getEnvFallback "XDG_DATA_HOME" defaultDataHome);
}) })
# "Modern" deterministic setup. # "Modern" deterministic setup.
@ -101,13 +100,11 @@ in
{ {
home.file = mkMerge [ home.file = mkMerge [
(mapAttrs' (mapAttrs' (name: file: nameValuePair "${cfg.configHome}/${name}" file)
(name: file: nameValuePair "${config.xdg.configHome}/${name}" file)
cfg.configFile) cfg.configFile)
(mapAttrs' (mapAttrs' (name: file: nameValuePair "${cfg.dataHome}/${name}" file)
(name: file: nameValuePair "${config.xdg.dataHome}/${name}" file)
cfg.dataFile) cfg.dataFile)
{ "${config.xdg.cacheHome}/.keep".text = ""; } { "${cfg.cacheHome}/.keep".text = ""; }
]; ];
} }
]; ];

@ -1,226 +1,256 @@
{ pkgs { pkgs
# Note, this should be "the standard library" + HM extensions. # Note, this should be "the standard library" + HM extensions.
, lib , lib
# Whether to enable module type checking. # Whether to enable module type checking.
, check ? true , check ? true
# If disabled, the pkgs attribute passed to this function is used instead. # If disabled, the pkgs attribute passed to this function is used instead.
, useNixpkgsModule ? true , useNixpkgsModule ? true }:
}:
with lib; with lib;
let let
hostPlatform = pkgs.stdenv.hostPlatform; modules = [
./accounts/email.nix
loadModule = file: { condition ? true }: { ./config/i18n.nix
inherit file condition; ./files.nix
}; ./home-environment.nix
./i18n/input-method/default.nix
allModules = [ ./manual.nix
(loadModule ./accounts/email.nix { }) ./misc/dconf.nix
(loadModule ./config/i18n.nix { condition = hostPlatform.isLinux; }) ./misc/debug.nix
(loadModule ./files.nix { }) ./misc/fontconfig.nix
(loadModule ./home-environment.nix { }) ./misc/gtk.nix
(loadModule ./manual.nix { }) ./misc/lib.nix
(loadModule ./misc/dconf.nix { }) ./misc/news.nix
(loadModule ./misc/debug.nix { }) ./misc/numlock.nix
(loadModule ./misc/fontconfig.nix { }) ./misc/pam.nix
(loadModule ./misc/gtk.nix { }) ./misc/qt.nix
(loadModule ./misc/lib.nix { }) ./misc/submodule-support.nix
(loadModule ./misc/news.nix { }) ./misc/tmpfiles.nix
(loadModule ./misc/nixpkgs.nix { condition = useNixpkgsModule; }) ./misc/version.nix
(loadModule ./misc/numlock.nix { condition = hostPlatform.isLinux; }) ./misc/vte.nix
(loadModule ./misc/pam.nix { }) ./misc/xdg-desktop-entries.nix
(loadModule ./misc/qt.nix { }) ./misc/xdg-mime-apps.nix
(loadModule ./misc/submodule-support.nix { }) ./misc/xdg-mime.nix
(loadModule ./misc/tmpfiles.nix { condition = hostPlatform.isLinux; }) ./misc/xdg-system-dirs.nix
(loadModule ./misc/version.nix { }) ./misc/xdg-user-dirs.nix
(loadModule ./misc/vte.nix { }) ./misc/xdg.nix
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; }) ./programs/abook.nix
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; }) ./programs/afew.nix
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; }) ./programs/alacritty.nix
(loadModule ./misc/xdg.nix { }) ./programs/alot.nix
(loadModule ./programs/abook.nix { condition = hostPlatform.isLinux; }) ./programs/aria2.nix
(loadModule ./programs/afew.nix { }) ./programs/astroid.nix
(loadModule ./programs/alacritty.nix { }) ./programs/atuin.nix
(loadModule ./programs/alot.nix { }) ./programs/autojump.nix
(loadModule ./programs/aria2.nix { }) ./programs/autorandr.nix
(loadModule ./programs/astroid.nix { }) ./programs/bash.nix
(loadModule ./programs/autojump.nix { }) ./programs/bat.nix
(loadModule ./programs/autorandr.nix { }) ./programs/beets.nix
(loadModule ./programs/bash.nix { }) ./programs/bottom.nix
(loadModule ./programs/bat.nix { }) ./programs/broot.nix
(loadModule ./programs/beets.nix { }) ./programs/browserpass.nix
(loadModule ./programs/broot.nix { }) ./programs/chromium.nix
(loadModule ./programs/browserpass.nix { }) ./programs/command-not-found/command-not-found.nix
(loadModule ./programs/chromium.nix { }) ./programs/dircolors.nix
(loadModule ./programs/command-not-found/command-not-found.nix { }) ./programs/direnv.nix
(loadModule ./programs/dircolors.nix { }) ./programs/eclipse.nix
(loadModule ./programs/direnv.nix { }) ./programs/emacs.nix
(loadModule ./programs/eclipse.nix { }) ./programs/exa.nix
(loadModule ./programs/emacs.nix { }) ./programs/feh.nix
(loadModule ./programs/feh.nix { }) ./programs/firefox.nix
(loadModule ./programs/firefox.nix { }) ./programs/fish.nix
(loadModule ./programs/fish.nix { }) ./programs/foot.nix
(loadModule ./programs/fzf.nix { }) ./programs/fzf.nix
(loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; }) ./programs/getmail.nix
(loadModule ./programs/gh.nix { }) ./programs/gh.nix
(loadModule ./programs/git.nix { }) ./programs/git.nix
(loadModule ./programs/gnome-terminal.nix { }) ./programs/gnome-terminal.nix
(loadModule ./programs/go.nix { }) ./programs/go.nix
(loadModule ./programs/gpg.nix { }) ./programs/gpg.nix
(loadModule ./programs/home-manager.nix { }) ./programs/hexchat.nix
(loadModule ./programs/htop.nix { }) ./programs/himalaya.nix
(loadModule ./programs/i3status.nix { }) ./programs/home-manager.nix
(loadModule ./programs/i3status-rust.nix { condition = hostPlatform.isLinux; }) ./programs/htop.nix
(loadModule ./programs/info.nix { }) ./programs/i3status-rust.nix
(loadModule ./programs/irssi.nix { }) ./programs/i3status.nix
(loadModule ./programs/lieer.nix { }) ./programs/info.nix
(loadModule ./programs/jq.nix { }) ./programs/irssi.nix
(loadModule ./programs/kakoune.nix { }) ./programs/java.nix
(loadModule ./programs/keychain.nix { }) ./programs/jq.nix
(loadModule ./programs/kitty.nix { }) ./programs/kakoune.nix
(loadModule ./programs/lesspipe.nix { }) ./programs/keychain.nix
(loadModule ./programs/lf.nix { }) ./programs/kitty.nix
(loadModule ./programs/lsd.nix { }) ./programs/lazygit.nix
(loadModule ./programs/man.nix { }) ./programs/lesspipe.nix
(loadModule ./programs/matplotlib.nix { }) ./programs/lf.nix
(loadModule ./programs/mbsync.nix { }) ./programs/lieer.nix
(loadModule ./programs/mcfly.nix { }) ./programs/lsd.nix
(loadModule ./programs/mercurial.nix { }) ./programs/man.nix
(loadModule ./programs/mpv.nix { }) ./programs/mangohud.nix
(loadModule ./programs/msmtp.nix { }) ./programs/matplotlib.nix
(loadModule ./programs/mu.nix { }) ./programs/mbsync.nix
(loadModule ./programs/ncmpcpp.nix { }) ./programs/mcfly.nix
(loadModule ./programs/ne.nix { }) ./programs/mercurial.nix
(loadModule ./programs/neomutt.nix { }) ./programs/mpv.nix
(loadModule ./programs/neovim.nix { }) ./programs/msmtp.nix
(loadModule ./programs/newsboat.nix { }) ./programs/mu.nix
(loadModule ./programs/noti.nix { }) ./programs/ncmpcpp.nix
(loadModule ./programs/notmuch.nix { }) ./programs/ncspot.nix
(loadModule ./programs/nushell.nix { }) ./programs/ne.nix
(loadModule ./programs/obs-studio.nix { }) ./programs/neomutt.nix
(loadModule ./programs/octant.nix { }) ./programs/neovim.nix
(loadModule ./programs/offlineimap.nix { }) ./programs/newsboat.nix
(loadModule ./programs/opam.nix { }) ./programs/nix-index.nix
(loadModule ./programs/password-store.nix { }) ./programs/nnn.nix
(loadModule ./programs/pazi.nix { }) ./programs/noti.nix
(loadModule ./programs/pet.nix { }) ./programs/notmuch.nix
(loadModule ./programs/pidgin.nix { }) ./programs/nushell.nix
(loadModule ./programs/powerline-go.nix { }) ./programs/obs-studio.nix
(loadModule ./programs/qutebrowser.nix { }) ./programs/octant.nix
(loadModule ./programs/readline.nix { }) ./programs/offlineimap.nix
(loadModule ./programs/rofi.nix { }) ./programs/opam.nix
(loadModule ./programs/rofi-pass.nix { }) ./programs/password-store.nix
(loadModule ./programs/rtorrent.nix { }) ./programs/pazi.nix
(loadModule ./programs/skim.nix { }) ./programs/pet.nix
(loadModule ./programs/starship.nix { }) ./programs/pidgin.nix
(loadModule ./programs/sbt.nix { }) ./programs/piston-cli.nix
(loadModule ./programs/ssh.nix { }) ./programs/powerline-go.nix
(loadModule ./programs/taskwarrior.nix { }) ./programs/qutebrowser.nix
(loadModule ./programs/termite.nix { }) ./programs/rbw.nix
(loadModule ./programs/texlive.nix { }) ./programs/readline.nix
(loadModule ./programs/tmux.nix { }) ./programs/rofi-pass.nix
(loadModule ./programs/urxvt.nix { }) ./programs/rofi.nix
(loadModule ./programs/vim.nix { }) ./programs/rtorrent.nix
(loadModule ./programs/vscode.nix { }) ./programs/sbt.nix
(loadModule ./programs/vscode/haskell.nix { }) ./programs/scmpuff.nix
(loadModule ./programs/waybar.nix { condition = hostPlatform.isLinux; }) ./programs/senpai.nix
(loadModule ./programs/z-lua.nix { }) ./programs/skim.nix
(loadModule ./programs/zathura.nix { }) ./programs/sm64ex.nix
(loadModule ./programs/zoxide.nix { }) ./programs/ssh.nix
(loadModule ./programs/zplug.nix { }) ./programs/starship.nix
(loadModule ./programs/zsh.nix { }) ./programs/taskwarrior.nix
(loadModule ./programs/zsh/prezto.nix { }) ./programs/terminator.nix
(loadModule ./services/blueman-applet.nix { }) ./programs/termite.nix
(loadModule ./services/caffeine.nix { condition = hostPlatform.isLinux; }) ./programs/texlive.nix
(loadModule ./services/cbatticon.nix { condition = hostPlatform.isLinux; }) ./programs/tmux.nix
(loadModule ./services/clipmenu.nix { condition = hostPlatform.isLinux; }) ./programs/topgrade.nix
(loadModule ./services/compton.nix { }) ./programs/urxvt.nix
(loadModule ./services/dropbox.nix { condition = hostPlatform.isLinux; }) ./programs/vim.nix
(loadModule ./services/dunst.nix { }) ./programs/vscode.nix
(loadModule ./services/dwm-status.nix { condition = hostPlatform.isLinux; }) ./programs/vscode/haskell.nix
(loadModule ./services/emacs.nix { condition = hostPlatform.isLinux; }) ./programs/waybar.nix
(loadModule ./services/flameshot.nix { }) ./programs/xmobar.nix
(loadModule ./services/fluidsynth.nix { condition = hostPlatform.isLinux; }) ./programs/z-lua.nix
(loadModule ./services/redshift-gammastep/gammastep.nix { condition = hostPlatform.isLinux; }) ./programs/zathura.nix
(loadModule ./services/getmail.nix { condition = hostPlatform.isLinux; }) ./programs/zoxide.nix
(loadModule ./services/gnome-keyring.nix { }) ./programs/zplug.nix
(loadModule ./services/gpg-agent.nix { }) ./programs/zsh.nix
(loadModule ./services/grobi.nix { condition = hostPlatform.isLinux; }) ./programs/zsh/prezto.nix
(loadModule ./services/hound.nix { condition = hostPlatform.isLinux; }) ./services/barrier.nix
(loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; }) ./services/betterlockscreen.nix
(loadModule ./services/kanshi.nix { condition = hostPlatform.isLinux; }) ./services/blueman-applet.nix
(loadModule ./services/kbfs.nix { }) ./services/caffeine.nix
(loadModule ./services/kdeconnect.nix { }) ./services/cbatticon.nix
(loadModule ./services/keepassx.nix { }) ./services/clipmenu.nix
(loadModule ./services/keybase.nix { }) ./services/compton.nix
(loadModule ./services/keynav.nix { condition = hostPlatform.isLinux; }) ./services/devilspie2.nix
(loadModule ./services/lieer.nix { condition = hostPlatform.isLinux; }) ./services/dropbox.nix
(loadModule ./services/lorri.nix { condition = hostPlatform.isLinux; }) ./services/dunst.nix
(loadModule ./services/mako.nix { condition = hostPlatform.isLinux; }) ./services/dwm-status.nix
(loadModule ./services/mbsync.nix { }) ./services/easyeffects.nix
(loadModule ./services/mpd.nix { }) ./services/emacs.nix
(loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; }) ./services/etesync-dav.nix
(loadModule ./services/muchsync.nix { condition = hostPlatform.isLinux; }) ./services/flameshot.nix
(loadModule ./services/network-manager-applet.nix { }) ./services/fluidsynth.nix
(loadModule ./services/nextcloud-client.nix { }) ./services/fnott.nix
(loadModule ./services/owncloud-client.nix { }) ./services/getmail.nix
(loadModule ./services/parcellite.nix { }) ./services/git-sync.nix
(loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; }) ./services/gnome-keyring.nix
(loadModule ./services/pasystray.nix { }) ./services/gpg-agent.nix
(loadModule ./services/pbgopy.nix { condition = hostPlatform.isLinux; }) ./services/grobi.nix
(loadModule ./services/picom.nix { }) ./services/hound.nix
(loadModule ./services/plan9port.nix { condition = hostPlatform.isLinux; }) ./services/imapnotify.nix
(loadModule ./services/playerctld.nix { condition = hostPlatform.isLinux; }) ./services/kanshi.nix
(loadModule ./services/polybar.nix { }) ./services/kbfs.nix
(loadModule ./services/pulseeffects.nix { condition = hostPlatform.isLinux; }) ./services/kdeconnect.nix
(loadModule ./services/random-background.nix { }) ./services/keepassx.nix
(loadModule ./services/redshift-gammastep/redshift.nix { }) ./services/keybase.nix
(loadModule ./services/rsibreak.nix { condition = hostPlatform.isLinux; }) ./services/keynav.nix
(loadModule ./services/screen-locker.nix { }) ./services/lieer.nix
(loadModule ./services/stalonetray.nix { }) ./services/lorri.nix
(loadModule ./services/status-notifier-watcher.nix { }) ./services/mako.nix
(loadModule ./services/spotifyd.nix { condition = hostPlatform.isLinux; }) ./services/mbsync.nix
(loadModule ./services/sxhkd.nix { condition = hostPlatform.isLinux; }) ./services/mpd.nix
(loadModule ./services/syncthing.nix { }) ./services/mpdris2.nix
(loadModule ./services/taffybar.nix { }) ./services/mpris-proxy.nix
(loadModule ./services/tahoe-lafs.nix { }) ./services/muchsync.nix
(loadModule ./services/taskwarrior-sync.nix { condition = hostPlatform.isLinux; }) ./services/network-manager-applet.nix
(loadModule ./services/udiskie.nix { }) ./services/nextcloud-client.nix
(loadModule ./services/unclutter.nix { }) ./services/notify-osd.nix
(loadModule ./services/unison.nix { condition = hostPlatform.isLinux; }) ./services/owncloud-client.nix
(loadModule ./services/window-managers/awesome.nix { }) ./services/pantalaimon.nix
(loadModule ./services/window-managers/bspwm/default.nix { condition = hostPlatform.isLinux; }) ./services/parcellite.nix
(loadModule ./services/window-managers/i3-sway/i3.nix { }) ./services/pass-secret-service.nix
(loadModule ./services/window-managers/i3-sway/sway.nix { condition = hostPlatform.isLinux; }) ./services/password-store-sync.nix
(loadModule ./services/window-managers/xmonad.nix { }) ./services/pasystray.nix
(loadModule ./services/wlsunset.nix { condition = hostPlatform.isLinux; }) ./services/pbgopy.nix
(loadModule ./services/xcape.nix { condition = hostPlatform.isLinux; }) ./services/picom.nix
(loadModule ./services/xembed-sni-proxy.nix { condition = hostPlatform.isLinux; }) ./services/plan9port.nix
(loadModule ./services/xscreensaver.nix { }) ./services/playerctld.nix
(loadModule ./services/xsuspender.nix { condition = hostPlatform.isLinux; }) ./services/polybar.nix
(loadModule ./systemd.nix { }) ./services/poweralertd.nix
(loadModule ./targets/darwin { condition = hostPlatform.isDarwin; }) ./services/pulseeffects.nix
(loadModule ./targets/generic-linux.nix { condition = hostPlatform.isLinux; }) ./services/random-background.nix
(loadModule ./xcursor.nix { }) ./services/redshift-gammastep/gammastep.nix
(loadModule ./xresources.nix { }) ./services/redshift-gammastep/redshift.nix
(loadModule ./xsession.nix { }) ./services/rsibreak.nix
(loadModule (pkgs.path + "/nixos/modules/misc/assertions.nix") { }) ./services/screen-locker.nix
(loadModule (pkgs.path + "/nixos/modules/misc/meta.nix") { }) ./services/spotifyd.nix
]; ./services/stalonetray.nix
./services/status-notifier-watcher.nix
modules = map (getAttr "file") (filter (getAttr "condition") allModules); ./services/sxhkd.nix
./services/syncthing.nix
./services/taffybar.nix
./services/tahoe-lafs.nix
./services/taskwarrior-sync.nix
./services/trayer.nix
./services/udiskie.nix
./services/unclutter.nix
./services/unison.nix
./services/volnoti.nix
./services/window-managers/awesome.nix
./services/window-managers/bspwm/default.nix
./services/window-managers/i3-sway/i3.nix
./services/window-managers/i3-sway/sway.nix
./services/window-managers/xmonad.nix
./services/wlsunset.nix
./services/xcape.nix
./services/xembed-sni-proxy.nix
./services/xidlehook.nix
./services/xscreensaver.nix
./services/xsettingsd.nix
./services/xsuspender.nix
./systemd.nix
./targets/darwin
./targets/generic-linux.nix
./xcursor.nix
./xresources.nix
./xsession.nix
(pkgs.path + "/nixos/modules/misc/assertions.nix")
(pkgs.path + "/nixos/modules/misc/meta.nix")
] ++ optional useNixpkgsModule ./misc/nixpkgs.nix
++ optional (!useNixpkgsModule) ./misc/nixpkgs-disabled.nix;
pkgsModule = { config, ... }: { pkgsModule = { config, ... }: {
config = { config = {
_module.args.baseModules = modules; _module.args.baseModules = modules;
_module.args.pkgsPath = lib.mkDefault ( _module.args.pkgsPath = lib.mkDefault
if versionAtLeast config.home.stateVersion "20.09" then (if versionAtLeast config.home.stateVersion "20.09" then
pkgs.path pkgs.path
else else
<nixpkgs>); <nixpkgs>);
@ -232,6 +262,4 @@ let
}; };
}; };
in in modules ++ [ pkgsModule ]
modules ++ [ pkgsModule ]

@ -27,7 +27,11 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions =
[ (hm.assertions.assertPlatform "programs.abook" pkgs platforms.linux) ];
home.packages = [ pkgs.abook ]; home.packages = [ pkgs.abook ];
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") { xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
text = '' text = ''
# Generated by Home Manager. # Generated by Home Manager.

@ -6,9 +6,7 @@ let
cfg = config.programs.afew; cfg = config.programs.afew;
in in {
{
options.programs.afew = { options.programs.afew = {
enable = mkEnableOption "the afew initial tagging script for Notmuch"; enable = mkEnableOption "the afew initial tagging script for Notmuch";

@ -13,14 +13,14 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.alacritty; default = pkgs.alacritty;
defaultText = literalExample "pkgs.alacritty"; defaultText = literalExpression "pkgs.alacritty";
description = "The Alacritty package to install."; description = "The Alacritty package to install.";
}; };
settings = mkOption { settings = mkOption {
type = yamlFormat.type; type = yamlFormat.type;
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
window.dimensions = { window.dimensions = {
lines = 3; lines = 3;

@ -25,7 +25,7 @@ with lib;
+ "}[,\\]]?'"; + "}[,\\]]?'";
shellcommand_external_filtering = "False"; shellcommand_external_filtering = "False";
}; };
example = literalExample '' example = literalExpression ''
{ {
type = "shellcommand"; type = "shellcommand";
command = "abook --mutt-query"; command = "abook --mutt-query";

@ -200,7 +200,7 @@ in {
handle_mouse = true; handle_mouse = true;
prefer_plaintext = true; prefer_plaintext = true;
}; };
example = literalExample '' example = literalExpression ''
{ {
auto_remove_unread = true; auto_remove_unread = true;
ask_subject = false; ask_subject = false;

@ -31,7 +31,7 @@ in {
</citerefentry> </citerefentry>
for options. for options.
''; '';
example = literalExample '' example = literalExpression ''
{ {
listen-port = 60000; listen-port = 60000;
dht-listen-port = 60000; dht-listen-port = 60000;

@ -22,9 +22,9 @@ let
sendmail = astroid.sendMailCommand; sendmail = astroid.sendMailCommand;
additional_sent_tags = ""; additional_sent_tags = "";
default = boolOpt primary; default = boolOpt primary;
save_drafts_to = "${maildir.absPath}/${folders.drafts}"; save_drafts_to = "${maildir.absPath}/${folders.drafts}/cur/";
save_sent = "true"; save_sent = "true";
save_sent_to = "${maildir.absPath}/${folders.sent}"; save_sent_to = "${maildir.absPath}/${folders.sent}/cur/";
select_query = ""; select_query = "";
} // optionalAttrs (signature.showSignature != "none") { } // optionalAttrs (signature.showSignature != "none") {
signature_attach = boolOpt (signature.showSignature == "attach"); signature_attach = boolOpt (signature.showSignature == "attach");
@ -93,7 +93,7 @@ in {
extraConfig = mkOption { extraConfig = mkOption {
type = jsonFormat.type; type = jsonFormat.type;
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
poll.interval = 0; poll.interval = 0;
} }

@ -0,0 +1,90 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.programs.atuin;
tomlFormat = pkgs.formats.toml { };
in {
meta.maintainers = [ maintainers.hawkw ];
options.programs.atuin = {
enable = mkEnableOption "atuin";
package = mkOption {
type = types.package;
default = pkgs.atuin;
defaultText = literalExpression "pkgs.atuin";
description = "The package to use for atuin.";
};
enableBashIntegration = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable Atuin's Bash integration. This will bind
<literal>ctrl-r</literal> to open the Atuin history.
'';
};
enableZshIntegration = mkEnableOption "Zsh integration" // {
default = true;
description = ''
Whether to enable Atuin's Zsh integration.
</para><para>
If enabled, this will bind <literal>ctrl-r</literal> and the up-arrow
key to open the Atuin history.
'';
};
settings = mkOption {
type = with types;
let
prim = oneOf [ bool int str ];
primOrPrimAttrs = either prim (attrsOf prim);
entry = either prim (listOf primOrPrimAttrs);
entryOrAttrsOf = t: either entry (attrsOf t);
entries = entryOrAttrsOf (entryOrAttrsOf entry);
in attrsOf entries // { description = "Atuin configuration"; };
default = { };
example = literalExpression ''
{
auto_sync = true;
sync_frequency = "5m";
sync_address = "https://api.atuin.sh";
search_mode = "prefix";
}
'';
description = ''
Configuration written to
<filename>~/.config/atuin/config.toml</filename>.
</para><para>
See <link xlink:href="https://github.com/ellie/atuin/blob/main/docs/config.md" /> for the full list
of options.
'';
};
};
config = mkIf cfg.enable {
# Always add the configured `atuin` package.
home.packages = [ cfg.package ];
# If there are user-provided settings, generate the config file.
xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) {
source = tomlFormat.generate "atuin-config" cfg.settings;
};
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
eval "$(${cfg.package}/bin/atuin init bash)"
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${cfg.package}/bin/atuin init zsh)"
'';
};
}

@ -106,7 +106,7 @@ let
transform = mkOption { transform = mkOption {
type = types.nullOr (matrixOf 3 3 types.float); type = types.nullOr (matrixOf 3 3 types.float);
default = null; default = null;
example = literalExample '' example = literalExpression ''
[ [
[ 0.6 0.0 0.0 ] [ 0.6 0.0 0.0 ]
[ 0.0 0.6 0.0 ] [ 0.0 0.6 0.0 ]
@ -169,7 +169,7 @@ let
exclusive. exclusive.
''; '';
default = null; default = null;
example = literalExample '' example = literalExpression ''
{ {
x = 1.25; x = 1.25;
y = 1.25; y = 1.25;
@ -280,7 +280,7 @@ in {
type = globalHooksModule; type = globalHooksModule;
description = "Global hook scripts"; description = "Global hook scripts";
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
postswitch = { postswitch = {
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart"; "notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
@ -312,7 +312,7 @@ in {
type = types.attrsOf profileModule; type = types.attrsOf profileModule;
description = "Autorandr profiles specification."; description = "Autorandr profiles specification.";
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
"work" = { "work" = {
fingerprint = { fingerprint = {

@ -75,7 +75,14 @@ in
# Warn if closing shell with running jobs. # Warn if closing shell with running jobs.
"checkjobs" "checkjobs"
]; ];
description = "Shell options to set."; example = [
"extglob"
"-cdspell"
];
description = ''
Shell options to set. Prefix an option with
<quote><literal>-</literal></quote> to unset.
'';
}; };
sessionVariables = mkOption { sessionVariables = mkOption {
@ -90,7 +97,7 @@ in
shellAliases = mkOption { shellAliases = mkOption {
default = {}; default = {};
type = types.attrsOf types.str; type = types.attrsOf types.str;
example = literalExample '' example = literalExpression ''
{ {
ll = "ls -l"; ll = "ls -l";
".." = "cd .."; ".." = "cd ..";
@ -111,23 +118,21 @@ in
''; '';
}; };
bashrcExtra = mkOption { initExtra = mkOption {
# Hide for now, may want to rename in the future.
visible = false;
default = ""; default = "";
type = types.lines; type = types.lines;
description = '' description = ''
Extra commands that should be added to Extra commands that should be run when initializing an
<filename>~/.bashrc</filename>. interactive shell.
''; '';
}; };
initExtra = mkOption { bashrcExtra = mkOption {
default = ""; default = "";
type = types.lines; type = types.lines;
description = '' description = ''
Extra commands that should be run when initializing an Extra commands that should be placed in <filename>~/.bashrc</filename>.
interactive shell. Note that these commands will be run even in non-interactive shells.
''; '';
}; };
@ -148,8 +153,10 @@ in
mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}") cfg.shellAliases mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}") cfg.shellAliases
); );
shoptsStr = concatStringsSep "\n" ( shoptsStr = let
map (v: "shopt -s ${v}") cfg.shellOptions switch = v: if hasPrefix "-" v then "-u" else "-s";
in concatStringsSep "\n" (
map (v: "shopt ${switch v} ${removePrefix "-" v}") cfg.shellOptions
); );
sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables; sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
@ -171,22 +178,7 @@ in
} }
)); ));
in mkIf cfg.enable { in mkIf cfg.enable {
programs.bash.bashrcExtra = '' home.file.".bash_profile".source = pkgs.writeShellScript "bash_profile" ''
# 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 -*-
# include .profile if it exists # include .profile if it exists
[[ -f ~/.profile ]] && . ~/.profile [[ -f ~/.profile ]] && . ~/.profile
@ -194,9 +186,7 @@ in
[[ -f ~/.bashrc ]] && . ~/.bashrc [[ -f ~/.bashrc ]] && . ~/.bashrc
''; '';
home.file.".profile".text = '' home.file.".profile".source = pkgs.writeShellScript "profile" ''
# -*- mode: sh -*-
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
${sessionVarsStr} ${sessionVarsStr}
@ -204,18 +194,23 @@ in
${cfg.profileExtra} ${cfg.profileExtra}
''; '';
home.file.".bashrc".text = '' home.file.".bashrc".source = pkgs.writeShellScript "bashrc" ''
# -*- mode: sh -*-
${cfg.bashrcExtra} ${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 != "") { home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
text = '' source = pkgs.writeShellScript "bash_logout" cfg.logoutExtra;
# -*- mode: sh -*-
${cfg.logoutExtra}
'';
}; };
} }
); );

@ -6,6 +6,11 @@ let
cfg = config.programs.bat; cfg = config.programs.bat;
toConfigFile = generators.toKeyValue {
mkKeyValue = k: v: "--${k}=${lib.escapeShellArg v}";
listsAsDuplicateKeys = true;
};
in { in {
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
@ -13,11 +18,12 @@ in {
enable = mkEnableOption "bat, a cat clone with wings"; enable = mkEnableOption "bat, a cat clone with wings";
config = mkOption { config = mkOption {
type = types.attrsOf types.str; type = with types; attrsOf (either str (listOf str));
default = { }; default = { };
example = { example = {
theme = "TwoDark"; theme = "TwoDark";
pager = "less -FR"; pager = "less -FR";
map-syntax = [ "*.jenkinsfile:Groovy" "*.props:Java Properties" ];
}; };
description = '' description = ''
Bat configuration. Bat configuration.
@ -27,7 +33,7 @@ in {
themes = mkOption { themes = mkOption {
type = types.attrsOf types.lines; type = types.attrsOf types.lines;
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
dracula = builtins.readFile (pkgs.fetchFromGitHub { dracula = builtins.readFile (pkgs.fetchFromGitHub {
owner = "dracula"; owner = "dracula";
@ -48,10 +54,8 @@ in {
home.packages = [ pkgs.bat ]; home.packages = [ pkgs.bat ];
xdg.configFile = mkMerge ([{ xdg.configFile = mkMerge ([{
"bat/config" = mkIf (cfg.config != { }) { "bat/config" =
text = concatStringsSep "\n" mkIf (cfg.config != { }) { text = toConfigFile cfg.config; };
(mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config);
};
}] ++ flip mapAttrsToList cfg.themes }] ++ flip mapAttrsToList cfg.themes
(name: body: { "bat/themes/${name}.tmTheme" = { text = body; }; })); (name: body: { "bat/themes/${name}.tmTheme" = { text = body; }; }));
}; };

@ -31,9 +31,9 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.beets; default = pkgs.beets;
defaultText = literalExample "pkgs.beets"; defaultText = literalExpression "pkgs.beets";
example = example =
literalExample "(pkgs.beets.override { enableCheck = true; })"; literalExpression "(pkgs.beets.override { enableCheck = true; })";
description = '' description = ''
The <literal>beets</literal> package to use. The <literal>beets</literal> package to use.
Can be used to specify extensions. Can be used to specify extensions.

@ -0,0 +1,66 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.bottom;
tomlFormat = pkgs.formats.toml { };
configDir = if pkgs.stdenv.isDarwin then
"Library/Application Support"
else
config.xdg.configHome;
in {
options = {
programs.bottom = {
enable = mkEnableOption ''
bottom, a cross-platform graphical process/system monitor with a
customizable interface'';
package = mkOption {
type = types.package;
default = pkgs.bottom;
defaultText = literalExpression "pkgs.bottom";
description = "Package providing <command>bottom</command>.";
};
settings = mkOption {
type = tomlFormat.type;
default = { };
description = ''
Configuration written to
<filename>$XDG_CONFIG_HOME/bottom/bottom.toml</filename> on Linux or
<filename>$HOME/Library/Application Support/bottom/bottom.toml</filename> on Darwin.
</para><para>
See <link xlink:href="https://github.com/ClementTsang/bottom/blob/master/sample_configs/default_config.toml"/>
for the default configuration.
'';
example = literalExpression ''
{
flags = {
avg_cpu = true;
temperature_type = "c";
};
colors = {
low_battery_color = "red";
};
}
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
home.file."${configDir}/bottom/bottom.toml" = mkIf (cfg.settings != { }) {
source = tomlFormat.generate "bottom.toml" cfg.settings;
};
};
meta.maintainers = [ maintainers.polykernel ];
}

@ -6,20 +6,12 @@ let
cfg = config.programs.broot; cfg = config.programs.broot;
configFile = config: tomlFormat = pkgs.formats.toml { };
pkgs.runCommand "conf.toml" {
buildInputs = [ pkgs.remarshal ];
preferLocalBuild = true;
allowSubstitutes = false;
} ''
remarshal -if json -of toml \
< ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \
> $out
'';
brootConf = { brootConf = {
verbs = cfg.verbs; verbs = cfg.verbs;
skin = cfg.skin; skin = cfg.skin;
modal = cfg.modal;
}; };
in { in {
@ -52,6 +44,8 @@ in {
''; '';
}; };
modal = mkEnableOption "modal (vim) mode";
verbs = mkOption { verbs = mkOption {
type = with types; listOf (attrsOf (either bool str)); type = with types; listOf (attrsOf (either bool str));
default = [ default = [
@ -73,7 +67,7 @@ in {
execution = "less {file}"; execution = "less {file}";
} }
]; ];
example = literalExample '' example = literalExpression ''
[ [
{ invocation = "p"; execution = ":parent"; } { invocation = "p"; execution = ":parent"; }
{ invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}" ; } { invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}" ; }
@ -130,14 +124,14 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.broot; default = pkgs.broot;
defaultText = literalExample "pkgs.broot"; defaultText = literalExpression "pkgs.broot";
description = "Package providing broot"; description = "Package providing broot";
}; };
skin = mkOption { skin = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = { }; default = { };
example = literalExample '' example = literalExpression ''
{ {
status_normal_fg = "grayscale(18)"; status_normal_fg = "grayscale(18)";
status_normal_bg = "grayscale(3)"; status_normal_bg = "grayscale(3)";
@ -194,7 +188,8 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ cfg.package ]; 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 # Dummy file to prevent broot from trying to reinstall itself
xdg.configFile."broot/launcher/installed-v1".text = ""; xdg.configFile."broot/launcher/installed-v1".text = "";

@ -5,7 +5,9 @@ with lib;
let let
browserModule = defaultPkg: name: visible: browserModule = defaultPkg: name: visible:
let browser = (builtins.parseDrvName defaultPkg.name).name; let
browser = (builtins.parseDrvName defaultPkg.name).name;
isProprietaryChrome = hasPrefix "Google Chrome" name;
in { in {
enable = mkOption { enable = mkOption {
inherit visible; inherit visible;
@ -19,10 +21,12 @@ let
inherit visible; inherit visible;
type = types.package; type = types.package;
default = defaultPkg; default = defaultPkg;
defaultText = literalExample "pkgs.${browser}"; defaultText = literalExpression "pkgs.${browser}";
description = "The ${name} package to use."; 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 { extensions = mkOption {
inherit visible; inherit visible;
type = with types; type = with types;
@ -68,7 +72,7 @@ let
}; };
in listOf (coercedTo str (v: { id = v; }) extensionType); in listOf (coercedTo str (v: { id = v; }) extensionType);
default = [ ]; default = [ ];
example = literalExample '' example = literalExpression ''
[ [
{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # ublock origin { id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # ublock origin
{ {
@ -110,10 +114,12 @@ let
brave = "BraveSoftware/Brave-Browser"; brave = "BraveSoftware/Brave-Browser";
}; };
linuxDirs = { brave = "BraveSoftware/Brave-Browser"; };
configDir = if pkgs.stdenv.isDarwin then configDir = if pkgs.stdenv.isDarwin then
"Library/Application Support/${getAttr browser darwinDirs}" "Library/Application Support/" + (darwinDirs."${browser}" or browser)
else else
"${config.xdg.configHome}/${browser}"; "${config.xdg.configHome}/" + (linuxDirs."${browser}" or browser);
extensionJson = ext: extensionJson = ext:
assert ext.crxPath != null -> ext.version != null; assert ext.crxPath != null -> ext.version != null;
@ -129,10 +135,19 @@ let
in mkIf cfg.enable { in mkIf cfg.enable {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
home.file = listToAttrs (map extensionJson cfg.extensions); home.file = listToAttrs (map extensionJson (cfg.extensions or [ ]));
}; };
in { 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 = { options.programs = {
chromium = browserModule pkgs.chromium "Chromium" true; chromium = browserModule pkgs.chromium "Chromium" true;
google-chrome = browserModule pkgs.google-chrome "Google Chrome" false; google-chrome = browserModule pkgs.google-chrome "Google Chrome" false;

@ -11,13 +11,8 @@ let
dir = "bin"; dir = "bin";
src = ./command-not-found.pl; src = ./command-not-found.pl;
isExecutable = true; isExecutable = true;
inherit (pkgs) perl;
inherit (cfg) dbPath; inherit (cfg) dbPath;
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [ perl = pkgs.perl.withPackages (p: [ p.DBDSQLite p.StringShellQuote ]);
pkgs.perlPackages.DBI
pkgs.perlPackages.DBDSQLite
pkgs.perlPackages.StringShellQuote
]);
}; };
shInit = commandNotFoundHandlerName: '' shInit = commandNotFoundHandlerName: ''

@ -1,4 +1,4 @@
#! @perl@/bin/perl -w @perlFlags@ #! @perl@/bin/perl -w
use strict; use strict;
use DBI; use DBI;
@ -29,16 +29,17 @@ if (!defined $res || scalar @$res == 0) {
exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV)); exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV));
} else { } else {
print STDERR <<EOF; print STDERR <<EOF;
The program $program is currently not installed. You can install it by typing: The program '$program' is not in your PATH. You can make it available in an
nix-env -iA nixos.$package ephemeral shell by typing:
nix-shell -p $package
EOF EOF
} }
} else { } else {
print STDERR <<EOF; print STDERR <<EOF;
The program $program is currently not installed. It is provided by The program '$program' is not in your PATH. It is provided by several packages.
several packages. You can install it by typing one of the following: You can make it available in an ephemeral shell by typing one of the following:
EOF EOF
print STDERR " nix-env -iA nixos.$_->{package}\n" foreach @$res; print STDERR " nix-shell -p $_->{package}\n" foreach @$res;
} }
exit 127; exit 127;

@ -51,7 +51,7 @@ in {
See <command>dircolors --print-database</command> See <command>dircolors --print-database</command>
for options. for options.
''; '';
example = literalExample '' example = literalExpression ''
{ {
OTHER_WRITABLE = "30;46"; OTHER_WRITABLE = "30;46";
".sh" = "01;32"; ".sh" = "01;32";
@ -204,8 +204,8 @@ in {
}; };
home.file.".dir_colors".text = concatStringsSep "\n" ([ ] home.file.".dir_colors".text = concatStringsSep "\n" ([ ]
++ optional (cfg.extraConfig != "") cfg.extraConfig ++ mapAttrsToList formatLine cfg.settings ++ [ "" ]
++ mapAttrsToList formatLine cfg.settings) + "\n"; ++ optional (cfg.extraConfig != "") cfg.extraConfig);
programs.bash.initExtra = mkIf cfg.enableBashIntegration '' programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors) eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)

@ -9,6 +9,14 @@ let
tomlFormat = pkgs.formats.toml { }; tomlFormat = pkgs.formats.toml { };
in { in {
imports = [
(mkRenamedOptionModule [
"programs"
"direnv"
"enableNixDirenvIntegration"
] [ "programs" "direnv" "nix-direnv" "enable" ])
];
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options.programs.direnv = { options.programs.direnv = {
@ -58,15 +66,22 @@ in {
enableFishIntegration = mkOption { enableFishIntegration = mkOption {
default = true; default = true;
type = types.bool; type = types.bool;
readOnly = true;
description = '' description = ''
Whether to enable Fish integration. Whether to enable Fish integration. Note, enabling the direnv module
will always active its functionality for Fish since the direnv package
automatically gets loaded in Fish.
''; '';
}; };
enableNixDirenvIntegration = mkEnableOption '' nix-direnv = {
<link enable = mkEnableOption ''
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>, <link
a fast, persistent use_nix implementation for direnv''; xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
a fast, persistent use_nix implementation for direnv'';
enableFlakes = mkEnableOption "Flake support in nix-direnv";
};
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
@ -77,9 +92,11 @@ in {
}; };
xdg.configFile."direnv/direnvrc" = let xdg.configFile."direnv/direnvrc" = let
package =
pkgs.nix-direnv.override { inherit (cfg.nix-direnv) enableFlakes; };
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
++ optional cfg.enableNixDirenvIntegration ++ optional cfg.nix-direnv.enable
"source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc"); "source ${package}/share/nix-direnv/direnvrc");
in mkIf (text != "") { inherit text; }; in mkIf (text != "") { inherit text; };
programs.bash.initExtra = mkIf cfg.enableBashIntegration ( programs.bash.initExtra = mkIf cfg.enableBashIntegration (
@ -92,9 +109,5 @@ in {
programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${pkgs.direnv}/bin/direnv hook zsh)" eval "$(${pkgs.direnv}/bin/direnv hook zsh)"
''; '';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
${pkgs.direnv}/bin/direnv hook fish | source
'';
}; };
} }

@ -16,8 +16,8 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.eclipses.eclipse-platform; default = pkgs.eclipses.eclipse-platform;
defaultText = literalExample "pkgs.eclipses.eclipse-platform"; defaultText = literalExpression "pkgs.eclipses.eclipse-platform";
example = literalExample "pkgs.eclipses.eclipse-java"; example = literalExpression "pkgs.eclipses.eclipse-java";
description = '' description = ''
The Eclipse package to install. The Eclipse package to install.
''; '';

@ -13,6 +13,12 @@ let
emacsWithPackages = emacsPackages.emacsWithPackages; emacsWithPackages = emacsPackages.emacsWithPackages;
createConfPackage = epkgs:
epkgs.trivialBuild {
pname = "default";
src = pkgs.writeText "default.el" cfg.extraConfig;
};
in { in {
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
@ -23,16 +29,33 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.emacs; default = pkgs.emacs;
defaultText = literalExample "pkgs.emacs"; defaultText = literalExpression "pkgs.emacs";
example = literalExample "pkgs.emacs25-nox"; example = literalExpression "pkgs.emacs25-nox";
description = "The Emacs package to use."; description = "The Emacs package to use.";
}; };
# NOTE: The config is placed in default.el instead of ~/.emacs.d so that
# it won't conflict with Emacs configuration frameworks. Users of these
# frameworks would still benefit from this option as it would easily allow
# them to have Nix-computed paths in their configuration.
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
(setq standard-indent 2)
'';
description = ''
Configuration to include in the Emacs default init file. See
<link xlink:href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Init-File.html"/>
for more.
'';
};
extraPackages = mkOption { extraPackages = mkOption {
default = self: [ ]; default = self: [ ];
type = hm.types.selectorFunction; type = hm.types.selectorFunction;
defaultText = "epkgs: []"; defaultText = "epkgs: []";
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]"; example = literalExpression "epkgs: [ epkgs.emms epkgs.magit ]";
description = '' description = ''
Extra packages available to Emacs. To get a list of Extra packages available to Emacs. To get a list of
available packages run: available packages run:
@ -44,7 +67,7 @@ in {
default = self: super: { }; default = self: super: { };
type = hm.types.overlayFunction; type = hm.types.overlayFunction;
defaultText = "self: super: {}"; defaultText = "self: super: {}";
example = literalExample '' example = literalExpression ''
self: super: rec { self: super: rec {
haskell-mode = self.melpaPackages.haskell-mode; haskell-mode = self.melpaPackages.haskell-mode;
# ... # ...
@ -68,6 +91,10 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ cfg.finalPackage ]; home.packages = [ cfg.finalPackage ];
programs.emacs.finalPackage = emacsWithPackages cfg.extraPackages; programs.emacs = {
finalPackage = emacsWithPackages cfg.extraPackages;
extraPackages = epkgs:
optional (cfg.extraConfig != "") (createConfPackage epkgs);
};
}; };
} }

@ -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 <command>ls</command>";
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;
};
}

@ -9,19 +9,15 @@ let
cfg = config.programs.firefox; cfg = config.programs.firefox;
mozillaConfigPath = mozillaConfigPath =
if isDarwin if isDarwin then "Library/Application Support/Mozilla" else ".mozilla";
then "Library/Application Support/Mozilla"
else ".mozilla";
firefoxConfigPath = firefoxConfigPath = if isDarwin then
if isDarwin "Library/Application Support/Firefox"
then "Library/Application Support/Firefox" else
else "${mozillaConfigPath}/firefox"; "${mozillaConfigPath}/firefox";
profilesPath = profilesPath =
if isDarwin if isDarwin then "${firefoxConfigPath}/Profiles" else firefoxConfigPath;
then "${firefoxConfigPath}/Profiles"
else firefoxConfigPath;
# The extensions path shared by all profiles; will not be supported # The extensions path shared by all profiles; will not be supported
# by future Firefox versions. # by future Firefox versions.
@ -32,46 +28,72 @@ let
paths = cfg.extensions; paths = cfg.extensions;
}; };
profiles = profiles = flip mapAttrs' cfg.profiles (_: profile:
flip mapAttrs' cfg.profiles (_: profile: nameValuePair "Profile${toString profile.id}" {
nameValuePair "Profile${toString profile.id}" { Name = profile.name;
Name = profile.name; Path = if isDarwin then "Profiles/${profile.path}" else profile.path;
Path = IsRelative = 1;
if isDarwin Default = if profile.isDefault then 1 else 0;
then "Profiles/${profile.path}" }) // {
else profile.path; General = { StartWithLastProfile = 1; };
IsRelative = 1;
Default = if profile.isDefault then 1 else 0;
}
) // {
General = {
StartWithLastProfile = 1;
};
}; };
profilesIni = generators.toINI {} profiles; profilesIni = generators.toINI { } profiles;
mkUserJs = prefs: extraPrefs: '' mkUserJs = prefs: extraPrefs: bookmarks:
// Generated by Home Manager. let
prefs' = lib.optionalAttrs ({ } != bookmarks) {
${concatStrings (mapAttrsToList (name: value: '' "browser.bookmarks.file" = toString (firefoxBookmarksFile bookmarks);
user_pref("${name}", ${builtins.toJSON value}); "browser.places.importBookmarksHTML" = true;
'') prefs)} } // prefs;
in ''
${extraPrefs} // Generated by Home Manager.
'';
${concatStrings (mapAttrsToList (name: value: ''
in user_pref("${name}", ${builtins.toJSON value});
'') prefs')}
{
${extraPrefs}
'';
firefoxBookmarksFile = bookmarks:
let
escapeXML = replaceStrings [ ''"'' "'" "<" ">" "&" ] [
"&quot;"
"&apos;"
"&lt;"
"&gt;"
"&amp;"
];
mapper = _: entry: ''
<DT><A HREF="${escapeXML entry.url}" ADD_DATE="0" LAST_MODIFIED="0"${
lib.optionalString (entry.keyword != null)
" SHORTCUTURL=\"${escapeXML entry.keyword}\""
}>${escapeXML entry.name}</A>
'';
bookmarksEntries = lib.attrsets.mapAttrsToList mapper bookmarks;
in pkgs.writeText "firefox-bookmarks.html" ''
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks Menu</H1>
<DL><p>
${concatStrings bookmarksEntries}
</p></DL>
'';
in {
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
imports = [ imports = [
(mkRemovedOptionModule ["programs" "firefox" "enableAdobeFlash"] (mkRemovedOptionModule [ "programs" "firefox" "enableAdobeFlash" ]
"Support for this option has been removed.") "Support for this option has been removed.")
(mkRemovedOptionModule ["programs" "firefox" "enableGoogleTalk"] (mkRemovedOptionModule [ "programs" "firefox" "enableGoogleTalk" ]
"Support for this option has been removed.") "Support for this option has been removed.")
(mkRemovedOptionModule ["programs" "firefox" "enableIcedTea"] (mkRemovedOptionModule [ "programs" "firefox" "enableIcedTea" ]
"Support for this option has been removed.") "Support for this option has been removed.")
]; ];
@ -81,11 +103,22 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = default = if versionAtLeast config.home.stateVersion "19.09" then
if versionAtLeast config.home.stateVersion "19.09" pkgs.firefox
then pkgs.firefox else
else pkgs.firefox-unwrapped; pkgs.firefox-unwrapped;
defaultText = literalExample "pkgs.firefox"; defaultText = literalExpression "pkgs.firefox";
example = literalExpression ''
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 = '' description = ''
The Firefox package to use. If state version  19.09 then The Firefox package to use. If state version  19.09 then
this should be a wrapped Firefox package. For earlier state this should be a wrapped Firefox package. For earlier state
@ -95,8 +128,8 @@ in
extensions = mkOption { extensions = mkOption {
type = types.listOf types.package; type = types.listOf types.package;
default = []; default = [ ];
example = literalExample '' example = literalExpression ''
with pkgs.nur.repos.rycee.firefox-addons; [ with pkgs.nur.repos.rycee.firefox-addons; [
https-everywhere https-everywhere
privacy-badger privacy-badger
@ -130,7 +163,7 @@ in
}; };
profiles = mkOption { profiles = mkOption {
type = types.attrsOf (types.submodule ({config, name, ...}: { type = types.attrsOf (types.submodule ({ config, name, ... }: {
options = { options = {
name = mkOption { name = mkOption {
type = types.str; type = types.str;
@ -148,8 +181,8 @@ in
settings = mkOption { settings = mkOption {
type = with types; attrsOf (either bool (either int str)); type = with types; attrsOf (either bool (either int str));
default = {}; default = { };
example = literalExample '' example = literalExpression ''
{ {
"browser.startup.homepage" = "https://nixos.org"; "browser.startup.homepage" = "https://nixos.org";
"browser.search.region" = "GB"; "browser.search.region" = "GB";
@ -199,6 +232,45 @@ in
''; '';
}; };
bookmarks = mkOption {
type = types.attrsOf (types.submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = types.str;
default = name;
description = "Bookmark name.";
};
keyword = mkOption {
type = types.nullOr types.str;
default = null;
description = "Bookmark search keyword.";
};
url = mkOption {
type = types.str;
description = "Bookmark url, use %s for search terms.";
};
};
}));
default = { };
example = literalExpression ''
{
wikipedia = {
keyword = "wiki";
url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go";
};
"kernel.org" = {
url = "https://www.kernel.org";
};
}
'';
description = ''
Preloaded bookmarks. Note, this may silently overwrite any
previously existing bookmarks!
'';
};
path = mkOption { path = mkOption {
type = types.str; type = types.str;
default = name; default = name;
@ -213,7 +285,7 @@ in
}; };
}; };
})); }));
default = {}; default = { };
description = "Attribute set of Firefox profiles."; description = "Attribute set of Firefox profiles.";
}; };
@ -232,95 +304,84 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
( (let
let defaults =
defaults = catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles)); in {
in { assertion = cfg.profiles == { } || length defaults == 1;
assertion = cfg.profiles == {} || length defaults == 1; message = "Must have exactly one default Firefox profile but found "
message = + toString (length defaults) + optionalString (length defaults > 1)
"Must have exactly one default Firefox profile but found " (", namely " + concatStringsSep ", " defaults);
+ toString (length defaults) })
+ optionalString (length defaults > 1)
(", namely " + concatStringsSep ", " defaults); (let
} duplicates = filterAttrs (_: v: length v != 1) (zipAttrs
) (mapAttrsToList (n: v: { "${toString v.id}" = n; }) (cfg.profiles)));
( mkMsg = n: v: " - ID ${n} is used by ${concatStringsSep ", " v}";
let in {
duplicates = assertion = duplicates == { };
filterAttrs (_: v: length v != 1) message = ''
(zipAttrs Must not have Firefox profiles with duplicate IDs but
(mapAttrsToList (n: v: { "${toString v.id}" = n; }) '' + concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
(cfg.profiles))); })
mkMsg = n: v: " - ID ${n} is used by ${concatStringsSep ", " v}";
in {
assertion = duplicates == {};
message =
"Must not have Firefox profiles with duplicate IDs but\n"
+ concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
}
)
]; ];
home.packages = warnings = optional (cfg.enableGnomeExtensions or false) ''
let Using 'programs.firefox.enableGnomeExtensions' has been deprecated and
# The configuration expected by the Firefox wrapper. will be removed in the future. Please change to overriding the package
fcfg = { configuration using 'programs.firefox.package' instead. You can refer to
enableGnomeExtensions = cfg.enableGnomeExtensions; its example for how to do this.
}; '';
home.packages = let
# The configuration expected by the Firefox wrapper.
fcfg = { enableGnomeExtensions = cfg.enableGnomeExtensions; };
# A bit of hackery to force a config into the wrapper.
browserName = cfg.package.browserName or (builtins.parseDrvName
cfg.package.name).name;
# The configuration expected by the Firefox wrapper builder.
bcfg = setAttrByPath [ browserName ] fcfg;
package = if isDarwin then
cfg.package
else if versionAtLeast config.home.stateVersion "19.09" then
cfg.package.override (old: { cfg = old.cfg or { } // fcfg; })
else
(pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
in [ package ];
home.file = mkMerge ([{
"${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != [ ]) {
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
recursive = true;
};
# A bit of hackery to force a config into the wrapper. "${firefoxConfigPath}/profiles.ini" =
browserName = cfg.package.browserName mkIf (cfg.profiles != { }) { text = profilesIni; };
or (builtins.parseDrvName cfg.package.name).name; }] ++ flip mapAttrsToList cfg.profiles (_: profile: {
"${profilesPath}/${profile.path}/.keep".text = "";
# The configuration expected by the Firefox wrapper builder.
bcfg = setAttrByPath [browserName] fcfg;
package =
if isDarwin then
cfg.package
else if versionAtLeast config.home.stateVersion "19.09" then
cfg.package.override { cfg = fcfg; }
else
(pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
in
[ package ];
home.file = mkMerge (
[{
"${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != []) {
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
recursive = true;
};
"${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) { "${profilesPath}/${profile.path}/chrome/userChrome.css" =
text = profilesIni; mkIf (profile.userChrome != "") { text = profile.userChrome; };
};
}]
++ flip mapAttrsToList cfg.profiles (_: profile: {
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
mkIf (profile.userChrome != "") {
text = profile.userChrome;
};
"${profilesPath}/${profile.path}/chrome/userContent.css" = "${profilesPath}/${profile.path}/chrome/userContent.css" =
mkIf (profile.userContent != "") { mkIf (profile.userContent != "") { text = profile.userContent; };
text = profile.userContent;
};
"${profilesPath}/${profile.path}/user.js" = "${profilesPath}/${profile.path}/user.js" =
mkIf (profile.settings != {} || profile.extraConfig != "") { mkIf (profile.settings != { } || profile.extraConfig != "") {
text = mkUserJs profile.settings profile.extraConfig; text =
}; mkUserJs profile.settings profile.extraConfig profile.bookmarks;
};
"${profilesPath}/${profile.path}/extensions" = mkIf (cfg.extensions != []) { "${profilesPath}/${profile.path}/extensions" =
mkIf (cfg.extensions != [ ]) {
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
recursive = true; recursive = true;
force = true; force = true;
}; };
}) }));
);
}; };
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save