mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-13 11:19:27 +08:00
Compare commits
21 Commits
release-21
...
release-17
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2945576b7 | ||
|
|
bea5f92ec5 | ||
|
|
963de93c55 | ||
|
|
eda46344a0 | ||
|
|
5db56a320c | ||
|
|
698094b4d6 | ||
|
|
7943291ac4 | ||
|
|
59dee6a501 | ||
|
|
967d0f93a2 | ||
|
|
337168f47e | ||
|
|
124acb089c | ||
|
|
b9382832ad | ||
|
|
f7628e2996 | ||
|
|
467ba9cafd | ||
|
|
6730c32c98 | ||
|
|
b6affe8d57 | ||
|
|
ef5a8a5941 | ||
|
|
de2c181eae | ||
|
|
5fd31df9d3 | ||
|
|
61101184b4 | ||
|
|
474478c4a3 |
303
.github/CODEOWNERS
vendored
303
.github/CODEOWNERS
vendored
@@ -1,303 +0,0 @@
|
||||
* @rycee
|
||||
|
||||
/flake.nix @bqv @kisik21
|
||||
|
||||
/modules/home-environment.nix @rycee
|
||||
|
||||
/modules/misc/dconf.nix @gnidorah @rycee
|
||||
|
||||
/modules/misc/fontconfig.nix @rycee
|
||||
/tests/modules/misc/fontconfig @rycee
|
||||
|
||||
/modules/misc/gtk.nix @rycee
|
||||
|
||||
/modules/config/i18n.nix @midchildan
|
||||
/tests/modules/config/i18n @midchildan
|
||||
|
||||
/modules/misc/news.nix @rycee
|
||||
|
||||
/modules/misc/numlock.nix @evanjs
|
||||
/tests/modules/misc/numlock @evanjs
|
||||
|
||||
/modules/misc/pam.nix @rycee
|
||||
/tests/modules/misc/pam @rycee
|
||||
|
||||
/modules/misc/qt.nix @rycee
|
||||
|
||||
/modules/misc/submodule-support.nix @rycee
|
||||
|
||||
/modules/misc/tmpfiles.nix @dawidsowa
|
||||
|
||||
/modules/misc/vte.nix @rycee
|
||||
|
||||
/modules/misc/xdg-mime-apps.nix @pacien
|
||||
|
||||
/modules/misc/xdg-user-dirs.nix @pacien
|
||||
|
||||
/modules/misc/xdg-system-dirs.nix @tadfisher
|
||||
/tests/modules/misc/xdg/system-dirs.nix @tadfisher
|
||||
|
||||
/modules/programs/aria2.nix @JustinLovinger
|
||||
|
||||
/modules/programs/autojump.nix @evanjs
|
||||
/tests/modules/programs/autojump @evanjs
|
||||
|
||||
/modules/programs/autorandr.nix @uvNikita
|
||||
|
||||
/modules/programs/bash.nix @rycee
|
||||
|
||||
/modules/programs/bat.nix @marsam
|
||||
|
||||
/modules/programs/beets.nix @rycee
|
||||
|
||||
/modules/programs/broot.nix @aheaume
|
||||
|
||||
/modules/programs/dircolors.nix @JustinLovinger
|
||||
|
||||
/modules/programs/direnv.nix @rycee
|
||||
|
||||
/modules/programs/eclipse.nix @rycee
|
||||
|
||||
/modules/programs/emacs.nix @rycee
|
||||
|
||||
/modules/programs/exa.nix @kalhauge
|
||||
|
||||
/modules/programs/firefox.nix @rycee
|
||||
|
||||
/modules/programs/foot.nix @plabadens
|
||||
/tests/modules/programs/foot @plabadens
|
||||
|
||||
/modules/programs/gh.nix @Gerschtli
|
||||
/tests/modules/programs/gh @Gerschtli
|
||||
|
||||
/modules/programs/git.nix @rycee
|
||||
|
||||
/modules/programs/gnome-terminal.nix @rycee
|
||||
|
||||
/modules/programs/go.nix @rvolosatovs
|
||||
|
||||
/modules/programs/home-manager.nix @rycee
|
||||
|
||||
/modules/programs/htop.nix @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
|
||||
/tests/modules/programs/lf @owm111
|
||||
|
||||
/modules/programs/lieer.nix @tadfisher
|
||||
|
||||
/modules/programs/lsd.nix @marsam
|
||||
|
||||
/modules/programs/matplotlib.nix @rprospero
|
||||
|
||||
/modules/programs/mbsync.nix @KarlJoad
|
||||
/tests/modules/programs/mbsync @KarlJoad
|
||||
|
||||
/modules/programs/mcfly.nix @marsam
|
||||
|
||||
/modules/programs/mpv.nix @tadeokondrak @thiagokokada
|
||||
/tests/modules/programs/mpv @thiagokokada
|
||||
|
||||
/modules/programs/mu.nix @KarlJoad
|
||||
|
||||
/modules/programs/ncmpcpp.nix @olmokramer
|
||||
/tests/modules/programs/ncmpcpp @olmokramer
|
||||
/tests/modules/programs/ncmpcpp-linux @olmokramer
|
||||
|
||||
/modules/programs/ncspot.nix @marsam
|
||||
|
||||
/modules/programs/ne.nix @cwyc
|
||||
/tests/modules/programs/ne @cwyc
|
||||
|
||||
/modules/programs/newsboat.nix @sumnerevans
|
||||
/tests/modules/programs/newsboat @sumnerevans
|
||||
|
||||
/modules/programs/nix-index.nix @ambroisie
|
||||
/tests/modules/programs/nix-index @ambroisie
|
||||
|
||||
/modules/programs/noti.nix @marsam
|
||||
|
||||
/modules/programs/nushell.nix @Philipp-M
|
||||
/tests/modules/programs/nushell @Philipp-M
|
||||
|
||||
/modules/programs/obs-studio.nix @adisbladis
|
||||
|
||||
/modules/programs/octant.nix @06kellyjac
|
||||
|
||||
/modules/programs/opam.nix @marsam
|
||||
|
||||
/modules/programs/openssh.nix @rycee
|
||||
|
||||
/modules/programs/password-store.nix @pacien
|
||||
|
||||
/modules/programs/pazi.nix @marsam
|
||||
|
||||
/modules/programs/pidgin.nix @rycee
|
||||
|
||||
/modules/programs/powerline-go.nix @DamienCassou
|
||||
|
||||
/modules/programs/rofi.nix @thiagokokada
|
||||
/tests/modules/programs/rofi @thiagokokada
|
||||
|
||||
/modules/programs/rofi-pass.nix @seylerius
|
||||
/tests/modules/programs/rofi-pass @seylerius
|
||||
|
||||
/modules/programs/rtorrent.nix @marsam
|
||||
|
||||
/modules/programs/sbt.nix @kubukoz
|
||||
/tests/modules/programs/sbt @kubukoz
|
||||
|
||||
/modules/programs/scmpuff.nix @cpcloud
|
||||
/tests/modules/programs/scmpuff @cpcloud
|
||||
|
||||
/modules/programs/ssh.nix @rycee
|
||||
|
||||
/modules/programs/starship.nix @marsam
|
||||
|
||||
/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/z-lua.nix @marsam
|
||||
|
||||
/modules/programs/zathura.nix @rprospero
|
||||
|
||||
/modules/programs/zoxide.nix @marsam
|
||||
|
||||
/modules/programs/zsh/prezto.nix @NickHu
|
||||
|
||||
/modules/services/barrier.nix @Kritnich
|
||||
/tests/modules/services/barrier @Kritnich
|
||||
|
||||
/modules/services/caffeine.nix @uvNikita
|
||||
|
||||
/modules/services/cbatticon.nix @pmiddend
|
||||
|
||||
/modules/services/clipmenu.nix @DamienCassou
|
||||
|
||||
/modules/services/dropbox.nix @eyJhb
|
||||
/tests/modules/services/dropbox @eyJhb
|
||||
|
||||
/modules/services/dunst.nix @rycee
|
||||
|
||||
/modules/services/emacs.nix @tadfisher
|
||||
|
||||
/modules/services/etesync-dav.nix @Valodim
|
||||
|
||||
/modules/services/flameshot.nix @moredhel
|
||||
|
||||
/modules/services/fluidsynth.nix @Valodim
|
||||
|
||||
/modules/services/gnome-keyring.nix @rycee
|
||||
|
||||
/modules/services/gpg-agent.nix @rycee
|
||||
|
||||
/modules/services/grobi.nix @mbrgm
|
||||
|
||||
/modules/services/hound.nix @adisbladis
|
||||
|
||||
/modules/services/imapnotify.nix @nickhu
|
||||
|
||||
/modules/services/kanshi.nix @nurelin
|
||||
/tests/modules/services/kanshi @nurelin
|
||||
|
||||
/modules/services/kdeconnect.nix @adisbladis
|
||||
|
||||
/modules/services/keepassx.nix @rycee
|
||||
|
||||
/modules/services/lieer.nix @tadfisher
|
||||
|
||||
/modules/services/lorri.nix @Gerschtli
|
||||
|
||||
/modules/services/mako.nix @onny
|
||||
|
||||
/modules/services/mbsync.nix @pjones
|
||||
|
||||
/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/parcellite.nix @gleber
|
||||
|
||||
/modules/services/pass-secret-service.nix @cab404
|
||||
|
||||
/modules/services/password-store-sync.nix @pacien
|
||||
|
||||
/modules/services/pasystray.nix @pltanton
|
||||
|
||||
/modules/services/pbgopy.nix @ivarwithoutbones
|
||||
/tests/modules/services/pbgopy @ivarwithoutbones
|
||||
|
||||
/modules/services/plan9port.nix @ehmry
|
||||
|
||||
/modules/services/playerctld.nix @fendse
|
||||
/tests/modules/playerctld @fendse
|
||||
|
||||
/modules/services/poweralertd.nix @ThibautMarty
|
||||
|
||||
/modules/services/pulseeffects.nix @jonringer
|
||||
|
||||
/modules/services/random-background.nix @rycee
|
||||
|
||||
/modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada
|
||||
/tests/modules/redshift-gammastep @thiagokokada
|
||||
|
||||
/modules/services/status-notifier-watcher.nix @pltanton
|
||||
|
||||
/modules/services/syncthing.nix @rycee
|
||||
|
||||
/modules/services/taffybar.nix @rycee
|
||||
|
||||
/modules/services/tahoe-lafs.nix @rycee
|
||||
|
||||
/modules/services/taskwarrior-sync.nix @minijackson @pacien
|
||||
|
||||
/modules/services/udiskie.nix @rycee
|
||||
|
||||
/modules/services/unison.nix @pacien
|
||||
|
||||
/modules/services/window-managers/i3-sway/i3.nix @sumnerevans
|
||||
/tests/modules/services/window-managers/i3 @sumnerevans
|
||||
|
||||
/modules/services/window-managers/i3-sway/lib @sumnerevans
|
||||
|
||||
/modules/services/window-managers/i3-sway/sway.nix @alexarice @sumnerevans
|
||||
/tests/modules/services/window-managers/sway @sumnerevans
|
||||
|
||||
/modules/services/wlsunset.nix @matrss
|
||||
/tests/modules/services/wlsunset @matrss
|
||||
|
||||
/modules/services/xcape.nix @nickhu
|
||||
|
||||
/modules/services/xembed-sni-proxy.nix @rycee
|
||||
|
||||
/modules/services/xscreensaver.nix @rycee
|
||||
|
||||
/modules/services/xsuspender.nix @offlinehacker
|
||||
|
||||
/modules/systemd.nix @rycee
|
||||
|
||||
/modules/xcursor.nix @league
|
||||
|
||||
/modules/xresources.nix @rycee
|
||||
|
||||
/modules/xsession.nix @rycee
|
||||
31
.github/ISSUE_TEMPLATE.md
vendored
31
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,31 +0,0 @@
|
||||
<!--
|
||||
|
||||
Don't forget to 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 at irc.oftc.net or Matrix room
|
||||
https://matrix.to/#/#hm:rycee.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.
|
||||
-->
|
||||
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,44 +0,0 @@
|
||||
### Description
|
||||
|
||||
<!--
|
||||
|
||||
Please provide a brief description of your change.
|
||||
|
||||
-->
|
||||
|
||||
### Checklist
|
||||
|
||||
<!--
|
||||
|
||||
Please go through the following checklist before opening a non-WIP
|
||||
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
|
||||
|
||||
-->
|
||||
|
||||
- [ ] Change is backwards compatible.
|
||||
|
||||
- [ ] Code formatted with `./format`.
|
||||
|
||||
- [ ] Code tested through `nix-shell --pure tests -A run.all`.
|
||||
|
||||
- [ ] Test cases updated/added. See [example](https://github.com/nix-community/home-manager/commit/f3fbb50b68df20da47f9b0def5607857fcc0d021#diff-b61a6d542f9036550ba9c401c80f00ef).
|
||||
|
||||
- [ ] Commit messages are formatted like
|
||||
|
||||
```
|
||||
{component}: {description}
|
||||
|
||||
{long description}
|
||||
```
|
||||
|
||||
See [CONTRIBUTING](https://github.com/nix-community/home-manager/blob/master/doc/contributing.adoc#sec-commit-style) for more information and [recent commit messages](https://github.com/nix-community/home-manager/commits/master) for examples.
|
||||
|
||||
- If this PR adds a new module
|
||||
|
||||
- [ ] Added myself as module maintainer. See [example](https://github.com/nix-community/home-manager/blob/068ff76a10e95820f886ac46957edcff4e44621d/modules/programs/lesspipe.nix#L6).
|
||||
|
||||
- [ ] Added myself and the module files to `.github/CODEOWNERS`.
|
||||
17
.github/dependabot.yml
vendored
17
.github/dependabot.yml
vendored
@@ -1,17 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "master"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci:"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "release-20.09"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci:"
|
||||
75
.github/stale.yml
vendored
75
.github/stale.yml
vendored
@@ -1,75 +0,0 @@
|
||||
# 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>
|
||||
28
.github/workflows/github_pages.yml
vendored
28
.github/workflows/github_pages.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: GitHub Pages
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
publish:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v16
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: nix-community
|
||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||
- run: |
|
||||
nix-build -A docs.html
|
||||
cp -r result/share/doc/home-manager public
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./public
|
||||
24
.github/workflows/test.yml
vendored
24
.github/workflows/test.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Test
|
||||
on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "30 2 * * *"
|
||||
jobs:
|
||||
tests:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v16
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.3.16/install
|
||||
nix_path: nixpkgs=channel:nixos-21.05
|
||||
- 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
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
/flake.lock
|
||||
/result*
|
||||
@@ -1,43 +0,0 @@
|
||||
image: nixos/nix:latest
|
||||
|
||||
variables:
|
||||
NIX_PATH: "nixpkgs=channel:nixos-unstable"
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
Run tests:
|
||||
stage: test
|
||||
script:
|
||||
- nix-shell --pure tests -A run.files-text
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "master"
|
||||
when: always
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
script:
|
||||
- mkdir -p ~/.config/nixpkgs
|
||||
- echo '{ manual.html.enable = true; }' > ~/.config/nixpkgs/home.nix
|
||||
- nix-shell . -A install
|
||||
- mkdir public
|
||||
- cp -r ~/.nix-profile/share/doc/home-manager/* public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "master"
|
||||
when: always
|
||||
|
||||
Deploy NUR:
|
||||
stage: deploy
|
||||
variables:
|
||||
HM_BRANCH: $CI_COMMIT_REF_NAME
|
||||
HM_COMMIT_SHA: $CI_COMMIT_SHA
|
||||
trigger:
|
||||
project: rycee/nur-expressions
|
||||
branch: master
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH =~ /^release-/
|
||||
when: always
|
||||
13
.travis.yml
Normal file
13
.travis.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
language: nix
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
before_script:
|
||||
- mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
|
||||
- mkdir -p ~/.config/nixpkgs
|
||||
- echo "{}" > ~/.config/nixpkgs/home.nix
|
||||
|
||||
script:
|
||||
nix-shell . -A install
|
||||
@@ -1 +0,0 @@
|
||||
doc/contributing.adoc
|
||||
158
CONTRIBUTING.md
Normal file
158
CONTRIBUTING.md
Normal file
@@ -0,0 +1,158 @@
|
||||
Contributing
|
||||
============
|
||||
|
||||
Thanks for wanting to contribute to Home Manager! These are some
|
||||
guidelines to make the process as smooth as possible for both you and
|
||||
the Home Manager developers.
|
||||
|
||||
If you are only looking to report a problem then it is sufficient to
|
||||
read through the following section on reporting issues. If you instead
|
||||
want to directly contribute improvements and additions then please
|
||||
have a look at everything here.
|
||||
|
||||
Reporting an issue
|
||||
------------------
|
||||
|
||||
If you notice a problem with Home Manager and want to report it then
|
||||
have a look among the already [open issues][], if you find one
|
||||
matching yours then feel free to comment on it to add any additional
|
||||
information you may have.
|
||||
|
||||
If no matching issue exists then go to the [new issue][] page and
|
||||
write a description of your problem. Include as much information as
|
||||
you can, ideally also include relevant excerpts from your Home Manager
|
||||
configuration.
|
||||
|
||||
Contributing code
|
||||
-----------------
|
||||
|
||||
If you want to contribute code to improve Home Manager then please
|
||||
follow these guidelines.
|
||||
|
||||
### Fork and create a pull request ###
|
||||
|
||||
If you have not previously forked Home Manager then you need to do
|
||||
that first. Have a look at GitHub's "[Fork A Repo][]" for instructions
|
||||
on how to do this.
|
||||
|
||||
Once you have a fork of Home Manager you should create a branch
|
||||
starting at the most recent `master`. Give your branch a reasonably
|
||||
descriptive name. Perform your changes on this branch and when you are
|
||||
happy with the result push the branch to GitHub and
|
||||
[create a pull request][].
|
||||
|
||||
Assuming your clone is at `$HOME/devel/home-manager` then you can make
|
||||
the `home-manager` command use it by either
|
||||
|
||||
1. overriding the default path by using the `-I` command line option:
|
||||
|
||||
home-manager -I home-manager=$HOME/devel/home-manager
|
||||
|
||||
or
|
||||
|
||||
2. changing the default path by ensuring your configuration includes
|
||||
|
||||
programs.home-manager.enable = true;
|
||||
programs.home-manager.path = "$HOME/devel/home-manager";
|
||||
|
||||
and running `home-manager switch` to activate the change.
|
||||
Afterwards, `home-manager build` and `home-manager switch` will
|
||||
use your cloned repository.
|
||||
|
||||
The first option is good if you only temporarily want to use your
|
||||
clone.
|
||||
|
||||
### Commits ###
|
||||
|
||||
The commits in your pull request should be reasonably self-contained,
|
||||
that is, each commit should make sense in isolation. In particular,
|
||||
you will be asked to amend any commit that introduces syntax errors or
|
||||
similar problems even if they are fixed in a later commit.
|
||||
|
||||
The commit messages should follow the format
|
||||
|
||||
{component}: {description}
|
||||
|
||||
{long description}
|
||||
|
||||
where `{component}` refers to the code component (or module) your
|
||||
change affects, `{description}` is a 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.
|
||||
|
||||
When adding a new module, say `foo.nix`, we use the fixed commit
|
||||
format `foo: add module`. You can, of course, still include a long
|
||||
description if you wish.
|
||||
|
||||
In addition to the above commit message guidelines, try to follow the
|
||||
[seven rules][] as much as possible.
|
||||
|
||||
### Style guidelines ###
|
||||
|
||||
The code in Home Manager should follow the [Nixpkgs syntax
|
||||
guidelines][]. Note, we prefer `lowerCamelCase` for variable and
|
||||
attribute names with the accepted exception of variables directly
|
||||
referencing packages in Nixpkgs which use a hyphenated style. For
|
||||
example, the Home Manager option `services.gpg-agent.enableSshSupport`
|
||||
references the `gpg-agent` package in Nixpkgs.
|
||||
|
||||
### News ###
|
||||
|
||||
Home Manager includes a system for presenting news to the user. When
|
||||
making a change you, therefore, have the option to also include an
|
||||
associated news entry. In general, a news entry should only be added
|
||||
for truly noteworthy news. For example, a bug fix or new option does
|
||||
generally not need a news entry.
|
||||
|
||||
If you do have a change worthy of a news entry then please add one in
|
||||
[`news.nix`][] but you should follow some basic guidelines:
|
||||
|
||||
- The entry timestamp should be in ISO-8601 format having "+00:00" as
|
||||
time zone. For example, "2017-09-13T17:10:14+00:00". A suitable
|
||||
timestamp can be produced by the command
|
||||
|
||||
date --iso-8601=second --universal
|
||||
|
||||
- The entry condition should be as specific as possible. For example,
|
||||
if you are changing or deprecating a specific option then you could
|
||||
restrict the news to those users who actually use this option.
|
||||
|
||||
- Wrap the news message so that it will fit in the typical terminal,
|
||||
that is, at most 80 characters wide. Ideally a bit less.
|
||||
|
||||
- Unlike commit messages, news will be read without any connection to
|
||||
the Home Manager source code. It is therefore important to make the
|
||||
message understandable in isolation and to those who do not have
|
||||
knowledge of the Home Manager internals. To this end it should be
|
||||
written in more descriptive, prose like way.
|
||||
|
||||
- If you refer to an option then write its full attribute path. That
|
||||
is, instead of writing
|
||||
|
||||
> The option 'foo' has been deprecated, please use 'bar' instead.
|
||||
|
||||
it should read
|
||||
|
||||
> The option 'services.myservice.foo' has been deprecated, please
|
||||
> use 'services.myservice.bar' instead.
|
||||
|
||||
- A new module, say `foo.nix`, should always include a news entry
|
||||
(without any condition) that has a message along the lines of
|
||||
|
||||
> A new service is available: 'services.foo'.
|
||||
|
||||
or
|
||||
|
||||
> A new program configuration is available: 'program.foo'.
|
||||
|
||||
depending on the type of module.
|
||||
|
||||
[open issues]: https://github.com/rycee/home-manager/issues
|
||||
[new issue]: https://github.com/rycee/home-manager/issues/new
|
||||
[Fork A Repo]: https://help.github.com/articles/fork-a-repo/
|
||||
[create a pull request]: https://help.github.com/articles/creating-a-pull-request/
|
||||
[seven rules]: https://chris.beams.io/posts/git-commit/#seven-rules
|
||||
[`news.nix`]: https://github.com/rycee/home-manager/blob/master/modules/misc/news.nix
|
||||
[Nixpkgs syntax guidelines]: https://nixos.org/nixpkgs/manual/#sec-syntax
|
||||
66
FAQ.md
Normal file
66
FAQ.md
Normal file
@@ -0,0 +1,66 @@
|
||||
Frequently Asked Questions (FAQ)
|
||||
================================
|
||||
|
||||
Why is there a collision error when switching generation?
|
||||
---------------------------------------------------------
|
||||
|
||||
Home Manager currently installs packages into the user environment,
|
||||
precisely as if the packages were installed through
|
||||
`nix-env --install`. This means that you will get a collision error if
|
||||
your Home Manager configuration attempts to install a package that you
|
||||
already have installed manually, that is, packages that shows up when
|
||||
you run `nix-env --query`.
|
||||
|
||||
For example, imagine you have the `hello` package installed in your
|
||||
environment
|
||||
|
||||
```console
|
||||
$ nix-env --query
|
||||
hello-2.10
|
||||
```
|
||||
|
||||
and your Home Manager configuration contains
|
||||
|
||||
home.packages = [ pkgs.hello ];
|
||||
|
||||
Then attempting to switch to this configuration will result in an
|
||||
error similar to
|
||||
|
||||
```console
|
||||
$ home-manager switch
|
||||
these derivations will be built:
|
||||
/nix/store/xg69wsnd1rp8xgs9qfsjal017nf0ldhm-home-manager-path.drv
|
||||
[…]
|
||||
Activating installPackages
|
||||
replacing old ‘home-manager-path’
|
||||
installing ‘home-manager-path’
|
||||
building path(s) ‘/nix/store/b5c0asjz9f06l52l9812w6k39ifr49jj-user-environment’
|
||||
Wide character in die at /nix/store/64jc9gd2rkbgdb4yjx3nrgc91bpjj5ky-buildenv.pl line 79.
|
||||
collision between ‘/nix/store/fmwa4axzghz11cnln5absh31nbhs9lq1-home-manager-path/bin/hello’ and ‘/nix/store/c2wyl8b9p4afivpcz8jplc9kis8rj36d-hello-2.10/bin/hello’; use ‘nix-env --set-flag priority NUMBER PKGNAME’ to change the priority of one of the conflicting packages
|
||||
builder for ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed with exit code 2
|
||||
error: build of ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed
|
||||
```
|
||||
|
||||
The solution is typically to uninstall the package from the
|
||||
environment using `nix-env --uninstall` and reattempt the Home Manager
|
||||
generation switch.
|
||||
|
||||
Why are the session variables not set?
|
||||
--------------------------------------
|
||||
|
||||
Home Manager is only able to set session variables automatically if it
|
||||
manages your Bash or Z shell configuration. If you don't want to let
|
||||
Home Manager manage your shell then you will have to manually source
|
||||
the
|
||||
|
||||
~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
|
||||
file in an appropriate way. In Bash and Z shell this can be done by
|
||||
adding
|
||||
|
||||
```sh
|
||||
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
```
|
||||
|
||||
to your `.profile` and `.zshrc` files, respectively. The
|
||||
`hm-session-vars.sh` file should work in most Bourne-like shells.
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2020 Home Manager contributors
|
||||
Copyright (c) 2017-2018 Robert Helgesson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
205
README.md
205
README.md
@@ -3,36 +3,23 @@ Home Manager using Nix
|
||||
|
||||
This project provides a basic system for managing a user environment
|
||||
using the [Nix][] package manager together with the Nix libraries
|
||||
found in [Nixpkgs][]. It allows declarative configuration of user
|
||||
specific (non global) packages and dotfiles.
|
||||
|
||||
Before attempting to use Home Manager please read the warning below.
|
||||
|
||||
For a more systematic overview of Home Manager and its available
|
||||
options, please see the [Home Manager manual][manual].
|
||||
found in [Nixpkgs][]. Before attempting to use Home Manager please
|
||||
read the warning below.
|
||||
|
||||
Words of warning
|
||||
----------------
|
||||
|
||||
Unfortunately, it is quite possible to get difficult to understand
|
||||
errors when working with Home Manager, such as infinite loops with no
|
||||
clear source reference. You should therefore be comfortable using the
|
||||
Nix language and the various tools in the Nix ecosystem. Reading
|
||||
through the [Nix Pills][] document is a good way to familiarize
|
||||
yourself with them.
|
||||
|
||||
If you are not very familiar with Nix but still want to use Home
|
||||
Manager then you are strongly encouraged to start with a small and
|
||||
very simple configuration and gradually make it more elaborate as you
|
||||
learn.
|
||||
This project is under development. I personally use it to manage
|
||||
several user configurations but it may fail catastrophically for you.
|
||||
So beware!
|
||||
|
||||
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 overwritten was from a previous Home Manager
|
||||
that it is about to be overwrite was from a previous Home Manager
|
||||
generation or from manual configuration.
|
||||
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 21.05 (the
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 17.09 (the
|
||||
current stable version), it may or may not work on other Linux
|
||||
distributions and NixOS versions.
|
||||
|
||||
@@ -44,72 +31,73 @@ on how to manually perform a rollback.
|
||||
Now when your expectations have been built up and you are eager to try
|
||||
all this out you can go ahead and read the rest of this text.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
You can chat with us on IRC in the channel [#home-manager][] on
|
||||
[OFTC][].
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Currently the easiest way to install Home Manager is as follows:
|
||||
|
||||
1. Make sure you have a working Nix installation. Specifically, make
|
||||
sure that your user is able to build and install Nix packages. For
|
||||
example, you should be able to successfully run a command like
|
||||
`nix-instantiate '<nixpkgs>' -A hello` without having to switch to
|
||||
the root user. For a multi-user install of Nix this means that
|
||||
your user must be covered by the
|
||||
[`allowed-users`][nixAllowedUsers] Nix option. On NixOS you can
|
||||
control this option using the
|
||||
1. Make sure you have a working Nix installation. If you are not
|
||||
using NixOS then you may here have to run
|
||||
|
||||
```console
|
||||
$ mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
|
||||
```
|
||||
|
||||
since Home Manager uses these directories to manage your profile
|
||||
generations. On NixOS these should already be available.
|
||||
|
||||
Also make sure that your user is able to build and install Nix
|
||||
packages. For example, you should be able to successfully run a
|
||||
command like `nix-instantiate '<nixpkgs>' -A hello`. For a
|
||||
multi-user install of Nix this means that your user must be
|
||||
covered by the [`allowed-users`][nixAllowedUsers] Nix option. On
|
||||
NixOS you can control this option using the
|
||||
[`nix.allowedUsers`][nixosAllowedUsers] system option.
|
||||
|
||||
Note that Nix 2.4 (`nixUnstable`) is not yet supported.
|
||||
|
||||
2. Add the appropriate Home Manager channel. If you are following
|
||||
Nixpkgs master or an unstable channel you can run
|
||||
2. Assign a temporary variable holding the URL to the appropriate
|
||||
archive. Typically this is
|
||||
|
||||
```console
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
$ HM_PATH=https://github.com/rycee/home-manager/archive/master.tar.gz
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 21.05 channel you can run
|
||||
or
|
||||
|
||||
```console
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
$ HM_PATH=https://github.com/rycee/home-manager/archive/release-17.09.tar.gz
|
||||
```
|
||||
|
||||
On NixOS you may need to log out and back in for the channel to
|
||||
become available. On non-NixOS you may have to add
|
||||
depending on whether you follow Nixpkgs unstable or version 17.09.
|
||||
|
||||
```shell
|
||||
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||
```
|
||||
|
||||
to your shell (see [nix#2033](https://github.com/NixOS/nix/issues/2033)).
|
||||
|
||||
3. Install Home Manager and create the first Home Manager generation:
|
||||
3. Create an initial Home Manager configuration file:
|
||||
|
||||
```console
|
||||
$ nix-shell '<home-manager>' -A install
|
||||
$ cat > ~/.config/nixpkgs/home.nix <<EOF
|
||||
{
|
||||
programs.home-manager.enable = true;
|
||||
programs.home-manager.path = $HM_PATH;
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
Once finished, Home Manager should be active and available in your
|
||||
user environment.
|
||||
4. Install Home Manager and create the first Home Manager generation:
|
||||
|
||||
3. If you do not plan on having Home Manager manage your shell
|
||||
```console
|
||||
$ nix-shell $HM_PATH -A install
|
||||
```
|
||||
|
||||
Home Manager should now be active and available in your user
|
||||
environment.
|
||||
|
||||
5. If you do not plan on having Home Manager manage your shell
|
||||
configuration then you must source the
|
||||
|
||||
```
|
||||
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
"$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. Unfortunately, we currently only
|
||||
support POSIX.2-like shells such as [Bash][] or [Z shell][].
|
||||
|
||||
For example, if you use Bash then add
|
||||
|
||||
@@ -117,19 +105,13 @@ Currently the easiest way to install Home Manager is as follows:
|
||||
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
```
|
||||
|
||||
or this when managing home configuration together with system
|
||||
configuration
|
||||
|
||||
```bash
|
||||
. "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh"
|
||||
```
|
||||
|
||||
to your `~/.profile` file.
|
||||
|
||||
If instead of using channels you want to run Home Manager from a Git
|
||||
checkout of the repository then you can use the
|
||||
`programs.home-manager.path` option to specify the absolute path to
|
||||
the repository.
|
||||
Note, because the `HM_PATH` variable above points to the live Home
|
||||
Manager repository you will automatically get updates whenever you
|
||||
build a new generation. If you dislike automatic updates then perform
|
||||
a Git clone of the desired branch and instead do the above steps with
|
||||
`HM_PATH` set to the _absolute path_ of your clone.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@@ -141,8 +123,8 @@ configuration generations.
|
||||
|
||||
As an example, let us expand the initial configuration file from the
|
||||
installation above to install the htop and fortune packages, install
|
||||
Emacs with a few extra packages enabled, install Firefox with
|
||||
smooth scrolling disabled, and enable the user gpg-agent service.
|
||||
Emacs with a few extra packages enabled, install Firefox with the
|
||||
IcedTea plugin enabled, and enable the user gpg-agent service.
|
||||
|
||||
To satisfy the above setup we should elaborate the
|
||||
`~/.config/nixpkgs/home.nix` file as follows:
|
||||
@@ -166,13 +148,7 @@ To satisfy the above setup we should elaborate the
|
||||
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
profiles = {
|
||||
myprofile = {
|
||||
settings = {
|
||||
"general.smoothScroll" = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
enableIcedTea = true;
|
||||
};
|
||||
|
||||
services.gpg-agent = {
|
||||
@@ -203,9 +179,8 @@ $ home-manager build
|
||||
which will create a `result` link to a directory containing an
|
||||
activation script and the generated home directory files.
|
||||
|
||||
Documentation of available configuration options, including
|
||||
descriptions and usage examples, is available in the [Home Manager
|
||||
manual][configuration options] or offline by running
|
||||
To see available configuration options with descriptions and usage
|
||||
examples run
|
||||
|
||||
```console
|
||||
$ man home-configuration.nix
|
||||
@@ -256,7 +231,7 @@ such collision is detected the activation will terminate before
|
||||
changing anything on your computer.
|
||||
|
||||
For example, suppose you have a wonderful, painstakingly created
|
||||
`~/.config/git/config` and add
|
||||
`~/.gitconfig` and add
|
||||
|
||||
```nix
|
||||
{
|
||||
@@ -279,7 +254,7 @@ then result in
|
||||
$ home-manager switch
|
||||
…
|
||||
Activating checkLinkTargets
|
||||
Existing file '/home/jdoe/.config/git/config' is in the way
|
||||
Existing file '/home/jdoe/.gitconfig' is in the way
|
||||
Please move the above files and try again
|
||||
```
|
||||
|
||||
@@ -317,59 +292,6 @@ in your system configuration and
|
||||
|
||||
in your Home Manager configuration.
|
||||
|
||||
Nix Flakes
|
||||
----------
|
||||
|
||||
Home Manager includes a `flake.nix` file for compatibility with [Nix Flakes][]
|
||||
for those that wish to use it as a module. A bare-minimum `flake.nix` would be
|
||||
as follows:
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
};
|
||||
|
||||
outputs = { home-manager, nixpkgs, ... }: {
|
||||
nixosConfigurations = {
|
||||
hostname = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./configuration.nix
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.jdoe = import ./home.nix;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Note, the Home Manager library is exported by the flake under
|
||||
`lib.hm`.
|
||||
|
||||
When using flakes, switch to new configurations as you do for the
|
||||
whole system (e. g. `nixos-rebuild switch --flake <path>`) instead of
|
||||
using the `home-manager` command line tool.
|
||||
|
||||
Releases
|
||||
--------
|
||||
|
||||
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-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.
|
||||
|
||||
[Bash]: https://www.gnu.org/software/bash/
|
||||
[Nix]: https://nixos.org/nix/
|
||||
[NixOS]: https://nixos.org/
|
||||
@@ -377,10 +299,3 @@ an issue.
|
||||
[nixAllowedUsers]: https://nixos.org/nix/manual/#conf-allowed-users
|
||||
[nixosAllowedUsers]: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers
|
||||
[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.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
|
||||
|
||||
18
default.nix
18
default.nix
@@ -1,18 +1,14 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
rec {
|
||||
docs = with import ./doc { inherit pkgs; }; {
|
||||
html = manual.html;
|
||||
manPages = manPages;
|
||||
json = options.json;
|
||||
home-manager = import ./home-manager {
|
||||
inherit pkgs;
|
||||
path = toString ./.;
|
||||
};
|
||||
|
||||
home-manager = pkgs.callPackage ./home-manager { path = toString ./.; };
|
||||
|
||||
install =
|
||||
pkgs.callPackage ./home-manager/install.nix { inherit home-manager; };
|
||||
install = import ./home-manager/install.nix {
|
||||
inherit home-manager pkgs;
|
||||
};
|
||||
|
||||
nixos = import ./nixos;
|
||||
|
||||
path = ./.;
|
||||
}
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
[[ch-contributing]]
|
||||
== Contributing
|
||||
|
||||
:open-issues: https://github.com/nix-community/home-manager/issues
|
||||
:new-issue: https://github.com/nix-community/home-manager/issues/new
|
||||
:fork-a-repo: https://help.github.com/articles/fork-a-repo/
|
||||
:create-a-pull-request: https://help.github.com/articles/creating-a-pull-request/
|
||||
:seven-rules: https://chris.beams.io/posts/git-commit/#seven-rules
|
||||
:news-nix: https://github.com/nix-community/home-manager/blob/master/modules/misc/news.nix
|
||||
:nixfmt: https://github.com/serokell/nixfmt/
|
||||
:example-commit-message: https://github.com/nix-community/home-manager/commit/69f8e47e9e74c8d3d060ca22e18246b7f7d988ef
|
||||
|
||||
Contributions to Home Manager are very welcome. To make the process as smooth as possible for both you and the Home Manager maintainers we provide some guidelines that we ask you to follow. See <<sec-contrib-getting-started>> for information on how to set up a suitable development environment and <<sec-guidelines>> for the actual guidelines.
|
||||
|
||||
This text is mainly directed at those who would like to make code contributions to Home Manager. If you just want to report a bug then first look among the already {open-issues}[open issues], if you find one matching yours then feel free to comment on it to add any additional information you may have. If no matching issue exists then go to the {new-issue}[new issue] page and write a description of your problem. Include as much information as you can, ideally also include relevant excerpts from your Home Manager configuration.
|
||||
|
||||
[[sec-contrib-getting-started]]
|
||||
=== Getting started
|
||||
|
||||
If you have not previously forked Home Manager then you need to do that first. Have a look at GitHub's {fork-a-repo}[Fork a repo] for instructions on how to do this.
|
||||
|
||||
Once you have a fork of Home Manager you should create a branch starting at the most recent `master` branch. Give your branch a reasonably descriptive name. Commit your changes to this branch and when you are happy with the result and it fulfills <<sec-guidelines>> then push the branch to GitHub and {create-a-pull-request}[create a pull request].
|
||||
|
||||
Assuming your clone is at `$HOME/devel/home-manager` then you can make the `home-manager` command use it by either
|
||||
|
||||
1. overriding the default path by using the `-I` command line option:
|
||||
+
|
||||
[source,console]
|
||||
$ home-manager -I home-manager=$HOME/devel/home-manager
|
||||
+
|
||||
or
|
||||
|
||||
2. changing the default path by ensuring your configuration includes
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.home-manager.enable = true;
|
||||
programs.home-manager.path = "$HOME/devel/home-manager";
|
||||
----
|
||||
+
|
||||
and running `home-manager switch` to activate the change. Afterwards, `home-manager build` and `home-manager switch` will use your cloned repository.
|
||||
|
||||
The first option is good if you only temporarily want to use your clone.
|
||||
|
||||
[[sec-guidelines]]
|
||||
=== Guidelines
|
||||
:irc-home-manager: https://webchat.oftc.net/?channels=home-manager
|
||||
:valuable-options: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md#valuable-options
|
||||
:rfc-42: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md
|
||||
:assertions: https://nixos.org/manual/nixos/stable/index.html#sec-assertions
|
||||
|
||||
If your contribution satisfy the following rules then there is a good chance it will be merged without too much trouble. The rules are enforced by the Home Manager maintainers and to a lesser extent the Home Manager CI system.
|
||||
|
||||
If you are uncertain how these rules affect the change you would like to make then feel free to start a discussion in the {irc-home-manager}[#home-manager] IRC channel, ideally before you start developing.
|
||||
|
||||
[[sec-guidelines-back-compat]]
|
||||
==== Maintain backward compatibility
|
||||
|
||||
Your contribution should not cause another user's existing configuration to break unless there is a very good reason and the change should be announced to the user through an {assertions}[assertion] or similar.
|
||||
|
||||
Remember that Home Manager is used in many different environments and you should consider how your change may effect others. For example,
|
||||
|
||||
- Does your change work for people that do not use NixOS? Consider other GNU/Linux distributions and macOS.
|
||||
- Does your change work for people whose configuration is built on one system and deployed on another system?
|
||||
|
||||
[[sec-guidelines-forward-compat]]
|
||||
==== Keep forward compatibility in mind
|
||||
|
||||
The master branch of Home Manager tracks the unstable channel of Nixpkgs, which may update package versions at any time. It is therefore important to consider how a package update may affect your code and try to reduce the risk of breakage.
|
||||
|
||||
The most effective way to reduce this risk is to follow the advice in <<sec-guidelines-valuable-options>>.
|
||||
|
||||
[[sec-guidelines-valuable-options]]
|
||||
==== Add only valuable options
|
||||
|
||||
When creating a new module it is tempting to include every option supported by the software. This is _strongly_ discouraged. Providing many options increases maintenance burden and risk of breakage considerably. This is why only the most {valuable-options}[important software options] should be modeled explicitly. Less important options should be expressible through an `extraConfig` escape hatch.
|
||||
|
||||
A good rule of thumb for the first implementation of a module is to only add explicit options for those settings that absolutely must be set for the software to function correctly. It follows that a module for software that provides sensible default values for all settings would require no explicit options at all.
|
||||
|
||||
If the software uses a structured configuration format like a JSON, YAML, INI, TOML, or even a plain list of key/value pairs then consider using a `settings` option as described in {rfc-42}[Nix RFC 42].
|
||||
|
||||
[[sec-guidelines-add-tests]]
|
||||
==== Add relevant tests
|
||||
|
||||
If at all possible, make sure to add new tests and expand existing tests so that your change will keep working in the future. See <<sec-tests>> for more information about the Home Manager test suite.
|
||||
|
||||
All contributed code _must_ pass the test suite.
|
||||
|
||||
[[sec-guidelines-module-maintainer]]
|
||||
|
||||
==== Add relevant documentation
|
||||
:docbook: https://tdg.docbook.org/
|
||||
:asciidoc: https://asciidoc.org/
|
||||
:docbook-rocks: https://berbiche.github.io/docbook.rocks/
|
||||
|
||||
Many code changes require changing the documentation as well. Module options should be documented with DocBook. See {docbook-rocks}[DocBook rocks!] for a quick introduction and {docbook}[DocBook 5: The Definitive Guide] for in-depth information of DocBook. Home Manager is itself documented using a combination of DocBook and {asciidoc}[AsciiDoc]. All text is hosted in Home Manager's Git repository.
|
||||
|
||||
The HTML version of the manual containing both the module option descriptions and the documentation of Home Manager can be generated and opened by typing the following in a shell within a clone of the Home Manager Git repository:
|
||||
|
||||
[source,console]
|
||||
$ nix-build -A docs.html
|
||||
$ xdg-open ./result/share/doc/home-manager/index.html
|
||||
|
||||
When you have made changes to a module, it is a good idea to check that the man page version of the module options looks good:
|
||||
|
||||
[source,console]
|
||||
$ nix-build -A docs.manPages
|
||||
$ man ./result/share/man/man5/home-configuration.nix.5
|
||||
|
||||
==== Add yourself as a module maintainer
|
||||
|
||||
Every new module _must_ include a named maintainer using the `meta.maintainers` attribute. If you are a user of a module that currently lacks a maintainer then please consider adopting it.
|
||||
|
||||
If you are present in the NixOS maintainer list then you can use that entry. If you are not then you can add yourself to `modules/lib/maintainers.nix` in the Home Manager project.
|
||||
|
||||
Also add yourself to `.github/CODEOWNERS` as owner of the associated module files, including the test files. You will then be automatically added as a reviewer on any new pull request that touches your files.
|
||||
|
||||
Maintainers are encouraged to join the IRC channel and participate when they have opportunity.
|
||||
|
||||
[[sec-guidelines-code-style]]
|
||||
==== Format your code
|
||||
|
||||
Make sure your code is formatted as described in <<sec-code-style>>. To maintain consistency throughout the project you are encouraged to browse through existing code and adopt its style also in new code.
|
||||
|
||||
[[sec-guidelines-commit-message-style]]
|
||||
==== Format your commit messages
|
||||
|
||||
Similar to <<sec-guidelines-code-style>> we encourage a consistent commit message format as described in <<sec-commit-style>>.
|
||||
|
||||
[[sec-guidelines-news-style]]
|
||||
==== Format your news entries
|
||||
|
||||
If your contribution includes a change that should be communicated to users of Home Manager then you can add a news entry. The entry must be formatted as described in <<sec-news>>.
|
||||
|
||||
When new modules are added a news entry should be included but you do not need to create this entry manually. The merging maintainer will create the entry for you. This is to reduce the risk of merge conflicts.
|
||||
|
||||
[[sec-guidelines-conditional-modules]]
|
||||
==== Use conditional modules and news
|
||||
|
||||
Home Manager includes a number of modules that are only usable on some of the supported platforms. The most common example of platform specific modules are those that define systemd user services, which only works on Linux systems.
|
||||
|
||||
If you add a module that is platform specific then make sure to include a condition in the `loadModule` function call. This will make the module accessible only on systems where the condition evaluates to `true`.
|
||||
|
||||
Similarly, if you are adding a news entry then it should be shown only to users that may find it relevant, see <<sec-news>> for a description of conditional news.
|
||||
|
||||
[[sec-guidelines-licensing]]
|
||||
==== Mind the license
|
||||
|
||||
The Home Manager project is covered by the MIT license and we can only accept contributions that fall under this license, or are licensed in a compatible way. When you contribute self written code and documentation it is assumed that you are doing so under the MIT license.
|
||||
|
||||
A potential gotcha with respect to licensing are option descriptions. Often it is convenient to copy from the upstream software documentation. When this is done it is important to verify that the license of the upstream documentation allows redistribution under the terms of the MIT license.
|
||||
|
||||
[[sec-commit-style]]
|
||||
=== Commits
|
||||
|
||||
The commits in your pull request should be reasonably self-contained, that is, each commit should make sense in isolation. In particular, you will be asked to amend any commit that introduces syntax errors or similar problems even if they are fixed in a later commit.
|
||||
|
||||
The commit messages should follow the {seven-rules}[seven rules]. We also ask you to include the affected code component or module in the first line. That is, a commit message should follow the template
|
||||
|
||||
----
|
||||
{component}: {description}
|
||||
|
||||
{long description}
|
||||
----
|
||||
|
||||
where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. 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
|
||||
===============================================================================
|
||||
The commit {example-commit-message}[69f8e47e9e74c8d3d060ca22e18246b7f7d988ef] contains the commit message
|
||||
|
||||
----
|
||||
starship: allow running in Emacs if vterm is used
|
||||
|
||||
The vterm buffer is backed by libvterm and can handle Starship prompts
|
||||
without issues.
|
||||
----
|
||||
|
||||
which ticks all the boxes necessary to be accepted in Home Manager.
|
||||
===============================================================================
|
||||
|
||||
Finally, when adding a new module, say `programs/foo.nix`, we use the fixed commit format `foo: add module`. You can, of course, still include a long description if you wish.
|
||||
|
||||
[[sec-code-style]]
|
||||
=== Code Style
|
||||
|
||||
The code in Home Manager is formatted by the {nixfmt}[nixfmt] tool and the formatting is checked in the pull request tests. Run the `format` tool inside the project repository before submitting your pull request.
|
||||
|
||||
Keep lines at a reasonable width, ideally 80 characters or less. This also applies to string literals.
|
||||
|
||||
We prefer `lowerCamelCase` for variable and attribute names with the accepted exception of variables directly referencing packages in Nixpkgs which use a hyphenated style. For example, the Home Manager option `services.gpg-agent.enableSshSupport` references the `gpg-agent` package in Nixpkgs.
|
||||
|
||||
[[sec-news]]
|
||||
=== News
|
||||
|
||||
Home Manager includes a system for presenting news to the user. When making a change you, therefore, have the option to also include an associated news entry. In general, a news entry should only be added for truly noteworthy news. For example, a bug fix or new option does generally not need a news entry.
|
||||
|
||||
If you do have a change worthy of a news entry then please add one in {news-nix}[`news.nix`] but you should follow some basic guidelines:
|
||||
|
||||
- The entry timestamp should be in ISO-8601 format having "+00:00" as time zone. For example, "2017-09-13T17:10:14+00:00". A suitable timestamp can be produced by the command
|
||||
+
|
||||
[source,console]
|
||||
$ date --iso-8601=second --universal
|
||||
|
||||
- The entry condition should be as specific as possible. For example, if you are changing or deprecating a specific option then you could restrict the news to those users who actually use this option.
|
||||
|
||||
- Wrap the news message so that it will fit in the typical terminal, that is, at most 80 characters wide. Ideally a bit less.
|
||||
|
||||
- Unlike commit messages, news will be read without any connection to the Home Manager source code. It is therefore important to make the message understandable in isolation and to those who do not have knowledge of the Home Manager internals. To this end it should be written in more descriptive, prose like way.
|
||||
|
||||
- If you refer to an option then write its full attribute path. That is, instead of writing
|
||||
+
|
||||
----
|
||||
The option 'foo' has been deprecated, please use 'bar' instead.
|
||||
----
|
||||
+
|
||||
it should read
|
||||
+
|
||||
----
|
||||
The option 'services.myservice.foo' has been deprecated, please
|
||||
use 'services.myservice.bar' instead.
|
||||
----
|
||||
|
||||
- A new module, say `foo.nix`, should always include a news entry that has a message along the lines of
|
||||
+
|
||||
----
|
||||
A new module is available: 'services.foo'.
|
||||
----
|
||||
+
|
||||
If the module is platform specific, e.g., a service module using systemd, then a condition like
|
||||
+
|
||||
[source,nix]
|
||||
condition = hostPlatform.isLinux;
|
||||
+
|
||||
should be added. If you contribute a module then you don't need to add this entry, the merger will create an entry for you.
|
||||
|
||||
[[sec-tests]]
|
||||
=== Tests
|
||||
|
||||
Home Manager includes a basic test suite and it is highly recommended to include at least one test when adding a module. Tests are typically in the form of "golden tests" where, for example, a generated configuration file is compared to a known correct file.
|
||||
|
||||
It is relatively easy to create tests by modeling the existing tests, found in the `tests` project directory.
|
||||
|
||||
The full Home Manager test suite can be run by executing
|
||||
|
||||
[source,console]
|
||||
$ nix-shell --pure tests -A run.all
|
||||
|
||||
in the project root. List all test cases through
|
||||
|
||||
[source,console]
|
||||
$ nix-shell --pure tests -A list
|
||||
|
||||
and run an individual test, for example `alacritty-empty-settings`, through
|
||||
|
||||
[source,console]
|
||||
$ nix-shell --pure tests -A run.alacritty-empty-settings
|
||||
120
doc/default.nix
120
doc/default.nix
@@ -1,120 +0,0 @@
|
||||
{ pkgs
|
||||
|
||||
# Note, this should be "the standard library" + HM extensions.
|
||||
, lib ? import ../modules/lib/stdlib-extended.nix pkgs.lib }:
|
||||
|
||||
let
|
||||
|
||||
nmdSrc = pkgs.fetchFromGitLab {
|
||||
name = "nmd";
|
||||
owner = "rycee";
|
||||
repo = "nmd";
|
||||
rev = "2398aa79ab12aa7aba14bc3b08a6efd38ebabdc5";
|
||||
sha256 = "0yxb48afvccn8vvpkykzcr4q1rgv8jsijqncia7a5ffzshcrwrnh";
|
||||
};
|
||||
|
||||
nmd = import nmdSrc { inherit lib pkgs; };
|
||||
|
||||
# Make sure the used package is scrubbed to avoid actually
|
||||
# instantiating derivations.
|
||||
scrubbedPkgsModule = {
|
||||
imports = [{
|
||||
_module.args = {
|
||||
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
|
||||
pkgs_i686 = lib.mkForce { };
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
buildModulesDocs = args:
|
||||
nmd.buildModulesDocs ({
|
||||
moduleRootPaths = [ ./.. ];
|
||||
mkModuleUrl = path:
|
||||
"https://github.com/nix-community/home-manager/blob/master/${path}#blob-path";
|
||||
channelName = "home-manager";
|
||||
} // args);
|
||||
|
||||
hmModulesDocs = buildModulesDocs {
|
||||
modules = import ../modules/modules.nix {
|
||||
inherit lib pkgs;
|
||||
check = false;
|
||||
} ++ [ scrubbedPkgsModule ];
|
||||
docBook.id = "home-manager-options";
|
||||
};
|
||||
|
||||
nixosModuleDocs = buildModulesDocs {
|
||||
modules = let
|
||||
nixosModule = module: pkgs.path + "/nixos/modules" + module;
|
||||
mockedNixos = with lib; {
|
||||
options = {
|
||||
environment.pathsToLink = mkSinkUndeclaredOptions { };
|
||||
systemd.services = mkSinkUndeclaredOptions { };
|
||||
users.users = mkSinkUndeclaredOptions { };
|
||||
};
|
||||
};
|
||||
in [
|
||||
../nixos/default.nix
|
||||
mockedNixos
|
||||
(nixosModule "/misc/assertions.nix")
|
||||
scrubbedPkgsModule
|
||||
];
|
||||
docBook = {
|
||||
id = "nixos-options";
|
||||
optionIdPrefix = "nixos-opt";
|
||||
};
|
||||
};
|
||||
|
||||
nixDarwinModuleDocs = buildModulesDocs {
|
||||
modules = let
|
||||
nixosModule = module: pkgs.path + "/nixos/modules" + module;
|
||||
mockedNixDarwin = with lib; {
|
||||
options = {
|
||||
environment.pathsToLink = mkSinkUndeclaredOptions { };
|
||||
system.activationScripts.postActivation.text =
|
||||
mkSinkUndeclaredOptions { };
|
||||
users.users = mkSinkUndeclaredOptions { };
|
||||
};
|
||||
};
|
||||
in [
|
||||
../nix-darwin/default.nix
|
||||
mockedNixDarwin
|
||||
(nixosModule "/misc/assertions.nix")
|
||||
scrubbedPkgsModule
|
||||
];
|
||||
docBook = {
|
||||
id = "nix-darwin-options";
|
||||
optionIdPrefix = "nix-darwin-opt";
|
||||
};
|
||||
};
|
||||
|
||||
docs = nmd.buildDocBookDocs {
|
||||
pathName = "home-manager";
|
||||
modulesDocs = [ hmModulesDocs nixDarwinModuleDocs nixosModuleDocs ];
|
||||
documentsDirectory = ./.;
|
||||
documentType = "book";
|
||||
chunkToc = ''
|
||||
<toc>
|
||||
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-home-manager-manual"><?dbhtml filename="index.html"?>
|
||||
<d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-nixos-options"><?dbhtml filename="nixos-options.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-nix-darwin-options"><?dbhtml filename="nix-darwin-options.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
|
||||
</d:tocentry>
|
||||
</toc>
|
||||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
inherit nmdSrc;
|
||||
|
||||
options = {
|
||||
json = hmModulesDocs.json.override {
|
||||
path = "share/doc/home-manager/options.json";
|
||||
};
|
||||
};
|
||||
|
||||
manPages = docs.manPages;
|
||||
|
||||
manual = { inherit (docs) html htmlOpenTool; };
|
||||
}
|
||||
171
doc/faq.adoc
171
doc/faq.adoc
@@ -1,171 +0,0 @@
|
||||
[[ch-faq]]
|
||||
== Frequently Asked Questions (FAQ)
|
||||
|
||||
=== Why is there a collision error when switching generation?
|
||||
|
||||
Home Manager currently installs packages into the user environment, precisely as if the packages were installed through `nix-env --install`. This means that you will get a collision error if your Home Manager configuration attempts to install a package that you already have installed manually, that is, packages that shows up when you run `nix-env --query`.
|
||||
|
||||
For example, imagine you have the `hello` package installed in your environment
|
||||
|
||||
[source,console]
|
||||
----
|
||||
$ nix-env --query
|
||||
hello-2.10
|
||||
----
|
||||
|
||||
and your Home Manager configuration contains
|
||||
|
||||
[source,nix]
|
||||
----
|
||||
home.packages = [ pkgs.hello ];
|
||||
----
|
||||
|
||||
Then attempting to switch to this configuration will result in an error similar to
|
||||
|
||||
[source,console]
|
||||
----
|
||||
$ home-manager switch
|
||||
these derivations will be built:
|
||||
/nix/store/xg69wsnd1rp8xgs9qfsjal017nf0ldhm-home-manager-path.drv
|
||||
[…]
|
||||
Activating installPackages
|
||||
replacing old ‘home-manager-path’
|
||||
installing ‘home-manager-path’
|
||||
building path(s) ‘/nix/store/b5c0asjz9f06l52l9812w6k39ifr49jj-user-environment’
|
||||
Wide character in die at /nix/store/64jc9gd2rkbgdb4yjx3nrgc91bpjj5ky-buildenv.pl line 79.
|
||||
collision between ‘/nix/store/fmwa4axzghz11cnln5absh31nbhs9lq1-home-manager-path/bin/hello’ and ‘/nix/store/c2wyl8b9p4afivpcz8jplc9kis8rj36d-hello-2.10/bin/hello’; use ‘nix-env --set-flag priority NUMBER PKGNAME’ to change the priority of one of the conflicting packages
|
||||
builder for ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed with exit code 2
|
||||
error: build of ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed
|
||||
----
|
||||
|
||||
The solution is typically to uninstall the package from the environment using `nix-env --uninstall` and reattempt the Home Manager generation switch.
|
||||
|
||||
=== Why are the session variables not set?
|
||||
|
||||
Home Manager is only able to set session variables automatically if it manages your Bash or Z shell configuration. If you don't want to let Home Manager manage your shell then you will have to manually source the `~/.nix-profile/etc/profile.d/hm-session-vars.sh` file in an appropriate way. In Bash and Z shell this can be done by adding
|
||||
|
||||
[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.
|
||||
|
||||
=== How to set up a configuration for multiple users/machines?
|
||||
:post-your-homenix: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/
|
||||
|
||||
A typical way to prepare a repository of configurations for multiple logins and machines is to prepare one "top-level" file for each unique combination.
|
||||
|
||||
For example, if you have two machines, called "kronos" and "rhea" on which you want to configure your user "jane" then you could create the files
|
||||
|
||||
- `kronos-jane.nix`,
|
||||
- `rhea-jane.nix`, and
|
||||
- `common.nix`
|
||||
|
||||
in your repository. On the kronos and rhea machines you can then make `~jane/.config/nixpkgs/home.nix` be a symbolic link to the corresponding file in your configuration repository.
|
||||
|
||||
The `kronos-jane.nix` and `rhea-jane.nix` files follow the format
|
||||
|
||||
[source,nix]
|
||||
----
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [ ./common.nix ];
|
||||
|
||||
# Various options that are specific for this machine/user.
|
||||
}
|
||||
----
|
||||
|
||||
while the `common.nix` file contains configuration shared across the two logins. Of course, instead of just a single `common.nix` file you can have multiple ones, even one per program or service.
|
||||
|
||||
You can get some inspiration from the {post-your-homenix}[Post your home-manager home.nix file!] Reddit thread.
|
||||
|
||||
=== Why do I get an error message about `ca.desrt.dconf`?
|
||||
|
||||
You are most likely trying to configure the GTK or Gnome Terminal but the DBus session is not aware of the dconf service. The full error you might get is
|
||||
|
||||
----
|
||||
error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt.dconf was not provided by any .service files
|
||||
----
|
||||
|
||||
The solution on NixOS is to add
|
||||
|
||||
[source,nix]
|
||||
services.dbus.packages = with pkgs; [ gnome.dconf ];
|
||||
|
||||
to your system configuration.
|
||||
|
||||
=== How do I install packages from Nixpkgs unstable?
|
||||
|
||||
If you are using a stable version of Nixpkgs but would like to install some particular packages from Nixpkgs unstable – or some other channel – then you can import the unstable Nixpkgs and refer to its packages within your configuration. Something like
|
||||
|
||||
[source,nix]
|
||||
----
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
home.packages = [
|
||||
pkgsUnstable.foo
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
----
|
||||
|
||||
should work provided you have a Nix channel called `nixpkgs-unstable`.
|
||||
|
||||
You can add the `nixpkgs-unstable` channel by running
|
||||
|
||||
[source,console]
|
||||
----
|
||||
# nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable
|
||||
# nix-channel --update
|
||||
----
|
||||
|
||||
Note, the package will not be affected by any package overrides, overlays, etc.
|
||||
|
||||
=== How do I override the package used by a module?
|
||||
:nixpkgs-overlays: https://nixos.org/nixpkgs/manual/#chap-overlays
|
||||
|
||||
By default Home Manager will install the package provided by your chosen `nixpkgs` channel but occasionally you might end up needing to change this package. This can typically be done in two ways.
|
||||
|
||||
1. If the module provides a `package` option, such as `programs.beets.package`, then this is the recommended way to perform the override. For example,
|
||||
+
|
||||
[source,nix]
|
||||
programs.beets.package = pkgs.beets.override { enableCheck = true; };
|
||||
|
||||
2. If no `package` option is available then you can typically override the relevant package using an {nixpkgs-overlays}[overlay].
|
||||
+
|
||||
For example, if you want to use the `programs.skim` module but use the `skim` package from Nixpkgs unstable, then a configuration like
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
programs.skim.enable = true;
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
skim = pkgsUnstable.skim;
|
||||
})
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
----
|
||||
+
|
||||
should work OK.
|
||||
@@ -1,263 +0,0 @@
|
||||
[[ch-installation]]
|
||||
== Installing Home Manager
|
||||
|
||||
:nix-darwin: https://github.com/LnL7/nix-darwin/
|
||||
|
||||
Home Manager can be used in three primary ways:
|
||||
|
||||
1. Using the standalone `home-manager` tool. For platforms other than
|
||||
NixOS and Darwin, this is the only available choice. It is also
|
||||
recommended for people on NixOS or Darwin that want to manage their
|
||||
home directory independent of the system as a whole. See
|
||||
<<sec-install-standalone>> for instructions on how to perform this
|
||||
installation.
|
||||
|
||||
2. As a module within a NixOS system configuration. This allows the
|
||||
user profiles to be built together with the system when running
|
||||
`nixos-rebuild`. See <<sec-install-nixos-module>> for a description of
|
||||
this setup.
|
||||
|
||||
3. As a module within a {nix-darwin}[nix-darwin] system configuration.
|
||||
This allows the user profiles to be built together with the system
|
||||
when running `darwin-rebuild`. See <<sec-install-nix-darwin-module>>
|
||||
for a description of this setup.
|
||||
|
||||
[[sec-install-standalone]]
|
||||
=== Standalone installation
|
||||
|
||||
:nix-allowed-users: https://nixos.org/nix/manual/#conf-allowed-users
|
||||
:nixos-allowed-users: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers
|
||||
|
||||
1. Make sure you have a working Nix installation. Specifically, make
|
||||
sure that your user is able to build and install Nix packages. For
|
||||
example, you should be able to successfully run a command like
|
||||
`nix-instantiate '<nixpkgs>' -A hello` without having to switch to the
|
||||
root user. For a multi-user install of Nix this means that your user
|
||||
must be covered by the {nix-allowed-users}[`allowed-users`] Nix
|
||||
option. On NixOS you can control this option using the
|
||||
{nixos-allowed-users}[`nix.allowedUsers`] system option.
|
||||
|
||||
2. Add the Home Manager channel that you wish to follow. If you are
|
||||
following Nixpkgs master or an unstable channel then this is done by
|
||||
running
|
||||
+
|
||||
[source,console]
|
||||
----
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
----
|
||||
+
|
||||
and if you follow a Nixpkgs version 21.05 channel, you can run
|
||||
+
|
||||
[source,console]
|
||||
----
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
----
|
||||
+
|
||||
On NixOS you may need to log out and back in for the channel to become
|
||||
available. On non-NixOS you may have to add
|
||||
+
|
||||
[source,bash]
|
||||
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||
+
|
||||
to your shell (see
|
||||
https://github.com/NixOS/nix/issues/2033[nix#2033]).
|
||||
|
||||
3. Run the Home Manager installation command and create the first Home
|
||||
Manager generation:
|
||||
+
|
||||
[source,console]
|
||||
$ nix-shell '<home-manager>' -A install
|
||||
+
|
||||
Once finished, Home Manager should be active and available in your
|
||||
user environment.
|
||||
|
||||
4. If you do not plan on having Home Manager manage your shell
|
||||
configuration then you must source the
|
||||
+
|
||||
[source,bash]
|
||||
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
+
|
||||
file in your shell configuration. Alternatively source
|
||||
+
|
||||
[source,bash]
|
||||
/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh
|
||||
+
|
||||
when managing home configuration together with system configuration.
|
||||
+
|
||||
Unfortunately, we currently only support POSIX.2-like shells such as
|
||||
https://www.gnu.org/software/bash/[Bash] or
|
||||
http://zsh.sourceforge.net/[Z shell].
|
||||
+
|
||||
For example, if you use Bash then add
|
||||
+
|
||||
[source,bash]
|
||||
----
|
||||
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
----
|
||||
+
|
||||
to your `~/.profile` file.
|
||||
|
||||
If instead of using channels you want to run Home Manager from a Git
|
||||
checkout of the repository then you can use the
|
||||
<<opt-programs.home-manager.path>> option to specify the absolute path
|
||||
to the repository.
|
||||
|
||||
[[sec-install-nixos-module]]
|
||||
=== NixOS module
|
||||
|
||||
Home Manager provides a NixOS module that allows you to prepare user
|
||||
environments directly from the system configuration file, which often
|
||||
is more convenient than using the `home-manager` tool. It also opens
|
||||
up additional possibilities, for example, to automatically configure
|
||||
user environments in NixOS declarative containers or on systems
|
||||
deployed through NixOps.
|
||||
|
||||
To make the NixOS module available for use you must `import` it into
|
||||
your system configuration. This is most conveniently done by adding a
|
||||
Home Manager channel. For example, if you are following Nixpkgs master
|
||||
or an unstable channel, you can run
|
||||
|
||||
[source,console]
|
||||
----
|
||||
# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||
# nix-channel --update
|
||||
----
|
||||
|
||||
and if you follow a Nixpkgs version 21.05 channel, you can run
|
||||
|
||||
[source,console]
|
||||
----
|
||||
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||
# nix-channel --update
|
||||
----
|
||||
|
||||
It is then possible to add
|
||||
|
||||
[source,nix]
|
||||
imports = [ <home-manager/nixos> ];
|
||||
|
||||
to your system `configuration.nix` file, which will introduce a new
|
||||
NixOS option called `home-manager.users` whose type is an attribute
|
||||
set that maps user names to Home Manager configurations.
|
||||
|
||||
For example, a NixOS configuration may include the lines
|
||||
|
||||
[source,nix]
|
||||
----
|
||||
users.users.eve.isNormalUser = true;
|
||||
home-manager.users.eve = { pkgs, ... }: {
|
||||
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||
programs.bash.enable = true;
|
||||
};
|
||||
----
|
||||
|
||||
and after a `nixos-rebuild switch` the user eve's environment should
|
||||
include a basic Bash configuration and the packages atool and httpie.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
By default packages will be installed to `$HOME/.nix-profile` but they
|
||||
can be installed to `/etc/profiles` if
|
||||
|
||||
[source,nix]
|
||||
home-manager.useUserPackages = true;
|
||||
|
||||
is added to the system configuration. This is necessary if, for
|
||||
example, you wish to use `nixos-rebuild build-vm`. This option may
|
||||
become the default value in the future.
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
By default, Home Manager uses a private `pkgs` instance that is
|
||||
configured via the `home-manager.users.<name>.nixpkgs` options. To
|
||||
instead use the global `pkgs` that is configured via the system level
|
||||
`nixpkgs` options, set
|
||||
|
||||
[source,nix]
|
||||
home-manager.useGlobalPkgs = true;
|
||||
|
||||
This saves an extra Nixpkgs evaluation, adds consistency, and removes
|
||||
the dependency on `NIX_PATH`, which is otherwise used for importing
|
||||
Nixpkgs.
|
||||
====
|
||||
|
||||
[[sec-install-nix-darwin-module]]
|
||||
=== nix-darwin module
|
||||
|
||||
Home Manager provides a module that allows you to prepare user
|
||||
environments directly from the {nix-darwin}[nix-darwin] configuration
|
||||
file, which often is more convenient than using the `home-manager`
|
||||
tool.
|
||||
|
||||
To make the NixOS module available for use you must `import` it into
|
||||
your system configuration. This is most conveniently done by adding a
|
||||
Home Manager channel. For example, if you are following Nixpkgs master
|
||||
or an unstable channel, you can run
|
||||
|
||||
[source,console]
|
||||
----
|
||||
# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||
# nix-channel --update
|
||||
----
|
||||
|
||||
and if you follow a Nixpkgs version 21.05 channel, you can run
|
||||
|
||||
[source,console]
|
||||
----
|
||||
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||
# nix-channel --update
|
||||
----
|
||||
|
||||
It is then possible to add
|
||||
|
||||
[source,nix]
|
||||
imports = [ <home-manager/nix-darwin> ];
|
||||
|
||||
to your nix-darwin `configuration.nix` file, which will introduce a
|
||||
new NixOS option called `home-manager` whose type is an attribute set
|
||||
that maps user names to Home Manager configurations.
|
||||
|
||||
For example, a nix-darwin configuration may include the lines
|
||||
|
||||
[source,nix]
|
||||
----
|
||||
home-manager.users.eve = { pkgs, ... }: {
|
||||
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||
programs.bash.enable = true;
|
||||
};
|
||||
----
|
||||
|
||||
and after a `darwin-rebuild switch` the user eve's environment
|
||||
should include a basic Bash configuration and the packages atool and
|
||||
httpie.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
By default user packages will not be ignored in favor of
|
||||
`environment.systemPackages`, but they will be intalled to
|
||||
`/etc/profiles/per-user/$USERNAME` if
|
||||
|
||||
[source,nix]
|
||||
home-manager.useUserPackages = true;
|
||||
|
||||
is added to the nix-darwin configuration. This option may become the
|
||||
default value in the future.
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
By default, Home Manager uses a private `pkgs` instance that is
|
||||
configured via the `home-manager.users.<name>.nixpkgs` options. To
|
||||
instead use the global `pkgs` that is configured via the system level
|
||||
`nixpkgs` options, set
|
||||
|
||||
[source,nix]
|
||||
home-manager.useGlobalPkgs = true;
|
||||
|
||||
This saves an extra Nixpkgs evaluation, adds consistency, and removes
|
||||
the dependency on `NIX_PATH`, which is otherwise used for importing
|
||||
Nixpkgs.
|
||||
====
|
||||
@@ -1,40 +0,0 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<refmeta>
|
||||
<refentrytitle><filename>home-configuration.nix</filename></refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
<refmiscinfo class="source">Home Manager</refmiscinfo>
|
||||
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><filename>home-configuration.nix</filename></refname>
|
||||
<refpurpose>Home Manager configuration specification</refpurpose>
|
||||
</refnamediv>
|
||||
<refsection>
|
||||
<title>Description</title>
|
||||
<para>
|
||||
The file <filename>~/.config/nixpkgs/home.nix</filename> contains the
|
||||
declarative specification of your Home Manager configuration. The command
|
||||
<command>home-manager</command> takes this file and realises the user
|
||||
environment configuration specified therein.
|
||||
</para>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>Options</title>
|
||||
<para>
|
||||
You can use the following options in
|
||||
<filename>home-configuration.nix</filename>:
|
||||
</para>
|
||||
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>See also</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>home-manager</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
</para>
|
||||
</refsection>
|
||||
</refentry>
|
||||
@@ -1,571 +0,0 @@
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<refmeta>
|
||||
<refentrytitle><command>home-manager</command>
|
||||
</refentrytitle><manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Home Manager</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><command>home-manager</command>
|
||||
</refname><refpurpose>reconfigure a user environment</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<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">
|
||||
packages
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
remove-generations <replaceable>ID …</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
switch
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
uninstall
|
||||
</arg>
|
||||
</group>
|
||||
<sbr />
|
||||
<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">
|
||||
<arg choice="plain">
|
||||
-f
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--file
|
||||
</arg>
|
||||
</group> <replaceable>path</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<group choice="req">
|
||||
<arg choice="plain">
|
||||
-h
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--help
|
||||
</arg>
|
||||
</group>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<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">
|
||||
-j
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--max-jobs
|
||||
</arg>
|
||||
</group>
|
||||
<replaceable>number</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--debug
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--keep-failed
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--keep-going
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--show-trace
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--(no-)substitute
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<group choice="req">
|
||||
<arg choice="plain">
|
||||
-v
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--verbose
|
||||
</arg>
|
||||
</group>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
<refsection>
|
||||
<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> or <filename>~/.config/nixpkgs/flake.nix</filename>.
|
||||
</para>
|
||||
<para>
|
||||
All operations using this tool expects a sub-command that indicates the
|
||||
operation to perform. It must be one of
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>build</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Build configuration into a <filename>result</filename> directory.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>instantiate</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Instantiate the configuration and print the resulting derivation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>edit</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Open the home configuration using the editor indicated by
|
||||
<envar>EDITOR</envar>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>expire-generations <replaceable>timestamp</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Remove generations older than <replaceable>timestamp</replaceable> where
|
||||
<replaceable>timestamp</replaceable> is interpreted as in the
|
||||
<option>-d</option> argument of the <citerefentry>
|
||||
<refentrytitle>date</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry> tool. For example <literal>-30
|
||||
days</literal> or <literal>2018-01-01</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>generations</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List all home environment generations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>help</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print tool help.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>news</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Show news entries in a pager.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>packages</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List all packages installed in <varname>home-manager-path</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>remove-generations <replaceable>ID …</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Remove indicated generations. Use the <option>generations</option>
|
||||
sub-command to find suitable generation numbers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>switch</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Build and activate the configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>uninstall</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Remove Home Manager from the user environment. This will
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
remove all managed files from the home directory,
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
remove packages installed through Home Manager from the user profile,
|
||||
and
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
optionally remove all Home Manager generations and make them
|
||||
available for immediate garbage collection.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>Options</title>
|
||||
<para>
|
||||
The tool accepts the options
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-A <replaceable>attrPath</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Optional attribute that selects a configuration expression in the
|
||||
configuration file. That is, if <filename>home.nix</filename> contains
|
||||
<programlisting language="nix">
|
||||
{
|
||||
joe-at-work = {pkgs, ...}: { home.packages = [ pkgs.fortune ]; };
|
||||
joe-at-home = {pkgs, ...}: { home.packages = [ pkgs.cowsay ]; };
|
||||
}
|
||||
</programlisting>
|
||||
then the command <command>home-manager switch -A joe-at-work</command>
|
||||
will activate the profile containing the fortune program.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-I <replaceable>path</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Add a path to the Nix expression search path. For example, to build a
|
||||
Home Manager profile using a specific Nixpkgs run <command>home-manager
|
||||
-I nixpkgs=/absolute/path/to/nixpkgs build</command>. By default
|
||||
<literal><nixpkgs></literal> is used.
|
||||
</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>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable automatic resolution of collisions between unmanaged and managed
|
||||
files. The name of the original file will be suffixed by the given
|
||||
extension. For example,
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>home-manager -b bck switch</userinput>
|
||||
</screen>
|
||||
will cause a colliding file <filename>~/.config/foo.conf</filename> to be
|
||||
moved to <filename>~/.config/foo.conf.bck</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-f <replaceable>path</replaceable></option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--file <replaceable>path</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Indicates the path to the Home Manager configuration file. If not given,
|
||||
<filename>~/.config/nixpkgs/home.nix</filename> is used.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-h</option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--help</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Prints usage information for the <command>home-manager</command> tool.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-n</option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--dry-run</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Perform a dry-run of the given operation, only prints what actions would
|
||||
be taken.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--option <replaceable>name</replaceable> <replaceable>value</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--cores <replaceable>number</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-j <replaceable>number</replaceable></option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--max-jobs <replaceable>number</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</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>--keep-failed</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--keep-going</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--show-trace</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--(no-)substitute</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-v</option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--verbose</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Activates verbose output.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>Files</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<filename>~/.local/share/home-manager/news-read-ids</filename>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Identifiers of news items that have been shown. Can be deleted to reset
|
||||
the read news indicator.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>Bugs</title>
|
||||
<para>
|
||||
Please report any bugs on the
|
||||
<link
|
||||
xlink:href="https://github.com/nix-community/home-manager/issues">project
|
||||
issue tracker</link>.
|
||||
</para>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>See also</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>home-configuration.nix</refentrytitle>
|
||||
<manvolnum>5</manvolnum> </citerefentry>
|
||||
</para>
|
||||
</refsection>
|
||||
</refentry>
|
||||
@@ -1,12 +0,0 @@
|
||||
<reference xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<title>Home Manager Reference Pages</title>
|
||||
<info>
|
||||
<author><personname>Home Manager contributors</personname></author>
|
||||
<copyright><year>2017–2020</year><holder>Home Manager contributors</holder>
|
||||
</copyright>
|
||||
</info>
|
||||
<xi:include href="man-configuration.xml" />
|
||||
<xi:include href="man-home-manager.xml" />
|
||||
</reference>
|
||||
@@ -1,52 +0,0 @@
|
||||
<book xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="book-home-manager-manual">
|
||||
<info>
|
||||
<title>Home Manager Manual</title>
|
||||
</info>
|
||||
<preface>
|
||||
<title>Preface</title>
|
||||
<para>
|
||||
This manual will eventually describes 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.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>.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
Commands prefixed with <literal>#</literal> have to be run as root, either
|
||||
requiring to login as root user or temporarily switching to it using
|
||||
<literal>sudo</literal> for example.
|
||||
</para>
|
||||
</note>
|
||||
</preface>
|
||||
<xi:include href="installation.xml" />
|
||||
<xi:include href="writing-modules.xml" />
|
||||
<xi:include href="contributing.xml" />
|
||||
<xi:include href="faq.xml" />
|
||||
<appendix xml:id="ch-options">
|
||||
<title>Configuration Options</title>
|
||||
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||
</appendix>
|
||||
<appendix xml:id="ch-nixos-options">
|
||||
<title>NixOS Module Options</title>
|
||||
<xi:include href="./nmd-result/nixos-options.xml" />
|
||||
</appendix>
|
||||
<appendix xml:id="ch-nix-darwin-options">
|
||||
<title>nix-darwin Module Options</title>
|
||||
<xi:include href="./nmd-result/nix-darwin-options.xml" />
|
||||
</appendix>
|
||||
<appendix xml:id="ch-tools">
|
||||
<title>Tools</title>
|
||||
<xi:include href="./man-home-manager.xml" />
|
||||
</appendix>
|
||||
<xi:include href="./release-notes/release-notes.xml" />
|
||||
</book>
|
||||
@@ -1,21 +0,0 @@
|
||||
[[ch-release-notes]]
|
||||
[appendix]
|
||||
== Release Notes
|
||||
|
||||
This section lists the release notes for stable versions of Home Manager and the current unstable version.
|
||||
|
||||
:leveloffset: 1
|
||||
|
||||
include::rl-2105.adoc[]
|
||||
|
||||
include::rl-2009.adoc[]
|
||||
|
||||
include::rl-2003.adoc[]
|
||||
|
||||
include::rl-1909.adoc[]
|
||||
|
||||
include::rl-1903.adoc[]
|
||||
|
||||
include::rl-1809.adoc[]
|
||||
|
||||
:leveloffset: 0
|
||||
@@ -1,4 +0,0 @@
|
||||
[[sec-release-18.09]]
|
||||
== Release 18.09
|
||||
|
||||
The 18.09 release branch became the stable branch in September, 2018.
|
||||
@@ -1,59 +0,0 @@
|
||||
[[sec-release-19.03]]
|
||||
== Release 19.03
|
||||
|
||||
The 19.03 release branch became the stable branch in April, 2019.
|
||||
|
||||
[[sec-release-19.03-highlights]]
|
||||
=== Highlights
|
||||
:opt-home-file-source: opt-home.file._name_.source
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* The <<{opt-home-file-source}>> option now allows source files to be
|
||||
hidden, that is, having a name starting with the `.` character. It
|
||||
also allows the source file name to contain characters not typically
|
||||
allowed for Nix store paths. For example, your configuration can now
|
||||
contain things such as
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home.file."my file".source = ./. + "/file with spaces!";
|
||||
----
|
||||
|
||||
* The type used for the systemd unit options under
|
||||
<<opt-systemd.user.services>>, <<opt-systemd.user.sockets>>, etc. has
|
||||
been changed to offer more robust merging of configurations. If you
|
||||
don't override values within systemd units then you are not affected
|
||||
by this change. Unfortunately, if you do override unit values you may
|
||||
encounter errors.
|
||||
+
|
||||
In particular, if you get an error saying that a ``unique option'' is
|
||||
``defined multiple times'' then you need to use the
|
||||
https://nixos.org/nixos/manual/#sec-option-definitions-setting-priorities[`mkForce`]
|
||||
function. For example,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
|
||||
----
|
||||
+
|
||||
becomes
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
|
||||
----
|
||||
+
|
||||
We had to make this change because the old merging was causing too
|
||||
many confusing situations for people.
|
||||
|
||||
[[sec-release-19.03-state-version-changes]]
|
||||
=== State Version Changes
|
||||
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the <<opt-home.stateVersion>> option is set
|
||||
to ``19.03'' or later.
|
||||
|
||||
* There is now an option <<opt-programs.beets.enable>> that defaults
|
||||
to `false`. Before the module would be active if the
|
||||
<<opt-programs.beets.settings>> option was non-empty.
|
||||
@@ -1,31 +0,0 @@
|
||||
[[sec-release-19.09]]
|
||||
== Release 19.09
|
||||
|
||||
The 19.09 release branch became the stable branch in October, 2019.
|
||||
|
||||
[[sec-release-19.09-highlights]]
|
||||
=== Highlights
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* The `programs.firefox.enableGoogleTalk` and
|
||||
`programs.firefox.enableIcedTea` options are now deprecated
|
||||
and will only work if Firefox ESR 52.x is used.
|
||||
|
||||
* The `home-manager` tool now provides an `uninstall` sub-command that
|
||||
can be used to uninstall Home Manager, if used in the standalone
|
||||
mode. That is, not as a NixOS module.
|
||||
|
||||
[[sec-release-19.09-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
|
||||
"19.09" or later.
|
||||
|
||||
* The <<opt-programs.firefox.package>> option now expects a wrapped
|
||||
Firefox package and defaults to `pkgs.firefox`.
|
||||
|
||||
* The options <<opt-home.keyboard.layout>> and
|
||||
<<opt-home.keyboard.variant>> now default to `null`, which indicates
|
||||
that the system value should be used.
|
||||
@@ -1,126 +0,0 @@
|
||||
[[sec-release-20.03]]
|
||||
== Release 20.03
|
||||
|
||||
The 20.03 release branch became the stable branch in April, 2020.
|
||||
|
||||
[[sec-release-20.03-highlights]]
|
||||
=== Highlights
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* Assigning a list to the <<opt-home.file>>, <<opt-xdg.configFile>>,
|
||||
and <<opt-xdg.dataFile>> options is now deprecated and will produce a
|
||||
warning message if used. Specifically, if your configuration currently
|
||||
contains something like
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home.file = [
|
||||
{
|
||||
target = ".config/foo.txt";
|
||||
text = "bar";
|
||||
}
|
||||
]
|
||||
----
|
||||
+
|
||||
then it should be updated to instead use the equivalent attribute set form
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home.file = {
|
||||
".config/foo.txt".text = "bar";
|
||||
}
|
||||
----
|
||||
+
|
||||
Support for the list form will be removed in Home Manager version
|
||||
20.09.
|
||||
|
||||
* The `lib` function attribute given to modules is now enriched with
|
||||
an attribute `hm` containing extra library functions specific for Home
|
||||
Manager. More specifically, `lib.hm` is now the same as `config.lib`
|
||||
and should be the preferred choice since it is more robust.
|
||||
+
|
||||
Therefore, if your configuration makes use of, for example,
|
||||
`config.lib.dag` to create activation script blocks, it is recommended
|
||||
to change to `lib.hm.dag`.
|
||||
+
|
||||
Note, in the unlikely case that you are
|
||||
+
|
||||
** using Home Manager's NixOS or nix-darwin module,
|
||||
** have made your own Home Manager module containing an top-level
|
||||
option named `config` or `options`, and
|
||||
** assign to this option in your system configuration inside a plain
|
||||
attribute set, i.e., without a function argument,
|
||||
|
||||
+
|
||||
then you must update your configuration to perform the option
|
||||
assignment inside a `config` attribute. For example, instead of
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home-manager.users.jane = { config = "foo"; };
|
||||
----
|
||||
+
|
||||
use
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home-manager.users.jane = { config.config = "foo"; };
|
||||
----
|
||||
|
||||
* The `services.compton` module has been deprecated and instead the
|
||||
new module `services.picom` should be used. This is because Nixpkgs no
|
||||
longer packages compton, and instead packages the (mostly) compatible
|
||||
fork called picom.
|
||||
|
||||
* The list form of the <<opt-programs.ssh.matchBlocks>> option has
|
||||
been deprecated and configurations requiring match blocks in a defined
|
||||
order should switch to using DAG entries instead. For example, a
|
||||
configuration
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.ssh.matchBlocks = [
|
||||
{
|
||||
host = "alpha.foo.com";
|
||||
user = "jd";
|
||||
}
|
||||
{
|
||||
host = "*.foo.com";
|
||||
user = "john.doe";
|
||||
}
|
||||
];
|
||||
----
|
||||
+
|
||||
can be expressed along the lines of
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.ssh.matchBlocks = {
|
||||
"*.example.com" = {
|
||||
user = "john.doe";
|
||||
}
|
||||
"alpha.example.com" = lib.hm.dag.entryBefore ["*.example.com"] {
|
||||
user = "jd";
|
||||
}
|
||||
};
|
||||
----
|
||||
+
|
||||
Support for the list form will be removed in Home Manager version
|
||||
20.09.
|
||||
|
||||
[[sec-release-20.03-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
|
||||
"20.03" or later.
|
||||
|
||||
* The <<opt-programs.zsh.history.path>> option is no longer prepended
|
||||
by `$HOME`, which allows specifying absolute paths, for example,
|
||||
using the xdg module. Also, the default value is fixed to
|
||||
`$HOME/.zsh_history` and `dotDir` path is not prepended to it
|
||||
anymore.
|
||||
* The newsboat module will now default in displaying `queries` before `urls` in
|
||||
its main window. This makes sense in the case when one has a lot of URLs and
|
||||
few queries.
|
||||
@@ -1,96 +0,0 @@
|
||||
[[sec-release-20.09]]
|
||||
== Release 20.09
|
||||
|
||||
The 20.09 release branch became the stable branch in late September, 2020.
|
||||
|
||||
[[sec-release-20.09-highlights]]
|
||||
=== Highlights
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* Nothing has happened.
|
||||
|
||||
[[sec-release-20.09-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
|
||||
"20.09" or later.
|
||||
|
||||
* The options <<opt-home.homeDirectory>> and <<opt-home.username>> no
|
||||
longer have default values and must therefore be provided in your
|
||||
configuration. Previously their values would default to the content of
|
||||
the environment variables `HOME` and `USER`, respectively.
|
||||
+
|
||||
--
|
||||
Further, the options <<opt-xdg.cacheHome>>, <<opt-xdg.configHome>>,
|
||||
and <<opt-xdg.dataHome>> will no longer be affected by the
|
||||
`XDG_CACHE_HOME`, `XDG_CONFIG_HOME`, and `XDG_DATA_HOME` environment
|
||||
variables. They now unconditionally default to
|
||||
|
||||
- `"${config.home.homeDirectory}/.cache"`,
|
||||
- `"${config.home.homeDirectory}/.config"`, and
|
||||
- `"${config.home.homeDirectory}/.local/share"`.
|
||||
|
||||
If you choose to switch to state version 20.09 then you must set these
|
||||
options if you use non-default XDG base directory paths.
|
||||
|
||||
The initial configuration generated by
|
||||
|
||||
[source,console]
|
||||
$ nix-shell '<home-manager>' -A install
|
||||
|
||||
will automatically include these options, when necessary.
|
||||
--
|
||||
|
||||
* Git's `smtpEncryption` option is now set to `tls` only if both <<opt-accounts.email.accounts.\_name_.smtp.tls.enable>> and <<opt-accounts.email.accounts.\_name_.smtp.tls.useStartTls>> are `true`. If only <<opt-accounts.email.accounts.\_name_.smtp.tls.enable>> is `true`, `ssl` is used instead.
|
||||
|
||||
* The `nixpkgs` module no longer references `<nixpkgs>`. Before it would do so when building the `pkgs` module argument. Starting with state version 20.09, the `pkgs` argument is instead built from the same Nixpkgs that was used to initialize the Home Manager modules. This is useful, for example, when using Home Manager within a Nix Flake. If you want to keep using `<nixpkgs>` with state version ≥ 20.09 then add
|
||||
+
|
||||
[source,nix]
|
||||
_module.args.pkgsPath = <nixpkgs>;
|
||||
+
|
||||
to your Home Manager configuration.
|
||||
|
||||
* The options `wayland.windowManager.sway.config.bars` and `opt-xsession.windowManager.i3.config.bars` have been changed so that most of the suboptions are now nullable and default to `null`. The default for these two options has been changed to manually set the old defaults for each suboption. The overall effect is that if the `bars` options is not set, then the default remains the same. On the other hand, something like:
|
||||
+
|
||||
--
|
||||
[source,nix]
|
||||
----
|
||||
bars = [ {
|
||||
command = "waybar";
|
||||
} ];
|
||||
----
|
||||
will now create the config:
|
||||
....
|
||||
bar {
|
||||
swaybar_command waybar
|
||||
}
|
||||
....
|
||||
instead of
|
||||
....
|
||||
bar {
|
||||
|
||||
font pango:monospace 8
|
||||
mode dock
|
||||
hidden_state hide
|
||||
position bottom
|
||||
status_command /nix/store/h7s6i9q1z5fxrlyyw5ls8vqxhf5bcs5a-i3status-2.13/bin/i3status
|
||||
swaybar_command waybar
|
||||
workspace_buttons yes
|
||||
strip_workspace_numbers no
|
||||
tray_output primary
|
||||
colors {
|
||||
background #000000
|
||||
statusline #ffffff
|
||||
separator #666666
|
||||
focused_workspace #4c7899 #285577 #ffffff
|
||||
active_workspace #333333 #5f676a #ffffff
|
||||
inactive_workspace #333333 #222222 #888888
|
||||
urgent_workspace #2f343a #900000 #ffffff
|
||||
binding_mode #2f343a #900000 #ffffff
|
||||
}
|
||||
|
||||
}
|
||||
....
|
||||
--
|
||||
@@ -1,200 +0,0 @@
|
||||
[[sec-release-21.05]]
|
||||
== Release 21.05
|
||||
|
||||
The 21.05 release branch became the stable branch in May, 2021.
|
||||
|
||||
[[sec-release-21.05-highlights]]
|
||||
=== Highlights
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* The <<opt-programs.broot.verbs>> option is now a list rather than an
|
||||
attribute set. To migrate, move the keys of the attrset into the list
|
||||
items' `invocation` keys. For example,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.broot.verbs = {
|
||||
"p" = { execution = ":parent"; };
|
||||
};
|
||||
----
|
||||
+
|
||||
becomes
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.broot.verbs = [
|
||||
{
|
||||
invocation = "p";
|
||||
execution = ":parent";
|
||||
}
|
||||
];
|
||||
----
|
||||
|
||||
* The <<opt-programs.mpv.package>> option has been changed to allow custom
|
||||
derivations. The following configuration is now possible:
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.mpv.package = (pkgs.wrapMpv (pkgs.mpv-unwrapped.override {
|
||||
vapoursynthSupport = true;
|
||||
}) {
|
||||
extraMakeWrapperArgs = [
|
||||
"--prefix" "LD_LIBRARY_PATH" ":" "${pkgs.vapoursynth-mvtools}/lib/vapoursynth"
|
||||
];
|
||||
});
|
||||
----
|
||||
+
|
||||
As a result of this change, <<opt-programs.mpv.package>> is no longer the
|
||||
resulting derivation. Use the newly introduced `programs.mpv.finalPackage`
|
||||
instead.
|
||||
|
||||
* The <<opt-programs.rofi.extraConfig>> option is now an attribute set rather
|
||||
than a string. To migrate, move each line into the attribute set,
|
||||
removing the `rofi.` prefix from the keys. For example,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.rofi.extraConfig = ''
|
||||
rofi.show-icons: true
|
||||
rofi.modi: drun,emoji,ssh
|
||||
'';
|
||||
----
|
||||
+
|
||||
becomes
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.rofi.extraConfig = {
|
||||
show-icons = true;
|
||||
modi = "drun,emoji,ssh";
|
||||
};
|
||||
----
|
||||
+
|
||||
* The <<opt-programs.rofi.theme>> option now supports defining a theme
|
||||
using an attribute set, the following configuration is now possible:
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
programs.rofi.theme = let
|
||||
# Necessary to avoid quoting non-string values
|
||||
inherit (config.lib.formats.rasi) mkLiteral;
|
||||
in {
|
||||
"@import" = "~/.config/rofi/theme.rasi";
|
||||
|
||||
"*" = {
|
||||
background-color = mkLiteral "#000000";
|
||||
foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )";
|
||||
border-color = mkLiteral "#FFFFFF";
|
||||
width = 512;
|
||||
};
|
||||
|
||||
"#textbox-prompt-colon" = {
|
||||
expand = false;
|
||||
str = ":";
|
||||
margin = mkLiteral "0px 0.3em 0em 0em";
|
||||
text-color = mkLiteral "@foreground-color";
|
||||
};
|
||||
};
|
||||
----
|
||||
|
||||
|
||||
* The `services.redshift.extraOptions` and `services.gammastep.extraOptions`
|
||||
options were removed in favor of <<opt-services.redshift.settings>> and
|
||||
`services.gammastep.settings`, that are now an attribute set rather
|
||||
than a string. They also support new features not available before, for
|
||||
example:
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
services.redshift = {
|
||||
dawnTime = "6:00-7:45";
|
||||
duskTime = "18:35-20:15";
|
||||
settings = {
|
||||
redshift = {
|
||||
gamma = 0.8;
|
||||
adjustment-method = "randr";
|
||||
};
|
||||
|
||||
randr = {
|
||||
screen = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
----
|
||||
+
|
||||
It is recommended to check either
|
||||
https://github.com/jonls/redshift/blob/master/redshift.conf.sample[redshift.conf.sample] or
|
||||
https://gitlab.com/chinstrap/gammastep/-/blob/master/gammastep.conf.sample[gammastep.conf.sample]
|
||||
for the available additional options in each program.
|
||||
|
||||
* Specifying `programs.neomutt.binds.map` or `programs.neomutt.macros.map` as a
|
||||
single string is now deprecated in favor of specfiying it as a list of
|
||||
strings.
|
||||
|
||||
* The `programs.neovim.configure` is deprecated in favor of other `programs.neovim` options;
|
||||
please use the other options at your disposal:
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
configure.packages.*.opt -> programs.neovim.plugins = [ { plugin = ...; optional = true; }]
|
||||
configure.packages.*.start -> programs.neovim.plugins = [ { plugin = ...; }]
|
||||
configure.customRC -> programs.neovim.extraConfig
|
||||
----
|
||||
|
||||
* Home Manager now respects the `NO_COLOR` environment variable as per
|
||||
https://no-color.org/[].
|
||||
|
||||
* Qt module now supports <<opt-qt.style.name>> to specify a theme name and
|
||||
<<opt-qt.style.package>> to specify a theme package. If you have set
|
||||
<<opt-qt.platformTheme>> to `gnome`, a <<opt-qt.style.package>> compatible
|
||||
with both Qt and Gtk is now required to be set. For instance:
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
qt = {
|
||||
platformTheme = "gnome";
|
||||
style = {
|
||||
name = "adwaita-dark";
|
||||
package = pkgs.adwaita-qt;
|
||||
};
|
||||
};
|
||||
----
|
||||
|
||||
* The library type `fontType` now has a `size` attribute in addition to `name`. For example:
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
font = {
|
||||
name = "DejaVu Sans";
|
||||
size = 8;
|
||||
};
|
||||
----
|
||||
|
||||
* The <<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
|
||||
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the `home.stateVersion` option is set to
|
||||
"21.05" or later.
|
||||
|
||||
* The `newsboat` module now stores generated configuration in
|
||||
`$XDG_CONFIG_HOME/newsboat`.
|
||||
@@ -1,187 +0,0 @@
|
||||
[[ch-writing-modules]]
|
||||
== Writing Home Manager Modules
|
||||
:writing-nixos-modules: https://nixos.org/nixos/manual/index.html#sec-writing-modules
|
||||
|
||||
The module system in Home Manager is based entirely on the NixOS module system so we will here only highlight aspects that are specific for Home Manager. For information about the module system as such please refer to the {writing-nixos-modules}[Writing NixOS Modules] chapter of the NixOS manual.
|
||||
|
||||
[[sec-option-types]]
|
||||
=== Option Types
|
||||
:wikipedia-dag: https://en.wikipedia.org/w/index.php?title=Directed_acyclic_graph&oldid=939656095
|
||||
:gvariant-description: https://developer.gnome.org/glib/stable/glib-GVariant.html#glib-GVariant.description
|
||||
|
||||
Overall the basic option types are the same in Home Manager as NixOS. A few Home Manager options, however, make use of custom types that are worth describing in more detail. These are the option types `dagOf` and `gvariant` that are used, for example, by <<opt-programs.ssh.matchBlocks>> and <<opt-dconf.settings>>.
|
||||
|
||||
`hm.types.dagOf`::
|
||||
Options of this type have attribute sets as values where each member is a node in a {wikipedia-dag}[directed acyclic graph] (DAG). This allows the attribute set entries to express dependency relations among themselves. This can, for example, be used to control the order of match blocks in a OpenSSH client configuration or the order of activation script blocks in <<opt-home.activation>>.
|
||||
+
|
||||
A number of functions are provided to create DAG nodes. The functions are shown below with examples using an option `foo.bar` of type `hm.types.dagOf types.int`.
|
||||
+
|
||||
`hm.dag.entryAnywhere (value: T)`:::
|
||||
Indicates that `value` can be placed anywhere within the DAG. This is also the default for plain attribute set entries, that is
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = {
|
||||
a = hm.dag.entryAnywhere 0;
|
||||
}
|
||||
----
|
||||
+
|
||||
and
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = {
|
||||
a = 0;
|
||||
}
|
||||
----
|
||||
+
|
||||
are equivalent.
|
||||
+
|
||||
`hm.dag.entryAfter (afters: list string) (value: T)`:::
|
||||
Indicates that `value` must be placed _after_ each of the attribute names in the given list. For example
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = {
|
||||
a = 0;
|
||||
b = hm.dag.entryAfter [ "a" ] 1;
|
||||
}
|
||||
----
|
||||
+
|
||||
would place `b` after `a` in the graph.
|
||||
+
|
||||
`hm.dag.entryBefore (befores: list string) (value: T)`:::
|
||||
Indicates that `value` must be placed _before_ each of the attribute names in the given list. For example
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = {
|
||||
b = hm.dag.entryBefore [ "a" ] 1;
|
||||
a = 0;
|
||||
}
|
||||
----
|
||||
+
|
||||
would place `b` before `a` in the graph.
|
||||
+
|
||||
`hm.dag.entryBetween (befores: list string) (afters: list string) (value: T)`:::
|
||||
Indicates that `value` must be placed _before_ the attribute names in the first list and _after_ the attribute names in the second list. For example
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = {
|
||||
a = 0;
|
||||
c = hm.dag.entryBetween [ "b" ] [ "a" ] 2;
|
||||
b = 1;
|
||||
}
|
||||
----
|
||||
+
|
||||
would place `c` before `b` and after `a` in the graph.
|
||||
|
||||
`hm.types.gvariant`::
|
||||
This type is useful for options representing {gvariant-description}[GVariant] values. The type accepts all primitive GVariant types as well as arrays and tuples. Dictionaries are not currently supported.
|
||||
+
|
||||
To create a GVariant value you can use a number of provided functions. Examples assume an option `foo.bar` of type `hm.types.gvariant`.
|
||||
+
|
||||
`hm.gvariant.mkBoolean (v: bool)`:::
|
||||
Takes a Nix value `v` to a GVariant `boolean` value. Note, Nix booleans are automatically coerced using this function. That is,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = hm.gvariant.mkBoolean true;
|
||||
----
|
||||
+
|
||||
is equivalent to
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = true;
|
||||
----
|
||||
`hm.gvariant.mkString (v: string)`:::
|
||||
Takes a Nix value `v` to a GVariant `string` value. Note, Nix strings are automatically coerced using this function. That is,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = hm.gvariant.mkString "a string";
|
||||
----
|
||||
+
|
||||
is equivalent to
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = "a string";
|
||||
----
|
||||
`hm.gvariant.mkObjectpath (v: string)`:::
|
||||
Takes a Nix value `v` to a GVariant `objectpath` value.
|
||||
`hm.gvariant.mkUchar (v: string)`:::
|
||||
Takes a Nix value `v` to a GVariant `uchar` value.
|
||||
`hm.gvariant.mkInt16 (v: int)`:::
|
||||
Takes a Nix value `v` to a GVariant `int16` value.
|
||||
`hm.gvariant.mkUint16 (v: int)`:::
|
||||
Takes a Nix value `v` to a GVariant `uint16` value.
|
||||
`hm.gvariant.mkInt32 (v: int)`:::
|
||||
Takes a Nix value `v` to a GVariant `int32` value. Note, Nix integers are automatically coerced using this function. That is,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = hm.gvariant.mkInt32 7;
|
||||
----
|
||||
+
|
||||
is equivalent to
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = 7;
|
||||
----
|
||||
`hm.gvariant.mkUint32 (v: int)`:::
|
||||
Takes a Nix value `v` to a GVariant `uint32` value.
|
||||
`hm.gvariant.mkInt64 (v: int)`:::
|
||||
Takes a Nix value `v` to a GVariant `int64` value.
|
||||
`hm.gvariant.mkUint64 (v: int)`:::
|
||||
Takes a Nix value `v` to a GVariant `uint64` value.
|
||||
`hm.gvariant.mkDouble (v: double)`:::
|
||||
Takes a Nix value `v` to a GVariant `double` value. Note, Nix floats are automatically coerced using this function. That is,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = hm.gvariant.mkDouble 3.14;
|
||||
----
|
||||
+
|
||||
is equivalent to
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
foo.bar = 3.14;
|
||||
----
|
||||
+
|
||||
`hm.gvariant.mkArray type elements`:::
|
||||
Builds a GVariant array containing the given list of elements, where each element is a GVariant value of the given type. The `type` value can be constructed using
|
||||
+
|
||||
--
|
||||
- `hm.gvariant.type.string`
|
||||
- `hm.gvariant.type.boolean`
|
||||
- `hm.gvariant.type.uchar`
|
||||
- `hm.gvariant.type.int16`
|
||||
- `hm.gvariant.type.uint16`
|
||||
- `hm.gvariant.type.int32`
|
||||
- `hm.gvariant.type.uint32`
|
||||
- `hm.gvariant.type.int64`
|
||||
- `hm.gvariant.type.uint64`
|
||||
- `hm.gvariant.type.double`
|
||||
- `hm.gvariant.type.arrayOf type`
|
||||
- `hm.gvariant.type.maybeOf type`
|
||||
- `hm.gvariant.type.tupleOf types`
|
||||
--
|
||||
+
|
||||
where `type` and `types` are themselves a type and list of types, respectively.
|
||||
+
|
||||
`hm.gvariant.mkEmptyArray type`:::
|
||||
An alias of `hm.gvariant.mkArray type []`.
|
||||
+
|
||||
`hm.gvariant.mkNothing type`:::
|
||||
Builds a GVariant maybe value whose (non-existent) element is of the given type. The `type` value is constructed as described for the `mkArray` function above.
|
||||
+
|
||||
`hm.gvariant.mkJust element`:::
|
||||
Builds a GVariant maybe value containing the given GVariant element.
|
||||
+
|
||||
`hm.gvariant.mkTuple elements`:::
|
||||
Builds a GVariant tuple containing the given list of elements, where each element is a GVariant value.
|
||||
46
flake.nix
46
flake.nix
@@ -1,46 +0,0 @@
|
||||
{
|
||||
description = "Home Manager for Nix";
|
||||
|
||||
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: {
|
||||
home-manager = nixpkgsFor.${system}.callPackage ./home-manager { };
|
||||
});
|
||||
|
||||
defaultPackage =
|
||||
forAllSystems (system: self.packages.${system}.home-manager);
|
||||
|
||||
lib = {
|
||||
hm = import ./modules/lib { lib = nixpkgs.lib; };
|
||||
homeManagerConfiguration = { configuration, system, homeDirectory
|
||||
, username, extraModules ? [ ], extraSpecialArgs ? { }
|
||||
, pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages
|
||||
, check ? true, stateVersion ? "20.09" }@args:
|
||||
assert nixpkgs.lib.versionAtLeast stateVersion "20.09";
|
||||
|
||||
import ./modules {
|
||||
inherit pkgs check extraSpecialArgs;
|
||||
configuration = { ... }: {
|
||||
imports = [ configuration ] ++ extraModules;
|
||||
home = { inherit homeDirectory stateVersion username; };
|
||||
nixpkgs = { inherit (pkgs) config overlays; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
50
format
50
format
@@ -1,50 +0,0 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/05f0934825c2a0750d4888c4735f9420c906b388.tar.gz -i bash -p findutils nixfmt
|
||||
|
||||
CHECK_ARG=
|
||||
|
||||
case $1 in
|
||||
-h)
|
||||
echo "$0 [-c]"
|
||||
;;
|
||||
-c)
|
||||
CHECK_ARG=-c
|
||||
;;
|
||||
esac
|
||||
|
||||
# The first block of excludes are files where nixfmt does a poor job,
|
||||
# IMHO. The second block of excludes are files touched by open pull
|
||||
# requests and we want to avoid merge conflicts.
|
||||
find . -name '*.nix' \
|
||||
! -path ./modules/programs/irssi.nix \
|
||||
\
|
||||
! -path ./home-manager/home-manager.nix \
|
||||
! -path ./modules/default.nix \
|
||||
! -path ./modules/files.nix \
|
||||
! -path ./modules/home-environment.nix \
|
||||
! -path ./modules/lib/default.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/bash.nix \
|
||||
! -path ./modules/programs/firefox.nix \
|
||||
! -path ./modules/programs/gpg.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/mpd.nix \
|
||||
! -path ./modules/services/sxhkd.nix \
|
||||
! -path ./modules/systemd.nix \
|
||||
! -path ./nix-darwin/default.nix \
|
||||
! -path ./tests/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 {} +
|
||||
@@ -1,357 +0,0 @@
|
||||
#!/bin/env bash
|
||||
|
||||
##################################################
|
||||
|
||||
# « home-manager » command-line completion
|
||||
#
|
||||
# © 2019 "Sam Boosalis" <samboosalis@gmail.com>
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
|
||||
##################################################
|
||||
# Contributing:
|
||||
|
||||
# Compatibility — Bash 3.
|
||||
#
|
||||
# OSX won't update Bash 3 (last updated circa 2009) to Bash 4,
|
||||
# and we'd like this completion script to work on both Linux and Mac.
|
||||
#
|
||||
# For example, OSX Yosemite (released circa 2014) ships with Bash 3:
|
||||
#
|
||||
# $ echo $BASH_VERSION
|
||||
# 3.2
|
||||
#
|
||||
# While Ubuntu LTS 14.04 (a.k.a. Trusty, also released circa 2016)
|
||||
# ships with the latest version, Bash 4 (updated circa 2016):
|
||||
#
|
||||
# $ echo $BASH_VERSION
|
||||
# 4.3
|
||||
#
|
||||
|
||||
# Testing
|
||||
#
|
||||
# (1) Invoke « shellcheck »
|
||||
#
|
||||
# * source: « https://github.com/koalaman/shellcheck »
|
||||
# * run: « shellcheck ./share/bash-completion/completions/home-manager »
|
||||
#
|
||||
# (2) Interpret via Bash 3
|
||||
#
|
||||
# * run: « bash --noprofile --norc ./share/bash-completion/completions/home-manager »
|
||||
#
|
||||
|
||||
##################################################
|
||||
# Examples:
|
||||
|
||||
# $ home-manager <TAB>
|
||||
#
|
||||
# -A
|
||||
# -I
|
||||
# -f
|
||||
# --file
|
||||
# -h
|
||||
# --help
|
||||
# -n
|
||||
# --dry-run
|
||||
# -v
|
||||
# --verbose
|
||||
# build
|
||||
# edit
|
||||
# expire-generations
|
||||
# generations
|
||||
# help
|
||||
# news
|
||||
# packages
|
||||
# remove-generations
|
||||
# switch
|
||||
# uninstall
|
||||
|
||||
# $ home-manager e<TAB>
|
||||
#
|
||||
# edit
|
||||
# expire-generations
|
||||
|
||||
# $ home-manager remove-generations 20<TAB>
|
||||
#
|
||||
# 200
|
||||
# 201
|
||||
# 202
|
||||
# 203
|
||||
|
||||
##################################################
|
||||
# Notes:
|
||||
|
||||
# « home-manager » Subcommands:
|
||||
#
|
||||
# help
|
||||
# edit
|
||||
# build
|
||||
# switch
|
||||
# generations
|
||||
# remove-generations
|
||||
# expire-generations
|
||||
# packages
|
||||
# news
|
||||
# uninstall
|
||||
|
||||
# « home-manager » Options:
|
||||
#
|
||||
# -b EXT
|
||||
# -f FILE
|
||||
# --file FILE
|
||||
# -A ATTRIBUTE
|
||||
# -I PATH
|
||||
# -v
|
||||
# --verbose
|
||||
# -n
|
||||
# --dry-run
|
||||
# -h
|
||||
# --help
|
||||
|
||||
# $ home-manager
|
||||
#
|
||||
# Usage: /home/sboo/.nix-profile/bin/home-manager [OPTION] COMMAND
|
||||
#
|
||||
# Options
|
||||
#
|
||||
# -f FILE The home configuration file.
|
||||
# Default is '~/.config/nixpkgs/home.nix'.
|
||||
# -A ATTRIBUTE Optional attribute that selects a configuration
|
||||
# expression in the configuration file.
|
||||
# -I PATH Add a path to the Nix expression search path.
|
||||
# -b EXT Move existing files to new path rather than fail.
|
||||
# -v Verbose output
|
||||
# -n Do a dry run, only prints what actions would be taken
|
||||
# -h Print this help
|
||||
#
|
||||
# Commands
|
||||
#
|
||||
# help Print this help
|
||||
#
|
||||
# edit Open the home configuration in $EDITOR
|
||||
#
|
||||
# build Build configuration into result directory
|
||||
#
|
||||
# switch Build and activate configuration
|
||||
#
|
||||
# generations List all home environment generations
|
||||
#
|
||||
# remove-generations ID...
|
||||
# Remove indicated generations. Use 'generations' command to
|
||||
# find suitable generation numbers.
|
||||
#
|
||||
# expire-generations TIMESTAMP
|
||||
# Remove generations older than TIMESTAMP where TIMESTAMP is
|
||||
# interpreted as in the -d argument of the date tool. For
|
||||
# example "-30 days" or "2018-01-01".
|
||||
#
|
||||
# packages List all packages installed in home-manager-path
|
||||
#
|
||||
# news Show news entries in a pager
|
||||
#
|
||||
# uninstall Remove Home Manager
|
||||
#
|
||||
##################################################
|
||||
# Dependencies:
|
||||
|
||||
command -v home-manager >/dev/null
|
||||
command -v grep >/dev/null
|
||||
command -v sed >/dev/null
|
||||
|
||||
##################################################
|
||||
# Code:
|
||||
|
||||
_home-manager_list-generation-identifiers ()
|
||||
|
||||
{
|
||||
|
||||
home-manager generations | sed -n -e 's/^................ : id \([[:alnum:]]\+\) -> .*/\1/p'
|
||||
|
||||
}
|
||||
|
||||
# NOTES
|
||||
#
|
||||
# (1) the « sed -n -e 's/.../.../p' » invocation:
|
||||
#
|
||||
# * the « -e '...' » option takes a Sed Script.
|
||||
# * the « -n » option only prints when « .../p » would print.
|
||||
# * the « s/xxx/yyy/ » Sed Script substitutes « yyy » whenever « xxx » is matched.
|
||||
#
|
||||
# (2) the « '^................ : id \([[:alnum:]]\+\) -> .*' » regular expression:
|
||||
#
|
||||
# * matches « 199 », for example, in the line « 2019-03-13 15:26 : id 199 -> /nix/store/mv619y9pzgsx3kndq0q7fjfvbqqdy5k8-home-manager-generation »
|
||||
#
|
||||
#
|
||||
|
||||
#------------------------------------------------#
|
||||
|
||||
# shellcheck disable=SC2120
|
||||
_home-manager_list-nix-attributes ()
|
||||
|
||||
{
|
||||
local HomeFile
|
||||
local HomeAttrsString
|
||||
# local HomeAttrsArray
|
||||
# local HomeAttr
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
HomeFile=$(readlink -f "$(_home-manager_get-default-home-file)")
|
||||
else
|
||||
HomeFile="$1"
|
||||
fi
|
||||
|
||||
HomeAttrsString=$(nix-instantiate --eval -E "let home = import ${HomeFile}; in (builtins.trace (builtins.toString (builtins.attrNames home)) null)" |& grep '^trace: ')
|
||||
HomeAttrsString="${HomeAttrsString#trace: }"
|
||||
|
||||
echo "${HomeAttrsString}"
|
||||
|
||||
# IFS=" " read -ar HomeAttrsArray <<< "${HomeAttrsString}"
|
||||
#
|
||||
# local HomeAttr
|
||||
# for HomeAttr in "${HomeAttrsArray[@]}"
|
||||
# do
|
||||
# echo "${HomeAttr}"
|
||||
# done
|
||||
|
||||
}
|
||||
|
||||
# e.g.:
|
||||
#
|
||||
# $ nix-instantiate --eval -E 'let home = import /home/sboo/configuration/configs/nixpkgs/home-attrs.nix; in (builtins.trace (builtins.toString (builtins.attrNames home)) null)' 1>/dev/null
|
||||
# trace: darwin linux
|
||||
#
|
||||
# $ _home-manager_list-nix-attributes
|
||||
# linux darwin
|
||||
#
|
||||
|
||||
#------------------------------------------------#
|
||||
|
||||
_home-manager_get-default-home-file ()
|
||||
|
||||
{
|
||||
local HomeFileDefault
|
||||
|
||||
HomeFileDefault="$(_home-manager_xdg-get-config-home)/nixpkgs/home.nix"
|
||||
|
||||
echo "${HomeFileDefault}"
|
||||
}
|
||||
|
||||
# e.g.:
|
||||
#
|
||||
# $ _home-manager_get-default-home-file
|
||||
# ~/.config/nixpkgs/home.nix
|
||||
#
|
||||
|
||||
##################################################
|
||||
# XDG-BaseDirs:
|
||||
|
||||
_home-manager_xdg-get-config-home () {
|
||||
|
||||
echo "${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------#
|
||||
|
||||
_home-manager_xdg-get-data-home () {
|
||||
|
||||
echo "${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------#
|
||||
_home-manager_xdg-get-cache-home () {
|
||||
|
||||
echo "${XDG_CACHE_HOME:-$HOME/.cache}"
|
||||
|
||||
}
|
||||
|
||||
##################################################
|
||||
|
||||
# shellcheck disable=SC2207
|
||||
_home-manager_completions ()
|
||||
{
|
||||
|
||||
#--------------------------#
|
||||
|
||||
local Subcommands
|
||||
Subcommands=( "help" "edit" "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" \
|
||||
"--cores" "--debug" "--keep-failed" "--keep-going" "-j" "--max-jobs" "--no-substitute" "--show-trace" "--substitute")
|
||||
|
||||
# ^ « home-manager »'s options.
|
||||
|
||||
#--------------------------#
|
||||
|
||||
local CurrentWord
|
||||
CurrentWord="${COMP_WORDS[$COMP_CWORD]}"
|
||||
|
||||
# ^ the word currently being completed
|
||||
|
||||
local PreviousWord
|
||||
if [ "$COMP_CWORD" -ge 1 ]
|
||||
then
|
||||
PreviousWord="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
else
|
||||
PreviousWord=""
|
||||
fi
|
||||
|
||||
# ^ the word to the left of the current word.
|
||||
#
|
||||
# e.g. in « home-manager -v -f ./<TAB> »:
|
||||
#
|
||||
# PreviousWord="-f"
|
||||
# CurrentWord="./"
|
||||
|
||||
#--------------------------#
|
||||
|
||||
COMPREPLY=()
|
||||
|
||||
case "$PreviousWord" in
|
||||
|
||||
"-f"|"--file")
|
||||
|
||||
COMPREPLY+=( $( compgen -A file -- "$CurrentWord") )
|
||||
;;
|
||||
|
||||
"-I")
|
||||
|
||||
COMPREPLY+=( $( compgen -A directory -- "$CurrentWord") )
|
||||
;;
|
||||
|
||||
"-A")
|
||||
|
||||
# shellcheck disable=SC2119
|
||||
COMPREPLY+=( $( compgen -W "$(_home-manager_list-nix-attributes)" -- "$CurrentWord") )
|
||||
;;
|
||||
|
||||
"remove-generations")
|
||||
|
||||
COMPREPLY+=( $( compgen -W "$(_home-manager_list-generation-identifiers)" -- "$CurrentWord" ) )
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
COMPREPLY+=( $( compgen -W "${Subcommands[*]}" -- "$CurrentWord" ) )
|
||||
COMPREPLY+=( $( compgen -W "${Options[*]}" -- "$CurrentWord" ) )
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
#--------------------------#
|
||||
}
|
||||
|
||||
##################################################
|
||||
|
||||
complete -F _home-manager_completions -o default home-manager
|
||||
|
||||
#complete -W "help edit build switch generations remove-generations expire-generations packages news" home-manager
|
||||
@@ -1,58 +0,0 @@
|
||||
#compdef home-manager
|
||||
|
||||
local state ret=1
|
||||
|
||||
_arguments \
|
||||
'-A[attribute]:ATTRIBUTE:()' \
|
||||
'-I[search path]:PATH:_files -/' \
|
||||
'-b[backup files]:EXT:()' \
|
||||
'--cores[cores]:NUM:()' \
|
||||
'--debug[debug]' \
|
||||
'--keep-failed[keep failed]' \
|
||||
'--keep-going[keep going]' \
|
||||
'(-h --help)'{--help,-h}'[help]' \
|
||||
'(-v --verbose)'{--verbose,-v}'[verbose]' \
|
||||
'(-n --dry-run)'{--dry-run,-n}'[dry run]' \
|
||||
'(-f --file)'{--file,-f}'[configuration file]:FILE:_files' \
|
||||
'(-j --max-jobs)'{--max-jobs,-j}'[max jobs]:NUM:()' \
|
||||
'--option[option]:NAME VALUE:()' \
|
||||
'--show-trace[show trace]' \
|
||||
'1: :->cmds' \
|
||||
'*:: :->args' && ret=0
|
||||
|
||||
case "$state" in
|
||||
cmds)
|
||||
_values 'command' \
|
||||
'help[help]' \
|
||||
'edit[edit]' \
|
||||
'build[build]' \
|
||||
'switch[switch]' \
|
||||
'generations[list generations]' \
|
||||
'remove-generations[remove generations]' \
|
||||
'expire-generations[expire generations]' \
|
||||
'packages[managed packages]' \
|
||||
'news[read the news]' \
|
||||
'uninstall[uninstall]' && ret=0
|
||||
;;
|
||||
args)
|
||||
case $line[1] in
|
||||
remove-generations)
|
||||
_values 'generations' \
|
||||
$(home-manager generations | cut -d ' ' -f 5) && ret=0
|
||||
;;
|
||||
build|switch)
|
||||
_arguments \
|
||||
'--cores[cores]:NUM:()' \
|
||||
'--debug[debug]' \
|
||||
'--keep-failed[keep failed]' \
|
||||
'--keep-going[keep going]' \
|
||||
'--max-jobs[max jobs]:NUM:()' \
|
||||
'--no-substitute[no substitute]' \
|
||||
'--option[option]:NAME VALUE:()' \
|
||||
'--show-trace[show trace]' \
|
||||
'--substitute[substitute]'
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
|
||||
return ret
|
||||
@@ -1,36 +1,34 @@
|
||||
{ runCommand, lib, bash, coreutils, findutils, gnused, less
|
||||
{ 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 runCommand "home-manager" {
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
meta = with lib; {
|
||||
in
|
||||
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager";
|
||||
|
||||
buildCommand = ''
|
||||
install -v -D -m755 ${./home-manager} $out/bin/home-manager
|
||||
|
||||
substituteInPlace $out/bin/home-manager \
|
||||
--subst-var-by bash "${pkgs.bash}" \
|
||||
--subst-var-by coreutils "${pkgs.coreutils}" \
|
||||
--subst-var-by less "${pkgs.less}" \
|
||||
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
|
||||
'';
|
||||
|
||||
meta = with pkgs.stdenv.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}'
|
||||
|
||||
install -D -m755 ${./completion.bash} \
|
||||
$out/share/bash-completion/completions/home-manager
|
||||
install -D -m755 ${./completion.zsh} \
|
||||
$out/share/zsh/site-functions/_home-manager
|
||||
''
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#!@bash@/bin/bash
|
||||
|
||||
# Prepare to use tools from Nixpkgs.
|
||||
PATH=@coreutils@/bin:@findutils@/bin:@gnused@/bin:@less@/bin${PATH:+:}$PATH
|
||||
# This code explicitly requires GNU Core Utilities and we therefore
|
||||
# need to ensure they are prioritized over any other similarly named
|
||||
# tools on the system.
|
||||
PATH=@coreutils@/bin:@less@/bin${PATH:+:}$PATH
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -10,28 +12,6 @@ function errorEcho() {
|
||||
echo $* >&2
|
||||
}
|
||||
|
||||
function setVerboseAndDryRun() {
|
||||
if [[ -v VERBOSE ]]; then
|
||||
export VERBOSE_ARG="--verbose"
|
||||
else
|
||||
export VERBOSE_ARG=""
|
||||
fi
|
||||
|
||||
if [[ -v DRY_RUN ]] ; then
|
||||
export DRY_RUN_CMD=echo
|
||||
else
|
||||
export DRY_RUN_CMD=""
|
||||
fi
|
||||
}
|
||||
|
||||
function setWorkDir() {
|
||||
if [[ ! -v WORK_DIR ]]; then
|
||||
WORK_DIR="$(mktemp --tmpdir -d home-manager-build.XXXXXXXXXX)"
|
||||
# shellcheck disable=2064
|
||||
trap "rm -r '$WORK_DIR'" EXIT
|
||||
fi
|
||||
}
|
||||
|
||||
# Attempts to set the HOME_MANAGER_CONFIG global variable.
|
||||
#
|
||||
# If no configuration file can be found then this function will print
|
||||
@@ -52,7 +32,7 @@ function setConfigFile() {
|
||||
for confFile in "$defaultConfFile" \
|
||||
"$HOME/.nixpkgs/home.nix" ; do
|
||||
if [[ -e "$confFile" ]] ; then
|
||||
HOME_MANAGER_CONFIG="$(realpath "$confFile")"
|
||||
HOME_MANAGER_CONFIG="$confFile"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@@ -74,74 +54,24 @@ 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 doInstantiate() {
|
||||
setFlakeAttribute
|
||||
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||
errorEcho "Can't instantiate 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
|
||||
|
||||
nix-instantiate \
|
||||
"<home-manager/home-manager/home-manager.nix>" \
|
||||
"${extraArgs[@]}" \
|
||||
"${PASSTHROUGH_OPTS[@]}" \
|
||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||
}
|
||||
|
||||
function doBuildAttr() {
|
||||
setConfigFile
|
||||
setHomeManagerNixPath
|
||||
|
||||
local extraArgs=("$@")
|
||||
local extraArgs="$*"
|
||||
|
||||
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||
extraArgs="$extraArgs -I $p"
|
||||
done
|
||||
|
||||
if [[ -v VERBOSE ]]; then
|
||||
extraArgs=("${extraArgs[@]}" "--show-trace")
|
||||
extraArgs="$extraArgs --show-trace"
|
||||
fi
|
||||
|
||||
# shellcheck disable=2086
|
||||
nix-build \
|
||||
"<home-manager/home-manager/home-manager.nix>" \
|
||||
"${extraArgs[@]}" \
|
||||
"${PASSTHROUGH_OPTS[@]}" \
|
||||
$extraArgs \
|
||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||
}
|
||||
@@ -185,46 +115,17 @@ function presentNews() {
|
||||
fi
|
||||
}
|
||||
|
||||
function doEdit() {
|
||||
if [[ ! -v EDITOR || -z $EDITOR ]]; then
|
||||
errorEcho "Please set the \$EDITOR environment variable"
|
||||
return 1
|
||||
fi
|
||||
|
||||
setConfigFile
|
||||
|
||||
# Don't quote $EDITOR in order to support values including options, e.g.,
|
||||
# "code --wait".
|
||||
#
|
||||
# shellcheck disable=2086
|
||||
exec $EDITOR "$HOME_MANAGER_CONFIG"
|
||||
}
|
||||
|
||||
function doBuild() {
|
||||
if [[ ! -w . ]]; then
|
||||
errorEcho "Cannot run build in read-only directory";
|
||||
return 1
|
||||
fi
|
||||
|
||||
setFlakeAttribute
|
||||
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||
local exitCode=0
|
||||
nix build \
|
||||
"${PASSTHROUGH_OPTS[@]}" \
|
||||
${DRY_RUN+--dry-run} \
|
||||
"$FLAKE_CONFIG_URI.activationPackage" \
|
||||
|| exitCode=1
|
||||
return $exitCode
|
||||
fi
|
||||
|
||||
setWorkDir
|
||||
|
||||
local newsInfo
|
||||
newsInfo=$(buildNews)
|
||||
|
||||
local exitCode
|
||||
|
||||
doBuildAttr --attr activationPackage \
|
||||
doBuildAttr -A activationPackage \
|
||||
&& exitCode=0 || exitCode=1
|
||||
|
||||
presentNews "$newsInfo"
|
||||
@@ -233,34 +134,24 @@ 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
|
||||
newsInfo=$(buildNews)
|
||||
|
||||
local generation
|
||||
local exitCode=0
|
||||
local wrkdir
|
||||
|
||||
# Build the generation and run the activate script. Note, we
|
||||
# specify an output link so that it is treated as a GC root. This
|
||||
# prevents an unfortunately timed GC from removing the generation
|
||||
# before activation completes.
|
||||
generation="$WORK_DIR/generation"
|
||||
wrkdir="$(mktemp -d)"
|
||||
generation=$(doBuildAttr -o "$wrkdir/result" -A activationPackage) \
|
||||
&& $generation/activate || exitCode=1
|
||||
|
||||
doBuildAttr \
|
||||
--out-link "$generation" \
|
||||
--attr activationPackage \
|
||||
&& "$generation/activate" || exitCode=1
|
||||
# Because the previous command never fails, the script keeps
|
||||
# running and $wrkdir is always removed.
|
||||
rm -r "$wrkdir"
|
||||
|
||||
presentNews "$newsInfo"
|
||||
|
||||
@@ -270,11 +161,11 @@ function doSwitch() {
|
||||
function doListGens() {
|
||||
# Whether to colorize the generations output.
|
||||
local color="never"
|
||||
if [[ ! -v NO_COLOR && -t 1 ]]; then
|
||||
if [[ -t 1 ]]; then
|
||||
color="always"
|
||||
fi
|
||||
|
||||
pushd "$NIX_STATE_DIR/profiles/per-user/$USER" > /dev/null
|
||||
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
|
||||
# shellcheck disable=2012
|
||||
ls --color=$color -gG --time-style=long-iso --sort time home-manager-*-link \
|
||||
| cut -d' ' -f 4- \
|
||||
@@ -285,9 +176,19 @@ function doListGens() {
|
||||
# Removes linked generations. Takes as arguments identifiers of
|
||||
# generations to remove.
|
||||
function doRmGenerations() {
|
||||
setVerboseAndDryRun
|
||||
if [[ -v VERBOSE ]]; then
|
||||
export VERBOSE_ARG="--verbose"
|
||||
else
|
||||
export VERBOSE_ARG=""
|
||||
fi
|
||||
|
||||
pushd "$NIX_STATE_DIR/profiles/per-user/$USER" > /dev/null
|
||||
if [[ -v DRY_RUN ]] ; then
|
||||
export DRY_RUN_CMD=echo
|
||||
else
|
||||
export DRY_RUN_CMD=""
|
||||
fi
|
||||
|
||||
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
|
||||
|
||||
for generationId in "$@"; do
|
||||
local linkName="home-manager-$generationId-link"
|
||||
@@ -305,28 +206,6 @@ function doRmGenerations() {
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function doRmAllGenerations() {
|
||||
$DRY_RUN_CMD rm $VERBOSE_ARG \
|
||||
"$NIX_STATE_DIR/profiles/per-user/$USER/home-manager"*
|
||||
}
|
||||
|
||||
function doExpireGenerations() {
|
||||
local profileDir="$NIX_STATE_DIR/profiles/per-user/$USER"
|
||||
|
||||
local generations
|
||||
generations="$( \
|
||||
find "$profileDir" -name 'home-manager-*-link' -not -newermt "$1" \
|
||||
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
|
||||
)"
|
||||
|
||||
if [[ -n $generations ]]; then
|
||||
# shellcheck disable=2086
|
||||
doRmGenerations $generations
|
||||
elif [[ -v VERBOSE ]]; then
|
||||
echo "No generations to expire"
|
||||
fi
|
||||
}
|
||||
|
||||
function doListPackages() {
|
||||
local outPath
|
||||
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
|
||||
@@ -354,27 +233,18 @@ function newsReadIdsFile() {
|
||||
# Builds news meta information to be sourced into this script.
|
||||
#
|
||||
# Note, we suppress build output to remove unnecessary verbosity. We
|
||||
# put the output in the work directory to avoid the risk of an
|
||||
# unfortunately timed GC removing it.
|
||||
# also use "no out link" to avoid the need for a build directory
|
||||
# (although this exposes the risk of GC removing the result before we
|
||||
# manage to source it).
|
||||
function buildNews() {
|
||||
local output
|
||||
output="$WORK_DIR/news-info.sh"
|
||||
|
||||
doBuildAttr \
|
||||
--out-link "$output" \
|
||||
--no-build-output \
|
||||
--quiet \
|
||||
--arg check false \
|
||||
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||
doBuildAttr --quiet \
|
||||
--attr newsInfo \
|
||||
> /dev/null
|
||||
|
||||
echo "$output"
|
||||
--no-out-link \
|
||||
--arg check false \
|
||||
--argstr newsReadIdsFile "$(newsReadIdsFile)"
|
||||
}
|
||||
|
||||
function doShowNews() {
|
||||
setWorkDir
|
||||
|
||||
local infoFile
|
||||
infoFile=$(buildNews) || return 1
|
||||
|
||||
@@ -402,95 +272,26 @@ function doShowNews() {
|
||||
fi
|
||||
}
|
||||
|
||||
function doUninstall() {
|
||||
setVerboseAndDryRun
|
||||
|
||||
echo "This will remove Home Manager from your system."
|
||||
|
||||
if [[ -v DRY_RUN ]]; then
|
||||
echo "This is a dry run, nothing will actually be uninstalled."
|
||||
fi
|
||||
|
||||
local confirmation
|
||||
read -r -n 1 -p "Really uninstall Home Manager? [y/n] " confirmation
|
||||
echo
|
||||
|
||||
case $confirmation in
|
||||
y|Y)
|
||||
echo "Switching to empty Home Manager configuration..."
|
||||
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
|
||||
echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG"
|
||||
doSwitch
|
||||
$DRY_RUN_CMD nix-env -e home-manager-path || true
|
||||
rm "$HOME_MANAGER_CONFIG"
|
||||
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
|
||||
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
||||
$DRY_RUN_CMD rm $VERBOSE_ARG \
|
||||
"$NIX_STATE_DIR/gcroots/per-user/$USER/current-home"
|
||||
;;
|
||||
*)
|
||||
echo "Yay!"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
local deleteProfiles
|
||||
read -r -n 1 \
|
||||
-p 'Remove all Home Manager generations? [y/n] ' \
|
||||
deleteProfiles
|
||||
echo
|
||||
|
||||
case $deleteProfiles in
|
||||
y|Y)
|
||||
doRmAllGenerations
|
||||
echo "All generations are now eligible for garbage collection."
|
||||
;;
|
||||
*)
|
||||
echo "Leaving generations but they may still be garbage collected."
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Home Manager is uninstalled but your home.nix is left untouched."
|
||||
}
|
||||
|
||||
function doHelp() {
|
||||
echo "Usage: $0 [OPTION] COMMAND"
|
||||
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 " --flake flake-uri Use home-manager configuration at flake-uri"
|
||||
echo " -b EXT Move existing files to new path rather than fail."
|
||||
echo " -v Verbose output"
|
||||
echo " -n Do a dry run, only prints what actions would be taken"
|
||||
echo " -h Print this help"
|
||||
echo
|
||||
echo "Options passed on to nix-build(1)"
|
||||
echo
|
||||
echo " --arg(str) NAME VALUE Override inputs passed to home-manager.nix"
|
||||
echo " --cores NUM"
|
||||
echo " --debug"
|
||||
echo " --keep-failed"
|
||||
echo " --keep-going"
|
||||
echo " -j, --max-jobs NUM"
|
||||
echo " --option NAME VALUE"
|
||||
echo " --show-trace"
|
||||
echo " --(no-)substitute"
|
||||
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 " -v Verbose output"
|
||||
echo " -n Do a dry run, only prints what actions would be taken"
|
||||
echo " -h Print this help"
|
||||
echo
|
||||
echo "Commands"
|
||||
echo
|
||||
echo " help Print this help"
|
||||
echo
|
||||
echo " edit Open the home configuration in \$EDITOR"
|
||||
echo
|
||||
echo " build Build configuration into result directory"
|
||||
echo
|
||||
echo " instantiate Instantiate the configuration and print the resulting derivation"
|
||||
echo
|
||||
echo " switch Build and activate configuration"
|
||||
echo
|
||||
echo " generations List all home environment generations"
|
||||
@@ -499,121 +300,67 @@ function doHelp() {
|
||||
echo " Remove indicated generations. Use 'generations' command to"
|
||||
echo " find suitable generation numbers."
|
||||
echo
|
||||
echo " expire-generations TIMESTAMP"
|
||||
echo " Remove generations older than TIMESTAMP where TIMESTAMP is"
|
||||
echo " interpreted as in the -d argument of the date tool. For"
|
||||
echo " example \"-30 days\" or \"2018-01-01\"."
|
||||
echo
|
||||
echo " packages List all packages installed in home-manager-path"
|
||||
echo
|
||||
echo " news Show news entries in a pager"
|
||||
echo
|
||||
echo " uninstall Remove Home Manager"
|
||||
}
|
||||
|
||||
readonly NIX_STATE_DIR="${NIX_STATE_DIR:-/nix/var/nix}"
|
||||
|
||||
EXTRA_NIX_PATH=()
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE=""
|
||||
PASSTHROUGH_OPTS=()
|
||||
COMMAND=""
|
||||
COMMAND_ARGS=()
|
||||
FLAKE_ARG=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$1"
|
||||
shift
|
||||
# As a special case, if the user has given --help anywhere on the
|
||||
# command line then print help and exit.
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == "--help" ]]; then
|
||||
doHelp
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
while getopts f:I:A:vnh opt; do
|
||||
case $opt in
|
||||
build|instantiate|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
|
||||
COMMAND="$opt"
|
||||
f)
|
||||
HOME_MANAGER_CONFIG="$OPTARG"
|
||||
;;
|
||||
-A)
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
|
||||
shift
|
||||
I)
|
||||
EXTRA_NIX_PATH+=("$OPTARG")
|
||||
;;
|
||||
-I)
|
||||
EXTRA_NIX_PATH+=("$1")
|
||||
shift
|
||||
A)
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
|
||||
;;
|
||||
-b)
|
||||
export HOME_MANAGER_BACKUP_EXT="$1"
|
||||
shift
|
||||
v)
|
||||
export VERBOSE=1
|
||||
;;
|
||||
-f|--file)
|
||||
HOME_MANAGER_CONFIG="$1"
|
||||
shift
|
||||
n)
|
||||
export DRY_RUN=1
|
||||
;;
|
||||
--flake)
|
||||
FLAKE_ARG="$1"
|
||||
shift
|
||||
;;
|
||||
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
|
||||
PASSTHROUGH_OPTS+=("$opt")
|
||||
;;
|
||||
--update-input)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||
shift
|
||||
;;
|
||||
--override-input)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
h)
|
||||
doHelp
|
||||
exit 0
|
||||
;;
|
||||
-n|--dry-run)
|
||||
export DRY_RUN=1
|
||||
;;
|
||||
--option|--arg|--argstr)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||
shift 2
|
||||
;;
|
||||
-j|--max-jobs|--cores)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||
shift
|
||||
;;
|
||||
--debug|--keep-failed|--keep-going|--show-trace\
|
||||
|--substitute|--no-substitute)
|
||||
PASSTHROUGH_OPTS+=("$opt")
|
||||
;;
|
||||
-v|--verbose)
|
||||
export VERBOSE=1
|
||||
;;
|
||||
--version)
|
||||
echo 21.05
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
case $COMMAND in
|
||||
expire-generations|remove-generations)
|
||||
COMMAND_ARGS+=("$opt")
|
||||
;;
|
||||
*)
|
||||
errorEcho "$0: unknown option '$opt'"
|
||||
errorEcho "Run '$0 --help' for usage help"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
errorEcho "Unknown option -$OPTARG"
|
||||
doHelp >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z $COMMAND ]]; then
|
||||
# Get rid of the options.
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
doHelp >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $COMMAND in
|
||||
edit)
|
||||
doEdit
|
||||
;;
|
||||
cmd="$1"
|
||||
shift 1
|
||||
|
||||
case "$cmd" in
|
||||
build)
|
||||
doBuild
|
||||
;;
|
||||
instantiate)
|
||||
doInstantiate
|
||||
;;
|
||||
switch)
|
||||
doSwitch
|
||||
;;
|
||||
@@ -621,15 +368,7 @@ case $COMMAND in
|
||||
doListGens
|
||||
;;
|
||||
remove-generations)
|
||||
doRmGenerations "${COMMAND_ARGS[@]}"
|
||||
;;
|
||||
expire-generations)
|
||||
if [[ ${#COMMAND_ARGS[@]} != 1 ]]; then
|
||||
errorEcho "expire-generations expects one argument, got ${#COMMAND_ARGS[@]}."
|
||||
exit 1
|
||||
else
|
||||
doExpireGenerations "${COMMAND_ARGS[@]}"
|
||||
fi
|
||||
doRmGenerations "$@"
|
||||
;;
|
||||
packages)
|
||||
doListPackages
|
||||
@@ -637,14 +376,11 @@ case $COMMAND in
|
||||
news)
|
||||
doShowNews --all
|
||||
;;
|
||||
uninstall)
|
||||
doUninstall
|
||||
;;
|
||||
help)
|
||||
help|--help)
|
||||
doHelp
|
||||
;;
|
||||
*)
|
||||
errorEcho "Unknown command: $COMMAND"
|
||||
errorEcho "Unknown command: $cmd"
|
||||
doHelp >&2
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> {}
|
||||
, confPath
|
||||
, confAttr ? null
|
||||
, confAttr
|
||||
, check ? true
|
||||
, newsReadIdsFile ? null
|
||||
}:
|
||||
@@ -9,9 +9,9 @@ with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
env = import ../modules {
|
||||
env = import <home-manager/modules> {
|
||||
configuration =
|
||||
if confAttr == "" || confAttr == null
|
||||
if confAttr == ""
|
||||
then confPath
|
||||
else (import confPath).${confAttr};
|
||||
pkgs = pkgs;
|
||||
|
||||
@@ -1,84 +1,37 @@
|
||||
{ home-manager, runCommand }:
|
||||
{ home-manager, pkgs }:
|
||||
|
||||
runCommand "home-manager-install" {
|
||||
propagatedBuildInputs = [ home-manager ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
shellHookOnly = true;
|
||||
shellHook = ''
|
||||
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
|
||||
|
||||
if [[ ! -e $confFile ]]; then
|
||||
pkgs.runCommand
|
||||
"home-manager-install"
|
||||
{
|
||||
propagatedBuildInputs = [ home-manager ];
|
||||
shellHook = ''
|
||||
echo
|
||||
echo "Creating initial Home Manager generation..."
|
||||
echo
|
||||
echo "Creating initial Home Manager configuration..."
|
||||
|
||||
nl=$'\n'
|
||||
xdgVars=""
|
||||
if [[ -v XDG_CACHE_HOME && $XDG_CACHE_HOME != "$HOME/.cache" ]]; then
|
||||
xdgVars="$xdgVars xdg.cacheHome = \"$XDG_CACHE_HOME\";$nl"
|
||||
if home-manager switch; then
|
||||
cat <<EOF
|
||||
|
||||
All done! The home-manager tool should now be installed and you
|
||||
can edit
|
||||
|
||||
''${XDG_CONFIG_HOME:-~/.config}/nixpkgs/home.nix
|
||||
|
||||
to configure Home Manager. Run 'man home-configuration.nix' to
|
||||
see all available options.
|
||||
EOF
|
||||
exit 0
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
Uh oh, the installation failed! Please create an issue at
|
||||
|
||||
https://github.com/rycee/home-manager/issues
|
||||
|
||||
if the error seems to be the fault of Home Manager.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
if [[ -v XDG_CONFIG_HOME && $XDG_CONFIG_HOME != "$HOME/.config" ]]; then
|
||||
xdgVars="$xdgVars xdg.configHome = \"$XDG_CONFIG_HOME\";$nl"
|
||||
fi
|
||||
if [[ -v XDG_DATA_HOME && $XDG_DATA_HOME != "$HOME/.local/share" ]]; then
|
||||
xdgVars="$xdgVars xdg.dataHome = \"$XDG_DATA_HOME\";$nl"
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$confFile")"
|
||||
cat > $confFile <<EOF
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
# Home Manager needs a bit of information about you and the
|
||||
# paths it should manage.
|
||||
home.username = "$USER";
|
||||
home.homeDirectory = "$HOME";
|
||||
$xdgVars
|
||||
# This value determines the Home Manager release that your
|
||||
# configuration is compatible with. This helps avoid breakage
|
||||
# when a new Home Manager release introduces backwards
|
||||
# incompatible changes.
|
||||
#
|
||||
# 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";
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Creating initial Home Manager generation..."
|
||||
echo
|
||||
|
||||
if home-manager switch; then
|
||||
cat <<EOF
|
||||
|
||||
All done! The home-manager tool should now be installed and you
|
||||
can edit
|
||||
|
||||
$confFile
|
||||
|
||||
to configure Home Manager. Run 'man home-configuration.nix' to
|
||||
see all available options.
|
||||
EOF
|
||||
exit 0
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
Uh oh, the installation failed! Please create an issue at
|
||||
|
||||
https://github.com/nix-community/home-manager/issues
|
||||
|
||||
if the error seems to be the fault of Home Manager.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
} ''
|
||||
echo This derivation is not buildable, instead run it using nix-shell.
|
||||
exit 1
|
||||
''
|
||||
'';
|
||||
}
|
||||
""
|
||||
|
||||
@@ -1,396 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.accounts.email;
|
||||
|
||||
gpgModule = types.submodule {
|
||||
options = {
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The key to use as listed in <command>gpg --list-keys</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
signByDefault = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Sign messages by default.";
|
||||
};
|
||||
|
||||
encryptByDefault = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Encrypt outgoing messages by default.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
signatureModule = types.submodule {
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = ''
|
||||
--
|
||||
Luke Skywalker
|
||||
May the force be with you.
|
||||
'';
|
||||
description = ''
|
||||
Signature content.
|
||||
'';
|
||||
};
|
||||
|
||||
showSignature = mkOption {
|
||||
type = types.enum [ "append" "attach" "none" ];
|
||||
default = "none";
|
||||
description = "Method to communicate the signature.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tlsModule = types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable TLS/SSL.
|
||||
'';
|
||||
};
|
||||
|
||||
useStartTls = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to use STARTTLS.
|
||||
'';
|
||||
};
|
||||
|
||||
certificatesFile = mkOption {
|
||||
type = types.path;
|
||||
default = config.accounts.email.certificatesFile;
|
||||
defaultText = "config.accounts.email.certificatesFile";
|
||||
description = ''
|
||||
Path to file containing certificate authorities that should
|
||||
be used to validate the connection authenticity. If
|
||||
<literal>null</literal> then the system default is used.
|
||||
Note, if set then the system default may still be accepted.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
imapModule = types.submodule {
|
||||
options = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
example = "imap.example.org";
|
||||
description = ''
|
||||
Hostname of IMAP server.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.nullOr types.port;
|
||||
default = null;
|
||||
example = 993;
|
||||
description = ''
|
||||
The port on which the IMAP server listens. If
|
||||
<literal>null</literal> then the default port is used.
|
||||
'';
|
||||
};
|
||||
|
||||
tls = mkOption {
|
||||
type = tlsModule;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for secure connections.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
smtpModule = types.submodule {
|
||||
options = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
example = "smtp.example.org";
|
||||
description = ''
|
||||
Hostname of SMTP server.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.nullOr types.port;
|
||||
default = null;
|
||||
example = 465;
|
||||
description = ''
|
||||
The port on which the SMTP server listens. If
|
||||
<literal>null</literal> then the default port is used.
|
||||
'';
|
||||
};
|
||||
|
||||
tls = mkOption {
|
||||
type = tlsModule;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for secure connections.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
maildirModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Path to maildir directory where mail for this account is
|
||||
stored. This is relative to the base maildir path.
|
||||
'';
|
||||
};
|
||||
|
||||
absPath = mkOption {
|
||||
type = types.path;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
default = "${cfg.maildirBasePath}/${config.path}";
|
||||
description = ''
|
||||
A convenience option whose value is the absolute path of
|
||||
this maildir.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
mailAccountOpts = { name, config, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Unique identifier of the account. This is set to the
|
||||
attribute name of the account configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
primary = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether this is the primary account. Only one account may be
|
||||
set as primary.
|
||||
'';
|
||||
};
|
||||
|
||||
flavor = mkOption {
|
||||
type = types.enum [ "plain" "gmail.com" "runbox.com" ];
|
||||
default = "plain";
|
||||
description = ''
|
||||
Some email providers have peculiar behavior that require
|
||||
special treatment. This option is therefore intended to
|
||||
indicate the nature of the provider.
|
||||
</para><para>
|
||||
When this indicates a specific provider then, for example,
|
||||
the IMAP and SMTP server configuration may be set
|
||||
automatically.
|
||||
'';
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.strMatching ".*@.*";
|
||||
example = "jane.doe@example.org";
|
||||
description = "The email address of this account.";
|
||||
};
|
||||
|
||||
aliases = mkOption {
|
||||
type = types.listOf (types.strMatching ".*@.*");
|
||||
default = [ ];
|
||||
example = [ "webmaster@example.org" "admin@example.org" ];
|
||||
description = "Alternative email addresses of this account.";
|
||||
};
|
||||
|
||||
realName = mkOption {
|
||||
type = types.str;
|
||||
example = "Jane Doe";
|
||||
description = "Name displayed when sending mails.";
|
||||
};
|
||||
|
||||
userName = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The server username of this account. This will be used as
|
||||
the SMTP and IMAP user name.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordCommand = mkOption {
|
||||
type = types.nullOr (types.either types.str (types.listOf types.str));
|
||||
default = null;
|
||||
apply = p: if isString p then splitString " " p else p;
|
||||
example = "secret-tool lookup email me@example.org";
|
||||
description = ''
|
||||
A command, which when run writes the account password on
|
||||
standard output.
|
||||
'';
|
||||
};
|
||||
|
||||
folders = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
inbox = mkOption {
|
||||
type = types.str;
|
||||
default = "Inbox";
|
||||
description = ''
|
||||
Relative path of the inbox mail.
|
||||
'';
|
||||
};
|
||||
|
||||
sent = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "Sent";
|
||||
description = ''
|
||||
Relative path of the sent mail folder.
|
||||
'';
|
||||
};
|
||||
|
||||
drafts = mkOption {
|
||||
type = types.str;
|
||||
default = "Drafts";
|
||||
description = ''
|
||||
Relative path of the drafts mail folder.
|
||||
'';
|
||||
};
|
||||
|
||||
trash = mkOption {
|
||||
type = types.str;
|
||||
default = "Trash";
|
||||
description = ''
|
||||
Relative path of the deleted mail folder.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Standard email folders.
|
||||
'';
|
||||
};
|
||||
|
||||
imap = mkOption {
|
||||
type = types.nullOr imapModule;
|
||||
default = null;
|
||||
description = ''
|
||||
The IMAP configuration to use for this account.
|
||||
'';
|
||||
};
|
||||
|
||||
signature = mkOption {
|
||||
type = signatureModule;
|
||||
default = { };
|
||||
description = ''
|
||||
Signature configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
gpg = mkOption {
|
||||
type = types.nullOr gpgModule;
|
||||
default = null;
|
||||
description = ''
|
||||
GPG configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
smtp = mkOption {
|
||||
type = types.nullOr smtpModule;
|
||||
default = null;
|
||||
description = ''
|
||||
The SMTP configuration to use for this account.
|
||||
'';
|
||||
};
|
||||
|
||||
maildir = mkOption {
|
||||
type = types.nullOr maildirModule;
|
||||
defaultText = { path = "\${name}"; };
|
||||
description = ''
|
||||
Maildir configuration for this account.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
{
|
||||
name = name;
|
||||
maildir = mkOptionDefault { path = "${name}"; };
|
||||
}
|
||||
|
||||
(mkIf (config.flavor == "gmail.com") {
|
||||
userName = mkDefault config.address;
|
||||
|
||||
imap = { host = "imap.gmail.com"; };
|
||||
|
||||
smtp = {
|
||||
host = "smtp.gmail.com";
|
||||
port = if config.smtp.tls.useStartTls then 587 else 465;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (config.flavor == "runbox.com") {
|
||||
imap = { host = "mail.runbox.com"; };
|
||||
|
||||
smtp = { host = "mail.runbox.com"; };
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
in {
|
||||
options.accounts.email = {
|
||||
certificatesFile = mkOption {
|
||||
type = types.path;
|
||||
default = "/etc/ssl/certs/ca-certificates.crt";
|
||||
description = ''
|
||||
Path to default file containing certificate authorities that
|
||||
should be used to validate the connection authenticity. This
|
||||
path may be overridden on a per-account basis.
|
||||
'';
|
||||
};
|
||||
|
||||
maildirBasePath = mkOption {
|
||||
type = types.str;
|
||||
default = "${config.home.homeDirectory}/Maildir";
|
||||
defaultText = "$HOME/Maildir";
|
||||
apply = p:
|
||||
if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}";
|
||||
description = ''
|
||||
The base directory for account maildir directories. May be a
|
||||
relative path, in which case it is relative the home
|
||||
directory.
|
||||
'';
|
||||
};
|
||||
|
||||
accounts = mkOption {
|
||||
type = types.attrsOf (types.submodule mailAccountOpts);
|
||||
default = { };
|
||||
description = "List of email accounts.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.accounts != { }) {
|
||||
assertions = [
|
||||
(let
|
||||
primaries =
|
||||
catAttrs "name" (filter (a: a.primary) (attrValues cfg.accounts));
|
||||
in {
|
||||
assertion = length primaries == 1;
|
||||
message = "Must have exactly one primary mail account but found "
|
||||
+ toString (length primaries) + optionalString (length primaries > 1)
|
||||
(", namely " + concatStringsSep ", " primaries);
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
# The glibc package in Nixpkgs is patched to make it possible to specify
|
||||
# an alternative path for the locale archive through a special environment
|
||||
# variable. This would allow different versions of glibc to coexist on the
|
||||
# same system because each version of glibc could look up different paths
|
||||
# for its locale archive should the archive format ever change in
|
||||
# incompatible ways.
|
||||
#
|
||||
# See also:
|
||||
# - localedef(1)
|
||||
# - https://nixos.org/manual/nixpkgs/stable/#locales
|
||||
# - https://github.com/NixOS/nixpkgs/issues/38991
|
||||
#
|
||||
# Note, the name of the said environment variable gets updated with each
|
||||
# breaking release of the glibcLocales package. Periodically check the link
|
||||
# below for changes:
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixpkgs-unstable/pkgs/development/libraries/glibc/nix-locale-archive.patch
|
||||
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
inherit (pkgs.glibcLocales) version;
|
||||
|
||||
archivePath = "${pkgs.glibcLocales}/lib/locale/locale-archive";
|
||||
|
||||
# lookup the version of glibcLocales and set the appropriate environment vars
|
||||
localeVars = if versionAtLeast version "2.27" then {
|
||||
LOCALE_ARCHIVE_2_27 = archivePath;
|
||||
} else if versionAtLeast version "2.11" then {
|
||||
LOCALE_ARCHIVE_2_11 = archivePath;
|
||||
} else
|
||||
{ };
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ midchildan ];
|
||||
|
||||
config = {
|
||||
# For shell sessions.
|
||||
home.sessionVariables = localeVars;
|
||||
|
||||
# For desktop apps.
|
||||
systemd.user.sessionVariables = localeVars;
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
{ configuration
|
||||
, pkgs
|
||||
, lib ? pkgs.lib
|
||||
, lib ? pkgs.stdenv.lib
|
||||
|
||||
# Whether to check that each option has a matching declaration.
|
||||
, check ? true
|
||||
# Extra arguments passed to specialArgs.
|
||||
, extraSpecialArgs ? { }
|
||||
}:
|
||||
|
||||
with lib;
|
||||
@@ -21,19 +19,10 @@ let
|
||||
in
|
||||
fold f res res.config.warnings;
|
||||
|
||||
extendedLib = import ./lib/stdlib-extended.nix pkgs.lib;
|
||||
|
||||
hmModules =
|
||||
import ./modules.nix {
|
||||
inherit check pkgs;
|
||||
lib = extendedLib;
|
||||
};
|
||||
|
||||
rawModule = extendedLib.evalModules {
|
||||
modules = [ configuration ] ++ hmModules;
|
||||
specialArgs = {
|
||||
modulesPath = builtins.toString ./.;
|
||||
} // extraSpecialArgs;
|
||||
rawModule = lib.evalModules {
|
||||
modules =
|
||||
[ configuration ]
|
||||
++ (import ./modules.nix { inherit check lib pkgs; });
|
||||
};
|
||||
|
||||
module = showWarnings (
|
||||
|
||||
@@ -6,20 +6,17 @@ let
|
||||
|
||||
cfg = config.home.file;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
homeDirectory = config.home.homeDirectory;
|
||||
|
||||
fileType = (import lib/file-type.nix {
|
||||
inherit homeDirectory lib pkgs;
|
||||
}).fileType;
|
||||
|
||||
sourceStorePath = file:
|
||||
let
|
||||
sourcePath = toString file.source;
|
||||
sourceName = config.lib.strings.storeFileName (baseNameOf sourcePath);
|
||||
in
|
||||
if builtins.hasContext sourcePath
|
||||
then file.source
|
||||
else builtins.path { path = file.source; name = sourceName; };
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*";
|
||||
|
||||
in
|
||||
|
||||
@@ -39,68 +36,41 @@ in
|
||||
};
|
||||
|
||||
config = {
|
||||
lib.file.mkOutOfStoreSymlink = path:
|
||||
let
|
||||
pathStr = toString path;
|
||||
name = hm.strings.storeFileName (baseNameOf pathStr);
|
||||
assertions = [
|
||||
(let
|
||||
badFiles =
|
||||
filter (f: hasPrefix "." (baseNameOf f))
|
||||
(map (v: toString v.source)
|
||||
(attrValues cfg));
|
||||
badFilesStr = toString badFiles;
|
||||
in
|
||||
pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out'';
|
||||
{
|
||||
assertion = badFiles == [];
|
||||
message = "Source file names must not start with '.': ${badFilesStr}";
|
||||
})
|
||||
];
|
||||
|
||||
# This verifies that the links we are about to create will not
|
||||
# overwrite an existing file.
|
||||
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
|
||||
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
|
||||
let
|
||||
# Paths that should be forcibly overwritten by Home Manager.
|
||||
# Caveat emptor!
|
||||
forcedPaths =
|
||||
concatMapStringsSep " " (p: ''"$HOME/${p}"'')
|
||||
(mapAttrsToList (n: v: v.target)
|
||||
(filterAttrs (n: v: v.force) cfg));
|
||||
|
||||
check = pkgs.writeText "check" ''
|
||||
. ${./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/*"
|
||||
|
||||
forcedPaths=(${forcedPaths})
|
||||
|
||||
newGenFiles="$1"
|
||||
shift
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
|
||||
forced=""
|
||||
for forcedPath in "''${forcedPaths[@]}"; do
|
||||
if [[ $targetPath == $forcedPath* ]]; then
|
||||
forced="yeah"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n $forced ]]; then
|
||||
$VERBOSE_ECHO "Skipping collision check for $targetPath"
|
||||
elif [[ -e "$targetPath" \
|
||||
&& ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
if [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
if [[ -e "$backup" ]]; then
|
||||
errorEcho "Existing file '$backup' would be clobbered by backing up '$targetPath'"
|
||||
collision=1
|
||||
else
|
||||
warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be moved to '$backup'"
|
||||
fi
|
||||
else
|
||||
errorEcho "Existing file '$targetPath' is in the way of '$sourcePath'"
|
||||
collision=1
|
||||
fi
|
||||
if [[ -e "$targetPath" \
|
||||
&& ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
|
||||
errorEcho "Existing file '$targetPath' is in the way"
|
||||
collision=1
|
||||
fi
|
||||
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"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
@@ -109,8 +79,8 @@ in
|
||||
function checkNewGenCollision() {
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${check} "$newGenFiles" {} +
|
||||
find "$newGenFiles" -type f -print0 -or -type l -print0 \
|
||||
| xargs -0 bash ${check} "$newGenFiles"
|
||||
}
|
||||
|
||||
checkNewGenCollision || exit 1
|
||||
@@ -138,7 +108,7 @@ in
|
||||
# and a failure during the intermediate state FA ∩ FB will not
|
||||
# result in lost links because this set of links are in both the
|
||||
# source and target generation.
|
||||
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
|
||||
home.activation.linkGeneration = dag.entryAfter ["writeBoundary"] (
|
||||
let
|
||||
link = pkgs.writeText "link" ''
|
||||
newGenFiles="$1"
|
||||
@@ -146,10 +116,6 @@ in
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
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"
|
||||
done
|
||||
@@ -158,18 +124,14 @@ in
|
||||
cleanup = pkgs.writeText "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/*"
|
||||
|
||||
newGenFiles="$1"
|
||||
shift 1
|
||||
for relativePath in "$@" ; do
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
||||
$VERBOSE_ECHO "Checking $targetPath: exists"
|
||||
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
warnEcho "Path '$targetPath' does not link into a Home Manager generation. Skipping delete."
|
||||
elif [[ ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
|
||||
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
|
||||
else
|
||||
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
|
||||
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath"
|
||||
@@ -198,8 +160,8 @@ in
|
||||
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${link} "$newGenFiles" {} +
|
||||
find "$newGenFiles" -type f -print0 -or -type l -print0 \
|
||||
| xargs -0 bash ${link} "$newGenFiles"
|
||||
}
|
||||
|
||||
function cleanOldGen() {
|
||||
@@ -224,7 +186,8 @@ in
|
||||
|
||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
echo "Creating profile generation $newGenNum"
|
||||
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath"
|
||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG $(basename "$newGenProfilePath") "$genProfilePath"
|
||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
|
||||
else
|
||||
echo "No change so reusing latest profile generation $oldGenNum"
|
||||
@@ -234,49 +197,16 @@ in
|
||||
''
|
||||
);
|
||||
|
||||
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
|
||||
''
|
||||
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 "${sourceStorePath v}" "${homeDirectory}/${v.target}" \
|
||||
&& changedFiles["${v.target}"]=0 \
|
||||
|| changedFiles["${v.target}"]=1
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
+ ''
|
||||
unset -f _cmp
|
||||
''
|
||||
);
|
||||
home-files = pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager-files";
|
||||
|
||||
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
|
||||
concatMapStrings (v: ''
|
||||
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then
|
||||
${v.onChange}
|
||||
fi
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
);
|
||||
nativeBuildInputs = [ pkgs.xlibs.lndir ];
|
||||
|
||||
# Symlink directories and files that have the right execute bit.
|
||||
# Copy files that need their execute bit changed.
|
||||
home-files = pkgs.runCommand
|
||||
"home-manager-files"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
(''
|
||||
# Symlink directories and files that have the right execute bit.
|
||||
# Copy files that need their execute bit changed.
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
|
||||
# Needed in case /nix is a symbolic link.
|
||||
realOut="$(realpath -m "$out")"
|
||||
|
||||
function insertFile() {
|
||||
local source="$1"
|
||||
local relTarget="$2"
|
||||
@@ -285,10 +215,10 @@ in
|
||||
|
||||
# Figure out the real absolute path to the target.
|
||||
local target
|
||||
target="$(realpath -m "$realOut/$relTarget")"
|
||||
target="$(realpath -m "$out/$relTarget")"
|
||||
|
||||
# Target path must be within $HOME.
|
||||
if [[ ! $target == $realOut* ]] ; then
|
||||
if [[ ! $target == $out* ]] ; then
|
||||
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -326,16 +256,14 @@ in
|
||||
}
|
||||
'' + concatStrings (
|
||||
mapAttrsToList (n: v: ''
|
||||
insertFile ${
|
||||
escapeShellArgs [
|
||||
(sourceStorePath v)
|
||||
v.target
|
||||
(if v.executable == null
|
||||
then "inherit"
|
||||
else toString v.executable)
|
||||
(toString v.recursive)
|
||||
]}
|
||||
insertFile "${v.source}" \
|
||||
"${v.target}" \
|
||||
"${if v.executable == null
|
||||
then "inherit"
|
||||
else builtins.toString v.executable}" \
|
||||
"${builtins.toString v.recursive}"
|
||||
'') cfg
|
||||
));
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ let
|
||||
|
||||
cfg = config.home;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
languageSubModule = types.submodule {
|
||||
options = {
|
||||
base = mkOption {
|
||||
@@ -16,35 +18,11 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
ctype = mkOption {
|
||||
address = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
Character classification category.
|
||||
'';
|
||||
};
|
||||
|
||||
numeric = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for numerical values.
|
||||
'';
|
||||
};
|
||||
|
||||
time = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for formatting times.
|
||||
'';
|
||||
};
|
||||
|
||||
collate = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for collation (alphabetical ordering).
|
||||
The language to use for addresses.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -56,14 +34,6 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
messages = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for messages, application UI languages, etc.
|
||||
'';
|
||||
};
|
||||
|
||||
paper = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
@@ -72,62 +42,29 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
time = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for personal names.
|
||||
The language to use for formatting times.
|
||||
'';
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for addresses.
|
||||
'';
|
||||
};
|
||||
|
||||
telephone = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for telephone numbers.
|
||||
'';
|
||||
};
|
||||
|
||||
measurement = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for measurement values.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
keyboardSubModule = types.submodule {
|
||||
options = {
|
||||
layout = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "us";
|
||||
defaultText = literalExample "null";
|
||||
type = types.str;
|
||||
default = "us";
|
||||
description = ''
|
||||
Keyboard layout. If <literal>null</literal>, then the system
|
||||
configuration will be used.
|
||||
</para><para>
|
||||
This defaults to <literal>null</literal> for state
|
||||
version ≥ 19.09 and <literal>"us"</literal> otherwise.
|
||||
Keyboard layout.
|
||||
'';
|
||||
};
|
||||
|
||||
model = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
type = types.str;
|
||||
default = "pc104";
|
||||
example = "presario";
|
||||
description = ''
|
||||
Keyboard model.
|
||||
@@ -144,19 +81,11 @@ let
|
||||
};
|
||||
|
||||
variant = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "";
|
||||
defaultText = literalExample "null";
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "colemak";
|
||||
description = ''
|
||||
X keyboard variant. If <literal>null</literal>, then the
|
||||
system configuration will be used.
|
||||
</para><para>
|
||||
This defaults to <literal>null</literal> for state
|
||||
version ≥ 19.09 and <literal>""</literal> otherwise.
|
||||
X keyboard variant.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -182,34 +111,14 @@ in
|
||||
options = {
|
||||
home.username = mkOption {
|
||||
type = types.str;
|
||||
defaultText = literalExample ''
|
||||
"$USER" for state version < 20.09,
|
||||
undefined for state version ≥ 20.09
|
||||
'';
|
||||
example = "jane.doe";
|
||||
defaultText = "$USER";
|
||||
description = "The user's username.";
|
||||
};
|
||||
|
||||
home.homeDirectory = mkOption {
|
||||
type = types.path;
|
||||
defaultText = literalExample ''
|
||||
"$HOME" for state version < 20.09,
|
||||
undefined for state version ≥ 20.09
|
||||
'';
|
||||
apply = toString;
|
||||
example = "/home/jane.doe";
|
||||
description = "The user's home directory. Must be an absolute path.";
|
||||
};
|
||||
|
||||
home.profileDirectory = mkOption {
|
||||
type = types.path;
|
||||
defaultText = "~/.nix-profile";
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
The profile directory where Home Manager generations are
|
||||
installed.
|
||||
'';
|
||||
defaultText = "$HOME";
|
||||
description = "The user's home directory.";
|
||||
};
|
||||
|
||||
home.language = mkOption {
|
||||
@@ -219,12 +128,9 @@ in
|
||||
};
|
||||
|
||||
home.keyboard = mkOption {
|
||||
type = types.nullOr keyboardSubModule;
|
||||
type = keyboardSubModule;
|
||||
default = {};
|
||||
description = ''
|
||||
Keyboard configuration. Set to <literal>null</literal> to
|
||||
disable Home Manager keyboard management.
|
||||
'';
|
||||
description = "Keyboard configuration.";
|
||||
};
|
||||
|
||||
home.sessionVariables = mkOption {
|
||||
@@ -246,45 +152,24 @@ in
|
||||
Note, these variables may be set in any order so no session
|
||||
variable may have a runtime dependency on another session
|
||||
variable. In particular code like
|
||||
<programlisting language="nix">
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "$FOO World!";
|
||||
};
|
||||
<programlisting>
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "$FOO World!";
|
||||
};
|
||||
</programlisting>
|
||||
may not work as expected. If you need to reference another
|
||||
session variable, then do so inside Nix instead. The above
|
||||
example then becomes
|
||||
<programlisting language="nix">
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
<programlisting>
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
|
||||
home.sessionPath = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
example = [
|
||||
".git/safe/../../bin"
|
||||
"\${xdg.configHome}/emacs/bin"
|
||||
"~/.local/bin"
|
||||
];
|
||||
description = "Extra directories to add to <envar>PATH</envar>.";
|
||||
};
|
||||
|
||||
home.sessionVariablesExtra = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = ''
|
||||
Extra configuration to add to the
|
||||
<filename>hm-session-vars.sh</filename> file.
|
||||
'';
|
||||
};
|
||||
|
||||
home.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
@@ -313,57 +198,23 @@ in
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether the activation script should start with an empty
|
||||
<envar>PATH</envar> variable. When <literal>false</literal>
|
||||
then the user's <envar>PATH</envar> will be used.
|
||||
<envvar>PATH</envvar> variable. When <literal>false</literal>
|
||||
then the user's <envvar>PATH</envvar> will be used.
|
||||
'';
|
||||
};
|
||||
|
||||
home.activation = mkOption {
|
||||
type = hm.types.dagOf types.str;
|
||||
internal = true;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
|
||||
''${builtins.toPath ./link-me-directly} $HOME
|
||||
''';
|
||||
}
|
||||
'';
|
||||
type = types.attrs;
|
||||
description = ''
|
||||
The activation scripts blocks to run when activating a Home
|
||||
Manager generation. Any entry here should be idempotent,
|
||||
meaning running twice or more times produces the same result
|
||||
as running it once.
|
||||
|
||||
Activation scripts for the home environment.
|
||||
</para><para>
|
||||
|
||||
If the script block produces any observable side effect, such
|
||||
as writing or deleting files, then it
|
||||
<emphasis>must</emphasis> be placed after the special
|
||||
<literal>writeBoundary</literal> script block. Prior to the
|
||||
write boundary one can place script blocks that verifies, but
|
||||
does not modify, the state of the system and exits if an
|
||||
unexpected state is found. For example, the
|
||||
<literal>checkLinkTargets</literal> script block checks for
|
||||
collisions between non-managed files and files defined in
|
||||
<varname><link linkend="opt-home.file">home.file</link></varname>.
|
||||
|
||||
</para><para>
|
||||
|
||||
A script block should respect the <varname>DRY_RUN</varname>
|
||||
variable, if it is set then the actions taken by the script
|
||||
should be logged to standard out and not actually performed.
|
||||
Any script should respect the <varname>DRY_RUN</varname>
|
||||
variable, if it is set then no actual action should be taken.
|
||||
The variable <varname>DRY_RUN_CMD</varname> is set to
|
||||
<command>echo</command> if dry run is enabled.
|
||||
|
||||
</para><para>
|
||||
|
||||
A script block should also respect the
|
||||
<varname>VERBOSE</varname> variable, and if set print
|
||||
information on standard out that may be useful for debugging
|
||||
any issue that may arise. The variable
|
||||
<varname>VERBOSE_ARG</varname> is set to
|
||||
<option>--verbose</option> if verbose output is enabled.
|
||||
<code>echo</code> if dry run is enabled. Thus, many cases you
|
||||
can use the idiom <code>$DRY_RUN_CMD rm -rf /</code>.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -381,15 +232,6 @@ in
|
||||
Extra commands to run in the Home Manager generation builder.
|
||||
'';
|
||||
};
|
||||
|
||||
home.extraProfileCommands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = ''
|
||||
Extra commands to run in the Home Manager profile builder.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
@@ -404,18 +246,8 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
home.username =
|
||||
mkIf (versionOlder config.home.stateVersion "20.09")
|
||||
(mkDefault (builtins.getEnv "USER"));
|
||||
home.homeDirectory =
|
||||
mkIf (versionOlder config.home.stateVersion "20.09")
|
||||
(mkDefault (builtins.getEnv "HOME"));
|
||||
|
||||
home.profileDirectory =
|
||||
if config.submoduleSupport.enable
|
||||
&& config.submoduleSupport.externalPackageInstall
|
||||
then "/etc/profiles/per-user/${cfg.username}"
|
||||
else cfg.homeDirectory + "/.nix-profile";
|
||||
home.username = mkDefault (builtins.getEnv "USER");
|
||||
home.homeDirectory = mkDefault (builtins.getEnv "HOME");
|
||||
|
||||
home.sessionVariables =
|
||||
let
|
||||
@@ -423,27 +255,13 @@ in
|
||||
in
|
||||
(maybeSet "LANG" cfg.language.base)
|
||||
//
|
||||
(maybeSet "LC_CTYPE" cfg.language.ctype)
|
||||
//
|
||||
(maybeSet "LC_NUMERIC" cfg.language.numeric)
|
||||
//
|
||||
(maybeSet "LC_TIME" cfg.language.time)
|
||||
//
|
||||
(maybeSet "LC_COLLATE" cfg.language.collate)
|
||||
(maybeSet "LC_ADDRESS" cfg.language.address)
|
||||
//
|
||||
(maybeSet "LC_MONETARY" cfg.language.monetary)
|
||||
//
|
||||
(maybeSet "LC_MESSAGES" cfg.language.messages)
|
||||
//
|
||||
(maybeSet "LC_PAPER" cfg.language.paper)
|
||||
//
|
||||
(maybeSet "LC_NAME" cfg.language.name)
|
||||
//
|
||||
(maybeSet "LC_ADDRESS" cfg.language.address)
|
||||
//
|
||||
(maybeSet "LC_TELEPHONE" cfg.language.telephone)
|
||||
//
|
||||
(maybeSet "LC_MEASUREMENT" cfg.language.measurement);
|
||||
(maybeSet "LC_TIME" cfg.language.time);
|
||||
|
||||
home.packages = [
|
||||
# Provide a file holding all session variables.
|
||||
@@ -457,62 +275,19 @@ in
|
||||
export __HM_SESS_VARS_SOURCED=1
|
||||
|
||||
${config.lib.shell.exportAll cfg.sessionVariables}
|
||||
'' + lib.optionalString (cfg.sessionPath != [ ]) ''
|
||||
export PATH="$PATH''${PATH:+:}${concatStringsSep ":" cfg.sessionPath}"
|
||||
'' + cfg.sessionVariablesExtra;
|
||||
'';
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
# A dummy entry acting as a boundary between the activation
|
||||
# script's "check" and the "write" phases.
|
||||
home.activation.writeBoundary = hm.dag.entryAnywhere "";
|
||||
home.activation.writeBoundary = dag.entryAnywhere "";
|
||||
|
||||
# Install packages to the user environment.
|
||||
#
|
||||
# Note, sometimes our target may not allow modification of the Nix
|
||||
# store and then we cannot rely on `nix-env -i`. This is the case,
|
||||
# for example, if we are running as a NixOS module and building a
|
||||
# virtual machine. Then we must instead rely on an external
|
||||
# mechanism for installing packages, which in NixOS is provided by
|
||||
# the `users.users.<name?>.packages` option. The activation
|
||||
# command is still needed since some modules need to run their
|
||||
# activation commands after the packages are guaranteed to be
|
||||
# installed.
|
||||
#
|
||||
# In case the user has moved from a user-install of Home Manager
|
||||
# to a submodule managed one we attempt to uninstall the
|
||||
# `home-manager-path` package if it is installed.
|
||||
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
|
||||
if config.submoduleSupport.externalPackageInstall
|
||||
then
|
||||
''
|
||||
if nix-env -q | grep '^home-manager-path$'; then
|
||||
$DRY_RUN_CMD nix-env -e home-manager-path
|
||||
fi
|
||||
''
|
||||
else
|
||||
''
|
||||
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
|
||||
''
|
||||
);
|
||||
home.activation.installPackages = dag.entryAfter ["writeBoundary"] ''
|
||||
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
||||
'';
|
||||
|
||||
home.activationPackage =
|
||||
let
|
||||
@@ -520,7 +295,7 @@ in
|
||||
noteEcho Activating ${res.name}
|
||||
${res.data}
|
||||
'';
|
||||
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||
sortedCommands = dag.topoSort cfg.activation;
|
||||
activationCmds =
|
||||
if sortedCommands ? result then
|
||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||
@@ -541,7 +316,9 @@ in
|
||||
]
|
||||
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||
|
||||
activationScript = pkgs.writeShellScript "activation-script" ''
|
||||
activationScript = pkgs.writeScript "activation-script" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
@@ -556,20 +333,14 @@ in
|
||||
${activationCmds}
|
||||
'';
|
||||
in
|
||||
pkgs.runCommand
|
||||
"home-manager-generation"
|
||||
{
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
''
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager-generation";
|
||||
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
|
||||
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
|
||||
|
||||
@@ -578,6 +349,7 @@ in
|
||||
|
||||
${cfg.extraBuilderCommands}
|
||||
'';
|
||||
};
|
||||
|
||||
home.path = pkgs.buildEnv {
|
||||
name = "home-manager-path";
|
||||
@@ -585,8 +357,6 @@ in
|
||||
paths = cfg.packages;
|
||||
inherit (cfg) extraOutputsToInstall;
|
||||
|
||||
postBuild = cfg.extraProfileCommands;
|
||||
|
||||
meta = {
|
||||
description = "Environment of packages installed through home-manager";
|
||||
};
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function setupVars() {
|
||||
local nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
|
||||
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"
|
||||
|
||||
local profilesPath="/nix/var/nix/profiles/per-user/$USER"
|
||||
local gcPath="/nix/var/nix/gcroots/per-user/$USER"
|
||||
local greatestGenNum
|
||||
|
||||
greatestGenNum=$( \
|
||||
nix-env --list-generations --profile "$genProfilePath" \
|
||||
| tail -1 \
|
||||
| sed -E 's/ *([[:digit:]]+) .*/\1/')
|
||||
find "$profilesPath" -name 'home-manager-*-link' \
|
||||
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
|
||||
| sort -rn \
|
||||
| head -1)
|
||||
|
||||
if [[ -n $greatestGenNum ]] ; then
|
||||
oldGenNum=$greatestGenNum
|
||||
@@ -22,15 +18,15 @@ function setupVars() {
|
||||
newGenNum=1
|
||||
fi
|
||||
|
||||
if [[ -e $profilesPath/home-manager ]] ; then
|
||||
oldGenPath="$(readlink -e "$profilesPath/home-manager")"
|
||||
if [[ -e $gcPath/current-home ]] ; then
|
||||
oldGenPath="$(readlink -e "$gcPath/current-home")"
|
||||
fi
|
||||
|
||||
$VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath"
|
||||
if [[ -v oldGenNum && ! -v oldGenPath
|
||||
|| ! -v oldGenNum && -v oldGenPath ]]; then
|
||||
errorEcho "Invalid profile number and current profile values! These"
|
||||
errorEcho "must be either both empty or both set but are now set to"
|
||||
errorEcho "Invalid profile number and GC root values! These must be"
|
||||
errorEcho "either both empty or both set but are now set to"
|
||||
errorEcho " '${oldGenNum:-}' and '${oldGenPath:-}'"
|
||||
errorEcho "If you don't mind losing previous profile generations then"
|
||||
errorEcho "the easiest solution is probably to run"
|
||||
@@ -39,6 +35,12 @@ function setupVars() {
|
||||
errorEcho "and trying home-manager switch again. Good luck!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
genProfilePath="$profilesPath/home-manager"
|
||||
newGenPath="@GENERATION_DIR@";
|
||||
newGenProfilePath="$profilesPath/home-manager-$newGenNum-link"
|
||||
newGenGcPath="$gcPath/current-home"
|
||||
}
|
||||
|
||||
if [[ -v VERBOSE ]]; then
|
||||
@@ -51,11 +53,6 @@ fi
|
||||
|
||||
echo "Starting home manager activation"
|
||||
|
||||
# Verify that we can connect to the Nix store and/or daemon. This will
|
||||
# also create the necessary directories in profiles and gcroots.
|
||||
$VERBOSE_ECHO "Sanity checking Nix"
|
||||
nix-build --expr '{}' --no-out-link
|
||||
|
||||
setupVars
|
||||
|
||||
if [[ -v DRY_RUN ]] ; then
|
||||
@@ -81,5 +78,6 @@ else
|
||||
fi
|
||||
$VERBOSE_ECHO " newGenPath=$newGenPath"
|
||||
$VERBOSE_ECHO " newGenNum=$newGenNum"
|
||||
$VERBOSE_ECHO " newGenProfilePath=$newGenProfilePath"
|
||||
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
|
||||
$VERBOSE_ECHO " genProfilePath=$genProfilePath"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# The check for terminal output and color support is heavily inspired
|
||||
# by https://unix.stackexchange.com/a/10065.
|
||||
#
|
||||
# Allow opt out by respecting the `NO_COLOR` environment variable.
|
||||
|
||||
function setupColors() {
|
||||
normalColor=""
|
||||
@@ -9,8 +7,8 @@ function setupColors() {
|
||||
warnColor=""
|
||||
noteColor=""
|
||||
|
||||
# Enable colors for terminals, and allow opting out.
|
||||
if [[ ! -v NO_COLOR && -t 1 ]]; then
|
||||
# Check if stdout is a terminal.
|
||||
if [[ -t 1 ]]; then
|
||||
# See if it supports colors.
|
||||
local ncolors
|
||||
ncolors=$(tput colors)
|
||||
|
||||
@@ -13,11 +13,13 @@ with lib;
|
||||
|
||||
rec {
|
||||
|
||||
emptyDag = { };
|
||||
emptyDag = {};
|
||||
|
||||
isDag = dag:
|
||||
let isEntry = e: (e ? data) && (e ? after) && (e ? before);
|
||||
in builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
|
||||
let
|
||||
isEntry = e: (e ? data) && (e ? after) && (e ? before);
|
||||
in
|
||||
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
|
||||
|
||||
# Takes an attribute set containing entries built by
|
||||
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
|
||||
@@ -78,19 +80,22 @@ rec {
|
||||
dagTopoSort = dag:
|
||||
let
|
||||
dagBefore = dag: name:
|
||||
mapAttrsToList (n: v: n)
|
||||
(filterAttrs (n: v: any (a: a == name) v.before) dag);
|
||||
normalizedDag = mapAttrs (n: v: {
|
||||
name = n;
|
||||
data = v.data;
|
||||
after = v.after ++ dagBefore dag n;
|
||||
}) dag;
|
||||
mapAttrsToList (n: v: n) (
|
||||
filterAttrs (n: v: any (a: a == name) v.before) dag
|
||||
);
|
||||
normalizedDag =
|
||||
mapAttrs (n: v: {
|
||||
name = n;
|
||||
data = v.data;
|
||||
after = v.after ++ dagBefore dag n;
|
||||
}) dag;
|
||||
before = a: b: any (c: a.name == c) b.after;
|
||||
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
|
||||
in if sorted ? result then {
|
||||
result = map (v: { inherit (v) name data; }) sorted.result;
|
||||
} else
|
||||
sorted;
|
||||
in
|
||||
if sorted ? result then
|
||||
{ result = map (v: { inherit (v) name data; }) sorted.result; }
|
||||
else
|
||||
sorted;
|
||||
|
||||
# Applies a function to each element of the given DAG.
|
||||
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
|
||||
@@ -98,20 +103,22 @@ rec {
|
||||
# Create a DAG entry with no particular dependency information.
|
||||
dagEntryAnywhere = data: {
|
||||
inherit data;
|
||||
before = [ ];
|
||||
after = [ ];
|
||||
before = [];
|
||||
after = [];
|
||||
};
|
||||
|
||||
dagEntryBetween = before: after: data: { inherit data before after; };
|
||||
dagEntryBetween = before: after: data: {
|
||||
inherit data before after;
|
||||
};
|
||||
|
||||
dagEntryAfter = after: data: {
|
||||
inherit data after;
|
||||
before = [ ];
|
||||
before = [];
|
||||
};
|
||||
|
||||
dagEntryBefore = before: data: {
|
||||
inherit data before;
|
||||
after = [ ];
|
||||
after = [];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib }:
|
||||
|
||||
rec {
|
||||
{
|
||||
dag =
|
||||
let
|
||||
d = import ./dag.nix { inherit lib; };
|
||||
@@ -16,11 +16,5 @@ rec {
|
||||
entryBefore = d.dagEntryBefore;
|
||||
};
|
||||
|
||||
gvariant = import ./gvariant.nix { inherit lib; };
|
||||
maintainers = import ./maintainers.nix;
|
||||
strings = import ./strings.nix { inherit lib; };
|
||||
types = import ./types.nix { inherit dag gvariant lib; };
|
||||
|
||||
shell = import ./shell.nix { inherit lib; };
|
||||
zsh = import ./zsh.nix { inherit lib; };
|
||||
}
|
||||
|
||||
@@ -2,6 +2,32 @@
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
# Figures out a valid Nix store name for the given path.
|
||||
storeFileName = path:
|
||||
let
|
||||
# All characters that are considered safe. Note "-" is not
|
||||
# included to avoid "-" followed by digit being interpreted as a
|
||||
# version.
|
||||
safeChars =
|
||||
[ "+" "." "_" "?" "=" ]
|
||||
++ lowerChars
|
||||
++ upperChars
|
||||
++ stringToCharacters "0123456789";
|
||||
|
||||
empties = l: genList (x: "") (length l);
|
||||
|
||||
unsafeInName = stringToCharacters (
|
||||
replaceStrings safeChars (empties safeChars) path
|
||||
);
|
||||
|
||||
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
|
||||
in
|
||||
"home_file_" + safeName;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
# Constructs a type suitable for a `home.file` like option. The
|
||||
# target path may be either absolute or relative, in which case it
|
||||
@@ -11,7 +37,7 @@ with lib;
|
||||
# Arguments:
|
||||
# - basePathDesc docbook compatible description of the base path
|
||||
# - basePath the file base path
|
||||
fileType = basePathDesc: basePath: types.attrsOf (types.submodule (
|
||||
fileType = basePathDesc: basePath: types.loaOf (types.submodule (
|
||||
{ name, config, ... }: {
|
||||
options = {
|
||||
target = mkOption {
|
||||
@@ -21,7 +47,6 @@ with lib;
|
||||
absPath = if hasPrefix "/" p then p else "${basePath}/${p}";
|
||||
in
|
||||
removePrefix (homeDirectory + "/") absPath;
|
||||
defaultText = literalExample "<name>";
|
||||
description = ''
|
||||
Path to target file relative to ${basePathDesc}.
|
||||
'';
|
||||
@@ -30,20 +55,17 @@ with lib;
|
||||
text = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.lines;
|
||||
description = ''
|
||||
Text of the file. If this option is null then
|
||||
<link linkend="opt-home.file._name_.source">home.file.<name?>.source</link>
|
||||
must be set.
|
||||
'';
|
||||
description = "Text of the file.";
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of the source file or directory. If
|
||||
<link linkend="opt-home.file._name_.text">home.file.<name?>.text</link>
|
||||
is non-null then this option will automatically point to a file
|
||||
containing that text.
|
||||
Path of the source file. The file name must not start
|
||||
with a period since Nix will not allow such names in
|
||||
the Nix store.
|
||||
</para><para>
|
||||
This may refer to a directory.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -73,32 +95,6 @@ with lib;
|
||||
are symbolic links to the files of the source directory.
|
||||
'';
|
||||
};
|
||||
|
||||
onChange = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell commands to run when file has changed between
|
||||
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.
|
||||
'';
|
||||
};
|
||||
|
||||
force = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
visible = false;
|
||||
description = ''
|
||||
Whether the target path should be unconditionally replaced
|
||||
by the managed file source. Warning, this will silently
|
||||
delete the target regardless of whether it is a file or
|
||||
link.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
@@ -106,7 +102,7 @@ with lib;
|
||||
source = mkIf (config.text != null) (
|
||||
mkDefault (pkgs.writeTextFile {
|
||||
inherit (config) executable text;
|
||||
name = hm.strings.storeFileName name;
|
||||
name = storeFileName name;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
# A partial and basic implementation of GVariant formatted strings.
|
||||
#
|
||||
# Note, this API is not considered fully stable and it might therefore
|
||||
# change in backwards incompatible ways without prior notice.
|
||||
|
||||
{ lib }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
mkPrimitive = t: v: {
|
||||
_type = "gvariant";
|
||||
type = t;
|
||||
value = v;
|
||||
__toString = self: "@${self.type} ${toString self.value}";
|
||||
};
|
||||
|
||||
type = {
|
||||
arrayOf = t: "a${t}";
|
||||
maybeOf = t: "m${t}";
|
||||
tupleOf = ts: "(${concatStrings ts})";
|
||||
string = "s";
|
||||
boolean = "b";
|
||||
uchar = "y";
|
||||
int16 = "n";
|
||||
uint16 = "q";
|
||||
int32 = "i";
|
||||
uint32 = "u";
|
||||
int64 = "x";
|
||||
uint64 = "t";
|
||||
double = "d";
|
||||
};
|
||||
|
||||
# Returns the GVariant type of a given Nix value. If no type can be
|
||||
# found for the value then the empty string is returned.
|
||||
typeOf = v:
|
||||
with type;
|
||||
if builtins.isBool v then
|
||||
boolean
|
||||
else if builtins.isInt v then
|
||||
int32
|
||||
else if builtins.isFloat v then
|
||||
double
|
||||
else if builtins.isString v then
|
||||
string
|
||||
else if builtins.isList v then
|
||||
let elemType = elemTypeOf v;
|
||||
in if elemType == "" then "" else arrayOf elemType
|
||||
else if builtins.isAttrs v && v ? type then
|
||||
v.type
|
||||
else
|
||||
"";
|
||||
|
||||
elemTypeOf = vs:
|
||||
if builtins.isList vs then
|
||||
if vs == [ ] then "" else typeOf (head vs)
|
||||
else
|
||||
"";
|
||||
|
||||
mkMaybe = elemType: elem:
|
||||
mkPrimitive (type.maybeOf elemType) elem // {
|
||||
__toString = self:
|
||||
if self.value == null then
|
||||
"@${self.type} nothing"
|
||||
else
|
||||
"just ${toString self.value}";
|
||||
};
|
||||
|
||||
in rec {
|
||||
|
||||
inherit type typeOf;
|
||||
|
||||
isArray = hasPrefix "a";
|
||||
isMaybe = hasPrefix "m";
|
||||
isTuple = hasPrefix "(";
|
||||
|
||||
# Returns the GVariant value that most closely matches the given Nix
|
||||
# value. If no GVariant value can be found then `null` is returned.
|
||||
#
|
||||
# No support for dictionaries, maybe types, or variants.
|
||||
mkValue = v:
|
||||
if builtins.isBool v then
|
||||
mkBoolean v
|
||||
else if builtins.isInt v then
|
||||
mkInt32 v
|
||||
else if builtins.isFloat v then
|
||||
mkDouble v
|
||||
else if builtins.isString v then
|
||||
mkString v
|
||||
else if builtins.isList v then
|
||||
if v == [ ] then mkArray type.string [ ] else mkArray (elemTypeOf v) v
|
||||
else if builtins.isAttrs v && (v._type or "") == "gvariant" then
|
||||
v
|
||||
else
|
||||
null;
|
||||
|
||||
mkArray = elemType: elems:
|
||||
mkPrimitive (type.arrayOf elemType) (map mkValue elems) // {
|
||||
__toString = self:
|
||||
"@${self.type} [${concatMapStringsSep "," toString self.value}]";
|
||||
};
|
||||
|
||||
mkEmptyArray = elemType: mkArray elemType [ ];
|
||||
|
||||
mkNothing = elemType: mkMaybe elemType null;
|
||||
|
||||
mkJust = elem: let gvarElem = mkValue elem; in mkMaybe gvarElem.type gvarElem;
|
||||
|
||||
mkTuple = elems:
|
||||
let
|
||||
gvarElems = map mkValue elems;
|
||||
tupleType = type.tupleOf (map (e: e.type) gvarElems);
|
||||
in mkPrimitive tupleType gvarElems // {
|
||||
__toString = self:
|
||||
"@${self.type} (${concatMapStringsSep "," toString self.value})";
|
||||
};
|
||||
|
||||
mkBoolean = v:
|
||||
mkPrimitive type.boolean v // {
|
||||
__toString = self: if self.value then "true" else "false";
|
||||
};
|
||||
|
||||
mkString = v:
|
||||
mkPrimitive type.string v // {
|
||||
__toString = self: "'${escape [ "'" "\\" ] self.value}'";
|
||||
};
|
||||
|
||||
mkObjectpath = v:
|
||||
mkPrimitive type.string v // {
|
||||
__toString = self: "objectpath '${escape [ "'" ] self.value}'";
|
||||
};
|
||||
|
||||
mkUchar = mkPrimitive type.uchar;
|
||||
|
||||
mkInt16 = mkPrimitive type.int16;
|
||||
|
||||
mkUint16 = mkPrimitive type.uint16;
|
||||
|
||||
mkInt32 = v:
|
||||
mkPrimitive type.int32 v // {
|
||||
__toString = self: toString self.value;
|
||||
};
|
||||
|
||||
mkUint32 = mkPrimitive type.uint32;
|
||||
|
||||
mkInt64 = mkPrimitive type.int64;
|
||||
|
||||
mkUint64 = mkPrimitive type.uint64;
|
||||
|
||||
mkDouble = v:
|
||||
mkPrimitive type.double v // {
|
||||
__toString = self: toString self.value;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
# Home Manager maintainers.
|
||||
#
|
||||
# This attribute set contains Home Manager module maintainers that do
|
||||
# not have an entry in the Nixpkgs maintainer list [1]. Entries here
|
||||
# are expected to be follow the same format as described in [1].
|
||||
#
|
||||
# [1] https://github.com/NixOS/nixpkgs/blob/fca0d6e093c82b31103dc0dacc48da2a9b06e24b/maintainers/maintainer-list.nix#LC1
|
||||
|
||||
{
|
||||
justinlovinger = {
|
||||
name = "Justin Lovinger";
|
||||
email = "git@justinlovinger.com";
|
||||
github = "JustinLovinger";
|
||||
githubId = 7183441;
|
||||
};
|
||||
owm111 = {
|
||||
email = "7798336+owm111@users.noreply.github.com";
|
||||
name = "Owen McGrath";
|
||||
github = "owm111";
|
||||
githubId = 7798336;
|
||||
};
|
||||
cwyc = {
|
||||
email = "cwyc@users.noreply.github.com";
|
||||
name = "cwyc";
|
||||
github = "cwyc";
|
||||
githubId = 16950437;
|
||||
};
|
||||
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;
|
||||
};
|
||||
kubukoz = {
|
||||
name = "Jakub Kozłowski";
|
||||
email = "kubukoz@users.noreply.github.com";
|
||||
github = "kubukoz";
|
||||
githubId = 894884;
|
||||
};
|
||||
matrss = {
|
||||
name = "Matthias Riße";
|
||||
email = "matrss@users.noreply.github.com";
|
||||
github = "matrss";
|
||||
githubId = 9308656;
|
||||
};
|
||||
seylerius = {
|
||||
email = "sable@seyleri.us";
|
||||
name = "Sable Seyler";
|
||||
github = "seylerius";
|
||||
githubId = 1145981;
|
||||
keys = [{
|
||||
logkeyid = "rsa4096/0x68BF2EAE6D91CAFF";
|
||||
fingerprint = "F0E0 0311 126A CD72 4392 25E6 68BF 2EAE 6D91 CAFF";
|
||||
}];
|
||||
};
|
||||
thiagokokada = {
|
||||
email = "thiagokokada@gmail.com";
|
||||
name = "Thiago Kenji Okada";
|
||||
github = "thiagokokada";
|
||||
githubId = 844343;
|
||||
};
|
||||
fendse = {
|
||||
email = "46252070+Fendse@users.noreply.github.com";
|
||||
github = "Fendse";
|
||||
githubId = 46252070;
|
||||
name = "Sara Johnsson";
|
||||
};
|
||||
msfjarvis = {
|
||||
email = "me@msfjarvis.dev";
|
||||
github = "msfjarvis";
|
||||
githubId = "13348378";
|
||||
name = "Harsh Shandilya";
|
||||
keys = [{
|
||||
longkeyid = "rsa4096/0xB7843F823355E9B9";
|
||||
fingerprint = "8F87 050B 0F9C B841 1515 7399 B784 3F82 3355 E9B9";
|
||||
}];
|
||||
};
|
||||
ambroisie = {
|
||||
email = "bruno.home-manager@belanyi.fr";
|
||||
github = "ambroisie";
|
||||
githubId = 12465195;
|
||||
name = "Bruno BELANYI";
|
||||
};
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
rec {
|
||||
# Produces a Bourne shell like variable export statement.
|
||||
export = n: v: ''export ${n}="${toString v}"'';
|
||||
export = n: v: "export ${n}=\"${toString v}\"";
|
||||
|
||||
# Given an attribute set containing shell variable names and their
|
||||
# assignment, this function produces a string containing an export
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Just a convenience function that returns the given Nixpkgs standard
|
||||
# library extended with the HM library.
|
||||
|
||||
nixpkgsLib:
|
||||
|
||||
let mkHmLib = import ./.;
|
||||
in nixpkgsLib.extend (self: super: { hm = mkHmLib { lib = super; }; })
|
||||
@@ -1,22 +0,0 @@
|
||||
{ lib }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
# Figures out a valid Nix store name for the given path.
|
||||
storeFileName = path:
|
||||
let
|
||||
# All characters that are considered safe. Note "-" is not
|
||||
# included to avoid "-" followed by digit being interpreted as a
|
||||
# version.
|
||||
safeChars = [ "+" "." "_" "?" "=" ] ++ lowerChars ++ upperChars
|
||||
++ stringToCharacters "0123456789";
|
||||
|
||||
empties = l: genList (x: "") (length l);
|
||||
|
||||
unsafeInName =
|
||||
stringToCharacters (replaceStrings safeChars (empties safeChars) path);
|
||||
|
||||
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
|
||||
in "hm_" + safeName;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
{ dag, lib }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
|
||||
|
||||
dagContentType = elemType:
|
||||
types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
data = mkOption { type = elemType; };
|
||||
after = mkOption { type = with types; uniq (listOf str); };
|
||||
before = mkOption { type = with types; uniq (listOf str); };
|
||||
};
|
||||
config = mkIf (elemType.name == "submodule") {
|
||||
data._module.args.dagName = name;
|
||||
};
|
||||
});
|
||||
|
||||
in rec {
|
||||
# A directed acyclic graph of some inner type.
|
||||
#
|
||||
# Note, if the element type is a submodule then the `name` argument
|
||||
# will always be set to the string "data" since it picks up the
|
||||
# internal structure of the DAG values. To give access to the
|
||||
# "actual" attribute name a new submodule argument is provided with
|
||||
# the name `dagName`.
|
||||
dagOf = elemType:
|
||||
let
|
||||
convertAllToDags = let
|
||||
maybeConvert = n: v: if isDagEntry v then v else dag.entryAnywhere v;
|
||||
in map (def: def // { value = mapAttrs maybeConvert def.value; });
|
||||
|
||||
attrEquivalent = types.attrsOf (dagContentType elemType);
|
||||
in mkOptionType rec {
|
||||
name = "dagOf";
|
||||
description = "DAG of ${elemType.description}s";
|
||||
check = isAttrs;
|
||||
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = m: dagOf (elemType.substSubModules m);
|
||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||
};
|
||||
|
||||
# A directed acyclic graph of some inner type OR a list of that
|
||||
# inner type. This is a temporary hack for use by the
|
||||
# `programs.ssh.matchBlocks` and is only guaranteed to be vaguely
|
||||
# correct!
|
||||
#
|
||||
# In particular, adding a dependency on one of the "unnamed-N-M"
|
||||
# entries generated by a list value is almost guaranteed to destroy
|
||||
# the list's order.
|
||||
#
|
||||
# This function will be removed in version 20.09.
|
||||
listOrDagOf = elemType:
|
||||
let
|
||||
paddedIndexStr = list: i:
|
||||
let padWidth = stringLength (toString (length list));
|
||||
in fixedWidthNumber padWidth i;
|
||||
|
||||
convertAll = loc: defs:
|
||||
let
|
||||
convertListValue = namePrefix: def:
|
||||
let
|
||||
vs = def.value;
|
||||
pad = paddedIndexStr vs;
|
||||
makeEntry = i: v: nameValuePair "${namePrefix}.${pad i}" v;
|
||||
warning = ''
|
||||
In file ${def.file}
|
||||
a list is being assigned to the option '${
|
||||
concatStringsSep "." loc
|
||||
}'.
|
||||
This will soon be an error due to the list form being deprecated.
|
||||
Please use the attribute set form instead with DAG functions to
|
||||
express the desired order of entries.
|
||||
'';
|
||||
in warn warning (listToAttrs (imap1 makeEntry vs));
|
||||
|
||||
convertValue = i: def:
|
||||
if isList def.value then
|
||||
convertListValue "unnamed-${paddedIndexStr defs i}" def
|
||||
else
|
||||
def.value;
|
||||
in imap1 (i: def: def // { value = convertValue i def; }) defs;
|
||||
|
||||
dagType = dagOf elemType;
|
||||
in mkOptionType rec {
|
||||
name = "listOrDagOf";
|
||||
description = "list or DAG of ${elemType.description}s";
|
||||
check = x: isList x || dagType.check x;
|
||||
merge = loc: defs: dagType.merge loc (convertAll loc defs);
|
||||
getSubOptions = dagType.getSubOptions;
|
||||
getSubModules = dagType.getSubModules;
|
||||
substSubModules = m: listOrDagOf (elemType.substSubModules m);
|
||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||
};
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
{ lib, dag ? import ./dag.nix { inherit lib; }
|
||||
, gvariant ? import ./gvariant.nix { inherit lib; } }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
typesDag = import ./types-dag.nix { inherit dag lib; };
|
||||
|
||||
# Needed since the type is called gvariant and its merge attribute
|
||||
# must refer back to the type.
|
||||
gvar = gvariant;
|
||||
|
||||
in rec {
|
||||
|
||||
inherit (typesDag) dagOf listOrDagOf;
|
||||
|
||||
selectorFunction = mkOptionType {
|
||||
name = "selectorFunction";
|
||||
description = "Function that takes an attribute set and returns a list"
|
||||
+ " containing a selection of the values of the input set";
|
||||
check = isFunction;
|
||||
merge = _loc: defs: as: concatMap (select: select as) (getValues defs);
|
||||
};
|
||||
|
||||
overlayFunction = mkOptionType {
|
||||
name = "overlayFunction";
|
||||
description = "An overlay function, takes self and super and returns"
|
||||
+ " an attribute set overriding the desired attributes.";
|
||||
check = isFunction;
|
||||
merge = _loc: defs: self: super:
|
||||
foldl' (res: def: mergeAttrs res (def.value self super)) { } defs;
|
||||
};
|
||||
|
||||
fontType = types.submodule {
|
||||
options = {
|
||||
package = mkOption {
|
||||
type = types.nullOr types.package;
|
||||
default = null;
|
||||
example = literalExample "pkgs.dejavu_fonts";
|
||||
description = ''
|
||||
Package providing the font. This package will be installed
|
||||
to your profile. If <literal>null</literal> then the font
|
||||
is assumed to already be available in your profile.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
example = "DejaVu Sans";
|
||||
description = ''
|
||||
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.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
gvariant = mkOptionType rec {
|
||||
name = "gvariant";
|
||||
description = "GVariant value";
|
||||
check = v: gvar.mkValue v != null;
|
||||
merge = loc: defs:
|
||||
let
|
||||
vdefs = map (d: d // { value = 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;
|
||||
# A bit naive to just check the first entry…
|
||||
sharedDefType = foldl' sameOrNull (head defTypes) defTypes;
|
||||
allChecked = all (x: check x) vals;
|
||||
in if sharedDefType == null then
|
||||
throw ("Cannot merge definitions of `${showOption loc}' with"
|
||||
+ " 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)
|
||||
else if gvar.isTuple sharedDefType && allChecked then
|
||||
mergeOneOption loc defs
|
||||
else if gvar.isMaybe sharedDefType && allChecked then
|
||||
mergeOneOption loc defs
|
||||
else if gvar.type.string == sharedDefType && allChecked then
|
||||
types.str.merge loc defs
|
||||
else if gvar.type.double == sharedDefType && allChecked then
|
||||
types.float.merge loc defs
|
||||
else
|
||||
mergeDefaultOption loc defs;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{ lib }:
|
||||
|
||||
rec {
|
||||
# Produces a Zsh shell like value
|
||||
toZshValue = v:
|
||||
if builtins.isBool v then
|
||||
if v then "true" else "false"
|
||||
else if builtins.isString v then
|
||||
''"${v}"''
|
||||
else if builtins.isList v then
|
||||
"(${lib.concatStringsSep " " (map toZshValue v)})"
|
||||
else
|
||||
''"${toString v}"'';
|
||||
|
||||
# Produces a Zsh shell like definition statement
|
||||
define = n: v: "${n}=${toZshValue v}";
|
||||
|
||||
# Given an attribute set containing shell variable names and their
|
||||
# assignments, this function produces a string containing a definition
|
||||
# statement for each set entry.
|
||||
defineAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList define vars);
|
||||
|
||||
# Produces a Zsh shell like export statement
|
||||
export = n: v: "export ${define n v}";
|
||||
|
||||
# Given an attribute set containing shell variable names and their
|
||||
# assignments, this function produces a string containing an export
|
||||
# statement for each set entry.
|
||||
exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars);
|
||||
}
|
||||
@@ -1,27 +1,49 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, baseModules, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.manual;
|
||||
/* For the purpose of generating docs, evaluate options with each derivation
|
||||
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
|
||||
It isn't perfect, but it seems to cover a vast majority of use cases.
|
||||
Caveat: even if the package is reached by a different means,
|
||||
the path above will be shown and not e.g. `${config.services.foo.package}`. */
|
||||
nixosManual = import <nixpkgs/nixos/doc/manual> {
|
||||
inherit pkgs config;
|
||||
version = "0.1";
|
||||
revision = "release-0.1";
|
||||
options =
|
||||
let
|
||||
scrubbedEval = evalModules {
|
||||
modules = [ { nixpkgs.system = pkgs.stdenv.system; } ] ++ baseModules;
|
||||
args = (config._module.args) // { modules = [ ]; };
|
||||
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
|
||||
};
|
||||
scrubDerivations = namePrefix: pkgSet: mapAttrs
|
||||
(name: value:
|
||||
let wholeName = "${namePrefix}.${name}"; in
|
||||
if isAttrs value then
|
||||
scrubDerivations wholeName value
|
||||
// (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
|
||||
else value
|
||||
)
|
||||
pkgSet;
|
||||
in scrubbedEval.options;
|
||||
};
|
||||
|
||||
docs = import ../doc { inherit lib pkgs; };
|
||||
homeEnvironmentManPages = pkgs.runCommand "home-environment-manpages" {
|
||||
allowedReferences = [ "out" ];
|
||||
} ''
|
||||
install -v -D -m444 \
|
||||
${nixosManual.manpages}/share/man/man5/configuration.nix.5 \
|
||||
$out/share/man/man5/home-configuration.nix.5
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
manual.html.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to install the HTML manual. This also installs the
|
||||
<command>home-manager-help</command> tool, which opens a local
|
||||
copy of the Home Manager manual in the system web browser.
|
||||
'';
|
||||
};
|
||||
|
||||
manual.manpages.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
@@ -35,34 +57,25 @@ in
|
||||
Thanks!
|
||||
'';
|
||||
};
|
||||
|
||||
manual.json.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to install a JSON formatted list of all Home Manager
|
||||
options. This can be located at
|
||||
<filename><profile directory>/share/doc/home-manager/options.json</filename>,
|
||||
and may be used for navigating definitions, auto-completing,
|
||||
and other miscellaneous tasks.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
home.packages = mkMerge [
|
||||
(mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ])
|
||||
(mkIf cfg.manpages.enable [ docs.manPages ])
|
||||
(mkIf cfg.json.enable [ docs.options.json ])
|
||||
];
|
||||
|
||||
# Whether a dependency on nmd should be introduced.
|
||||
home.extraBuilderCommands =
|
||||
mkIf (cfg.html.enable || cfg.manpages.enable || cfg.json.enable) ''
|
||||
mkdir $out/lib
|
||||
ln -s ${docs.nmdSrc} $out/lib/nmd
|
||||
'';
|
||||
config = mkIf config.manual.manpages.enable {
|
||||
home.packages = [ homeEnvironmentManPages ];
|
||||
};
|
||||
|
||||
# To fix error during manpage build.
|
||||
meta = {
|
||||
maintainers = [ maintainers.rycee ];
|
||||
doc = builtins.toFile "nothingness" ''
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-nothing">
|
||||
<title>this is just to make the docs compile</title>
|
||||
<para xml:id="sec-grsecurity"></para>
|
||||
<para xml:id="sec-emacs-docbook-xml"></para>
|
||||
</chapter>
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.dconf;
|
||||
|
||||
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
|
||||
|
||||
mkIniKeyValue = key: value: "${key}=${toString (hm.gvariant.mkValue value)}";
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.gnidorah maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
dconf = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
visible = false;
|
||||
description = ''
|
||||
Whether to enable dconf settings.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (attrsOf hm.types.gvariant);
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"org/gnome/calculator" = {
|
||||
button-mode = "programming";
|
||||
show-thousands = true;
|
||||
base = 10;
|
||||
word-size = 64;
|
||||
window-position = lib.hm.gvariant.mkTuple [100 100];
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Settings to write to the dconf configuration system.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable && cfg.settings != { }) {
|
||||
# Make sure the dconf directory exists.
|
||||
xdg.configFile."dconf/.keep".source = builtins.toFile "keep" "";
|
||||
|
||||
home.activation.dconfSettings = hm.dag.entryAfter [ "installPackages" ]
|
||||
(let iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
|
||||
in ''
|
||||
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
|
||||
DCONF_DBUS_RUN_SESSION=""
|
||||
else
|
||||
DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session"
|
||||
fi
|
||||
|
||||
if [[ -v DRY_RUN ]]; then
|
||||
echo $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / "<" ${iniFile}
|
||||
else
|
||||
$DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
|
||||
fi
|
||||
|
||||
unset DCONF_DBUS_RUN_SESSION
|
||||
'');
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.home = {
|
||||
enableDebugInfo = mkEnableOption "" // {
|
||||
description = ''
|
||||
Some Nix-packages provide debug symbols for
|
||||
<command>gdb</command> in the <literal>debug</literal>-output.
|
||||
This option ensures that those are automatically fetched from
|
||||
the binary cache if available and <command>gdb</command> is
|
||||
configured to find those symbols.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.home.enableDebugInfo {
|
||||
home.extraOutputsToInstall = [ "debug" ];
|
||||
|
||||
home.sessionVariables = {
|
||||
NIX_DEBUG_INFO_DIRS =
|
||||
"$NIX_DEBUG_INFO_DIRS\${NIX_DEBUG_INFO_DIRS:+:}${config.home.profileDirectory}/lib/debug";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -6,100 +6,36 @@ let
|
||||
|
||||
cfg = config.fonts.fontconfig;
|
||||
|
||||
profileDirectory = config.home.profileDirectory;
|
||||
in
|
||||
|
||||
in {
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
|
||||
"fonts"
|
||||
"fontconfig"
|
||||
"enable"
|
||||
])
|
||||
];
|
||||
|
||||
options = {
|
||||
fonts.fontconfig = {
|
||||
enable = mkOption {
|
||||
enableProfileFonts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to enable fontconfig configuration. This will, for
|
||||
example, allow fontconfig to discover fonts and
|
||||
configurations installed through
|
||||
Configure fontconfig to discover fonts installed through
|
||||
<varname>home.packages</varname> and
|
||||
<command>nix-env</command>.
|
||||
</para><para>
|
||||
Note, this is only necessary on non-NixOS systems.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
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";
|
||||
})
|
||||
];
|
||||
|
||||
home.extraProfileCommands = ''
|
||||
if [[ -d $out/lib/X11/fonts || -d $out/share/fonts ]]; then
|
||||
export FONTCONFIG_FILE="$(pwd)/fonts.conf"
|
||||
|
||||
cat > $FONTCONFIG_FILE << EOF
|
||||
config = mkIf cfg.enableProfileFonts {
|
||||
xdg.configFile."fontconfig/conf.d/10-nix-profile-fonts.conf".text = ''
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<dir>$out/lib/X11/fonts</dir>
|
||||
<dir>$out/share/fonts</dir>
|
||||
<cachedir>$out/lib/fontconfig/cache</cachedir>
|
||||
<dir>~/.nix-profile/lib/X11/fonts</dir>
|
||||
<dir>~/.nix-profile/share/fonts</dir>
|
||||
</fontconfig>
|
||||
EOF
|
||||
|
||||
${getBin pkgs.fontconfig}/bin/fc-cache -f
|
||||
rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG
|
||||
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig/cache
|
||||
|
||||
rm "$FONTCONFIG_FILE"
|
||||
unset FONTCONFIG_FILE
|
||||
fi
|
||||
|
||||
# Remove hacky dummy files.
|
||||
rm $out/lib/fontconfig/hm-dummy?
|
||||
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
|
||||
'';
|
||||
|
||||
xdg.configFile = {
|
||||
"fontconfig/conf.d/10-hm-fonts.conf".text = ''
|
||||
<?xml version='1.0'?>
|
||||
|
||||
<!-- Generated by Home Manager. -->
|
||||
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/conf.d</include>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/fonts.conf</include>
|
||||
|
||||
<dir>${config.home.path}/lib/X11/fonts</dir>
|
||||
<dir>${config.home.path}/share/fonts</dir>
|
||||
<dir>${profileDirectory}/lib/X11/fonts</dir>
|
||||
<dir>${profileDirectory}/share/fonts</dir>
|
||||
|
||||
<cachedir>${config.home.path}/lib/fontconfig/cache</cachedir>
|
||||
</fontconfig>
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,29 +11,51 @@ let
|
||||
toGtk3Ini = generators.toINI {
|
||||
mkKeyValue = key: value:
|
||||
let
|
||||
value' = if isBool value then
|
||||
(if value then "true" else "false")
|
||||
else
|
||||
toString value;
|
||||
in "${key}=${value'}";
|
||||
value' =
|
||||
if isBool value then (if value then "true" else "false")
|
||||
else toString value;
|
||||
in
|
||||
"${key}=${value'}";
|
||||
};
|
||||
|
||||
formatGtk2Option = n: v:
|
||||
let
|
||||
v' = if isBool v then
|
||||
(if v then "true" else "false")
|
||||
else if isString v then
|
||||
''"${v}"''
|
||||
else
|
||||
toString v;
|
||||
in "${n} = ${v'}";
|
||||
v' =
|
||||
if isBool v then (if v then "true" else "false")
|
||||
else if isString v then "\"${v}\""
|
||||
else toString v;
|
||||
in
|
||||
"${n} = ${v'}";
|
||||
|
||||
fontType = types.submodule {
|
||||
options = {
|
||||
package = mkOption {
|
||||
type = types.nullOr types.package;
|
||||
default = null;
|
||||
example = literalExample "pkgs.dejavu_fonts";
|
||||
description = ''
|
||||
Package providing the font. This package will be installed
|
||||
to your profile. If <literal>null</literal> then the font
|
||||
is assumed to already be available in your profile.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
example = "DejaVu Sans 8";
|
||||
description = ''
|
||||
The family name and size of the font within the package.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
themeType = types.submodule {
|
||||
options = {
|
||||
package = mkOption {
|
||||
type = types.nullOr types.package;
|
||||
default = null;
|
||||
example = literalExample "pkgs.gnome.gnome_themes_standard";
|
||||
example = literalExample "pkgs.gnome3.gnome_themes_standard";
|
||||
description = ''
|
||||
Package providing the theme. This package will be installed
|
||||
to your profile. If <literal>null</literal> then the theme
|
||||
@@ -49,21 +71,17 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
in
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "gtk" "gtk3" "waylandSupport" ] ''
|
||||
This options is not longer needed and can be removed.
|
||||
'')
|
||||
];
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
gtk = {
|
||||
enable = mkEnableOption "GTK 2/3 configuration";
|
||||
|
||||
font = mkOption {
|
||||
type = types.nullOr hm.types.fontType;
|
||||
type = types.nullOr fontType;
|
||||
default = null;
|
||||
description = ''
|
||||
The font to use in GTK+ 2/3 applications.
|
||||
@@ -82,105 +100,84 @@ in {
|
||||
description = "The GTK+2/3 theme to use.";
|
||||
};
|
||||
|
||||
gtk2 = {
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "gtk-can-change-accels = 1";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.gtkrc-2.0</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
configLocation = mkOption {
|
||||
type = types.path;
|
||||
default = "${config.home.homeDirectory}/.gtkrc-2.0";
|
||||
defaultText =
|
||||
literalExample ''"''${config.home.homeDirectory}/.gtkrc-2.0"'';
|
||||
example =
|
||||
literalExample ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"'';
|
||||
description = ''
|
||||
The location to put the GTK configuration file.
|
||||
'';
|
||||
gtk2 = mkOption {
|
||||
description = "Options specific to GTK+ 2";
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "gtk-can-change-accels = 1";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.gtkrc-2.0</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
gtk3 = {
|
||||
bookmarks = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "file:///home/jane/Documents" ];
|
||||
description = "Bookmarks in the sidebar of the GTK file browser";
|
||||
};
|
||||
gtk3 = mkOption {
|
||||
description = "Options specific to GTK+ 3";
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
|
||||
description = ''
|
||||
Extra configuration options to add to
|
||||
<filename>~/.config/gtk-3.0/settings.ini</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
default = { };
|
||||
example = {
|
||||
gtk-cursor-blink = false;
|
||||
gtk-recent-files-limit = 20;
|
||||
extraCss = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.config/gtk-3.0/gtk.css</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Extra configuration options to add to
|
||||
<filename>~/.config/gtk-3.0/settings.ini</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraCss = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.config/gtk-3.0/gtk.css</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (let
|
||||
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;
|
||||
};
|
||||
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; }
|
||||
//
|
||||
optionalAttrs (cfg.iconTheme != null)
|
||||
{ gtk-icon-theme-name = cfg.iconTheme.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;
|
||||
};
|
||||
optionalPackage = opt:
|
||||
optional (opt != null && opt.package != null) opt.package;
|
||||
in
|
||||
{
|
||||
|
||||
optionalPackage = opt:
|
||||
optional (opt != null && opt.package != null) opt.package;
|
||||
in {
|
||||
home.packages = optionalPackage cfg.font ++ optionalPackage cfg.theme
|
||||
++ optionalPackage cfg.iconTheme;
|
||||
home.packages =
|
||||
optionalPackage cfg.font
|
||||
++ optionalPackage cfg.theme
|
||||
++ optionalPackage cfg.iconTheme;
|
||||
|
||||
home.file.${cfg2.configLocation}.text =
|
||||
concatStringsSep "\n" (mapAttrsToList formatGtk2Option ini) + "\n"
|
||||
+ cfg2.extraConfig;
|
||||
home.file.".gtkrc-2.0".text =
|
||||
concatStringsSep "\n" (
|
||||
mapAttrsToList formatGtk2Option ini
|
||||
) + "\n" + cfg2.extraConfig;
|
||||
|
||||
home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation;
|
||||
xdg.configFile."gtk-3.0/settings.ini".text =
|
||||
toGtk3Ini { Settings = ini // cfg3.extraConfig; };
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
dconf.settings."org/gnome/desktop/interface" = dconfIni;
|
||||
});
|
||||
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
options = {
|
||||
lib = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
This option allows modules to define helper functions,
|
||||
constants, etc.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
# Adapted from Nixpkgs.
|
||||
|
||||
{ config, lib, pkgs, pkgsPath, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@@ -34,11 +34,7 @@ let
|
||||
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;
|
||||
check = traceValIfNot isConfig;
|
||||
merge = args: fold (def: mergeConfig def.value) {};
|
||||
};
|
||||
|
||||
@@ -49,7 +45,7 @@ let
|
||||
merge = lib.mergeOneOption;
|
||||
};
|
||||
|
||||
_pkgs = import pkgsPath (
|
||||
_pkgs = import <nixpkgs> (
|
||||
filterAttrs (n: v: v != null) config.nixpkgs
|
||||
);
|
||||
|
||||
@@ -80,9 +76,10 @@ in
|
||||
inside and outside Home Manager you can put it in a separate
|
||||
file and include something like
|
||||
|
||||
<programlisting language="nix">
|
||||
<programlisting>
|
||||
nixpkgs.config = import ./nixpkgs-config.nix;
|
||||
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
|
||||
xdg.configFile."nixpkgs/config.nix".source =
|
||||
./nixpkgs-config.nix;
|
||||
</programlisting>
|
||||
|
||||
in your Home Manager configuration.
|
||||
@@ -142,11 +139,8 @@ in
|
||||
|
||||
config = {
|
||||
_module.args = {
|
||||
pkgs = mkOverride modules.defaultPriority _pkgs;
|
||||
pkgs_i686 =
|
||||
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
|
||||
then _pkgs.pkgsi686Linux
|
||||
else { };
|
||||
pkgs = _pkgs;
|
||||
pkgs_i686 = _pkgs.pkgsi686Linux;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xsession.numlock;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.evanjs ];
|
||||
|
||||
options = { xsession.numlock.enable = mkEnableOption "Num Lock"; };
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.numlockx = {
|
||||
Unit = {
|
||||
Description = "NumLockX";
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${pkgs.numlockx}/bin/numlockx";
|
||||
};
|
||||
|
||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -6,12 +6,14 @@ let
|
||||
|
||||
vars = config.pam.sessionVariables;
|
||||
|
||||
in {
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
pam.sessionVariables = mkOption {
|
||||
default = { };
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
example = { EDITOR = "vim"; };
|
||||
description = ''
|
||||
@@ -21,15 +23,14 @@ in {
|
||||
<refentrytitle>pam_env.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>.
|
||||
</para><para>
|
||||
Note, this option will become deprecated in the future and its use is
|
||||
therefore discouraged.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (vars != { }) {
|
||||
home.file.".pam_environment".text = concatStringsSep "\n"
|
||||
(mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') vars) + "\n";
|
||||
config = mkIf (vars != {}) {
|
||||
home.file.".pam_environment".text =
|
||||
concatStringsSep "\n" (
|
||||
mapAttrsToList (n: v: "${n} OVERRIDE=${toString v}") vars
|
||||
) + "\n";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.qt;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkChangedOptionModule [ "qt" "useGtkTheme" ] [ "qt" "platformTheme" ]
|
||||
(config:
|
||||
if getAttrFromPath [ "qt" "useGtkTheme" ] config then "gtk" else null))
|
||||
];
|
||||
|
||||
options = {
|
||||
qt = {
|
||||
enable = mkEnableOption "Qt 4 and 5 configuration";
|
||||
|
||||
platformTheme = mkOption {
|
||||
type = types.nullOr (types.enum [ "gtk" "gnome" ]);
|
||||
default = null;
|
||||
example = "gnome";
|
||||
relatedPackages =
|
||||
[ "qgnomeplatform" [ "libsForQt5" "qtstyleplugins" ] ];
|
||||
description = ''
|
||||
Selects the platform theme to use for Qt applications.</para>
|
||||
<para>The options are
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>gtk</literal></term>
|
||||
<listitem><para>Use GTK theme with
|
||||
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>gnome</literal></term>
|
||||
<listitem><para>Use GNOME theme with
|
||||
<link xlink:href="https://github.com/FedoraQt/QGnomePlatform">qgnomeplatform</link>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
};
|
||||
|
||||
style = {
|
||||
name = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "adwaita-dark";
|
||||
relatedPackages = [ "adwaita-qt" [ "libsForQt5" "qtstyleplugins" ] ];
|
||||
description = ''
|
||||
Selects the style to use for Qt5 applications.</para>
|
||||
<para>The options are
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>adwaita</literal></term>
|
||||
<term><literal>adwaita-dark</literal></term>
|
||||
<listitem><para>Use Adwaita Qt style with
|
||||
<link xlink:href="https://github.com/FedoraQt/adwaita-qt">adwaita</link>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>cleanlooks</literal></term>
|
||||
<term><literal>gtk2</literal></term>
|
||||
<term><literal>motif</literal></term>
|
||||
<term><literal>plastique</literal></term>
|
||||
<listitem><para>Use styles from
|
||||
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.nullOr types.package;
|
||||
default = null;
|
||||
example = literalExample "pkgs.adwaita-qt";
|
||||
description = "Theme package to be used in Qt5 applications.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable && cfg.platformTheme != null) {
|
||||
assertions = [{
|
||||
assertion = (cfg.platformTheme == "gnome")
|
||||
-> ((cfg.style.name != null) && (cfg.style.package != null));
|
||||
message = ''
|
||||
`qt.platformTheme` "gnome" must have `qt.style` set to a theme that
|
||||
supports both Qt and Gtk, for example "adwaita" or "adwaita-dark".
|
||||
'';
|
||||
}];
|
||||
|
||||
# Necessary because home.sessionVariables is of types.attrs
|
||||
home.sessionVariables = (filterAttrs (n: v: v != null) {
|
||||
QT_QPA_PLATFORMTHEME =
|
||||
if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
|
||||
QT_STYLE_OVERRIDE = cfg.style.name;
|
||||
});
|
||||
|
||||
home.packages = if cfg.platformTheme == "gnome" then
|
||||
[ pkgs.qgnomeplatform ]
|
||||
++ lib.optionals (cfg.style.package != null) [ cfg.style.package ]
|
||||
else
|
||||
[ pkgs.libsForQt5.qtstyleplugins ];
|
||||
|
||||
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ]
|
||||
++ lib.optionals (cfg.style != null) [ "QT_STYLE_OVERRIDE" ];
|
||||
|
||||
# Enable GTK+ style for Qt4 in either case.
|
||||
# It doesn’t support the platform theme packages.
|
||||
home.activation.useGtkThemeInQt4 = hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
|
||||
--set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options.submoduleSupport = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
internal = true;
|
||||
description = ''
|
||||
Whether the Home Manager module system is used as a submodule
|
||||
in, for example, NixOS or nix-darwin.
|
||||
'';
|
||||
};
|
||||
|
||||
externalPackageInstall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
internal = true;
|
||||
description = ''
|
||||
Whether the packages of <option>home.packages</option> are
|
||||
installed separately from the Home Manager activation script.
|
||||
In NixOS, for example, this may be accomplished by installing
|
||||
the packages through
|
||||
<option>users.users.‹name?›.packages</option>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.systemd.user.tmpfiles;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.dawidsowa ];
|
||||
|
||||
options.systemd.user.tmpfiles.rules = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "L /home/user/Documents - - - - /mnt/data/Documents" ];
|
||||
description = ''
|
||||
Rules for creating and cleaning up temporary files
|
||||
automatically. See
|
||||
<citerefentry>
|
||||
<refentrytitle>tmpfiles.d</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>
|
||||
for the exact format.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf (cfg.rules != [ ]) {
|
||||
xdg = {
|
||||
dataFile."user-tmpfiles.d/home-manager.conf" = {
|
||||
text = ''
|
||||
# This file is created automatically and should not be modified.
|
||||
# Please change the option ‘systemd.user.tmpfiles.rules’ instead.
|
||||
${concatStringsSep "\n" cfg.rules}
|
||||
'';
|
||||
onChange = "${pkgs.systemd}/bin/systemd-tmpfiles --user --create";
|
||||
};
|
||||
configFile = {
|
||||
"systemd/user/basic.target.wants/systemd-tmpfiles-setup.service".source =
|
||||
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
|
||||
"systemd/user/systemd-tmpfiles-setup.service".source =
|
||||
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
|
||||
"systemd/user/timers.target.wants/systemd-tmpfiles-clean.timer".source =
|
||||
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.timer";
|
||||
"systemd/user/systemd-tmpfiles-clean.service".source =
|
||||
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
home.stateVersion = mkOption {
|
||||
type =
|
||||
types.enum [ "18.09" "19.03" "19.09" "20.03" "20.09" "21.03" "21.05" ];
|
||||
default = "18.09";
|
||||
description = ''
|
||||
It is occasionally necessary for Home Manager to change
|
||||
configuration defaults in a way that is incompatible with
|
||||
stateful data. This could, for example, include switching the
|
||||
default data format or location of a file.
|
||||
</para><para>
|
||||
The <emphasis>state version</emphasis> indicates which default
|
||||
settings are in effect and will therefore help avoid breaking
|
||||
program configurations. Switching to a higher state version
|
||||
typically requires performing some manual steps, such as data
|
||||
conversion or moving files.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options.programs = let
|
||||
description = ''
|
||||
Whether to enable integration with terminals using the VTE
|
||||
library. This will let the terminal track the current working
|
||||
directory.
|
||||
'';
|
||||
in {
|
||||
bash.enableVteIntegration = mkEnableOption "" // { inherit description; };
|
||||
|
||||
zsh.enableVteIntegration = mkEnableOption "" // { inherit description; };
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf config.programs.bash.enableVteIntegration {
|
||||
# Unfortunately we have to do a little dance here to fix two
|
||||
# problems with the upstream vte.sh file:
|
||||
#
|
||||
# - It does `PROMPT_COMMAND="__vte_prompt_command"` which
|
||||
# clobbers any previously assigned prompt command.
|
||||
#
|
||||
# - Its `__vte_prompt_command` function runs commands that will
|
||||
# overwrite the exit status of the command the user ran.
|
||||
programs.bash.initExtra = ''
|
||||
__HM_PROMPT_COMMAND="''${PROMPT_COMMAND:+''${PROMPT_COMMAND%;};}__hm_vte_prompt_command"
|
||||
. ${pkgs.vte}/etc/profile.d/vte.sh
|
||||
if [[ $(type -t __vte_prompt_command) = function ]]; then
|
||||
__hm_vte_prompt_command() {
|
||||
local old_exit_status=$?
|
||||
__vte_prompt_command
|
||||
return $old_exit_status
|
||||
}
|
||||
PROMPT_COMMAND="$__HM_PROMPT_COMMAND"
|
||||
fi
|
||||
unset __HM_PROMPT_COMMAND
|
||||
'';
|
||||
})
|
||||
|
||||
(mkIf config.programs.zsh.enableVteIntegration {
|
||||
programs.zsh.initExtra = ''
|
||||
. ${pkgs.vte}/etc/profile.d/vte.sh
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.mimeApps;
|
||||
|
||||
strListOrSingleton = with types;
|
||||
coercedTo (either (listOf str) str) toList (listOf str);
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
|
||||
options.xdg.mimeApps = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to manage <filename>$XDG_CONFIG_HOME/mimeapps.list</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The generated file is read-only.
|
||||
'';
|
||||
};
|
||||
|
||||
# descriptions from
|
||||
# https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-1.0.1.html
|
||||
|
||||
associations.added = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"mimetype1" = [ "foo1.desktop" "foo2.desktop" "foo3.desktop" ];
|
||||
"mimetype2" = "foo4.desktop";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Defines additional associations of applications with
|
||||
mimetypes, as if the .desktop file was listing this mimetype
|
||||
in the first place.
|
||||
'';
|
||||
};
|
||||
|
||||
associations.removed = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = { "mimetype1" = "foo5.desktop"; };
|
||||
description = ''
|
||||
Removes associations of applications with mimetypes, as if the
|
||||
.desktop file was <emphasis>not</emphasis> listing this
|
||||
mimetype in the first place.
|
||||
'';
|
||||
};
|
||||
|
||||
defaultApplications = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"mimetype1" = [ "default1.desktop" "default2.desktop" ];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
The default application to be used for a given mimetype. This
|
||||
is, for instance, the one that will be started when
|
||||
double-clicking on a file in a file manager. If the
|
||||
application is no longer installed, the next application in
|
||||
the list is attempted, and so on.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Deprecated but still used by some applications.
|
||||
xdg.dataFile."applications/mimeapps.list".source =
|
||||
config.xdg.configFile."mimeapps.list".source;
|
||||
|
||||
xdg.configFile."mimeapps.list".text =
|
||||
let joinValues = mapAttrs (n: concatStringsSep ";");
|
||||
in generators.toINI { } {
|
||||
"Added Associations" = joinValues cfg.associations.added;
|
||||
"Removed Associations" = joinValues cfg.associations.removed;
|
||||
"Default Applications" = joinValues cfg.defaultApplications;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.mime;
|
||||
|
||||
in {
|
||||
options = {
|
||||
xdg.mime.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to install programs and files to support the
|
||||
XDG Shared MIME-info specification and XDG MIME Applications
|
||||
specification at
|
||||
<link xlink:href="https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html"/>
|
||||
and
|
||||
<link xlink:href="https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html"/>,
|
||||
respectively.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.xdg.mime.enable {
|
||||
home.packages = [
|
||||
# Explicitly install package to provide basic mime types.
|
||||
pkgs.shared-mime-info
|
||||
|
||||
# Make sure the target directories will be real directories.
|
||||
(pkgs.runCommandLocal "dummy-xdg-mime-dirs1" { } ''
|
||||
mkdir -p $out/share/{applications,mime/packages}
|
||||
'')
|
||||
(pkgs.runCommandLocal "dummy-xdg-mime-dirs2" { } ''
|
||||
mkdir -p $out/share/{applications,mime/packages}
|
||||
'')
|
||||
];
|
||||
|
||||
home.extraProfileCommands = ''
|
||||
if [[ -w $out/share/mime && -w $out/share/mime/packages && -d $out/share/mime/packages ]]; then
|
||||
XDG_DATA_DIRS=$out/share \
|
||||
PKGSYSTEM_ENABLE_FSYNC=0 \
|
||||
${pkgs.buildPackages.shared-mime-info}/bin/update-mime-database \
|
||||
-V $out/share/mime > /dev/null
|
||||
fi
|
||||
|
||||
if [[ -w $out/share/applications ]]; then
|
||||
${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database \
|
||||
$out/share/applications
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.systemDirs;
|
||||
|
||||
configDirs = concatStringsSep ":" cfg.config;
|
||||
|
||||
dataDirs = concatStringsSep ":" cfg.data;
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ tadfisher ];
|
||||
|
||||
options.xdg.systemDirs = {
|
||||
config = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = literalExample ''[ "/etc/xdg" ]'';
|
||||
description = ''
|
||||
Directory names to add to <envar>XDG_CONFIG_DIRS</envar>
|
||||
in the user session.
|
||||
'';
|
||||
};
|
||||
|
||||
data = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = literalExample ''[ "/usr/share" "/usr/local/share" ]'';
|
||||
description = ''
|
||||
Directory names to add to <envar>XDG_DATA_DIRS</envar>
|
||||
in the user session.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (cfg.config != [ ]) {
|
||||
home.sessionVariables.XDG_CONFIG_DIRS =
|
||||
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||
|
||||
systemd.user.sessionVariables.XDG_CONFIG_DIRS =
|
||||
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||
})
|
||||
|
||||
(mkIf (cfg.data != [ ]) {
|
||||
home.sessionVariables.XDG_DATA_DIRS =
|
||||
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||
|
||||
systemd.user.sessionVariables.XDG_DATA_DIRS =
|
||||
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.userDirs;
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [
|
||||
"xdg"
|
||||
"userDirs"
|
||||
"publicShare"
|
||||
])
|
||||
];
|
||||
|
||||
options.xdg.userDirs = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to manage <filename>$XDG_CONFIG_HOME/user-dirs.dirs</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The generated file is read-only.
|
||||
'';
|
||||
};
|
||||
|
||||
# Well-known directory list from
|
||||
# https://gitlab.freedesktop.org/xdg/xdg-user-dirs/blob/master/man/user-dirs.dirs.xml
|
||||
|
||||
desktop = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Desktop";
|
||||
description = "The Desktop directory.";
|
||||
};
|
||||
|
||||
documents = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Documents";
|
||||
description = "The Documents directory.";
|
||||
};
|
||||
|
||||
download = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Downloads";
|
||||
description = "The Downloads directory.";
|
||||
};
|
||||
|
||||
music = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Music";
|
||||
description = "The Music directory.";
|
||||
};
|
||||
|
||||
pictures = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Pictures";
|
||||
description = "The Pictures directory.";
|
||||
};
|
||||
|
||||
publicShare = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Public";
|
||||
description = "The Public share directory.";
|
||||
};
|
||||
|
||||
templates = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Templates";
|
||||
description = "The Templates directory.";
|
||||
};
|
||||
|
||||
videos = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Videos";
|
||||
description = "The Videos directory.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
default = { };
|
||||
example = { XDG_MISC_DIR = "$HOME/Misc"; };
|
||||
description = "Other user directories.";
|
||||
};
|
||||
|
||||
createDirectories =
|
||||
mkEnableOption "automatic creation of the XDG user directories";
|
||||
};
|
||||
|
||||
config = let
|
||||
directories = {
|
||||
XDG_DESKTOP_DIR = cfg.desktop;
|
||||
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||
XDG_DOWNLOAD_DIR = cfg.download;
|
||||
XDG_MUSIC_DIR = cfg.music;
|
||||
XDG_PICTURES_DIR = cfg.pictures;
|
||||
XDG_PUBLICSHARE_DIR = cfg.publicShare;
|
||||
XDG_TEMPLATES_DIR = cfg.templates;
|
||||
XDG_VIDEOS_DIR = cfg.videos;
|
||||
} // cfg.extraConfig;
|
||||
in mkIf cfg.enable {
|
||||
xdg.configFile."user-dirs.dirs".text = let
|
||||
# For some reason, these need to be wrapped with quotes to be valid.
|
||||
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);
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -83,30 +83,14 @@ in
|
||||
};
|
||||
})
|
||||
|
||||
# Legacy non-deterministic setup.
|
||||
(mkIf (!cfg.enable && versionOlder config.home.stateVersion "20.09") {
|
||||
(mkIf (!cfg.enable) {
|
||||
xdg.cacheHome = getXdgDir "XDG_CACHE_HOME" defaultCacheHome;
|
||||
xdg.configHome = getXdgDir "XDG_CONFIG_HOME" defaultConfigHome;
|
||||
xdg.dataHome = getXdgDir "XDG_DATA_HOME" defaultDataHome;
|
||||
})
|
||||
|
||||
# "Modern" deterministic setup.
|
||||
(mkIf (!cfg.enable && versionAtLeast config.home.stateVersion "20.09") {
|
||||
xdg.cacheHome = mkDefault defaultCacheHome;
|
||||
xdg.configHome = mkDefault defaultConfigHome;
|
||||
xdg.dataHome = mkDefault defaultDataHome;
|
||||
})
|
||||
|
||||
{
|
||||
home.file = mkMerge [
|
||||
(mapAttrs'
|
||||
(name: file: nameValuePair "${config.xdg.configHome}/${name}" file)
|
||||
cfg.configFile)
|
||||
(mapAttrs'
|
||||
(name: file: nameValuePair "${config.xdg.dataHome}/${name}" file)
|
||||
cfg.dataFile)
|
||||
{ "${config.xdg.cacheHome}/.keep".text = ""; }
|
||||
];
|
||||
home.file = mkMerge [ cfg.configFile cfg.dataFile ];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,249 +1,98 @@
|
||||
{ pkgs
|
||||
|
||||
# Note, this should be "the standard library" + HM extensions.
|
||||
, lib
|
||||
|
||||
# Whether to enable module type checking.
|
||||
, check ? true
|
||||
|
||||
# If disabled, the pkgs attribute passed to this function is used instead.
|
||||
, useNixpkgsModule ? true
|
||||
# Whether these modules are inside a NixOS submodule.
|
||||
, nixosSubmodule ? false
|
||||
}:
|
||||
|
||||
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-system-dirs.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
|
||||
(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/exa.nix { })
|
||||
(loadModule ./programs/feh.nix { })
|
||||
(loadModule ./programs/firefox.nix { })
|
||||
(loadModule ./programs/fish.nix { })
|
||||
(loadModule ./programs/foot.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/fzf.nix { })
|
||||
(loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/gh.nix { })
|
||||
(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/java.nix { })
|
||||
(loadModule ./programs/jq.nix { })
|
||||
(loadModule ./programs/kakoune.nix { })
|
||||
(loadModule ./programs/keychain.nix { })
|
||||
(loadModule ./programs/kitty.nix { })
|
||||
(loadModule ./programs/lazygit.nix { })
|
||||
(loadModule ./programs/lesspipe.nix { })
|
||||
(loadModule ./programs/lf.nix { })
|
||||
(loadModule ./programs/lsd.nix { })
|
||||
(loadModule ./programs/man.nix { })
|
||||
(loadModule ./programs/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/ncspot.nix { })
|
||||
(loadModule ./programs/ne.nix { })
|
||||
(loadModule ./programs/neomutt.nix { })
|
||||
(loadModule ./programs/neovim.nix { })
|
||||
(loadModule ./programs/newsboat.nix { })
|
||||
(loadModule ./programs/nix-index.nix { })
|
||||
(loadModule ./programs/noti.nix { })
|
||||
(loadModule ./programs/notmuch.nix { })
|
||||
(loadModule ./programs/nushell.nix { })
|
||||
(loadModule ./programs/obs-studio.nix { })
|
||||
(loadModule ./programs/octant.nix { })
|
||||
(loadModule ./programs/offlineimap.nix { })
|
||||
(loadModule ./programs/opam.nix { })
|
||||
(loadModule ./programs/password-store.nix { })
|
||||
(loadModule ./programs/pazi.nix { })
|
||||
(loadModule ./programs/pet.nix { })
|
||||
(loadModule ./programs/pidgin.nix { })
|
||||
(loadModule ./programs/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/scmpuff.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/topgrade.nix { })
|
||||
(loadModule ./programs/urxvt.nix { })
|
||||
(loadModule ./programs/vim.nix { })
|
||||
(loadModule ./programs/vscode.nix { })
|
||||
(loadModule ./programs/vscode/haskell.nix { })
|
||||
(loadModule ./programs/waybar.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/z-lua.nix { })
|
||||
(loadModule ./programs/zathura.nix { })
|
||||
(loadModule ./programs/zoxide.nix { })
|
||||
(loadModule ./programs/zplug.nix { })
|
||||
(loadModule ./programs/zsh.nix { })
|
||||
(loadModule ./programs/zsh/prezto.nix { })
|
||||
(loadModule ./services/barrier.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/blueman-applet.nix { })
|
||||
(loadModule ./services/caffeine.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/cbatticon.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/clipmenu.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/compton.nix { })
|
||||
(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/etesync-dav.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/mpris-proxy.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/muchsync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/network-manager-applet.nix { })
|
||||
(loadModule ./services/nextcloud-client.nix { })
|
||||
(loadModule ./services/owncloud-client.nix { })
|
||||
(loadModule ./services/parcellite.nix { })
|
||||
(loadModule ./services/pass-secret-service.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/pasystray.nix { })
|
||||
(loadModule ./services/pbgopy.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/picom.nix { })
|
||||
(loadModule ./services/plan9port.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/playerctld.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/polybar.nix { })
|
||||
(loadModule ./services/poweralertd.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/pulseeffects.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/random-background.nix { })
|
||||
(loadModule ./services/redshift-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 = [
|
||||
./files.nix
|
||||
./home-environment.nix
|
||||
./manual.nix
|
||||
./misc/fontconfig.nix
|
||||
./misc/gtk.nix
|
||||
./misc/news.nix
|
||||
./misc/nixpkgs.nix
|
||||
./misc/pam.nix
|
||||
./misc/xdg.nix
|
||||
./programs/bash.nix
|
||||
./programs/beets.nix
|
||||
./programs/browserpass.nix
|
||||
./programs/command-not-found/command-not-found.nix
|
||||
./programs/eclipse.nix
|
||||
./programs/emacs.nix
|
||||
./programs/feh.nix
|
||||
./programs/firefox.nix
|
||||
./programs/fzf.nix
|
||||
./programs/git.nix
|
||||
./programs/gnome-terminal.nix
|
||||
./programs/home-manager.nix
|
||||
./programs/htop.nix
|
||||
./programs/info.nix
|
||||
./programs/lesspipe.nix
|
||||
./programs/man.nix
|
||||
./programs/mercurial.nix
|
||||
./programs/neovim.nix
|
||||
./programs/pidgin.nix
|
||||
./programs/rofi.nix
|
||||
./programs/ssh.nix
|
||||
./programs/termite.nix
|
||||
./programs/texlive.nix
|
||||
./programs/vim.nix
|
||||
./programs/zsh.nix
|
||||
./services/blueman-applet.nix
|
||||
./services/compton.nix
|
||||
./services/dunst.nix
|
||||
./services/gnome-keyring.nix
|
||||
./services/gpg-agent.nix
|
||||
./services/kbfs.nix
|
||||
./services/keepassx.nix
|
||||
./services/keybase.nix
|
||||
./services/network-manager-applet.nix
|
||||
./services/owncloud-client.nix
|
||||
./services/parcellite.nix
|
||||
./services/polybar.nix
|
||||
./services/random-background.nix
|
||||
./services/redshift.nix
|
||||
./services/screen-locker.nix
|
||||
./services/stalonetray.nix
|
||||
./services/syncthing.nix
|
||||
./services/taffybar.nix
|
||||
./services/tahoe-lafs.nix
|
||||
./services/udiskie.nix
|
||||
./services/unclutter.nix
|
||||
./services/window-managers/i3.nix
|
||||
./services/window-managers/xmonad.nix
|
||||
./services/xscreensaver.nix
|
||||
./systemd.nix
|
||||
./xcursor.nix
|
||||
./xresources.nix
|
||||
./xsession.nix
|
||||
<nixpkgs/nixos/modules/misc/assertions.nix>
|
||||
<nixpkgs/nixos/modules/misc/lib.nix>
|
||||
<nixpkgs/nixos/modules/misc/meta.nix>
|
||||
];
|
||||
|
||||
modules = map (getAttr "file") (filter (getAttr "condition") allModules);
|
||||
|
||||
pkgsModule = { config, ... }: {
|
||||
config = {
|
||||
_module.args.baseModules = modules;
|
||||
_module.args.pkgsPath = lib.mkDefault (
|
||||
if versionAtLeast config.home.stateVersion "20.09" then
|
||||
pkgs.path
|
||||
else
|
||||
<nixpkgs>);
|
||||
_module.args.pkgs = lib.mkDefault pkgs;
|
||||
_module.check = check;
|
||||
lib = lib.hm;
|
||||
} // optionalAttrs useNixpkgsModule {
|
||||
nixpkgs.system = mkDefault pkgs.system;
|
||||
pkgsModule = {
|
||||
options.nixosSubmodule = mkOption {
|
||||
type = types.bool;
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
};
|
||||
|
||||
config._module.args.baseModules = modules;
|
||||
config._module.args.pkgs = lib.mkDefault pkgs;
|
||||
config._module.check = check;
|
||||
config.lib = import ./lib { inherit lib; };
|
||||
config.nixosSubmodule = nixosSubmodule;
|
||||
config.nixpkgs.system = mkDefault pkgs.system;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.abook;
|
||||
|
||||
in {
|
||||
options.programs.abook = {
|
||||
enable = mkEnableOption "Abook";
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
field pager = Pager
|
||||
view CONTACT = name, email
|
||||
set autosave=true
|
||||
'';
|
||||
description = ''
|
||||
Extra lines added to <filename>$HOME/.config/abook/abookrc</filename>.
|
||||
Available configuration options are described in the abook repository:
|
||||
<link xlink:href="https://sourceforge.net/p/abook/git/ci/master/tree/sample.abookrc" />.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.abook ];
|
||||
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
||||
text = ''
|
||||
# Generated by Home Manager.
|
||||
# See http://abook.sourceforge.net/
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.afew;
|
||||
|
||||
in {
|
||||
options.programs.afew = {
|
||||
enable = mkEnableOption "the afew initial tagging script for Notmuch";
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''
|
||||
[SpamFilter]
|
||||
[KillThreadsFilter]
|
||||
[ListMailsFilter]
|
||||
[ArchiveSentMailsFilter]
|
||||
[InboxFilter]
|
||||
'';
|
||||
example = ''
|
||||
[SpamFilter]
|
||||
|
||||
[Filter.0]
|
||||
query = from:pointyheaded@boss.com
|
||||
tags = -new;+boss
|
||||
message = Message from above
|
||||
|
||||
[InboxFilter]
|
||||
'';
|
||||
description = ''
|
||||
Extra lines added to afew configuration file. Available
|
||||
configuration options are described in the afew manual:
|
||||
<link xlink:href="https://afew.readthedocs.io/en/latest/configuration.html" />.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.afew ];
|
||||
|
||||
xdg.configFile."afew/config".text = ''
|
||||
# Generated by Home Manager.
|
||||
# See https://afew.readthedocs.io/
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.alacritty;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in {
|
||||
options = {
|
||||
programs.alacritty = {
|
||||
enable = mkEnableOption "Alacritty";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.alacritty;
|
||||
defaultText = literalExample "pkgs.alacritty";
|
||||
description = "The Alacritty package to install.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = yamlFormat.type;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
window.dimensions = {
|
||||
lines = 3;
|
||||
columns = 200;
|
||||
};
|
||||
key_bindings = [
|
||||
{
|
||||
key = "K";
|
||||
mods = "Control";
|
||||
chars = "\\x0c";
|
||||
}
|
||||
];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/alacritty/alacritty.yml</filename>. See
|
||||
<link xlink:href="https://github.com/jwilm/alacritty/blob/master/alacritty.yml"/>
|
||||
for the default configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) {
|
||||
# TODO: Replace by the generate function but need to figure out how to
|
||||
# handle the escaping first.
|
||||
#
|
||||
# source = yamlFormat.generate "alacritty.yml" cfg.settings;
|
||||
|
||||
text =
|
||||
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
pkgs:
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.alot = {
|
||||
sendMailCommand = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
Command to send a mail. If msmtp is enabled for the account,
|
||||
then this is set to
|
||||
<command>msmtpq --read-envelope-from --read-recipients</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
contactCompletion = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
type = "shellcommand";
|
||||
command =
|
||||
"'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
|
||||
regexp = "'\\[?{" + ''
|
||||
"name": "(?P<name>.*)", "address": "(?P<email>.+)", "name-addr": ".*"''
|
||||
+ "}[,\\]]?'";
|
||||
shellcommand_external_filtering = "False";
|
||||
};
|
||||
example = literalExample ''
|
||||
{
|
||||
type = "shellcommand";
|
||||
command = "abook --mutt-query";
|
||||
regexp = "'^(?P<email>[^@]+@[^\t]+)\t+(?P<name>[^\t]+)'";
|
||||
ignorecase = "True";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Contact completion configuration as expected per alot.
|
||||
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
|
||||
explanation about possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra settings to add to this Alot account configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.notmuch.enable {
|
||||
alot.sendMailCommand = mkOptionDefault (if config.msmtp.enable then
|
||||
"msmtpq --read-envelope-from --read-recipients"
|
||||
else
|
||||
null);
|
||||
};
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
# alot config loader is sensitive to leading space !
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.alot;
|
||||
|
||||
enabledAccounts =
|
||||
filter (a: a.notmuch.enable) (attrValues config.accounts.email.accounts);
|
||||
|
||||
# sorted: primary first
|
||||
alotAccounts = sort (a: b: !(a.primary -> b.primary)) enabledAccounts;
|
||||
|
||||
boolStr = v: if v then "True" else "False";
|
||||
|
||||
mkKeyValue = key: value:
|
||||
let value' = if isBool value then boolStr value else toString value;
|
||||
in "${key} = ${value'}";
|
||||
|
||||
mk2ndLevelSectionName = name: "[" + name + "]";
|
||||
|
||||
tagSubmodule = types.submodule {
|
||||
options = {
|
||||
translated = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
Fixed string representation for this tag. The tag can be
|
||||
hidden from view, if the key translated is set to
|
||||
<literal>""</literal>, the empty string.
|
||||
'';
|
||||
};
|
||||
|
||||
translation = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
A pair of strings that define a regular substitution to
|
||||
compute the string representation on the fly using
|
||||
<literal>re.sub</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
normal = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "'','', 'white','light red', 'white','#d66'";
|
||||
description = ''
|
||||
How to display the tag when unfocused.
|
||||
See <link xlink:href="https://alot.readthedocs.io/en/latest/configuration/theming.html#tagstring-formatting"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
focus = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "How to display the tag when focused.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
accountStr = account:
|
||||
with account;
|
||||
concatStringsSep "\n" ([ "[[${name}]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) ({
|
||||
address = address;
|
||||
realname = realName;
|
||||
sendmail_command =
|
||||
optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
|
||||
sent_box = "maildir" + "://" + maildir.absPath + "/" + folders.sent;
|
||||
draft_box = "maildir" + "://" + maildir.absPath + "/" + folders.drafts;
|
||||
} // optionalAttrs (aliases != [ ]) {
|
||||
aliases = concatStringsSep "," aliases;
|
||||
} // optionalAttrs (gpg != null) {
|
||||
gpg_key = gpg.key;
|
||||
encrypt_by_default = if gpg.encryptByDefault then "all" else "none";
|
||||
sign_by_default = boolStr gpg.signByDefault;
|
||||
} // optionalAttrs (signature.showSignature != "none") {
|
||||
signature = pkgs.writeText "signature.txt" signature.text;
|
||||
signature_as_attachment = boolStr (signature.showSignature == "attach");
|
||||
}) ++ [ alot.extraConfig ] ++ [ "[[[abook]]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion);
|
||||
|
||||
configFile = let
|
||||
bindingsToStr = attrSet:
|
||||
concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${v}") attrSet);
|
||||
in ''
|
||||
# Generated by Home Manager.
|
||||
# See http://alot.readthedocs.io/en/latest/configuration/config_options.html
|
||||
|
||||
${generators.toKeyValue { inherit mkKeyValue; } cfg.settings}
|
||||
${cfg.extraConfig}
|
||||
[tags]
|
||||
'' + (let
|
||||
submoduleToAttrs = m:
|
||||
filterAttrs (name: v: name != "_module" && v != null) m;
|
||||
in generators.toINI { mkSectionName = mk2ndLevelSectionName; }
|
||||
(mapAttrs (name: x: submoduleToAttrs x) cfg.tags)) + ''
|
||||
[bindings]
|
||||
${bindingsToStr cfg.bindings.global}
|
||||
|
||||
[[bufferlist]]
|
||||
${bindingsToStr cfg.bindings.bufferlist}
|
||||
[[search]]
|
||||
${bindingsToStr cfg.bindings.search}
|
||||
[[envelope]]
|
||||
${bindingsToStr cfg.bindings.envelope}
|
||||
[[taglist]]
|
||||
${bindingsToStr cfg.bindings.taglist}
|
||||
[[thread]]
|
||||
${bindingsToStr cfg.bindings.thread}
|
||||
|
||||
[accounts]
|
||||
|
||||
${concatStringsSep "\n\n" (map accountStr alotAccounts)}
|
||||
'';
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.alot = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to enable the Alot mail user agent. Alot uses the
|
||||
Notmuch email system and will therefore be automatically
|
||||
enabled for each email account that is managed by Notmuch.
|
||||
'';
|
||||
};
|
||||
|
||||
hooks = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Content of the hooks file.
|
||||
'';
|
||||
};
|
||||
|
||||
bindings = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
global = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Global keybindings.";
|
||||
};
|
||||
|
||||
bufferlist = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Bufferlist mode keybindings.";
|
||||
};
|
||||
|
||||
search = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Search mode keybindings.";
|
||||
};
|
||||
|
||||
envelope = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Envelope mode keybindings.";
|
||||
};
|
||||
|
||||
taglist = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Taglist mode keybindings.";
|
||||
};
|
||||
|
||||
thread = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Thread mode keybindings.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Keybindings.
|
||||
'';
|
||||
};
|
||||
|
||||
tags = mkOption {
|
||||
type = types.attrsOf tagSubmodule;
|
||||
default = { };
|
||||
description = "How to display the tags.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types;
|
||||
let primitive = either (either (either str int) bool) float;
|
||||
in attrsOf primitive;
|
||||
default = {
|
||||
initial_command = "search tag:inbox AND NOT tag:killed";
|
||||
auto_remove_unread = true;
|
||||
handle_mouse = true;
|
||||
prefer_plaintext = true;
|
||||
};
|
||||
example = literalExample ''
|
||||
{
|
||||
auto_remove_unread = true;
|
||||
ask_subject = false;
|
||||
thread_indent_replies = 2;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration options added to alot configuration file.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra lines added to alot configuration file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
accounts.email.accounts = mkOption {
|
||||
type = with types; attrsOf (submodule (import ./alot-accounts.nix pkgs));
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.alot ];
|
||||
|
||||
xdg.configFile."alot/config".text = configFile;
|
||||
|
||||
xdg.configFile."alot/hooks.py" = mkIf (cfg.hooks != "") {
|
||||
text = ''
|
||||
# Generated by Home Manager.
|
||||
'' + cfg.hooks;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.aria2;
|
||||
|
||||
formatLine = n: v:
|
||||
let
|
||||
formatValue = v:
|
||||
if builtins.isBool v then
|
||||
(if v then "true" else "false")
|
||||
else
|
||||
toString v;
|
||||
in "${n}=${formatValue v}";
|
||||
in {
|
||||
meta.maintainers = [ hm.maintainers.justinlovinger ];
|
||||
|
||||
options.programs.aria2 = {
|
||||
enable = mkEnableOption "aria2";
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (oneOf [ bool float int str ]);
|
||||
default = { };
|
||||
description = ''
|
||||
Options to add to <filename>aria2.conf</filename> file.
|
||||
See
|
||||
<citerefentry>
|
||||
<refentrytitle>aria2c</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
for options.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
listen-port = 60000;
|
||||
dht-listen-port = 60000;
|
||||
seed-ratio = 1.0;
|
||||
max-upload-limit = "50K";
|
||||
ftp-pasv = true;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra lines added to <filename>aria2.conf</filename> file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.aria2 ];
|
||||
|
||||
xdg.configFile."aria2/aria2.conf".text = concatStringsSep "\n" ([ ]
|
||||
++ mapAttrsToList formatLine cfg.settings
|
||||
++ optional (cfg.extraConfig != "") cfg.extraConfig);
|
||||
};
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.astroid = {
|
||||
enable = mkEnableOption "Astroid";
|
||||
|
||||
sendMailCommand = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Command to send a mail. If msmtp is enabled for the account,
|
||||
then this is set to
|
||||
<command>msmtpq --read-envelope-from --read-recipients</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrsOf types.anything;
|
||||
default = { };
|
||||
example = { select_query = ""; };
|
||||
description = ''
|
||||
Extra settings to add to this astroid account configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.notmuch.enable {
|
||||
astroid.sendMailCommand = mkIf config.msmtp.enable
|
||||
(mkOptionDefault "msmtpq --read-envelope-from --read-recipients");
|
||||
};
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
{
|
||||
"astroid": {
|
||||
"config": {
|
||||
"version": "11"
|
||||
},
|
||||
"debug": {
|
||||
"dryrun_sending": "false"
|
||||
},
|
||||
"hints": {
|
||||
"level": "0"
|
||||
},
|
||||
"log": {
|
||||
"syslog": "false",
|
||||
"stdout": "true",
|
||||
"level": "info"
|
||||
}
|
||||
},
|
||||
"startup": {
|
||||
"queries": {
|
||||
"inbox": "tag:inbox"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
"height": "10",
|
||||
"font_description": "default"
|
||||
},
|
||||
"thread_index": {
|
||||
"page_jump_rows": "6",
|
||||
"sort_order": "newest",
|
||||
"cell": {
|
||||
"font_description": "default",
|
||||
"line_spacing": "2",
|
||||
"date_length": "10",
|
||||
"message_count_length": "4",
|
||||
"authors_length": "20",
|
||||
"subject_color": "#807d74",
|
||||
"subject_color_selected": "#000000",
|
||||
"background_color_selected": "",
|
||||
"background_color_marked": "#fff584",
|
||||
"background_color_marked_selected": "#bcb559",
|
||||
"tags_length": "80",
|
||||
"tags_upper_color": "#e5e5e5",
|
||||
"tags_lower_color": "#333333",
|
||||
"tags_alpha": "0.5",
|
||||
"hidden_tags": "attachment,flagged,unread"
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
"time": {
|
||||
"clock_format": "local",
|
||||
"same_year": "%b %-e",
|
||||
"diff_year": "%x"
|
||||
}
|
||||
},
|
||||
"editor": {
|
||||
"charset": "utf-8",
|
||||
"save_draft_on_force_quit": "true",
|
||||
"attachment_words": "attach",
|
||||
"attachment_directory": "~",
|
||||
"markdown_processor": "marked"
|
||||
},
|
||||
"mail": {
|
||||
"reply": {
|
||||
"quote_line": "Excerpts from %1's message of %2:",
|
||||
"mailinglist_reply_to_sender": "true"
|
||||
},
|
||||
"forward": {
|
||||
"quote_line": "Forwarding %1's message of %2:",
|
||||
"disposition": "inline"
|
||||
},
|
||||
"sent_tags": "sent",
|
||||
"message_id_fqdn": "",
|
||||
"message_id_user": "",
|
||||
"user_agent": "default",
|
||||
"send_delay": "2",
|
||||
"close_on_success": "false",
|
||||
"format_flowed": "false"
|
||||
},
|
||||
"poll": {
|
||||
"interval": "60",
|
||||
"always_full_refresh": "false"
|
||||
},
|
||||
"attachment": {
|
||||
"external_open_cmd": "xdg-open"
|
||||
},
|
||||
"thread_view": {
|
||||
"open_html_part_external": "false",
|
||||
"preferred_type": "plain",
|
||||
"preferred_html_only": "false",
|
||||
"allow_remote_when_encrypted": "false",
|
||||
"open_external_link": "xdg-open",
|
||||
"default_save_directory": "~",
|
||||
"indent_messages": "false",
|
||||
"gravatar": {
|
||||
"enable": "true"
|
||||
},
|
||||
"mark_unread_delay": "0.5",
|
||||
"expand_flagged": "true"
|
||||
},
|
||||
"crypto": {
|
||||
"gpg": {
|
||||
"path": "gpg2",
|
||||
"always_trust": "true",
|
||||
"enabled": "true"
|
||||
}
|
||||
},
|
||||
"saved_searches": {
|
||||
"show_on_startup": "false",
|
||||
"save_history": "true",
|
||||
"history_lines_to_show": "15",
|
||||
"history_lines": "1000"
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
with builtins;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.astroid;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
astroidAccounts =
|
||||
filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts;
|
||||
|
||||
boolOpt = b: if b then "true" else "false";
|
||||
|
||||
accountAttr = account:
|
||||
with account;
|
||||
{
|
||||
email = address;
|
||||
name = realName;
|
||||
sendmail = astroid.sendMailCommand;
|
||||
additional_sent_tags = "";
|
||||
default = boolOpt primary;
|
||||
save_drafts_to = "${maildir.absPath}/${folders.drafts}";
|
||||
save_sent = "true";
|
||||
save_sent_to = "${maildir.absPath}/${folders.sent}";
|
||||
select_query = "";
|
||||
} // optionalAttrs (signature.showSignature != "none") {
|
||||
signature_attach = boolOpt (signature.showSignature == "attach");
|
||||
signature_default_on = boolOpt (signature.showSignature != "none");
|
||||
signature_file = pkgs.writeText "signature.txt" signature.text;
|
||||
signature_file_markdown = "false";
|
||||
signature_separate = "true"; # prepends '--\n' to the signature
|
||||
} // optionalAttrs (gpg != null) {
|
||||
always_gpg_sign = boolOpt gpg.signByDefault;
|
||||
gpgkey = gpg.key;
|
||||
} // astroid.extraConfig;
|
||||
|
||||
# See https://github.com/astroidmail/astroid/wiki/Configuration-Reference
|
||||
finalConfig = let
|
||||
template = fromJSON (readFile ./astroid-config-template.json);
|
||||
astroidConfig = foldl' recursiveUpdate template [
|
||||
{
|
||||
astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc";
|
||||
accounts = mapAttrs (n: accountAttr) astroidAccounts;
|
||||
crypto.gpg.path = "${pkgs.gnupg}/bin/gpg";
|
||||
}
|
||||
cfg.extraConfig
|
||||
cfg.externalEditor
|
||||
];
|
||||
in astroidConfig;
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.astroid = {
|
||||
enable = mkEnableOption "Astroid";
|
||||
|
||||
pollScript = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "mbsync gmail";
|
||||
description = ''
|
||||
Script to run to fetch/update mails.
|
||||
'';
|
||||
};
|
||||
|
||||
externalEditor = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
# Converts it into JSON that can be merged into the configuration.
|
||||
apply = cmd:
|
||||
optionalAttrs (cmd != null) {
|
||||
editor = {
|
||||
"external_editor" = "true";
|
||||
"cmd" = cmd;
|
||||
};
|
||||
};
|
||||
example =
|
||||
"nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
|
||||
description = ''
|
||||
You can use <code>%1</code>, <code>%2</code>, and
|
||||
<code>%3</code> to refer respectively to:
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem><para>file name</para></listitem>
|
||||
<listitem><para>server name</para></listitem>
|
||||
<listitem><para>socket ID</para></listitem>
|
||||
</orderedlist>
|
||||
See <link xlink:href='https://github.com/astroidmail/astroid/wiki/Customizing-editor' />.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = jsonFormat.type;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
poll.interval = 0;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
JSON config that will override the default Astroid configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
accounts.email.accounts = mkOption {
|
||||
type = with types; attrsOf (submodule (import ./astroid-accounts.nix));
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.astroid ];
|
||||
|
||||
xdg.configFile."astroid/config".source =
|
||||
jsonFormat.generate "astroid-config" finalConfig;
|
||||
|
||||
xdg.configFile."astroid/poll.sh" = {
|
||||
executable = true;
|
||||
text = ''
|
||||
# Generated by Home Manager
|
||||
|
||||
${cfg.pollScript}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.autojump;
|
||||
package = pkgs.autojump;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.evanjs ];
|
||||
|
||||
options.programs.autojump = {
|
||||
enable = mkEnableOption "autojump";
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ package ];
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (mkBefore ''
|
||||
. ${package}/share/autojump/autojump.bash
|
||||
'');
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
. ${package}/share/autojump/autojump.zsh
|
||||
'';
|
||||
|
||||
programs.fish.promptInit = mkIf cfg.enableFishIntegration ''
|
||||
. ${package}/share/autojump/autojump.fish
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.autorandr;
|
||||
|
||||
matrixOf = n: m: elemType:
|
||||
mkOptionType rec {
|
||||
name = "matrixOf";
|
||||
description =
|
||||
"${toString n}×${toString m} matrix of ${elemType.description}s";
|
||||
check = xss:
|
||||
let listOfSize = l: xs: isList xs && length xs == l;
|
||||
in listOfSize n xss
|
||||
&& all (xs: listOfSize m xs && all elemType.check xs) xss;
|
||||
merge = mergeOneOption;
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "*" "*" ]);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
|
||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||
};
|
||||
|
||||
profileModule = types.submodule {
|
||||
options = {
|
||||
fingerprint = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description = ''
|
||||
Output name to EDID mapping.
|
||||
Use <code>autorandr --fingerprint</code> to get current setup values.
|
||||
'';
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.attrsOf configModule;
|
||||
description = "Per output profile configuration.";
|
||||
default = { };
|
||||
};
|
||||
|
||||
hooks = mkOption {
|
||||
type = profileHooksModule;
|
||||
description = "Profile hook scripts.";
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configModule = types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether to enable the output.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
crtc = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
description = "Output video display controller.";
|
||||
default = null;
|
||||
example = 0;
|
||||
};
|
||||
|
||||
primary = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether output should be marked as primary";
|
||||
default = false;
|
||||
};
|
||||
|
||||
position = mkOption {
|
||||
type = types.str;
|
||||
description = "Output position";
|
||||
default = "";
|
||||
example = "5760x0";
|
||||
};
|
||||
|
||||
mode = mkOption {
|
||||
type = types.str;
|
||||
description = "Output resolution.";
|
||||
default = "";
|
||||
example = "3840x2160";
|
||||
};
|
||||
|
||||
rate = mkOption {
|
||||
type = types.str;
|
||||
description = "Output framerate.";
|
||||
default = "";
|
||||
example = "60.00";
|
||||
};
|
||||
|
||||
gamma = mkOption {
|
||||
type = types.str;
|
||||
description = "Output gamma configuration.";
|
||||
default = "";
|
||||
example = "1.0:0.909:0.833";
|
||||
};
|
||||
|
||||
rotate = mkOption {
|
||||
type = types.nullOr (types.enum [ "normal" "left" "right" "inverted" ]);
|
||||
description = "Output rotate configuration.";
|
||||
default = null;
|
||||
example = "left";
|
||||
};
|
||||
|
||||
transform = mkOption {
|
||||
type = types.nullOr (matrixOf 3 3 types.float);
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
[
|
||||
[ 0.6 0.0 0.0 ]
|
||||
[ 0.0 0.6 0.0 ]
|
||||
[ 0.0 0.0 1.0 ]
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Refer to
|
||||
<citerefentry>
|
||||
<refentrytitle>xrandr</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
for the documentation of the transform matrix.
|
||||
'';
|
||||
};
|
||||
|
||||
dpi = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
description = "Output DPI configuration.";
|
||||
default = null;
|
||||
example = 96;
|
||||
};
|
||||
|
||||
scale = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
method = mkOption {
|
||||
type = types.enum [ "factor" "pixel" ];
|
||||
description = "Output scaling method.";
|
||||
default = "factor";
|
||||
example = "pixel";
|
||||
};
|
||||
|
||||
x = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Horizontal scaling factor/pixels.";
|
||||
};
|
||||
|
||||
y = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Vertical scaling factor/pixels.";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
Output scale configuration.
|
||||
</para><para>
|
||||
Either configure by pixels or a scaling factor. When using pixel method the
|
||||
<citerefentry>
|
||||
<refentrytitle>xrandr</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
option
|
||||
<parameter class="command">--scale-from</parameter>
|
||||
will be used; when using factor method the option
|
||||
<parameter class="command">--scale</parameter>
|
||||
will be used.
|
||||
</para><para>
|
||||
This option is a shortcut version of the transform option and they are mutually
|
||||
exclusive.
|
||||
'';
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
{
|
||||
x = 1.25;
|
||||
y = 1.25;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hookType = types.lines;
|
||||
|
||||
globalHooksModule = types.submodule {
|
||||
options = {
|
||||
postswitch = mkOption {
|
||||
type = types.attrsOf hookType;
|
||||
description = "Postswitch hook executed after mode switch.";
|
||||
default = { };
|
||||
};
|
||||
|
||||
preswitch = mkOption {
|
||||
type = types.attrsOf hookType;
|
||||
description = "Preswitch hook executed before mode switch.";
|
||||
default = { };
|
||||
};
|
||||
|
||||
predetect = mkOption {
|
||||
type = types.attrsOf hookType;
|
||||
description = ''
|
||||
Predetect hook executed before autorandr attempts to run xrandr.
|
||||
'';
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
profileHooksModule = types.submodule {
|
||||
options = {
|
||||
postswitch = mkOption {
|
||||
type = hookType;
|
||||
description = "Postswitch hook executed after mode switch.";
|
||||
default = "";
|
||||
};
|
||||
|
||||
preswitch = mkOption {
|
||||
type = hookType;
|
||||
description = "Preswitch hook executed before mode switch.";
|
||||
default = "";
|
||||
};
|
||||
|
||||
predetect = mkOption {
|
||||
type = hookType;
|
||||
description = ''
|
||||
Predetect hook executed before autorandr attempts to run xrandr.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hookToFile = folder: name: hook:
|
||||
nameValuePair "autorandr/${folder}/${name}" {
|
||||
source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook";
|
||||
};
|
||||
profileToFiles = name: profile:
|
||||
with profile;
|
||||
mkMerge ([
|
||||
{
|
||||
"autorandr/${name}/setup".text = concatStringsSep "\n"
|
||||
(mapAttrsToList fingerprintToString fingerprint);
|
||||
"autorandr/${name}/config".text =
|
||||
concatStringsSep "\n" (mapAttrsToList configToString profile.config);
|
||||
}
|
||||
(mkIf (hooks.postswitch != "")
|
||||
(listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
|
||||
(mkIf (hooks.preswitch != "")
|
||||
(listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
|
||||
(mkIf (hooks.predetect != "")
|
||||
(listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
|
||||
]);
|
||||
fingerprintToString = name: edid: "${name} ${edid}";
|
||||
configToString = name: config:
|
||||
if config.enable then
|
||||
concatStringsSep "\n" ([ "output ${name}" ]
|
||||
++ optional (config.position != "") "pos ${config.position}"
|
||||
++ optional (config.crtc != null) "crtc ${toString config.crtc}"
|
||||
++ optional config.primary "primary"
|
||||
++ optional (config.dpi != null) "dpi ${toString config.dpi}"
|
||||
++ optional (config.gamma != "") "gamma ${config.gamma}"
|
||||
++ optional (config.mode != "") "mode ${config.mode}"
|
||||
++ optional (config.rate != "") "rate ${config.rate}"
|
||||
++ optional (config.rotate != null) "rotate ${config.rotate}"
|
||||
++ optional (config.transform != null) ("transform "
|
||||
+ concatMapStringsSep "," toString (flatten config.transform))
|
||||
++ optional (config.scale != null)
|
||||
((if config.scale.method == "factor" then "scale" else "scale-from")
|
||||
+ " ${toString config.scale.x}x${toString config.scale.y}"))
|
||||
else ''
|
||||
output ${name}
|
||||
off
|
||||
'';
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.autorandr = {
|
||||
enable = mkEnableOption "Autorandr";
|
||||
|
||||
hooks = mkOption {
|
||||
type = globalHooksModule;
|
||||
description = "Global hook scripts";
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
postswitch = {
|
||||
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
|
||||
"change-background" = readFile ./change-background.sh;
|
||||
"change-dpi" = '''
|
||||
case "$AUTORANDR_CURRENT_PROFILE" in
|
||||
default)
|
||||
DPI=120
|
||||
;;
|
||||
home)
|
||||
DPI=192
|
||||
;;
|
||||
work)
|
||||
DPI=144
|
||||
;;
|
||||
*)
|
||||
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
|
||||
'''
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
profiles = mkOption {
|
||||
type = types.attrsOf profileModule;
|
||||
description = "Autorandr profiles specification.";
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"work" = {
|
||||
fingerprint = {
|
||||
eDP1 = "<EDID>";
|
||||
DP1 = "<EDID>";
|
||||
};
|
||||
config = {
|
||||
eDP1.enable = false;
|
||||
DP1 = {
|
||||
enable = true;
|
||||
crtc = 0;
|
||||
primary = true;
|
||||
position = "0x0";
|
||||
mode = "3840x2160";
|
||||
gamma = "1.0:0.909:0.833";
|
||||
rate = "60.00";
|
||||
rotate = "left";
|
||||
};
|
||||
};
|
||||
hooks.postswitch = readFile ./work-postswitch.sh;
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = flatten (mapAttrsToList (profile:
|
||||
{ config, ... }:
|
||||
mapAttrsToList (output: opts: {
|
||||
assertion = opts.scale == null || opts.transform == null;
|
||||
message = ''
|
||||
Cannot use the profile output options 'scale' and 'transform' simultaneously.
|
||||
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
|
||||
'';
|
||||
}) config) cfg.profiles);
|
||||
|
||||
home.packages = [ pkgs.autorandr ];
|
||||
xdg.configFile = mkMerge ([
|
||||
(mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)
|
||||
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
|
||||
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
|
||||
(mkMerge (mapAttrsToList profileToFiles cfg.profiles))
|
||||
]);
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers.uvnikita ];
|
||||
}
|
||||
@@ -11,14 +11,6 @@ in
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "programs" "bash" "enableAutojump" ] [
|
||||
"programs"
|
||||
"autojump"
|
||||
"enable"
|
||||
])
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.bash = {
|
||||
enable = mkEnableOption "GNU Bourne-Again SHell";
|
||||
@@ -30,8 +22,8 @@ in
|
||||
};
|
||||
|
||||
historyFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
type = types.str;
|
||||
default = "$HOME/.bash_history";
|
||||
description = "Location of the bash history file.";
|
||||
};
|
||||
|
||||
@@ -89,17 +81,19 @@ in
|
||||
|
||||
shellAliases = mkOption {
|
||||
default = {};
|
||||
type = types.attrsOf types.str;
|
||||
example = literalExample ''
|
||||
{
|
||||
ll = "ls -l";
|
||||
".." = "cd ..";
|
||||
}
|
||||
'';
|
||||
example = { ll = "ls -l"; ".." = "cd .."; };
|
||||
description = ''
|
||||
An attribute set that maps aliases (the top level attribute names in
|
||||
this option) to command strings or directly to build outputs.
|
||||
this option) to command strings or directly to build outputs. The
|
||||
aliases are added to all users' shells.
|
||||
'';
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
enableAutojump = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Enable the autojump navigation tool.";
|
||||
};
|
||||
|
||||
profileExtra = mkOption {
|
||||
@@ -111,6 +105,17 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
bashrcExtra = mkOption {
|
||||
# Hide for now, may want to rename in the future.
|
||||
visible = false;
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Extra commands that should be added to
|
||||
<filename>~/.bashrc</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
initExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
@@ -119,31 +124,13 @@ in
|
||||
interactive shell.
|
||||
'';
|
||||
};
|
||||
|
||||
bashrcExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Extra commands that should be placed in <filename>~/.bashrc</filename>.
|
||||
Note that these commands will be run even in non-interactive shells.
|
||||
'';
|
||||
};
|
||||
|
||||
logoutExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Extra commands that should be run when logging out of an
|
||||
interactive shell.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = (
|
||||
let
|
||||
aliasesStr = concatStringsSep "\n" (
|
||||
mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}") cfg.shellAliases
|
||||
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
|
||||
);
|
||||
|
||||
shoptsStr = concatStringsSep "\n" (
|
||||
@@ -155,12 +142,10 @@ in
|
||||
historyControlStr =
|
||||
concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") (
|
||||
{
|
||||
HISTFILE = "\"${cfg.historyFile}\"";
|
||||
HISTFILESIZE = toString cfg.historyFileSize;
|
||||
HISTSIZE = toString cfg.historySize;
|
||||
}
|
||||
// optionalAttrs (cfg.historyFile != null) {
|
||||
HISTFILE = "\"${cfg.historyFile}\"";
|
||||
}
|
||||
// optionalAttrs (cfg.historyControl != []) {
|
||||
HISTCONTROL = concatStringsSep ":" cfg.historyControl;
|
||||
}
|
||||
@@ -169,7 +154,25 @@ in
|
||||
}
|
||||
));
|
||||
in mkIf cfg.enable {
|
||||
home.file.".bash_profile".source = pkgs.writeShellScript "bash_profile" ''
|
||||
programs.bash.bashrcExtra = ''
|
||||
# Commands that should be applied only for interactive shells.
|
||||
if [[ -n $PS1 ]]; then
|
||||
${historyControlStr}
|
||||
|
||||
${shoptsStr}
|
||||
|
||||
${aliasesStr}
|
||||
|
||||
${cfg.initExtra}
|
||||
|
||||
${optionalString cfg.enableAutojump
|
||||
". ${pkgs.autojump}/share/autojump/autojump.bash"}
|
||||
fi
|
||||
'';
|
||||
|
||||
home.file.".bash_profile".text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
# include .profile if it exists
|
||||
[[ -f ~/.profile ]] && . ~/.profile
|
||||
|
||||
@@ -177,32 +180,24 @@ in
|
||||
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
||||
'';
|
||||
|
||||
home.file.".profile".source = pkgs.writeShellScript "profile" ''
|
||||
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
|
||||
home.file.".profile".text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
|
||||
${sessionVarsStr}
|
||||
|
||||
${cfg.profileExtra}
|
||||
'';
|
||||
|
||||
home.file.".bashrc".source = pkgs.writeShellScript "bashrc" ''
|
||||
home.file.".bashrc".text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
${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 != "") {
|
||||
source = pkgs.writeShellScript "bash_logout" cfg.logoutExtra;
|
||||
};
|
||||
home.packages =
|
||||
optional (cfg.enableAutojump) pkgs.autojump;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.bat;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.marsam ];
|
||||
|
||||
options.programs.bat = {
|
||||
enable = mkEnableOption "bat, a cat clone with wings";
|
||||
|
||||
config = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = {
|
||||
theme = "TwoDark";
|
||||
pager = "less -FR";
|
||||
};
|
||||
description = ''
|
||||
Bat configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
themes = mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
dracula = builtins.readFile (pkgs.fetchFromGitHub {
|
||||
owner = "dracula";
|
||||
repo = "sublime"; # Bat uses sublime syntax for its themes
|
||||
rev = "26c57ec282abcaa76e57e055f38432bd827ac34e";
|
||||
sha256 = "019hfl4zbn4vm4154hh3bwk6hm7bdxbr1hdww83nabxwjn99ndhv";
|
||||
} + "/Dracula.tmTheme");
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Additional themes to provide.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.bat ];
|
||||
|
||||
xdg.configFile = mkMerge ([{
|
||||
"bat/config" = mkIf (cfg.config != { }) {
|
||||
text = concatStringsSep "\n"
|
||||
(mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config);
|
||||
};
|
||||
}] ++ flip mapAttrsToList cfg.themes
|
||||
(name: body: { "bat/themes/${name}.tmTheme" = { text = body; }; }));
|
||||
};
|
||||
}
|
||||
@@ -6,43 +6,16 @@ let
|
||||
|
||||
cfg = config.programs.beets;
|
||||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in
|
||||
|
||||
in {
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
programs.beets = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = if versionAtLeast config.home.stateVersion "19.03" then
|
||||
false
|
||||
else
|
||||
cfg.settings != { };
|
||||
defaultText = "false";
|
||||
description = ''
|
||||
Whether to enable the beets music library manager. This
|
||||
defaults to <literal>false</literal> for state
|
||||
version ≥ 19.03. For earlier versions beets is enabled if
|
||||
<option>programs.beets.settings</option> is non-empty.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.beets;
|
||||
defaultText = literalExample "pkgs.beets";
|
||||
example =
|
||||
literalExample "(pkgs.beets.override { enableCheck = true; })";
|
||||
description = ''
|
||||
The <literal>beets</literal> package to use.
|
||||
Can be used to specify extensions.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = yamlFormat.type;
|
||||
default = { };
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/beets/config.yaml</filename>
|
||||
@@ -51,10 +24,10 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
config = mkIf (cfg.settings != {}) {
|
||||
home.packages = [ pkgs.beets ];
|
||||
|
||||
xdg.configFile."beets/config.yaml".source =
|
||||
yamlFormat.generate "beets-config" cfg.settings;
|
||||
xdg.configFile."beets/config.yaml".text =
|
||||
builtins.toJSON config.programs.beets.settings;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.broot;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
brootConf = {
|
||||
verbs = cfg.verbs;
|
||||
skin = cfg.skin;
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.aheaume ];
|
||||
|
||||
options.programs.broot = {
|
||||
enable = mkEnableOption "Broot, a better way to navigate directories";
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
verbs = mkOption {
|
||||
type = with types; listOf (attrsOf (either bool str));
|
||||
default = [
|
||||
{
|
||||
invocation = "p";
|
||||
execution = ":parent";
|
||||
}
|
||||
{
|
||||
invocation = "edit";
|
||||
shortcut = "e";
|
||||
execution = "$EDITOR {file}";
|
||||
}
|
||||
{
|
||||
invocation = "create {subpath}";
|
||||
execution = "$EDITOR {directory}/{subpath}";
|
||||
}
|
||||
{
|
||||
invocation = "view";
|
||||
execution = "less {file}";
|
||||
}
|
||||
];
|
||||
example = literalExample ''
|
||||
[
|
||||
{ invocation = "p"; execution = ":parent"; }
|
||||
{ invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}" ; }
|
||||
{ invocation = "create {subpath}"; execution = "$EDITOR {directory}/{subpath}"; }
|
||||
{ invocation = "view"; execution = "less {file}"; }
|
||||
{
|
||||
invocation = "blop {name}\\.{type}";
|
||||
execution = "/bin/mkdir {parent}/{type} && /usr/bin/nvim {parent}/{type}/{name}.{type}";
|
||||
from_shell = true;
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Define new verbs. For more information, see
|
||||
<link xlink:href="https://dystroy.org/broot/documentation/configuration/#verb-definition-attributes"/>.
|
||||
</para><para>
|
||||
The possible attributes are:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>invocation</literal> (optional)</term>
|
||||
<listitem><para>how the verb is called by the user, with placeholders for arguments</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>execution</literal> (mandatory)</term>
|
||||
<listitem><para>how the verb is executed</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>key</literal> (optional)</term>
|
||||
<listitem><para>a keyboard key triggering execution</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>shortcut</literal> (optional)</term>
|
||||
<listitem><para>an alternate way to call the verb (without
|
||||
the arguments part)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>leave_broot</literal> (optional)</term>
|
||||
<listitem><para>whether to quit broot on execution
|
||||
(default: <literal>true</literal>)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>from_shell</literal> (optional)</term>
|
||||
<listitem><para>whether the verb must be executed from the
|
||||
parent shell (default:
|
||||
<literal>false</literal>)</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.broot;
|
||||
defaultText = literalExample "pkgs.broot";
|
||||
description = "Package providing broot";
|
||||
};
|
||||
|
||||
skin = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
status_normal_fg = "grayscale(18)";
|
||||
status_normal_bg = "grayscale(3)";
|
||||
status_error_fg = "red";
|
||||
status_error_bg = "yellow";
|
||||
tree_fg = "red";
|
||||
selected_line_bg = "grayscale(7)";
|
||||
permissions_fg = "grayscale(12)";
|
||||
size_bar_full_bg = "red";
|
||||
size_bar_void_bg = "black";
|
||||
directory_fg = "lightyellow";
|
||||
input_fg = "cyan";
|
||||
flag_value_fg = "lightyellow";
|
||||
table_border_fg = "red";
|
||||
code_fg = "lightyellow";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Color configuration.
|
||||
</para><para>
|
||||
Complete list of keys (expected to change before the v1 of broot):
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>char_match</literal></para></listitem>
|
||||
<listitem><para><literal>code</literal></para></listitem>
|
||||
<listitem><para><literal>directory</literal></para></listitem>
|
||||
<listitem><para><literal>exe</literal></para></listitem>
|
||||
<listitem><para><literal>file</literal></para></listitem>
|
||||
<listitem><para><literal>file_error</literal></para></listitem>
|
||||
<listitem><para><literal>flag_label</literal></para></listitem>
|
||||
<listitem><para><literal>flag_value</literal></para></listitem>
|
||||
<listitem><para><literal>input</literal></para></listitem>
|
||||
<listitem><para><literal>link</literal></para></listitem>
|
||||
<listitem><para><literal>permissions</literal></para></listitem>
|
||||
<listitem><para><literal>selected_line</literal></para></listitem>
|
||||
<listitem><para><literal>size_bar_full</literal></para></listitem>
|
||||
<listitem><para><literal>size_bar_void</literal></para></listitem>
|
||||
<listitem><para><literal>size_text</literal></para></listitem>
|
||||
<listitem><para><literal>spinner</literal></para></listitem>
|
||||
<listitem><para><literal>status_error</literal></para></listitem>
|
||||
<listitem><para><literal>status_normal</literal></para></listitem>
|
||||
<listitem><para><literal>table_border</literal></para></listitem>
|
||||
<listitem><para><literal>tree</literal></para></listitem>
|
||||
<listitem><para><literal>unlisted</literal></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>
|
||||
Add <literal>_fg</literal> for a foreground color and
|
||||
<literal>_bg</literal> for a background colors.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
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 = "";
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br {
|
||||
f=$(mktemp)
|
||||
(
|
||||
set +e
|
||||
broot --outcmd "$f" "$@"
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
rm -f "$f"
|
||||
exit "$code"
|
||||
fi
|
||||
)
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
return "$code"
|
||||
fi
|
||||
d=$(cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
}
|
||||
'');
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br {
|
||||
f=$(mktemp)
|
||||
(
|
||||
set +e
|
||||
broot --outcmd "$f" "$@"
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
rm -f "$f"
|
||||
exit "$code"
|
||||
fi
|
||||
)
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
return "$code"
|
||||
fi
|
||||
d=$(cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
}
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br
|
||||
set f (mktemp)
|
||||
broot --outcmd $f $argv
|
||||
if test $status -ne 0
|
||||
rm -f "$f"
|
||||
return "$code"
|
||||
end
|
||||
set d (cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
end
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -2,7 +2,13 @@
|
||||
|
||||
with lib;
|
||||
|
||||
let browsers = [ "chrome" "chromium" "firefox" "vivaldi" ];
|
||||
let
|
||||
browsers = [
|
||||
"chrome"
|
||||
"chromium"
|
||||
"firefox"
|
||||
"vivaldi"
|
||||
];
|
||||
in {
|
||||
options = {
|
||||
programs.browserpass = {
|
||||
@@ -18,59 +24,57 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf config.programs.browserpass.enable {
|
||||
home.file = foldl' (a: b: a // b) { } (concatMap (x:
|
||||
with pkgs.stdenv;
|
||||
home.file = builtins.concatLists (with pkgs.stdenv; map (x:
|
||||
if x == "chrome" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Google/Chrome/NativeMessagingHosts"
|
||||
else
|
||||
".config/google-chrome/NativeMessagingHosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}]
|
||||
else if x == "chromium" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Chromium/NativeMessagingHosts"
|
||||
else
|
||||
".config/chromium/NativeMessagingHosts";
|
||||
let dir = if isDarwin
|
||||
then "Library/Application Support/Google/Chrome/NativeMessagingHosts"
|
||||
else ".config/google-chrome/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
target = "${dir}/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
}
|
||||
{
|
||||
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
}
|
||||
]
|
||||
else if x == "chromium" then
|
||||
let dir = if isDarwin
|
||||
then "Library/Application Support/Chromium/NativeMessagingHosts"
|
||||
else ".config/chromium/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
}
|
||||
]
|
||||
else if x == "firefox" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
|
||||
}]
|
||||
[ {
|
||||
target = (if isDarwin
|
||||
then "Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else ".mozilla/native-messaging-hosts")
|
||||
+ "/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/lib/mozilla/native-messaging-hosts/com.dannyvankooten.browserpass.json";
|
||||
} ]
|
||||
else if x == "vivaldi" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Vivaldi/NativeMessagingHosts"
|
||||
else
|
||||
".config/vivaldi/NativeMessagingHosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}]
|
||||
else
|
||||
throw "unknown browser ${x}") config.programs.browserpass.browsers);
|
||||
let dir = if isDarwin
|
||||
then "Library/Application Support/Vivaldi/NativeMessagingHosts"
|
||||
else ".config/vivaldi/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
}
|
||||
]
|
||||
else throw "unknown browser ${x}") config.programs.browserpass.browsers);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
browserModule = defaultPkg: name: visible:
|
||||
let
|
||||
browser = (builtins.parseDrvName defaultPkg.name).name;
|
||||
isProprietaryChrome = hasPrefix "Google Chrome" name;
|
||||
in {
|
||||
enable = mkOption {
|
||||
inherit visible;
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether to enable ${name}.";
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
inherit visible;
|
||||
type = types.package;
|
||||
default = defaultPkg;
|
||||
defaultText = literalExample "pkgs.${browser}";
|
||||
description = "The ${name} package to use.";
|
||||
};
|
||||
} // optionalAttrs (!isProprietaryChrome) {
|
||||
# Extensions do not work with Google Chrome
|
||||
# see https://github.com/nix-community/home-manager/issues/1383
|
||||
extensions = mkOption {
|
||||
inherit visible;
|
||||
type = with types;
|
||||
let
|
||||
extensionType = submodule {
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = strMatching "[a-zA-Z]{32}";
|
||||
description = ''
|
||||
The extension's ID from the Chome Web Store url or the unpacked crx.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
|
||||
updateUrl = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
URL of the extension's update manifest XML file. Linux only.
|
||||
'';
|
||||
default = "https://clients2.google.com/service/update2/crx";
|
||||
visible = pkgs.stdenv.isLinux;
|
||||
readOnly = pkgs.stdenv.isDarwin;
|
||||
};
|
||||
|
||||
crxPath = mkOption {
|
||||
type = nullOr path;
|
||||
description = ''
|
||||
Path to the extension's crx file. Linux only.
|
||||
'';
|
||||
default = null;
|
||||
visible = pkgs.stdenv.isLinux;
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
type = nullOr str;
|
||||
description = ''
|
||||
The extension's version, required for local installation. Linux only.
|
||||
'';
|
||||
default = null;
|
||||
visible = pkgs.stdenv.isLinux;
|
||||
};
|
||||
};
|
||||
};
|
||||
in listOf (coercedTo str (v: { id = v; }) extensionType);
|
||||
default = [ ];
|
||||
example = literalExample ''
|
||||
[
|
||||
{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # ublock origin
|
||||
{
|
||||
id = "dcpihecpambacapedldabdbpakmachpb";
|
||||
updateUrl = "https://raw.githubusercontent.com/iamadamdev/bypass-paywalls-chrome/master/updates.xml";
|
||||
}
|
||||
{
|
||||
id = "aaaaaaaaaabbbbbbbbbbcccccccccc";
|
||||
crxPath = "/home/share/extension.crx";
|
||||
version = "1.0";
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of ${name} extensions to install.
|
||||
To find the extension ID, check its URL on the
|
||||
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
|
||||
</para><para>
|
||||
To install extensions outside of the Chrome Web Store set
|
||||
<literal>updateUrl</literal> or <literal>crxPath</literal> and
|
||||
<literal>version</literal> as explained in the
|
||||
<link xlink:href="https://developer.chrome.com/docs/extensions/mv2/external_extensions">Chrome
|
||||
documentation</link>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
browserConfig = cfg:
|
||||
let
|
||||
|
||||
drvName = (builtins.parseDrvName cfg.package.name).name;
|
||||
browser = if drvName == "ungoogled-chromium" then "chromium" else drvName;
|
||||
|
||||
darwinDirs = {
|
||||
chromium = "Chromium";
|
||||
google-chrome = "Google/Chrome";
|
||||
google-chrome-beta = "Google/Chrome Beta";
|
||||
google-chrome-dev = "Google/Chrome Dev";
|
||||
brave = "BraveSoftware/Brave-Browser";
|
||||
};
|
||||
|
||||
linuxDirs = { brave = "BraveSoftware/Brave-Browser"; };
|
||||
|
||||
configDir = if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/" + (darwinDirs."${browser}" or browser)
|
||||
else
|
||||
"${config.xdg.configHome}/" + (linuxDirs."${browser}" or browser);
|
||||
|
||||
extensionJson = ext:
|
||||
assert ext.crxPath != null -> ext.version != null;
|
||||
with builtins; {
|
||||
name = "${configDir}/External Extensions/${ext.id}.json";
|
||||
value.text = toJSON (if ext.crxPath != null then {
|
||||
external_crx = ext.crxPath;
|
||||
external_version = ext.version;
|
||||
} else {
|
||||
external_update_url = ext.updateUrl;
|
||||
});
|
||||
};
|
||||
|
||||
in mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
home.file = listToAttrs (map extensionJson (cfg.extensions 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;
|
||||
google-chrome-beta =
|
||||
browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
|
||||
google-chrome-dev =
|
||||
browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
|
||||
brave = browserModule pkgs.brave "Brave Browser" false;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(browserConfig config.programs.chromium)
|
||||
(browserConfig config.programs.google-chrome)
|
||||
(browserConfig config.programs.google-chrome-beta)
|
||||
(browserConfig config.programs.google-chrome-dev)
|
||||
(browserConfig config.programs.brave)
|
||||
];
|
||||
}
|
||||
@@ -13,11 +13,8 @@ let
|
||||
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
|
||||
]);
|
||||
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
|
||||
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
|
||||
};
|
||||
|
||||
shInit = commandNotFoundHandlerName: ''
|
||||
@@ -34,13 +31,14 @@ let
|
||||
}
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
|
||||
{
|
||||
options.programs.command-not-found = {
|
||||
enable = mkEnableOption "command-not-found hook for interactive shell";
|
||||
|
||||
dbPath = mkOption {
|
||||
default =
|
||||
"/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite";
|
||||
default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ;
|
||||
description = ''
|
||||
Absolute path to <filename>programs.sqlite</filename>. By
|
||||
default this file will be provided by your channel
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dircolors;
|
||||
|
||||
formatLine = n: v: "${n} ${toString v}";
|
||||
in {
|
||||
meta.maintainers = [ hm.maintainers.justinlovinger ];
|
||||
|
||||
options.programs.dircolors = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to manage <filename>.dir_colors</filename>
|
||||
and set <code>LS_COLORS</code>.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
default = { };
|
||||
description = ''
|
||||
Options to add to <filename>.dir_colors</filename> file.
|
||||
See <command>dircolors --print-database</command>
|
||||
for options.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
OTHER_WRITABLE = "30;46";
|
||||
".sh" = "01;32";
|
||||
".csh" = "01;32";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra lines added to <filename>.dir_colors</filename> file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Add default settings from `dircolors --print-database`.
|
||||
programs.dircolors.settings = {
|
||||
RESET = mkDefault "0";
|
||||
DIR = mkDefault "01;34";
|
||||
LINK = mkDefault "01;36";
|
||||
MULTIHARDLINK = mkDefault "00";
|
||||
FIFO = mkDefault "40;33";
|
||||
SOCK = mkDefault "01;35";
|
||||
DOOR = mkDefault "01;35";
|
||||
BLK = mkDefault "40;33;01";
|
||||
CHR = mkDefault "40;33;01";
|
||||
ORPHAN = mkDefault "40;31;01";
|
||||
MISSING = mkDefault "00";
|
||||
SETUID = mkDefault "37;41";
|
||||
SETGID = mkDefault "30;43";
|
||||
CAPABILITY = mkDefault "30;41";
|
||||
STICKY_OTHER_WRITABLE = mkDefault "30;42";
|
||||
OTHER_WRITABLE = mkDefault "34;42";
|
||||
STICKY = mkDefault "37;44";
|
||||
EXEC = mkDefault "01;32";
|
||||
".tar" = mkDefault "01;31";
|
||||
".tgz" = mkDefault "01;31";
|
||||
".arc" = mkDefault "01;31";
|
||||
".arj" = mkDefault "01;31";
|
||||
".taz" = mkDefault "01;31";
|
||||
".lha" = mkDefault "01;31";
|
||||
".lz4" = mkDefault "01;31";
|
||||
".lzh" = mkDefault "01;31";
|
||||
".lzma" = mkDefault "01;31";
|
||||
".tlz" = mkDefault "01;31";
|
||||
".txz" = mkDefault "01;31";
|
||||
".tzo" = mkDefault "01;31";
|
||||
".t7z" = mkDefault "01;31";
|
||||
".zip" = mkDefault "01;31";
|
||||
".z" = mkDefault "01;31";
|
||||
".dz" = mkDefault "01;31";
|
||||
".gz" = mkDefault "01;31";
|
||||
".lrz" = mkDefault "01;31";
|
||||
".lz" = mkDefault "01;31";
|
||||
".lzo" = mkDefault "01;31";
|
||||
".xz" = mkDefault "01;31";
|
||||
".zst" = mkDefault "01;31";
|
||||
".tzst" = mkDefault "01;31";
|
||||
".bz2" = mkDefault "01;31";
|
||||
".bz" = mkDefault "01;31";
|
||||
".tbz" = mkDefault "01;31";
|
||||
".tbz2" = mkDefault "01;31";
|
||||
".tz" = mkDefault "01;31";
|
||||
".deb" = mkDefault "01;31";
|
||||
".rpm" = mkDefault "01;31";
|
||||
".jar" = mkDefault "01;31";
|
||||
".war" = mkDefault "01;31";
|
||||
".ear" = mkDefault "01;31";
|
||||
".sar" = mkDefault "01;31";
|
||||
".rar" = mkDefault "01;31";
|
||||
".alz" = mkDefault "01;31";
|
||||
".ace" = mkDefault "01;31";
|
||||
".zoo" = mkDefault "01;31";
|
||||
".cpio" = mkDefault "01;31";
|
||||
".7z" = mkDefault "01;31";
|
||||
".rz" = mkDefault "01;31";
|
||||
".cab" = mkDefault "01;31";
|
||||
".wim" = mkDefault "01;31";
|
||||
".swm" = mkDefault "01;31";
|
||||
".dwm" = mkDefault "01;31";
|
||||
".esd" = mkDefault "01;31";
|
||||
".jpg" = mkDefault "01;35";
|
||||
".jpeg" = mkDefault "01;35";
|
||||
".mjpg" = mkDefault "01;35";
|
||||
".mjpeg" = mkDefault "01;35";
|
||||
".gif" = mkDefault "01;35";
|
||||
".bmp" = mkDefault "01;35";
|
||||
".pbm" = mkDefault "01;35";
|
||||
".pgm" = mkDefault "01;35";
|
||||
".ppm" = mkDefault "01;35";
|
||||
".tga" = mkDefault "01;35";
|
||||
".xbm" = mkDefault "01;35";
|
||||
".xpm" = mkDefault "01;35";
|
||||
".tif" = mkDefault "01;35";
|
||||
".tiff" = mkDefault "01;35";
|
||||
".png" = mkDefault "01;35";
|
||||
".svg" = mkDefault "01;35";
|
||||
".svgz" = mkDefault "01;35";
|
||||
".mng" = mkDefault "01;35";
|
||||
".pcx" = mkDefault "01;35";
|
||||
".mov" = mkDefault "01;35";
|
||||
".mpg" = mkDefault "01;35";
|
||||
".mpeg" = mkDefault "01;35";
|
||||
".m2v" = mkDefault "01;35";
|
||||
".mkv" = mkDefault "01;35";
|
||||
".webm" = mkDefault "01;35";
|
||||
".ogm" = mkDefault "01;35";
|
||||
".mp4" = mkDefault "01;35";
|
||||
".m4v" = mkDefault "01;35";
|
||||
".mp4v" = mkDefault "01;35";
|
||||
".vob" = mkDefault "01;35";
|
||||
".qt" = mkDefault "01;35";
|
||||
".nuv" = mkDefault "01;35";
|
||||
".wmv" = mkDefault "01;35";
|
||||
".asf" = mkDefault "01;35";
|
||||
".rm" = mkDefault "01;35";
|
||||
".rmvb" = mkDefault "01;35";
|
||||
".flc" = mkDefault "01;35";
|
||||
".avi" = mkDefault "01;35";
|
||||
".fli" = mkDefault "01;35";
|
||||
".flv" = mkDefault "01;35";
|
||||
".gl" = mkDefault "01;35";
|
||||
".dl" = mkDefault "01;35";
|
||||
".xcf" = mkDefault "01;35";
|
||||
".xwd" = mkDefault "01;35";
|
||||
".yuv" = mkDefault "01;35";
|
||||
".cgm" = mkDefault "01;35";
|
||||
".emf" = mkDefault "01;35";
|
||||
".ogv" = mkDefault "01;35";
|
||||
".ogx" = mkDefault "01;35";
|
||||
".aac" = mkDefault "00;36";
|
||||
".au" = mkDefault "00;36";
|
||||
".flac" = mkDefault "00;36";
|
||||
".m4a" = mkDefault "00;36";
|
||||
".mid" = mkDefault "00;36";
|
||||
".midi" = mkDefault "00;36";
|
||||
".mka" = mkDefault "00;36";
|
||||
".mp3" = mkDefault "00;36";
|
||||
".mpc" = mkDefault "00;36";
|
||||
".ogg" = mkDefault "00;36";
|
||||
".ra" = mkDefault "00;36";
|
||||
".wav" = mkDefault "00;36";
|
||||
".oga" = mkDefault "00;36";
|
||||
".opus" = mkDefault "00;36";
|
||||
".spx" = mkDefault "00;36";
|
||||
".xspf" = mkDefault "00;36";
|
||||
};
|
||||
|
||||
home.file.".dir_colors".text = concatStringsSep "\n" ([ ]
|
||||
++ mapAttrsToList formatLine cfg.settings ++ [ "" ]
|
||||
++ optional (cfg.extraConfig != "") cfg.extraConfig);
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
eval (${pkgs.coreutils}/bin/dircolors -c ~/.dir_colors)
|
||||
'';
|
||||
|
||||
# Set `LS_COLORS` before Oh My Zsh and `initExtra`.
|
||||
programs.zsh.initExtraBeforeCompInit = mkIf cfg.enableZshIntegration ''
|
||||
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.direnv;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [
|
||||
"programs"
|
||||
"direnv"
|
||||
"enableNixDirenvIntegration"
|
||||
] [ "programs" "direnv" "nix-direnv" "enable" ])
|
||||
];
|
||||
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options.programs.direnv = {
|
||||
enable = mkEnableOption "direnv, the environment switcher";
|
||||
|
||||
config = mkOption {
|
||||
type = tomlFormat.type;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/direnv/config.toml</filename>.
|
||||
</para><para>
|
||||
See
|
||||
<citerefentry>
|
||||
<refentrytitle>direnv.toml</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>.
|
||||
for the full list of options.
|
||||
'';
|
||||
};
|
||||
|
||||
stdlib = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Custom stdlib written to
|
||||
<filename>~/.config/direnv/direnvrc</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
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 {
|
||||
home.packages = [ pkgs.direnv ];
|
||||
|
||||
xdg.configFile."direnv/config.toml" = mkIf (cfg.config != { }) {
|
||||
source = tomlFormat.generate "direnv-config" cfg.config;
|
||||
};
|
||||
|
||||
xdg.configFile."direnv/direnvrc" = let
|
||||
package =
|
||||
pkgs.nix-direnv.override { inherit (cfg.nix-direnv) enableFlakes; };
|
||||
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
|
||||
++ optional cfg.nix-direnv.enable
|
||||
"source ${package}/share/nix-direnv/direnvrc");
|
||||
in mkIf (text != "") { inherit text; };
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
|
||||
'');
|
||||
|
||||
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
|
||||
'';
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user