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

@ -10,7 +10,7 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "release-20.09"
target-branch: "release-21.05"
schedule:
interval: "weekly"
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 }}
steps:
- uses: actions/checkout@v2
- uses: cachix/install-nix-action@v12
- uses: cachix/install-nix-action@v14
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v8
- uses: cachix/cachix-action@v10
with:
name: nix-community
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'

@ -6,18 +6,19 @@ on:
jobs:
tests:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: cachix/install-nix-action@v12
- uses: cachix/install-nix-action@v14.1
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v8
- uses: cachix/cachix-action@v10
with:
name: nix-community
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- run: ./format -c
- run: nix-shell . -A install
- run: nix-shell --pure 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
previous manual configuration. For example, the Gnome Terminal module
will write to your dconf store and cannot tell whether a configuration
that it is about to be overwrite was from a previous Home Manager
that it is about to be overwritten was from a previous Home Manager
generation or from manual configuration.
Home Manager targets [NixOS][] unstable and NixOS version 20.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
distributions and NixOS versions.
@ -48,8 +48,7 @@ Contact
-------
You can chat with us on IRC in the channel [#home-manager][] on
[freenode][]. The [channel logs][] are hosted courtesy of
[samueldr][].
[OFTC][].
Installation
------------
@ -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
Nixpkgs master or an unstable channel you can run
```console
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
$ nix-channel --update
```shell
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
nix-channel --update
```
and if you follow a Nixpkgs version 20.09 channel you can run
and if you follow a Nixpkgs version 21.05 channel you can run
```console
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.09.tar.gz home-manager
$ nix-channel --update
```shell
nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
nix-channel --update
```
On NixOS you may need to log out and back in for the channel to
@ -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:
```console
$ nix-shell '<home-manager>' -A install
```shell
nix-shell '<home-manager>' -A install
```
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
configuration then you must source the
```
```shell
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
```
file in your shell configuration. Unfortunately, in this specific
case we currently only support POSIX.2-like shells such as
[Bash][] or [Z shell][].
file in your shell configuration. This file can be sourced
directly by POSIX.2-like shells such as [Bash][] or [Z shell][].
[Fish][] users can use utilities such as [foreign-env][] or
[babelfish][].
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
installation above to install the htop and fortune packages, install
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
`~/.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
```console
$ home-manager switch
```shell
home-manager switch
```
or if you are not feeling so lucky,
```console
$ home-manager build
```shell
home-manager build
```
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
manual][configuration options] or offline by running
```console
$ man home-configuration.nix
```shell
man home-configuration.nix
```
Rollbacks
@ -280,7 +280,7 @@ then result in
$ home-manager switch
Activating checkLinkTargets
Existing file '/home/jdoe/.gitconfig' is in the way
Existing file '/home/jdoe/.config/git/config' is in the way
Please move the above files and try again
```
@ -367,7 +367,7 @@ Home Manager is developed against `nixpkgs-unstable` branch, which
often causes it to contain tweaks for changes/packages not yet
released in stable NixOS. To avoid breaking users' configurations,
Home Manager is released in branches corresponding to NixOS releases
(e.g. `release-20.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
an issue.
@ -380,9 +380,11 @@ an issue.
[Z shell]: http://zsh.sourceforge.net/
[manual]: https://nix-community.github.io/home-manager/
[configuration options]: https://nix-community.github.io/home-manager/options.html
[#home-manager]: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager
[freenode]: https://freenode.net/
[channel logs]: https://logs.nix.samueldr.com/home-manager/
[#home-manager]: https://webchat.oftc.net/?channels=home-manager
[OFTC]: https://oftc.net/
[samueldr]: https://github.com/samueldr/
[Nix Pills]: https://nixos.org/nixos/nix-pills/
[Nix Flakes]: https://nixos.wiki/wiki/Flakes
[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> { } }:
rec {
docs = with import ./doc { inherit pkgs; }; {
docs = with import ./docs { inherit pkgs; }; {
html = manual.html;
manPages = manPages;
json = options.json;

@ -44,7 +44,7 @@ The first option is good if you only temporarily want to use your clone.
[[sec-guidelines]]
=== Guidelines
:irc-home-manager: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager
:irc-home-manager: https://webchat.oftc.net/?channels=home-manager
:valuable-options: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md#valuable-options
:rfc-42: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md
:assertions: https://nixos.org/manual/nixos/stable/index.html#sec-assertions
@ -163,7 +163,7 @@ The commit messages should follow the {seven-rules}[seven rules]. We also ask yo
{long description}
----
where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. Note, `{description}` should start with a lower case letter. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <<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]]
.Compliant commit message

@ -9,8 +9,8 @@ let
name = "nmd";
owner = "rycee";
repo = "nmd";
rev = "2398aa79ab12aa7aba14bc3b08a6efd38ebabdc5";
sha256 = "0yxb48afvccn8vvpkykzcr4q1rgv8jsijqncia7a5ffzshcrwrnh";
rev = "12bc57594e12525d2e4422fa7034b2d54e9ea09a";
sha256 = "0fpankfx2c99x4n1mhdy730yxy2b03qcw4zvjxyk4b1v60h8057n";
};
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.
You could also opt to unistall _all_ of the packages from your profile with `nix-env --uninstall '*'`.
=== 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]
----
. "$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?
: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
[source,nix]
services.dbus.packages = with pkgs; [ gnome3.dconf ];
programs.dconf.enable = true;
to your system configuration.

@ -47,11 +47,11 @@ $ nix-channel --add https://github.com/nix-community/home-manager/archive/master
$ 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]
----
$ 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
----
+
@ -86,9 +86,12 @@ file in your shell configuration. Alternatively source
+
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
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
+
@ -125,11 +128,11 @@ or an unstable channel, you can run
# 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]
----
# 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
----
@ -203,11 +206,11 @@ or an unstable channel, you can run
# 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]
----
# 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
----
@ -224,13 +227,17 @@ For example, a nix-darwin configuration may include the lines
[source,nix]
----
users.users.eve = {
name = "eve";
home = "/Users/eve";
}
home-manager.users.eve = { pkgs, ... }: {
home.packages = [ pkgs.atool pkgs.httpie ];
programs.bash.enable = true;
};
----
and after a `darwin-rebuild --switch` the user eve's environment
and after a `darwin-rebuild switch` the user eve's environment
should include a basic Bash configuration and the packages atool and
httpie.

@ -12,47 +12,51 @@
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>home-manager</command> <group choice="req">
<command>home-manager</command> <group choice="req">
<arg choice="plain">
build
</arg>
<arg choice="plain">
instantiate
</arg>
<arg choice="plain">
edit
</arg>
<arg choice="plain">
expire-generations <replaceable>timestamp</replaceable>
</arg>
<arg choice="plain">
generations
</arg>
<arg choice="plain">
help
</arg>
<arg choice="plain">
news
</arg>
<arg choice="plain">
option <replaceable>option.name</replaceable>
</arg>
<arg choice="plain">
packages
</arg>
<arg choice="plain">
remove-generations <replaceable>ID …</replaceable>
</arg>
<arg choice="plain">
switch
</arg>
<arg choice="plain">
uninstall
</arg>
@ -61,59 +65,63 @@
<arg>
-A <replaceable>attrPath</replaceable>
</arg>
<arg>
-I <replaceable>path</replaceable>
</arg>
<arg>
--flake <replaceable>flake-uri</replaceable>
</arg>
<arg>
-b <replaceable>ext</replaceable>
</arg>
<arg>
<group choice="req">
<group choice="req">
<arg choice="plain">
-f
</arg>
<arg choice="plain">
--file
</arg>
</group> <replaceable>path</replaceable>
</arg>
<arg>
<group choice="req">
<group choice="req">
<arg choice="plain">
-h
</arg>
<arg choice="plain">
--help
</arg>
</group>
</arg>
<arg>
<group choice="req">
<group choice="req">
<arg choice="plain">
-n
</arg>
<arg choice="plain">
--dry-run
</arg>
</group>
</arg>
<arg>
--option <replaceable>name</replaceable> <replaceable>value</replaceable>
</arg>
<arg>
--cores <replaceable>number</replaceable>
</arg>
<arg>
<group choice="req">
<arg choice="plain">
@ -126,29 +134,41 @@
</group>
<replaceable>number</replaceable>
</arg>
<arg>
--debug
</arg>
<arg>
--impure
</arg>
<arg>
--keep-failed
</arg>
<arg>
--keep-going
</arg>
<arg>
--show-trace
</arg>
<arg>
--(no-)substitute
</arg>
<arg>
<group choice="req">
--no-out-link
</arg>
<arg>
<group choice="req">
<arg choice="plain">
-v
</arg>
<arg choice="plain">
--verbose
</arg>
@ -160,7 +180,7 @@
<title>Description</title>
<para>
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>
All operations using this tool expects a sub-command that indicates the
@ -242,6 +262,18 @@
</para>
</listitem>
</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>
<term>
<option>packages</option>
@ -343,6 +375,18 @@
</para>
</listitem>
</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>
<term>
<option>-b <replaceable>extension</replaceable></option>
@ -440,6 +484,30 @@
</para>
</listitem>
</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>
<term>
<option>--keep-failed</option>
@ -488,6 +556,19 @@
</para>
</listitem>
</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>
<term>
<option>-v</option>

@ -9,15 +9,13 @@
<preface>
<title>Preface</title>
<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.
</para>
<para>
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>
hosted by <link xlink:href="https://freenode.net/">freenode</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>.
<link xlink:href="https://webchat.oftc.net/?channels=home-manager">#home-manager</link>
hosted by <link xlink:href="https://oftc.net/">OFTC</link>.
If your problem is caused by a bug in Home Manager then it should
be reported on the
<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
include::rl-2111.adoc[]
include::rl-2105.adoc[]
include::rl-2009.adoc[]

@ -1,8 +1,7 @@
[[sec-release-21.05]]
== Release 21.05
This is the current unstable branch and the information in this
section is therefore not final.
The 21.05 release branch became the stable branch in May, 2021.
[[sec-release-21.05-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]
for the available additional options in each program.
* Specifying `programs.neomutt.binds.map` or `programs.neomutt.macros.map` as a
single string is now deprecated in favor of specfiying it as a list of
strings.
* The `programs.neovim.configure` is deprecated in favor of other `programs.neovim` options;
please use the other options at your disposal:
+
@ -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]]
=== 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
"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";
outputs = { self, nixpkgs }: rec {
nixosModules.home-manager = import ./nixos;
darwinModules.home-manager = import ./nix-darwin;
lib = {
hm = import ./modules/lib { lib = nixpkgs.lib; };
homeManagerConfiguration = { configuration, system, homeDirectory
, username, extraSpecialArgs ? { }
, pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages
, check ? true }@args:
import ./modules {
inherit pkgs check extraSpecialArgs;
configuration = { ... }: {
imports = [ configuration ];
home = { inherit homeDirectory username; };
outputs = { self, nixpkgs }:
let
# List of systems supported by home-manager binary
supportedSystems = nixpkgs.lib.platforms.unix;
# Function to generate a set based on supported systems
forAllSystems = f:
nixpkgs.lib.genAttrs supportedSystems (system: f system);
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
in rec {
nixosModules.home-manager = import ./nixos;
nixosModule = self.nixosModules.home-manager;
darwinModules.home-manager = import ./nix-darwin;
darwinModule = self.darwinModules.home-manager;
packages = forAllSystems (system:
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
#! 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=
@ -18,7 +18,6 @@ esac
find . -name '*.nix' \
! -path ./modules/programs/irssi.nix \
\
! -path ./home-manager/default.nix \
! -path ./home-manager/home-manager.nix \
! -path ./modules/default.nix \
! -path ./modules/files.nix \
@ -27,31 +26,15 @@ find . -name '*.nix' \
! -path ./modules/lib/file-type.nix \
! -path ./modules/manual.nix \
! -path ./modules/misc/news.nix \
! -path ./modules/misc/nixpkgs.nix \
! -path ./modules/misc/xdg.nix \
! -path ./modules/modules.nix \
! -path ./modules/programs/afew.nix \
! -path ./modules/programs/bash.nix \
! -path ./modules/programs/firefox.nix \
! -path ./modules/programs/gpg.nix \
! -path ./modules/programs/lesspipe.nix \
! -path ./modules/programs/ssh.nix \
! -path ./modules/programs/tmux.nix \
! -path ./modules/programs/zsh.nix \
! -path ./modules/services/gpg-agent.nix \
! -path ./modules/services/kbfs.nix \
! -path ./modules/services/keybase.nix \
! -path ./modules/services/mpd.nix \
! -path ./modules/services/sxhkd.nix \
! -path ./modules/services/window-managers/i3.nix \
! -path ./modules/systemd.nix \
! -path ./nix-darwin/default.nix \
! -path ./tests/default.nix \
! -path ./tests/modules/home-environment/default.nix \
! -path ./tests/modules/home-environment/session-variables.nix \
! -path ./tests/modules/programs/gpg/override-defaults.nix \
! -path ./tests/modules/programs/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 {} +

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

@ -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 -/' \
'-b[backup files]:EXT:()' \
'--cores[cores]:NUM:()' \
'--debug[debug]' \
'--impure[impure]' \
'--keep-failed[keep failed]' \
'--keep-going[keep going]' \
'(-h --help)'{--help,-h}'[help]' \
@ -15,6 +17,7 @@ _arguments \
'(-f --file)'{--file,-f}'[configuration file]:FILE:_files' \
'(-j --max-jobs)'{--max-jobs,-j}'[max jobs]:NUM:()' \
'--option[option]:NAME VALUE:()' \
'--builders[builders]:SPEC:()' \
'--show-trace[show trace]' \
'1: :->cmds' \
'*:: :->args' && ret=0
@ -24,6 +27,7 @@ case "$state" in
_values 'command' \
'help[help]' \
'edit[edit]' \
'option[inspect option]' \
'build[build]' \
'switch[switch]' \
'generations[list generations]' \
@ -42,11 +46,17 @@ case "$state" in
build|switch)
_arguments \
'--cores[cores]:NUM:()' \
'--debug[debug]' \
'--impure[impure]' \
'--keep-failed[keep failed]' \
'--keep-going[keep going]' \
'--max-jobs[max jobs]:NUM:()' \
'--no-out-link[no out link]' \
'--no-substitute[no substitute]' \
'--option[option]:NAME VALUE:()' \
'--show-trace[show trace]'
'--show-trace[show trace]' \
'--substitute[substitute]' \
'--builders[builders]:SPEC:()'
;;
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
# before `$HOME/.config/nixpkgs/home-manager` and
# `$HOME/.nixpkgs/home-manager`.
, path ? null
}:
# Extra path to Home Manager. If set then this path will be tried
# before `$HOME/.config/nixpkgs/home-manager` and
# `$HOME/.nixpkgs/home-manager`.
, path ? null }:
let
pathStr = if path == null then "" else path;
in
nixos-option = pkgs.nixos-option or (callPackage
(pkgs.path + "/nixos/modules/installer/tools/nixos-option") { });
runCommand
"home-manager"
{
preferLocalBuild = true;
allowSubstitutes = false;
meta = with lib; {
description = "A user environment configurator";
maintainers = [ maintainers.rycee ];
platforms = platforms.unix;
license = licenses.mit;
};
}
''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
in runCommand "home-manager" {
preferLocalBuild = true;
allowSubstitutes = false;
meta = with lib; {
description = "A user environment configurator";
maintainers = [ maintainers.rycee ];
platforms = platforms.unix;
license = licenses.mit;
};
} ''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${bash}" \
--subst-var-by coreutils "${coreutils}" \
--subst-var-by findutils "${findutils}" \
--subst-var-by gnused "${gnused}" \
--subst-var-by less "${less}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${bash}" \
--subst-var-by coreutils "${coreutils}" \
--subst-var-by findutils "${findutils}" \
--subst-var-by gnused "${gnused}" \
--subst-var-by less "${less}" \
--subst-var-by nixos-option "${nixos-option}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
install -D -m755 ${./completion.bash} \
$out/share/bash-completion/completions/home-manager
install -D -m755 ${./completion.zsh} \
$out/share/zsh/site-functions/_home-manager
''
install -D -m755 ${./completion.bash} \
$out/share/bash-completion/completions/home-manager
install -D -m755 ${./completion.zsh} \
$out/share/zsh/site-functions/_home-manager
install -D -m755 ${./completion.fish} \
$out/share/fish/vendor_completions.d/home-manager.fish
''

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

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

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

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

@ -39,6 +39,28 @@ in
};
config = {
assertions = [(
let
dups =
attrNames
(filterAttrs (n: v: v > 1)
(foldAttrs (acc: v: acc + v) 0
(mapAttrsToList (n: v: { ${v.target} = 1; }) cfg)));
dupsStr = concatStringsSep ", " dups;
in {
assertion = dups == [];
message = ''
Conflicting managed target files: ${dupsStr}
This may happen, for example, if you have a configuration similar to
home.file = {
conflict1 = { source = ./foo.nix; target = "baz"; };
conflict2 = { source = ./bar.nix; target = "baz"; };
}'';
})
];
lib.file.mkOutOfStoreSymlink = path:
let
pathStr = toString path;
@ -53,7 +75,7 @@ in
# Paths that should be forcibly overwritten by Home Manager.
# Caveat emptor!
forcedPaths =
concatMapStringsSep " " (p: ''"$HOME/${p}"'')
concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'')
(mapAttrsToList (n: v: v.target)
(filterAttrs (n: v: v.force) cfg));
@ -62,7 +84,7 @@ in
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*"
forcedPaths=(${forcedPaths})
@ -84,7 +106,12 @@ in
$VERBOSE_ECHO "Skipping collision check for $targetPath"
elif [[ -e "$targetPath" \
&& ! "$(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"
if [[ -e "$backup" ]]; then
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'"
fi
else
# Fail if nothing else works
errorEcho "Existing file '$targetPath' is in the way of '$sourcePath'"
collision=1
fi
@ -100,7 +128,7 @@ in
done
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
fi
'';
@ -140,27 +168,35 @@ in
# source and target generation.
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
let
link = pkgs.writeText "link" ''
link = pkgs.writeShellScript "link" ''
newGenFiles="$1"
shift
for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
# The target exists, back it up
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
$DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
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
'';
cleanup = pkgs.writeText "cleanup" ''
cleanup = pkgs.writeShellScript "cleanup" ''
. ${./lib-bash/color-echo.sh}
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*"
newGenFiles="$1"
shift 1
@ -235,31 +271,50 @@ in
);
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
''
let
homeDirArg = escapeShellArg homeDirectory;
in ''
function _cmp() {
if [[ -d $1 && -d $2 ]]; then
diff -rq "$1" "$2" &> /dev/null
else
cmp --quiet "$1" "$2"
fi
}
declare -A changedFiles
'' + concatMapStrings (v: ''
cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \
&& changedFiles["${v.target}"]=0 \
|| changedFiles["${v.target}"]=1
'') (filter (v: v.onChange != "") (attrValues cfg))
'' + concatMapStrings (v:
let
sourceArg = escapeShellArg (sourceStorePath v);
targetArg = escapeShellArg v.target;
in ''
_cmp ${sourceArg} ${homeDirArg}/${targetArg} \
&& changedFiles[${targetArg}]=0 \
|| changedFiles[${targetArg}]=1
'') (filter (v: v.onChange != "") (attrValues cfg))
+ ''
unset -f _cmp
''
);
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
concatMapStrings (v: ''
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then
${v.onChange}
if (( ''${changedFiles[${escapeShellArg v.target}]} == 1 )); then
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
'') (filter (v: v.onChange != "") (attrValues cfg))
);
# Symlink directories and files that have the right execute bit.
# Copy files that need their execute bit changed.
home-files = pkgs.runCommand
home-files = pkgs.runCommandLocal
"home-manager-files"
{
nativeBuildInputs = [ pkgs.xorg.lndir ];
preferLocalBuild = true;
allowSubstitutes = false;
}
(''
mkdir -p $out
@ -273,6 +328,15 @@ in
local executable="$3"
local recursive="$4"
# If the target already exists then we have a collision. Note, this
# should not happen due to the assertion found in the 'files' module.
# We therefore simply log the conflict and otherwise ignore it, mainly
# to make the `files-target-config` test work as expected.
if [[ -e "$realOut/$relTarget" ]]; then
echo "File conflict for file '$relTarget'" >&2
return
fi
# Figure out the real absolute path to the target.
local target
target="$(realpath -m "$realOut/$relTarget")"

@ -115,7 +115,7 @@ let
if versionAtLeast config.home.stateVersion "19.09"
then null
else "us";
defaultText = literalExample "null";
defaultText = literalExpression "null";
description = ''
Keyboard layout. If <literal>null</literal>, then the system
configuration will be used.
@ -149,7 +149,7 @@ let
if versionAtLeast config.home.stateVersion "19.09"
then null
else "";
defaultText = literalExample "null";
defaultText = literalExpression "null";
example = "colemak";
description = ''
X keyboard variant. If <literal>null</literal>, then the
@ -182,7 +182,7 @@ in
options = {
home.username = mkOption {
type = types.str;
defaultText = literalExample ''
defaultText = literalExpression ''
"$USER" for state version < 20.09,
undefined for state version 20.09
'';
@ -192,7 +192,7 @@ in
home.homeDirectory = mkOption {
type = types.path;
defaultText = literalExample ''
defaultText = literalExpression ''
"$HOME" for state version < 20.09,
undefined for state version 20.09
'';
@ -321,7 +321,7 @@ in
home.activation = mkOption {
type = hm.types.dagOf types.str;
default = {};
example = literalExample ''
example = literalExpression ''
{
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
@ -373,6 +373,16 @@ in
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 {
type = types.lines;
default = "";
@ -390,6 +400,21 @@ in
Extra commands to run in the Home Manager profile builder.
'';
};
home.enableNixpkgsReleaseCheck = mkOption {
type = types.bool;
default = true;
description = ''
Determines whether to check for release version mismatch between Home
Manager and Nixpkgs. Using mismatched versions is likely to cause errors
and unexpected behavior. It is therefore highly recommended to use a
release of Home Manager than corresponds with your chosen release of
Nixpkgs.
</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 = {
@ -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 =
mkIf (versionOlder config.home.stateVersion "20.09")
(mkDefault (builtins.getEnv "USER"));
@ -493,7 +543,24 @@ in
''
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
# script's PATH.
activationBinPaths = lib.makeBinPath [
pkgs.bash
pkgs.coreutils
pkgs.diffutils # For `cmp` and `diff`.
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
pkgs.ncurses # For `tput`.
]
activationBinPaths = lib.makeBinPath (
[
pkgs.bash
pkgs.coreutils
pkgs.diffutils # For `cmp` and `diff`.
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
pkgs.ncurses # For `tput`.
] ++ config.home.extraActivationPath
)
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
activationScript = pkgs.writeScript "activation-script" ''
#!${pkgs.runtimeShell}
activationScript = pkgs.writeShellScript "activation-script" ''
set -eu
set -o pipefail
@ -552,6 +619,9 @@ in
cp ${activationScript} $out/activate
mkdir $out/bin
ln -s $out/activate $out/bin/home-manager-generation
substituteInPlace $out/activate \
--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 gcPath="$nixStateDir/gcroots/per-user/$USER"
genProfilePath="$profilesPath/home-manager"
newGenPath="@GENERATION_DIR@";
newGenGcPath="$gcPath/current-home"
declare -gr genProfilePath="$profilesPath/home-manager"
declare -gr newGenPath="@GENERATION_DIR@";
declare -gr newGenGcPath="$gcPath/current-home"
local greatestGenNum
greatestGenNum=$( \
@ -16,14 +16,15 @@ function setupVars() {
| sed -E 's/ *([[:digit:]]+) .*/\1/')
if [[ -n $greatestGenNum ]] ; then
oldGenNum=$greatestGenNum
newGenNum=$((oldGenNum + 1))
declare -gr oldGenNum=$greatestGenNum
declare -gr newGenNum=$((oldGenNum + 1))
else
newGenNum=1
declare -gr newGenNum=1
fi
if [[ -e $profilesPath/home-manager ]] ; then
oldGenPath="$(readlink -e "$profilesPath/home-manager")"
declare -gr oldGenPath
fi
$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;
};
assertions = import ./assertions.nix { inherit lib; };
gvariant = import ./gvariant.nix { inherit lib; };
maintainers = import ./maintainers.nix;
strings = import ./strings.nix { inherit lib; };

@ -21,7 +21,7 @@ with lib;
absPath = if hasPrefix "/" p then p else "${basePath}/${p}";
in
removePrefix (homeDirectory + "/") absPath;
defaultText = literalExample "<name>";
defaultText = literalExpression "<name>";
description = ''
Path to target file relative to ${basePathDesc}.
'';
@ -82,6 +82,9 @@ with lib;
generations. The script will be run
<emphasis>after</emphasis> the new files have been linked
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;
isGVariant = v: v._type or "" == "gvariant";
isArray = hasPrefix "a";
isMaybe = hasPrefix "m";
isTuple = hasPrefix "(";
@ -122,8 +124,9 @@ in rec {
};
mkString = v:
mkPrimitive type.string v // {
__toString = self: "'${escape [ "'" "\\" ] self.value}'";
let sanitize = s: replaceStrings [ "\n" ] [ "\\n" ] (escape [ "'" "\\" ] s);
in mkPrimitive type.string v // {
__toString = self: "'${sanitize self.value}'";
};
mkObjectpath = v:

@ -25,12 +25,34 @@
github = "cwyc";
githubId = 16950437;
};
chisui = {
name = "Philipp Dargel";
email = "chisui@users.noreply.github.com";
github = "chisui";
githubId = 4526429;
};
olmokramer = {
name = "Olmo Kramer";
email = "olmokramer@users.noreply.github.com";
github = "olmokramer";
githubId = 3612514;
};
kalhauge = {
name = "Christian Gram Kalhauge";
email = "kalhauge@users.noreply.github.com";
github = "kalhauge";
githubId = 1182166;
};
kamadorueda = {
name = "Kevin Amado";
email = "kamadorueda@gmail.com";
github = "kamadorueda";
githubId = 47480384;
keys = [{
longkeyid = "rsa4096/0x04D0CEAF916A9A40";
fingerprint = "2BE3 BAFD 793E A349 ED1F F00F 04D0 CEAF 916A 9A40";
}];
};
kubukoz = {
name = "Jakub Kozłowski";
email = "kubukoz@users.noreply.github.com";
@ -53,16 +75,62 @@
fingerprint = "F0E0 0311 126A CD72 4392 25E6 68BF 2EAE 6D91 CAFF";
}];
};
thiagokokada = {
email = "thiagokokada@gmail.com";
name = "Thiago Kenji Okada";
github = "thiagokokada";
githubId = 844343;
};
fendse = {
email = "46252070+Fendse@users.noreply.github.com";
github = "Fendse";
githubId = 46252070;
name = "Sara Johnsson";
};
msfjarvis = {
email = "me@msfjarvis.dev";
github = "msfjarvis";
githubId = "13348378";
name = "Harsh Shandilya";
keys = [{
longkeyid = "rsa4096/0xB7843F823355E9B9";
fingerprint = "8F87 050B 0F9C B841 1515 7399 B784 3F82 3355 E9B9";
}];
};
ambroisie = {
email = "bruno.home-manager@belanyi.fr";
github = "ambroisie";
githubId = 12465195;
name = "Bruno BELANYI";
};
malvo = {
email = "malte@malvo.org";
github = "malte-v";
githubId = 34393802;
name = "Malte Voos";
};
kranzes = {
email = "personal@ilanjoselevich.com";
github = "Kranzes";
githubId = 56614642;
name = "Ilan Joselevich";
};
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:
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 {
type = types.nullOr types.package;
default = null;
example = literalExample "pkgs.dejavu_fonts";
example = literalExpression "pkgs.dejavu_fonts";
description = ''
Package providing the font. This package will be installed
to your profile. If <literal>null</literal> then the font
@ -47,9 +47,18 @@ in rec {
name = mkOption {
type = types.str;
example = "DejaVu Sans 8";
example = "DejaVu Sans";
description = ''
The family name and size of the font within the package.
The family name of the font within the package.
'';
};
size = mkOption {
type = types.nullOr types.int;
default = null;
example = "8";
description = ''
The size of the font.
'';
};
};
@ -61,7 +70,11 @@ in rec {
check = v: gvar.mkValue v != null;
merge = loc: defs:
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;
defTypes = map (x: x.type) vals;
sameOrNull = x: y: if x == y then y else null;
@ -73,8 +86,10 @@ in rec {
+ " mismatched GVariant types given in"
+ " ${showFiles (getFiles defs)}.")
else if gvar.isArray sharedDefType && allChecked then
(types.listOf gvariant).merge loc
(map (d: d // { value = d.value.value; }) vdefs)
gvar.mkValue ((types.listOf gvariant).merge loc
(map (d: d // { value = d.value.value; }) vdefs)) // {
type = sharedDefType;
}
else if gvar.isTuple sharedDefType && allChecked then
mergeOneOption loc defs
else if gvar.isMaybe sharedDefType && allChecked then

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

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

@ -36,22 +36,11 @@ in {
};
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 = [
(pkgs.writeTextFile {
name = "hm-dummy1";
destination = "/lib/fontconfig/hm-dummy1";
text = "dummy";
})
(pkgs.writeTextFile {
name = "hm-dummy2";
destination = "/lib/fontconfig/hm-dummy2";
text = "dummy";
})
# Make sure that buildEnv creates a real directory path so that we avoid
# trying to write to a read-only location.
(pkgs.runCommandLocal "dummy-fc-dir1" { } "mkdir -p $out/lib/fontconfig")
(pkgs.runCommandLocal "dummy-fc-dir2" { } "mkdir -p $out/lib/fontconfig")
];
home.extraProfileCommands = ''
@ -76,9 +65,10 @@ in {
unset FONTCONFIG_FILE
fi
# Remove hacky dummy files.
rm $out/lib/fontconfig/hm-dummy?
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
# Remove the fontconfig directory if no files were available.
if [[ -d $out/lib/fontconfig ]] ; then
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
fi
'';
xdg.configFile = {

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

@ -116,6 +116,9 @@ in
#
# date --iso-8601=second --universal
#
# On darwin (or BSD like systems) use
#
# date -u +'%Y-%m-%dT%H:%M:%S+00:00'
news.entries = [
{
time = "2017-09-01T10:56:28+00:00";
@ -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";
message = ''
@ -1863,6 +1849,7 @@ in
lists to polybar-style 'foo-0, foo-1, ...' lists.
'';
}
{
time = "2021-02-25T22:36:43+00:00";
condition = config.programs.git.enable && any (msmtp: msmtp.enable)
@ -1873,6 +1860,7 @@ in
'accounts.email.accounts.<name>.msmtp.enable' is true.
'';
}
{
time = "2021-03-03T22:16:05+00:00";
message = ''
@ -1880,6 +1868,371 @@ in
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
isConfig = x:
builtins.isAttrs x || builtins.isFunction x;
isConfig = x: builtins.isAttrs x || builtins.isFunction x;
optCall = f: x:
if builtins.isFunction f
then f x
else f;
optCall = f: x: if builtins.isFunction f then f x else f;
mergeConfig = lhs_: rhs_:
let
lhs = optCall lhs_ { inherit pkgs; };
rhs = optCall rhs_ { inherit pkgs; };
in
lhs // rhs //
optionalAttrs (lhs ? packageOverrides) {
in lhs // rhs // optionalAttrs (lhs ? packageOverrides) {
packageOverrides = pkgs:
optCall lhs.packageOverrides pkgs //
optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs;
} //
optionalAttrs (lhs ? perlPackageOverrides) {
optCall lhs.packageOverrides pkgs
// optCall (attrByPath [ "packageOverrides" ] ({ }) rhs) pkgs;
} // optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides = pkgs:
optCall lhs.perlPackageOverrides pkgs //
optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs;
optCall lhs.perlPackageOverrides pkgs
// optCall (attrByPath [ "perlPackageOverrides" ] ({ }) rhs) pkgs;
};
configType = mkOptionType {
name = "nixpkgs-config";
description = "nixpkgs config";
check = x:
let traceXIfNot = c:
if c x then true
else lib.traceSeqN 1 x false;
let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
in traceXIfNot isConfig;
merge = args: fold (def: mergeConfig def.value) {};
merge = args: fold (def: mergeConfig def.value) { };
};
overlayType = mkOptionType {
@ -49,13 +40,9 @@ let
merge = lib.mergeOneOption;
};
_pkgs = import pkgsPath (
filterAttrs (n: v: v != null) config.nixpkgs
);
_pkgs = import pkgsPath (filterAttrs (n: v: v != null) config.nixpkgs);
in
{
in {
options.nixpkgs = {
config = mkOption {
default = null;
@ -91,17 +78,16 @@ in
overlays = mkOption {
default = null;
example = literalExample
''
[ (self: super: {
openssh = super.openssh.override {
hpnSupport = true;
withKerberos = true;
kerberos = self.libkrb5;
};
example = literalExpression ''
[ (self: super: {
openssh = super.openssh.override {
hpnSupport = true;
withKerberos = true;
kerberos = self.libkrb5;
};
) ]
'';
};
) ]
'';
type = types.nullOr (types.listOf overlayType);
description = ''
List of overlays to use with the Nix Packages collection. (For
@ -144,9 +130,10 @@ in
_module.args = {
pkgs = mkOverride modules.defaultPriority _pkgs;
pkgs_i686 =
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
then _pkgs.pkgsi686Linux
else { };
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 then
_pkgs.pkgsi686Linux
else
{ };
};
};
}

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

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

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

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

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

@ -10,7 +10,9 @@ in {
options = {
xdg.mime.enable = mkOption {
type = types.bool;
default = true;
default = pkgs.hostPlatform.isLinux;
defaultText =
literalExpression "true if host platform is Linux, false otherwise";
description = ''
Whether to install programs and files to support the
XDG Shared MIME-info specification and XDG MIME Applications
@ -24,6 +26,9 @@ in {
};
config = mkIf config.xdg.mime.enable {
assertions =
[ (hm.assertions.assertPlatform "xdg.mime" pkgs platforms.linux) ];
home.packages = [
# Explicitly install package to provide basic mime types.
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"; };
description = "Other user directories.";
};
createDirectories =
mkEnableOption "automatic creation of the XDG user directories";
};
config = mkIf cfg.enable {
xdg.configFile."user-dirs.dirs".text = let
options = {
XDG_DESKTOP_DIR = cfg.desktop;
XDG_DOCUMENTS_DIR = cfg.documents;
XDG_DOWNLOAD_DIR = cfg.download;
XDG_MUSIC_DIR = cfg.music;
XDG_PICTURES_DIR = cfg.pictures;
XDG_PUBLICSHARE_DIR = cfg.publicShare;
XDG_TEMPLATES_DIR = cfg.templates;
XDG_VIDEOS_DIR = cfg.videos;
} // cfg.extraConfig;
config = let
directories = {
XDG_DESKTOP_DIR = cfg.desktop;
XDG_DOCUMENTS_DIR = cfg.documents;
XDG_DOWNLOAD_DIR = cfg.download;
XDG_MUSIC_DIR = cfg.music;
XDG_PICTURES_DIR = cfg.pictures;
XDG_PUBLICSHARE_DIR = cfg.publicShare;
XDG_TEMPLATES_DIR = cfg.templates;
XDG_VIDEOS_DIR = cfg.videos;
} // cfg.extraConfig;
in mkIf cfg.enable {
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.
wrapped = mapAttrs (_: value: ''"${value}"'') options;
wrapped = mapAttrs (_: value: ''"${value}"'') directories;
in generators.toKeyValue { } wrapped;
xdg.configFile."user-dirs.conf".text = "enabled=False";
home.activation = mkIf cfg.createDirectories {
createXdgUserDirectories = let
directoriesList = attrValues directories;
mkdir = (dir: ''$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "${dir}"'');
in lib.hm.dag.entryAfter [ "writeBoundary" ]
(strings.concatMapStringsSep "\n" mkdir directoriesList);
};
};
}

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

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

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

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

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

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

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

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

@ -22,9 +22,9 @@ let
sendmail = astroid.sendMailCommand;
additional_sent_tags = "";
default = boolOpt primary;
save_drafts_to = "${maildir.absPath}/${folders.drafts}";
save_drafts_to = "${maildir.absPath}/${folders.drafts}/cur/";
save_sent = "true";
save_sent_to = "${maildir.absPath}/${folders.sent}";
save_sent_to = "${maildir.absPath}/${folders.sent}/cur/";
select_query = "";
} // optionalAttrs (signature.showSignature != "none") {
signature_attach = boolOpt (signature.showSignature == "attach");
@ -93,7 +93,7 @@ in {
extraConfig = mkOption {
type = jsonFormat.type;
default = { };
example = literalExample ''
example = literalExpression ''
{
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 {
type = types.nullOr (matrixOf 3 3 types.float);
default = null;
example = literalExample ''
example = literalExpression ''
[
[ 0.6 0.0 0.0 ]
[ 0.0 0.6 0.0 ]
@ -169,7 +169,7 @@ let
exclusive.
'';
default = null;
example = literalExample ''
example = literalExpression ''
{
x = 1.25;
y = 1.25;
@ -280,7 +280,7 @@ in {
type = globalHooksModule;
description = "Global hook scripts";
default = { };
example = literalExample ''
example = literalExpression ''
{
postswitch = {
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
@ -312,7 +312,7 @@ in {
type = types.attrsOf profileModule;
description = "Autorandr profiles specification.";
default = { };
example = literalExample ''
example = literalExpression ''
{
"work" = {
fingerprint = {

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

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

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

@ -5,7 +5,9 @@ with lib;
let
browserModule = defaultPkg: name: visible:
let browser = (builtins.parseDrvName defaultPkg.name).name;
let
browser = (builtins.parseDrvName defaultPkg.name).name;
isProprietaryChrome = hasPrefix "Google Chrome" name;
in {
enable = mkOption {
inherit visible;
@ -19,10 +21,12 @@ let
inherit visible;
type = types.package;
default = defaultPkg;
defaultText = literalExample "pkgs.${browser}";
defaultText = literalExpression "pkgs.${browser}";
description = "The ${name} package to use.";
};
} // optionalAttrs (!isProprietaryChrome) {
# Extensions do not work with Google Chrome
# see https://github.com/nix-community/home-manager/issues/1383
extensions = mkOption {
inherit visible;
type = with types;
@ -68,7 +72,7 @@ let
};
in listOf (coercedTo str (v: { id = v; }) extensionType);
default = [ ];
example = literalExample ''
example = literalExpression ''
[
{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # ublock origin
{
@ -110,10 +114,12 @@ let
brave = "BraveSoftware/Brave-Browser";
};
linuxDirs = { brave = "BraveSoftware/Brave-Browser"; };
configDir = if pkgs.stdenv.isDarwin then
"Library/Application Support/${getAttr browser darwinDirs}"
"Library/Application Support/" + (darwinDirs."${browser}" or browser)
else
"${config.xdg.configHome}/${browser}";
"${config.xdg.configHome}/" + (linuxDirs."${browser}" or browser);
extensionJson = ext:
assert ext.crxPath != null -> ext.version != null;
@ -129,10 +135,19 @@ let
in mkIf cfg.enable {
home.packages = [ cfg.package ];
home.file = listToAttrs (map extensionJson cfg.extensions);
home.file = listToAttrs (map extensionJson (cfg.extensions or [ ]));
};
in {
# Extensions do not work with the proprietary Google Chrome version
# see https://github.com/nix-community/home-manager/issues/1383
imports = map (flip mkRemovedOptionModule
"The `extensions` option does not work on Google Chrome anymore.") [
[ "programs" "google-chrome" "extensions" ]
[ "programs" "google-chrome-beta" "extensions" ]
[ "programs" "google-chrome-dev" "extensions" ]
];
options.programs = {
chromium = browserModule pkgs.chromium "Chromium" true;
google-chrome = browserModule pkgs.google-chrome "Google Chrome" false;

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

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

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

@ -9,6 +9,14 @@ let
tomlFormat = pkgs.formats.toml { };
in {
imports = [
(mkRenamedOptionModule [
"programs"
"direnv"
"enableNixDirenvIntegration"
] [ "programs" "direnv" "nix-direnv" "enable" ])
];
meta.maintainers = [ maintainers.rycee ];
options.programs.direnv = {
@ -58,15 +66,22 @@ in {
enableFishIntegration = mkOption {
default = true;
type = types.bool;
readOnly = true;
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 ''
<link
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
a fast, persistent use_nix implementation for direnv'';
nix-direnv = {
enable = mkEnableOption ''
<link
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 {
@ -77,9 +92,11 @@ in {
};
xdg.configFile."direnv/direnvrc" = let
package =
pkgs.nix-direnv.override { inherit (cfg.nix-direnv) enableFlakes; };
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
++ optional cfg.enableNixDirenvIntegration
"source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc");
++ optional cfg.nix-direnv.enable
"source ${package}/share/nix-direnv/direnvrc");
in mkIf (text != "") { inherit text; };
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
@ -92,9 +109,5 @@ in {
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
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 {
type = types.package;
default = pkgs.eclipses.eclipse-platform;
defaultText = literalExample "pkgs.eclipses.eclipse-platform";
example = literalExample "pkgs.eclipses.eclipse-java";
defaultText = literalExpression "pkgs.eclipses.eclipse-platform";
example = literalExpression "pkgs.eclipses.eclipse-java";
description = ''
The Eclipse package to install.
'';

@ -13,6 +13,12 @@ let
emacsWithPackages = emacsPackages.emacsWithPackages;
createConfPackage = epkgs:
epkgs.trivialBuild {
pname = "default";
src = pkgs.writeText "default.el" cfg.extraConfig;
};
in {
meta.maintainers = [ maintainers.rycee ];
@ -23,16 +29,33 @@ in {
package = mkOption {
type = types.package;
default = pkgs.emacs;
defaultText = literalExample "pkgs.emacs";
example = literalExample "pkgs.emacs25-nox";
defaultText = literalExpression "pkgs.emacs";
example = literalExpression "pkgs.emacs25-nox";
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 {
default = self: [ ];
type = hm.types.selectorFunction;
defaultText = "epkgs: []";
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
example = literalExpression "epkgs: [ epkgs.emms epkgs.magit ]";
description = ''
Extra packages available to Emacs. To get a list of
available packages run:
@ -44,7 +67,7 @@ in {
default = self: super: { };
type = hm.types.overlayFunction;
defaultText = "self: super: {}";
example = literalExample ''
example = literalExpression ''
self: super: rec {
haskell-mode = self.melpaPackages.haskell-mode;
# ...
@ -68,6 +91,10 @@ in {
config = mkIf cfg.enable {
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;
mozillaConfigPath =
if isDarwin
then "Library/Application Support/Mozilla"
else ".mozilla";
if isDarwin then "Library/Application Support/Mozilla" else ".mozilla";
firefoxConfigPath =
if isDarwin
then "Library/Application Support/Firefox"
else "${mozillaConfigPath}/firefox";
firefoxConfigPath = if isDarwin then
"Library/Application Support/Firefox"
else
"${mozillaConfigPath}/firefox";
profilesPath =
if isDarwin
then "${firefoxConfigPath}/Profiles"
else firefoxConfigPath;
if isDarwin then "${firefoxConfigPath}/Profiles" else firefoxConfigPath;
# The extensions path shared by all profiles; will not be supported
# by future Firefox versions.
@ -32,46 +28,72 @@ let
paths = cfg.extensions;
};
profiles =
flip mapAttrs' cfg.profiles (_: profile:
nameValuePair "Profile${toString profile.id}" {
Name = profile.name;
Path =
if isDarwin
then "Profiles/${profile.path}"
else profile.path;
IsRelative = 1;
Default = if profile.isDefault then 1 else 0;
}
) // {
General = {
StartWithLastProfile = 1;
};
profiles = flip mapAttrs' cfg.profiles (_: profile:
nameValuePair "Profile${toString profile.id}" {
Name = profile.name;
Path = if isDarwin then "Profiles/${profile.path}" else profile.path;
IsRelative = 1;
Default = if profile.isDefault then 1 else 0;
}) // {
General = { StartWithLastProfile = 1; };
};
profilesIni = generators.toINI {} profiles;
mkUserJs = prefs: extraPrefs: ''
// Generated by Home Manager.
${concatStrings (mapAttrsToList (name: value: ''
user_pref("${name}", ${builtins.toJSON value});
'') prefs)}
${extraPrefs}
'';
in
{
profilesIni = generators.toINI { } profiles;
mkUserJs = prefs: extraPrefs: bookmarks:
let
prefs' = lib.optionalAttrs ({ } != bookmarks) {
"browser.bookmarks.file" = toString (firefoxBookmarksFile bookmarks);
"browser.places.importBookmarksHTML" = true;
} // prefs;
in ''
// Generated by Home Manager.
${concatStrings (mapAttrsToList (name: value: ''
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 ];
imports = [
(mkRemovedOptionModule ["programs" "firefox" "enableAdobeFlash"]
(mkRemovedOptionModule [ "programs" "firefox" "enableAdobeFlash" ]
"Support for this option has been removed.")
(mkRemovedOptionModule ["programs" "firefox" "enableGoogleTalk"]
(mkRemovedOptionModule [ "programs" "firefox" "enableGoogleTalk" ]
"Support for this option has been removed.")
(mkRemovedOptionModule ["programs" "firefox" "enableIcedTea"]
(mkRemovedOptionModule [ "programs" "firefox" "enableIcedTea" ]
"Support for this option has been removed.")
];
@ -81,11 +103,22 @@ in
package = mkOption {
type = types.package;
default =
if versionAtLeast config.home.stateVersion "19.09"
then pkgs.firefox
else pkgs.firefox-unwrapped;
defaultText = literalExample "pkgs.firefox";
default = if versionAtLeast config.home.stateVersion "19.09" then
pkgs.firefox
else
pkgs.firefox-unwrapped;
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 = ''
The Firefox package to use. If state version  19.09 then
this should be a wrapped Firefox package. For earlier state
@ -95,8 +128,8 @@ in
extensions = mkOption {
type = types.listOf types.package;
default = [];
example = literalExample ''
default = [ ];
example = literalExpression ''
with pkgs.nur.repos.rycee.firefox-addons; [
https-everywhere
privacy-badger
@ -130,7 +163,7 @@ in
};
profiles = mkOption {
type = types.attrsOf (types.submodule ({config, name, ...}: {
type = types.attrsOf (types.submodule ({ config, name, ... }: {
options = {
name = mkOption {
type = types.str;
@ -148,8 +181,8 @@ in
settings = mkOption {
type = with types; attrsOf (either bool (either int str));
default = {};
example = literalExample ''
default = { };
example = literalExpression ''
{
"browser.startup.homepage" = "https://nixos.org";
"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 {
type = types.str;
default = name;
@ -213,7 +285,7 @@ in
};
};
}));
default = {};
default = { };
description = "Attribute set of Firefox profiles.";
};
@ -232,95 +304,84 @@ in
config = mkIf cfg.enable {
assertions = [
(
let
defaults =
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
in {
assertion = cfg.profiles == {} || length defaults == 1;
message =
"Must have exactly one default Firefox profile but found "
+ 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}";
in {
assertion = duplicates == {};
message =
"Must not have Firefox profiles with duplicate IDs but\n"
+ concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
}
)
(let
defaults =
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
in {
assertion = cfg.profiles == { } || length defaults == 1;
message = "Must have exactly one default Firefox profile but found "
+ 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}";
in {
assertion = duplicates == { };
message = ''
Must not have Firefox profiles with duplicate IDs but
'' + concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
})
];
home.packages =
let
# The configuration expected by the Firefox wrapper.
fcfg = {
enableGnomeExtensions = cfg.enableGnomeExtensions;
};
warnings = optional (cfg.enableGnomeExtensions or false) ''
Using 'programs.firefox.enableGnomeExtensions' has been deprecated and
will be removed in the future. Please change to overriding the package
configuration using 'programs.firefox.package' instead. You can refer to
its example for how to do this.
'';
home.packages = let
# The configuration expected by the Firefox wrapper.
fcfg = { 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.
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 { 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 != { }) { text = profilesIni; };
}] ++ flip mapAttrsToList cfg.profiles (_: profile: {
"${profilesPath}/${profile.path}/.keep".text = "";
"${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) {
text = profilesIni;
};
}]
++ flip mapAttrsToList cfg.profiles (_: profile: {
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
mkIf (profile.userChrome != "") {
text = profile.userChrome;
};
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
mkIf (profile.userChrome != "") { text = profile.userChrome; };
"${profilesPath}/${profile.path}/chrome/userContent.css" =
mkIf (profile.userContent != "") {
text = profile.userContent;
};
"${profilesPath}/${profile.path}/chrome/userContent.css" =
mkIf (profile.userContent != "") { text = profile.userContent; };
"${profilesPath}/${profile.path}/user.js" =
mkIf (profile.settings != {} || profile.extraConfig != "") {
text = mkUserJs profile.settings profile.extraConfig;
};
"${profilesPath}/${profile.path}/user.js" =
mkIf (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}";
recursive = true;
force = true;
};
})
);
}));
};
}

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

Loading…
Cancel
Save