Project import generated by Copybara.
GitOrigin-RevId: 9bf1f40af124573a54fd208b1f539eb694ef31a6
This commit is contained in:
parent
c5964f45bb
commit
72904c318c
517 changed files with 39119 additions and 0 deletions
229
third_party/home-manager/.github/CODEOWNERS
vendored
Normal file
229
third_party/home-manager/.github/CODEOWNERS
vendored
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
* @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/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/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/firefox.nix @rycee
|
||||||
|
|
||||||
|
/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/i3status.nix @JustinLovinger
|
||||||
|
|
||||||
|
/modules/programs/keychain.nix @marsam
|
||||||
|
|
||||||
|
/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
|
||||||
|
|
||||||
|
/modules/programs/mu.nix @KarlJoad
|
||||||
|
|
||||||
|
/modules/programs/ncmpcpp.nix @olmokramer
|
||||||
|
/tests/modules/programs/ncmpcpp @olmokramer
|
||||||
|
/tests/modules/programs/ncmpcpp-linux @olmokramer
|
||||||
|
|
||||||
|
/modules/programs/ne.nix @cwyc
|
||||||
|
/tests/modules/programs/ne @cwyc
|
||||||
|
|
||||||
|
/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/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/rtorrent.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/ssh.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/starship.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/texlive.nix @rycee
|
||||||
|
|
||||||
|
/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/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/flameshot.nix @moredhel
|
||||||
|
|
||||||
|
/modules/services/fluidsynth.nix @Valodim
|
||||||
|
|
||||||
|
/modules/services/gammastep.nix @petabyteboy
|
||||||
|
|
||||||
|
/modules/services/gnome-keyring.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/gpg-agent.nix @rycee
|
||||||
|
|
||||||
|
/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/muchsync.nix @pacien
|
||||||
|
|
||||||
|
/modules/services/network-manager-applet.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/parcellite.nix @gleber
|
||||||
|
|
||||||
|
/modules/services/password-store-sync.nix @pacien
|
||||||
|
|
||||||
|
/modules/services/pasystray.nix @pltanton
|
||||||
|
|
||||||
|
/modules/services/pulseeffects.nix @jonringer
|
||||||
|
|
||||||
|
/modules/services/random-background.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/redshift.nix @rycee
|
||||||
|
|
||||||
|
/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/sway.nix @alexarice
|
||||||
|
|
||||||
|
/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
|
23
third_party/home-manager/.github/ISSUE_TEMPLATE.md
vendored
Normal file
23
third_party/home-manager/.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
### Issue description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Please describe the issue. For support and help please use the IRC
|
||||||
|
channel #home-manager @ freenode.net instead.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Meta
|
||||||
|
|
||||||
|
#### Maintainer CC
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Please @ people who are in the `meta.maintainers` list of the
|
||||||
|
offending module. If in doubt, check `git blame` for whoever last
|
||||||
|
touched something.
|
||||||
|
-->
|
||||||
|
|
||||||
|
#### Technical details
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the
|
||||||
|
result.
|
||||||
|
-->
|
44
third_party/home-manager/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
44
third_party/home-manager/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
### 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`.
|
28
third_party/home-manager/.github/workflows/github_pages.yml
vendored
Normal file
28
third_party/home-manager/.github/workflows/github_pages.yml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
name: GitHub Pages
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: cachix/install-nix-action@v10
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@v6
|
||||||
|
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
|
22
third_party/home-manager/.github/workflows/test.yml
vendored
Normal file
22
third_party/home-manager/.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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@v2
|
||||||
|
- uses: cachix/install-nix-action@v10
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@v6
|
||||||
|
with:
|
||||||
|
name: nix-community
|
||||||
|
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||||
|
- run: nix-shell . -A install
|
||||||
|
- run: nix-shell --pure --max-jobs 4 tests -A run.all
|
2
third_party/home-manager/.gitignore
vendored
Normal file
2
third_party/home-manager/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/flake.lock
|
||||||
|
/result*
|
44
third_party/home-manager/.gitlab-ci.yml
vendored
Normal file
44
third_party/home-manager/.gitlab-ci.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
image: nixos/nix:latest
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# Pinned 2020-09-11.
|
||||||
|
NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/6d4b93323e7f78121f8d6db6c59f3889aa1dd931.tar.gz"
|
||||||
|
|
||||||
|
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
|
255
third_party/home-manager/CONTRIBUTING.adoc
vendored
Normal file
255
third_party/home-manager/CONTRIBUTING.adoc
vendored
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
[[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.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-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
|
||||||
|
|
||||||
|
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 never cause another user's existing configuration to break. Home Manager is used in many different environments and you should consider how you change may effect others. For example,
|
||||||
|
|
||||||
|
- 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://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. Note, `{description}` should start with a lower case letter. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <<ex-commit-message>> for a commit message that fulfills these requirements.
|
||||||
|
|
||||||
|
[[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
|
171
third_party/home-manager/FAQ.adoc
vendored
Normal file
171
third_party/home-manager/FAQ.adoc
vendored
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
[[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 do 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; [ gnome3.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.
|
21
third_party/home-manager/LICENSE
vendored
Normal file
21
third_party/home-manager/LICENSE
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017-2020 Robert Helgesson and Home Manager contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
368
third_party/home-manager/README.md
vendored
Normal file
368
third_party/home-manager/README.md
vendored
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
Home Manager using Nix
|
||||||
|
======================
|
||||||
|
|
||||||
|
This project provides a basic system for managing a user environment
|
||||||
|
using the [Nix][] package manager together with the Nix libraries
|
||||||
|
found in [Nixpkgs][]. Before attempting to use Home Manager please
|
||||||
|
read the warning below.
|
||||||
|
|
||||||
|
For a more systematic overview of Home Manager and its available
|
||||||
|
options, please see the [Home Manager manual][manual].
|
||||||
|
|
||||||
|
Words of warning
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This project is under development. I personally use it to manage
|
||||||
|
several user configurations but it may fail catastrophically for you.
|
||||||
|
So beware!
|
||||||
|
|
||||||
|
Before using Home Manager you should be comfortable using the Nix
|
||||||
|
language and the various tools in the Nix ecosystem. Reading through
|
||||||
|
the [Nix Pills][] document is a good way to familiarize yourself with
|
||||||
|
them.
|
||||||
|
|
||||||
|
In some cases Home Manager cannot detect whether it will overwrite a
|
||||||
|
previous manual configuration. For example, the Gnome Terminal module
|
||||||
|
will write to your dconf store and cannot tell whether a configuration
|
||||||
|
that it is about to be overwrite was from a previous Home Manager
|
||||||
|
generation or from manual configuration.
|
||||||
|
|
||||||
|
Home Manager targets [NixOS][] unstable and NixOS version 20.03 (the
|
||||||
|
current stable version), it may or may not work on other Linux
|
||||||
|
distributions and NixOS versions.
|
||||||
|
|
||||||
|
Also, the `home-manager` tool does not explicitly support rollbacks at
|
||||||
|
the moment so if your home directory gets messed up you'll have to fix
|
||||||
|
it yourself. See the [rollbacks](#rollbacks) section for instructions
|
||||||
|
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
|
||||||
|
[freenode][]. The [channel logs][] are hosted courtesy of
|
||||||
|
[samueldr][].
|
||||||
|
|
||||||
|
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
|
||||||
|
[`nix.allowedUsers`][nixosAllowedUsers] system option.
|
||||||
|
|
||||||
|
2. Add the appropriate Home Manager channel. Typically this is
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||||
|
$ nix-channel --update
|
||||||
|
```
|
||||||
|
|
||||||
|
if you are following Nixpkgs master or an unstable channel and
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager
|
||||||
|
$ nix-channel --update
|
||||||
|
```
|
||||||
|
|
||||||
|
if you follow a Nixpkgs version 20.03 channel.
|
||||||
|
|
||||||
|
On NixOS you may need to log out and back in for the channel to
|
||||||
|
become available. On non-NixOS you may have to add
|
||||||
|
|
||||||
|
```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:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nix-shell '<home-manager>' -A install
|
||||||
|
```
|
||||||
|
|
||||||
|
Once finished, Home Manager should be active and available in your
|
||||||
|
user environment.
|
||||||
|
|
||||||
|
3. If you do not plan on having Home Manager manage your shell
|
||||||
|
configuration then you must source the
|
||||||
|
|
||||||
|
```
|
||||||
|
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
file in your shell configuration. Unfortunately, in this specific
|
||||||
|
case we currently only support POSIX.2-like shells such as
|
||||||
|
[Bash][] or [Z shell][].
|
||||||
|
|
||||||
|
For example, if you use Bash then add
|
||||||
|
|
||||||
|
```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
|
||||||
|
`programs.home-manager.path` option to specify the absolute path to
|
||||||
|
the repository.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
Home Manager is typically managed through the `home-manager` tool.
|
||||||
|
This tool can, for example, apply configurations to your home
|
||||||
|
directory, list user packages installed by the tool, and list the
|
||||||
|
configuration generations.
|
||||||
|
|
||||||
|
As an example, let us expand the initial configuration file from the
|
||||||
|
installation above to install the htop and fortune packages, install
|
||||||
|
Emacs with a few extra packages enabled, install Firefox with the
|
||||||
|
IcedTea plugin enabled, and enable the user gpg-agent service.
|
||||||
|
|
||||||
|
To satisfy the above setup we should elaborate the
|
||||||
|
`~/.config/nixpkgs/home.nix` file as follows:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgs.htop
|
||||||
|
pkgs.fortune
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.emacs = {
|
||||||
|
enable = true;
|
||||||
|
extraPackages = epkgs: [
|
||||||
|
epkgs.nix-mode
|
||||||
|
epkgs.magit
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.firefox = {
|
||||||
|
enable = true;
|
||||||
|
profiles = {
|
||||||
|
myprofile = {
|
||||||
|
settings = {
|
||||||
|
"general.smoothScroll" = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gpg-agent = {
|
||||||
|
enable = true;
|
||||||
|
defaultCacheTtl = 1800;
|
||||||
|
enableSshSupport = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.home-manager = {
|
||||||
|
enable = true;
|
||||||
|
path = "…";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To activate this configuration you can then run
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ home-manager switch
|
||||||
|
```
|
||||||
|
|
||||||
|
or if you are not feeling so lucky,
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ 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
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ man home-configuration.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
Rollbacks
|
||||||
|
---------
|
||||||
|
|
||||||
|
While the `home-manager` tool does not explicitly support rollbacks at
|
||||||
|
the moment it is relatively easy to perform one manually. The steps to
|
||||||
|
do so are
|
||||||
|
|
||||||
|
1. Run `home-manager generations` to determine which generation you
|
||||||
|
wish to rollback to:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ home-manager generations
|
||||||
|
2018-01-04 11:56 : id 765 -> /nix/store/kahm1rxk77mnvd2l8pfvd4jkkffk5ijk-home-manager-generation
|
||||||
|
2018-01-03 10:29 : id 764 -> /nix/store/2wsmsliqr5yynqkdyjzb1y57pr5q2lsj-home-manager-generation
|
||||||
|
2018-01-01 12:21 : id 763 -> /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
|
||||||
|
2017-12-29 21:03 : id 762 -> /nix/store/6c0k1r03fxckql4vgqcn9ccb616ynb94-home-manager-generation
|
||||||
|
2017-12-25 18:51 : id 761 -> /nix/store/czc5y6vi1rvnkfv83cs3rn84jarcgsgh-home-manager-generation
|
||||||
|
…
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Copy the Nix store path of the generation you chose, e.g.,
|
||||||
|
|
||||||
|
/nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
|
||||||
|
|
||||||
|
for generation 763.
|
||||||
|
|
||||||
|
3. Run the `activate` script inside the copied store path:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation/activate
|
||||||
|
Starting home manager activation
|
||||||
|
…
|
||||||
|
```
|
||||||
|
|
||||||
|
Keeping your ~ safe from harm
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
To configure programs and services Home Manager must write various
|
||||||
|
things to your home directory. To prevent overwriting any existing
|
||||||
|
files when switching to a new generation, Home Manager will attempt to
|
||||||
|
detect collisions between existing files and generated files. If any
|
||||||
|
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
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
# …
|
||||||
|
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
userName = "Jane Doe";
|
||||||
|
userEmail = "jane.doe@example.org";
|
||||||
|
};
|
||||||
|
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
to your configuration. Attempting to switch to the generation will
|
||||||
|
then result in
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ home-manager switch
|
||||||
|
…
|
||||||
|
Activating checkLinkTargets
|
||||||
|
Existing file '/home/jdoe/.gitconfig' is in the way
|
||||||
|
Please move the above files and try again
|
||||||
|
```
|
||||||
|
|
||||||
|
Graphical services
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Home Manager includes a number of services intended to run in a
|
||||||
|
graphical session, for example `xscreensaver` and `dunst`.
|
||||||
|
Unfortunately, such services will not be started automatically unless
|
||||||
|
you let Home Manager start your X session. That is, you have something
|
||||||
|
like
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
# …
|
||||||
|
|
||||||
|
services.xserver.enable = true;
|
||||||
|
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
in your system configuration and
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
# …
|
||||||
|
|
||||||
|
xsession.enable = true;
|
||||||
|
xsession.windowManager.command = "…";
|
||||||
|
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
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.user = import ./home.nix;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
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-20.03`). 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/
|
||||||
|
[Nixpkgs]: https://nixos.org/nixpkgs/
|
||||||
|
[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.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager
|
||||||
|
[freenode]: https://freenode.net/
|
||||||
|
[channel logs]: https://logs.nix.samueldr.com/home-manager/
|
||||||
|
[samueldr]: https://github.com/samueldr/
|
||||||
|
[Nix Pills]: https://nixos.org/nixos/nix-pills/
|
||||||
|
[Nix Flakes]: https://nixos.wiki/wiki/Flakes
|
18
third_party/home-manager/default.nix
vendored
Normal file
18
third_party/home-manager/default.nix
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
docs = with import ./doc { inherit pkgs; }; {
|
||||||
|
html = manual.html;
|
||||||
|
manPages = manPages;
|
||||||
|
json = options.json;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager = pkgs.callPackage ./home-manager { path = toString ./.; };
|
||||||
|
|
||||||
|
install =
|
||||||
|
pkgs.callPackage ./home-manager/install.nix { inherit home-manager; };
|
||||||
|
|
||||||
|
nixos = import ./nixos;
|
||||||
|
|
||||||
|
path = ./.;
|
||||||
|
}
|
255
third_party/home-manager/doc/contributing.adoc
vendored
Normal file
255
third_party/home-manager/doc/contributing.adoc
vendored
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
[[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.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-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
|
||||||
|
|
||||||
|
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 never cause another user's existing configuration to break. Home Manager is used in many different environments and you should consider how you change may effect others. For example,
|
||||||
|
|
||||||
|
- 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://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. Note, `{description}` should start with a lower case letter. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <<ex-commit-message>> for a commit message that fulfills these requirements.
|
||||||
|
|
||||||
|
[[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
|
69
third_party/home-manager/doc/default.nix
vendored
Normal file
69
third_party/home-manager/doc/default.nix
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{ 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 { };
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
hmModulesDocs = nmd.buildModulesDocs {
|
||||||
|
modules = import ../modules/modules.nix {
|
||||||
|
inherit lib pkgs;
|
||||||
|
check = false;
|
||||||
|
} ++ [ scrubbedPkgsModule ];
|
||||||
|
moduleRootPaths = [ ./.. ];
|
||||||
|
mkModuleUrl = path:
|
||||||
|
"https://github.com/nix-community/home-manager/blob/master/${path}#blob-path";
|
||||||
|
channelName = "home-manager";
|
||||||
|
docBook.id = "home-manager-options";
|
||||||
|
};
|
||||||
|
|
||||||
|
docs = nmd.buildDocBookDocs {
|
||||||
|
pathName = "home-manager";
|
||||||
|
modulesDocs = [ hmModulesDocs ];
|
||||||
|
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-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
third_party/home-manager/doc/faq.adoc
vendored
Normal file
171
third_party/home-manager/doc/faq.adoc
vendored
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
[[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 do 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; [ gnome3.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.
|
334
third_party/home-manager/doc/installation.xml
vendored
Normal file
334
third_party/home-manager/doc/installation.xml
vendored
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
<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="ch-installation">
|
||||||
|
<title>Installing Home Manager</title>
|
||||||
|
<para>
|
||||||
|
Home Manager can be used in three primary ways:
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Using the standalone <command>home-manager</command> 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
|
||||||
|
<xref linkend="sec-install-standalone"/> for instructions on how to
|
||||||
|
perform this installation.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
As a module within a NixOS system configuration. This allows the user
|
||||||
|
profiles to be built together with the system when running
|
||||||
|
<command>nixos-rebuild</command>. See
|
||||||
|
<xref linkend="sec-install-nixos-module"/> for a description of this
|
||||||
|
setup.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
As a module within a
|
||||||
|
<link xlink:href="https://github.com/LnL7/nix-darwin/">nix-darwin</link>
|
||||||
|
system configuration. This allows the user profiles to be built together
|
||||||
|
with the system when running <command>darwin-rebuild</command>. See
|
||||||
|
<xref linkend="sec-install-nix-darwin-module"/> for a description of this
|
||||||
|
setup.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
<section xml:id="sec-install-standalone">
|
||||||
|
<title>Standalone installation</title>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
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 <literal>nix-instantiate '<nixpkgs>' -A hello</literal>
|
||||||
|
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
|
||||||
|
<link xlink:href="https://nixos.org/nix/manual/#conf-allowed-users"><literal>allowed-users</literal></link>
|
||||||
|
Nix option. On NixOS you can control this option using the
|
||||||
|
<link xlink:href="https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers"><literal>nix.allowedUsers</literal></link>
|
||||||
|
system option.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Add the Home Manager channel that you wish to follow. This is done by
|
||||||
|
running
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager</userinput>
|
||||||
|
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
if you are following Nixpkgs master or an unstable channel and
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager</userinput>
|
||||||
|
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
if you follow a Nixpkgs version 20.03 channel.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
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
|
||||||
|
<programlisting language="bash">
|
||||||
|
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||||
|
</programlisting>
|
||||||
|
to your shell (see
|
||||||
|
<link xlink:href="https://github.com/NixOS/nix/issues/2033">nix#2033</link>).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Run the Home Manager installation command and create the first Home
|
||||||
|
Manager generation:
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
<prompt>$</prompt> <userinput>nix-shell '<home-manager>' -A install</userinput>
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
Once finished, Home Manager should be active and available in your user
|
||||||
|
environment.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If you do not plan on having Home Manager manage your shell configuration
|
||||||
|
then you must source the
|
||||||
|
</para>
|
||||||
|
<programlisting language="bash">
|
||||||
|
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
file in your shell configuration. Unfortunately, we currently only support
|
||||||
|
POSIX.2-like shells such as
|
||||||
|
<link xlink:href="https://www.gnu.org/software/bash/">Bash</link> or
|
||||||
|
<link xlink:href="http://zsh.sourceforge.net/">Z shell</link>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
For example, if you use Bash then add
|
||||||
|
</para>
|
||||||
|
<programlisting language="bash">
|
||||||
|
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
to your <literal>~/.profile</literal> file.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If instead of using channels you want to run Home Manager from a Git
|
||||||
|
checkout of the repository then you can use the
|
||||||
|
<literal>programs.home-manager.path</literal> option to specify the absolute
|
||||||
|
path to the repository.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section xml:id="sec-install-nixos-module">
|
||||||
|
<title>NixOS module</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
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 <command>home-manager</command> tool. It also
|
||||||
|
opens up additional possibilities, for example, to automatically configure
|
||||||
|
user environments in NixOS declarative containers or on systems deployed
|
||||||
|
through NixOps.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To make the NixOS module available for use you must <option>import</option>
|
||||||
|
it into your system configuration. This is most conveniently done by adding
|
||||||
|
a Home Manager channel, for example
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen language="console">
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager</userinput>
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
if you are following Nixpkgs master or an unstable channel and
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen language="console">
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager</userinput>
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
if you follow a Nixpkgs version 20.03 channel.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
It is then possible to add
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
imports = [ <home-manager/nixos> ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
to your system <filename>configuration.nix</filename> file, which will
|
||||||
|
introduce a new NixOS option called <option>home-manager.users</option>
|
||||||
|
whose type is an attribute set that maps user names to Home Manager
|
||||||
|
configurations.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For example, a NixOS configuration may include the lines
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
users.users.eve.isNormalUser = true;
|
||||||
|
home-manager.users.eve = { pkgs, ... }: {
|
||||||
|
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||||
|
programs.bash.enable = true;
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
and after a <command>nixos-rebuild switch</command> the user eve's
|
||||||
|
environment should include a basic Bash configuration and the packages atool
|
||||||
|
and httpie.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
By default packages will be installed to
|
||||||
|
<filename>$HOME/.nix-profile</filename> but they can be installed to
|
||||||
|
<filename>/etc/profiles</filename> if
|
||||||
|
</para>
|
||||||
|
<programlisting language="nix">
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
is added to the system configuration. This is necessary if, for example,
|
||||||
|
you wish to use <command>nixos-rebuild build-vm</command>. This option may
|
||||||
|
become the default value in the future.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
By default, Home Manager uses a private <literal>pkgs</literal> instance
|
||||||
|
that is configured via the <option>home-manager.users.<name>.nixpkgs</option> options.
|
||||||
|
To instead use the global <literal>pkgs</literal> that is configured via
|
||||||
|
the system level <option>nixpkgs</option> options, set
|
||||||
|
</para>
|
||||||
|
<programlisting language="nix">
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
This saves an extra Nixpkgs evaluation, adds consistency, and removes the
|
||||||
|
dependency on <envar>NIX_PATH</envar>, which is otherwise used for
|
||||||
|
importing Nixpkgs.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</section>
|
||||||
|
<section xml:id="sec-install-nix-darwin-module">
|
||||||
|
<title>nix-darwin module</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Home Manager provides a module that allows you to prepare user
|
||||||
|
environments directly from the nix-darwin configuration file, which often is
|
||||||
|
more convenient than using the <command>home-manager</command> tool.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To make the NixOS module available for use you must <option>import</option>
|
||||||
|
it into your system configuration. This is most conveniently done by adding
|
||||||
|
a Home Manager channel, for example
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen language="console">
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager</userinput>
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
if you are following Nixpkgs master or an unstable channel and
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen language="console">
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/nix-community/home-manager/archive/release-20.03.tar.gz home-manager</userinput>
|
||||||
|
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
if you follow a Nixpkgs version 20.03 channel.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
It is then possible to add
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
imports = [ <home-manager/nix-darwin> ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
to your nix-darwin <filename>configuration.nix</filename> file, which will
|
||||||
|
introduce a new NixOS option called <option>home-manager</option> whose type
|
||||||
|
is an attribute set that maps user names to Home Manager configurations.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For example, a nix-darwin configuration may include the lines
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
home-manager.users.eve = { pkgs, ... }: {
|
||||||
|
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||||
|
programs.bash.enable = true;
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
and after a <command>darwin-rebuild --switch</command> the user eve's
|
||||||
|
environment should include a basic Bash configuration and the packages atool
|
||||||
|
and httpie.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
By default user packages will not be ignored in favor of
|
||||||
|
<option>environment.systemPackages</option>, but they will be intalled to
|
||||||
|
<option>/etc/profiles/per-user/$USERNAME</option> if
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
is added to the nix-darwin configuration. This option may become the default
|
||||||
|
value in the future.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
By default, Home Manager uses a private <literal>pkgs</literal> instance
|
||||||
|
that is configured via the <option>home-manager.users.<name>.nixpkgs</option> options.
|
||||||
|
To instead use the global <literal>pkgs</literal> that is configured via
|
||||||
|
the system level <option>nixpkgs</option> options, set
|
||||||
|
</para>
|
||||||
|
<programlisting language="nix">
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
This saves an extra Nixpkgs evaluation, adds consistency, and removes the
|
||||||
|
dependency on <envar>NIX_PATH</envar>, which is otherwise used for
|
||||||
|
importing Nixpkgs.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</section>
|
||||||
|
</chapter>
|
40
third_party/home-manager/doc/man-configuration.xml
vendored
Normal file
40
third_party/home-manager/doc/man-configuration.xml
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<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>
|
527
third_party/home-manager/doc/man-home-manager.xml
vendored
Normal file
527
third_party/home-manager/doc/man-home-manager.xml
vendored
Normal file
|
@ -0,0 +1,527 @@
|
||||||
|
<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>
|
||||||
|
-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>
|
||||||
|
--max-jobs <replaceable>number</replaceable>
|
||||||
|
</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>.
|
||||||
|
</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>-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>--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>--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>
|
12
third_party/home-manager/doc/man-pages.xml
vendored
Normal file
12
third_party/home-manager/doc/man-pages.xml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<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>
|
46
third_party/home-manager/doc/manual.xml
vendored
Normal file
46
third_party/home-manager/doc/manual.xml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<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.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager">#home-manager</link>
|
||||||
|
hosted by <link xlink:href="https://freenode.net/">freenode</link>.
|
||||||
|
The <link xlink:href="https://logs.nix.samueldr.com/home-manager/">channel logs</link>
|
||||||
|
are hosted courtesy of <link xlink:href="https://github.com/samueldr/">samueldr</link>.
|
||||||
|
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-tools">
|
||||||
|
<title>Tools</title>
|
||||||
|
<xi:include href="./man-home-manager.xml" />
|
||||||
|
</appendix>
|
||||||
|
<xi:include href="./release-notes/release-notes.xml" />
|
||||||
|
</book>
|
19
third_party/home-manager/doc/release-notes/release-notes.adoc
vendored
Normal file
19
third_party/home-manager/doc/release-notes/release-notes.adoc
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[[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-2009.adoc[]
|
||||||
|
|
||||||
|
include::rl-2003.adoc[]
|
||||||
|
|
||||||
|
include::rl-1909.adoc[]
|
||||||
|
|
||||||
|
include::rl-1903.adoc[]
|
||||||
|
|
||||||
|
include::rl-1809.adoc[]
|
||||||
|
|
||||||
|
:leveloffset: 0
|
4
third_party/home-manager/doc/release-notes/rl-1809.adoc
vendored
Normal file
4
third_party/home-manager/doc/release-notes/rl-1809.adoc
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[[sec-release-18.09]]
|
||||||
|
== Release 18.09
|
||||||
|
|
||||||
|
The 18.09 release branch became the stable branch in September, 2018.
|
59
third_party/home-manager/doc/release-notes/rl-1903.adoc
vendored
Normal file
59
third_party/home-manager/doc/release-notes/rl-1903.adoc
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
[[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.
|
31
third_party/home-manager/doc/release-notes/rl-1909.adoc
vendored
Normal file
31
third_party/home-manager/doc/release-notes/rl-1909.adoc
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
[[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.
|
126
third_party/home-manager/doc/release-notes/rl-2003.adoc
vendored
Normal file
126
third_party/home-manager/doc/release-notes/rl-2003.adoc
vendored
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
[[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.
|
97
third_party/home-manager/doc/release-notes/rl-2009.adoc
vendored
Normal file
97
third_party/home-manager/doc/release-notes/rl-2009.adoc
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
[[sec-release-20.09]]
|
||||||
|
== Release 20.09 (unreleased)
|
||||||
|
|
||||||
|
This is the current unstable branch and the information in this
|
||||||
|
section is therefore not final.
|
||||||
|
|
||||||
|
[[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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
....
|
||||||
|
--
|
187
third_party/home-manager/doc/writing-modules.adoc
vendored
Normal file
187
third_party/home-manager/doc/writing-modules.adoc
vendored
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
[[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.
|
23
third_party/home-manager/flake.nix
vendored
Normal file
23
third_party/home-manager/flake.nix
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
description = "Home Manager for Nix";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }: rec {
|
||||||
|
nixosModules.home-manager = import ./nixos;
|
||||||
|
|
||||||
|
darwinModules.home-manager = import ./nix-darwin;
|
||||||
|
|
||||||
|
lib = {
|
||||||
|
homeManagerConfiguration = { configuration, system, homeDirectory
|
||||||
|
, username
|
||||||
|
, pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages
|
||||||
|
, check ? true }@args:
|
||||||
|
import ./modules {
|
||||||
|
inherit pkgs check;
|
||||||
|
configuration = { ... }: {
|
||||||
|
imports = [ configuration ];
|
||||||
|
home = { inherit homeDirectory username; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
59
third_party/home-manager/format
vendored
Executable file
59
third_party/home-manager/format
vendored
Executable file
|
@ -0,0 +1,59 @@
|
||||||
|
#! /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/default.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/dconf.nix \
|
||||||
|
! -path ./modules/misc/news.nix \
|
||||||
|
! -path ./modules/misc/nixpkgs.nix \
|
||||||
|
! -path ./modules/misc/xdg.nix \
|
||||||
|
! -path ./modules/modules.nix \
|
||||||
|
! -path ./modules/programs/afew.nix \
|
||||||
|
! -path ./modules/programs/bash.nix \
|
||||||
|
! -path ./modules/programs/firefox.nix \
|
||||||
|
! -path ./modules/programs/gpg.nix \
|
||||||
|
! -path ./modules/programs/lesspipe.nix \
|
||||||
|
! -path ./modules/programs/ssh.nix \
|
||||||
|
! -path ./modules/programs/tmux.nix \
|
||||||
|
! -path ./modules/programs/zsh.nix \
|
||||||
|
! -path ./modules/services/gpg-agent.nix \
|
||||||
|
! -path ./modules/services/kbfs.nix \
|
||||||
|
! -path ./modules/services/keybase.nix \
|
||||||
|
! -path ./modules/services/mpd.nix \
|
||||||
|
! -path ./modules/services/sxhkd.nix \
|
||||||
|
! -path ./modules/services/window-managers/i3.nix \
|
||||||
|
! -path ./modules/systemd.nix \
|
||||||
|
! -path ./nix-darwin/default.nix \
|
||||||
|
! -path ./tests/default.nix \
|
||||||
|
! -path ./tests/modules/home-environment/default.nix \
|
||||||
|
! -path ./tests/modules/home-environment/session-variables.nix \
|
||||||
|
! -path ./tests/modules/programs/gpg/override-defaults.nix \
|
||||||
|
! -path ./tests/modules/programs/tmux/default.nix \
|
||||||
|
! -path ./tests/modules/programs/zsh/session-variables.nix \
|
||||||
|
! -path ./tests/modules/services/sxhkd/service.nix \
|
||||||
|
! -path ./tests/modules/systemd/services.nix \
|
||||||
|
! -path ./tests/modules/systemd/session-variables.nix \
|
||||||
|
-exec nixfmt $CHECK_ARG {} +
|
356
third_party/home-manager/home-manager/completion.bash
vendored
Normal file
356
third_party/home-manager/home-manager/completion.bash
vendored
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
#!/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" "--show-trace" )
|
||||||
|
|
||||||
|
# ^ « 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
|
40
third_party/home-manager/home-manager/default.nix
vendored
Normal file
40
third_party/home-manager/home-manager/default.nix
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ runCommand, lib, bash, coreutils, findutils, gnused, less
|
||||||
|
|
||||||
|
# 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; {
|
||||||
|
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
|
||||||
|
''
|
579
third_party/home-manager/home-manager/home-manager
vendored
Normal file
579
third_party/home-manager/home-manager/home-manager
vendored
Normal file
|
@ -0,0 +1,579 @@
|
||||||
|
#!@bash@/bin/bash
|
||||||
|
|
||||||
|
# Prepare to use tools from Nixpkgs.
|
||||||
|
PATH=@coreutils@/bin:@findutils@/bin:@gnused@/bin:@less@/bin${PATH:+:}$PATH
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
function errorEcho() {
|
||||||
|
# shellcheck disable=2048,2086
|
||||||
|
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
|
||||||
|
# an error message and exit with an error code.
|
||||||
|
function setConfigFile() {
|
||||||
|
if [[ -v HOME_MANAGER_CONFIG ]] ; then
|
||||||
|
if [[ ! -e "$HOME_MANAGER_CONFIG" ]] ; then
|
||||||
|
errorEcho "No configuration file found at $HOME_MANAGER_CONFIG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
HOME_MANAGER_CONFIG="$(realpath "$HOME_MANAGER_CONFIG")"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local defaultConfFile="${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
|
||||||
|
local confFile
|
||||||
|
for confFile in "$defaultConfFile" \
|
||||||
|
"$HOME/.nixpkgs/home.nix" ; do
|
||||||
|
if [[ -e "$confFile" ]] ; then
|
||||||
|
HOME_MANAGER_CONFIG="$(realpath "$confFile")"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
errorEcho "No configuration file found." \
|
||||||
|
"Please create one at $defaultConfFile"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHomeManagerNixPath() {
|
||||||
|
local path
|
||||||
|
for path in "@HOME_MANAGER_PATH@" \
|
||||||
|
"${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home-manager" \
|
||||||
|
"$HOME/.nixpkgs/home-manager" ; do
|
||||||
|
if [[ -e "$path" || "$path" =~ ^https?:// ]] ; then
|
||||||
|
export NIX_PATH="home-manager=$path${NIX_PATH:+:}$NIX_PATH"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function doInstantiate() {
|
||||||
|
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=("$@")
|
||||||
|
|
||||||
|
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||||
|
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
extraArgs=("${extraArgs[@]}" "--show-trace")
|
||||||
|
fi
|
||||||
|
|
||||||
|
nix-build \
|
||||||
|
"<home-manager/home-manager/home-manager.nix>" \
|
||||||
|
"${extraArgs[@]}" \
|
||||||
|
"${PASSTHROUGH_OPTS[@]}" \
|
||||||
|
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||||
|
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Presents news to the user. Takes as argument the path to a "news
|
||||||
|
# info" file as generated by `buildNews`.
|
||||||
|
function presentNews() {
|
||||||
|
local infoFile="$1"
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$infoFile"
|
||||||
|
|
||||||
|
# shellcheck disable=2154
|
||||||
|
if [[ $newsNumUnread -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
elif [[ "$newsDisplay" == "silent" ]]; then
|
||||||
|
return
|
||||||
|
elif [[ "$newsDisplay" == "notify" ]]; then
|
||||||
|
local msg
|
||||||
|
if [[ $newsNumUnread -eq 1 ]]; then
|
||||||
|
msg="There is an unread and relevant news item.\n"
|
||||||
|
msg+="Read it by running the command '$(basename "$0") news'."
|
||||||
|
else
|
||||||
|
msg="There are $newsNumUnread unread and relevant news items.\n"
|
||||||
|
msg+="Read them by running the command '$(basename "$0") news'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Not actually an error but here stdout is reserved for
|
||||||
|
# nix-build output.
|
||||||
|
errorEcho
|
||||||
|
errorEcho -e "$msg"
|
||||||
|
errorEcho
|
||||||
|
|
||||||
|
if [[ -v DISPLAY ]] && type -P notify-send > /dev/null; then
|
||||||
|
notify-send "Home Manager" "$msg"
|
||||||
|
fi
|
||||||
|
elif [[ "$newsDisplay" == "show" ]]; then
|
||||||
|
doShowNews --unread
|
||||||
|
else
|
||||||
|
errorEcho "Unknown 'news.display' setting '$newsDisplay'."
|
||||||
|
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
|
||||||
|
|
||||||
|
setWorkDir
|
||||||
|
|
||||||
|
local newsInfo
|
||||||
|
newsInfo=$(buildNews)
|
||||||
|
|
||||||
|
local exitCode
|
||||||
|
|
||||||
|
doBuildAttr --attr activationPackage \
|
||||||
|
&& exitCode=0 || exitCode=1
|
||||||
|
|
||||||
|
presentNews "$newsInfo"
|
||||||
|
|
||||||
|
return $exitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSwitch() {
|
||||||
|
setWorkDir
|
||||||
|
|
||||||
|
local newsInfo
|
||||||
|
newsInfo=$(buildNews)
|
||||||
|
|
||||||
|
local generation
|
||||||
|
local exitCode=0
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
doBuildAttr \
|
||||||
|
--out-link "$generation" \
|
||||||
|
--attr activationPackage \
|
||||||
|
&& "$generation/activate" || exitCode=1
|
||||||
|
|
||||||
|
presentNews "$newsInfo"
|
||||||
|
|
||||||
|
return $exitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
function doListGens() {
|
||||||
|
# Whether to colorize the generations output.
|
||||||
|
local color="never"
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
color="always"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd "$NIX_STATE_DIR/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- \
|
||||||
|
| sed -E 's/home-manager-([[:digit:]]*)-link/: id \1/'
|
||||||
|
popd > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Removes linked generations. Takes as arguments identifiers of
|
||||||
|
# generations to remove.
|
||||||
|
function doRmGenerations() {
|
||||||
|
setVerboseAndDryRun
|
||||||
|
|
||||||
|
pushd "$NIX_STATE_DIR/profiles/per-user/$USER" > /dev/null
|
||||||
|
|
||||||
|
for generationId in "$@"; do
|
||||||
|
local linkName="home-manager-$generationId-link"
|
||||||
|
|
||||||
|
if [[ ! -e $linkName ]]; then
|
||||||
|
errorEcho "No generation with ID $generationId"
|
||||||
|
elif [[ $linkName == $(readlink home-manager) ]]; then
|
||||||
|
errorEcho "Cannot remove the current generation $generationId"
|
||||||
|
else
|
||||||
|
echo Removing generation $generationId
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG $linkName
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
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$')"
|
||||||
|
if [[ -n "$outPath" ]] ; then
|
||||||
|
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
||||||
|
else
|
||||||
|
errorEcho "No home-manager packages seem to be installed."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function newsReadIdsFile() {
|
||||||
|
local dataDir="${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
||||||
|
local path="$dataDir/news-read-ids"
|
||||||
|
|
||||||
|
# If the path doesn't exist then we should create it, otherwise
|
||||||
|
# Nix will error out when we attempt to use builtins.readFile.
|
||||||
|
if [[ ! -f "$path" ]]; then
|
||||||
|
mkdir -p "$dataDir"
|
||||||
|
touch "$path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
function buildNews() {
|
||||||
|
local output
|
||||||
|
output="$WORK_DIR/news-info.sh"
|
||||||
|
|
||||||
|
doBuildAttr \
|
||||||
|
--out-link "$output" \
|
||||||
|
--no-build-output \
|
||||||
|
--quiet \
|
||||||
|
--arg check false \
|
||||||
|
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||||
|
--attr newsInfo \
|
||||||
|
> /dev/null
|
||||||
|
|
||||||
|
echo "$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
function doShowNews() {
|
||||||
|
setWorkDir
|
||||||
|
|
||||||
|
local infoFile
|
||||||
|
infoFile=$(buildNews) || return 1
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$infoFile"
|
||||||
|
|
||||||
|
# shellcheck disable=2154
|
||||||
|
case $1 in
|
||||||
|
--all)
|
||||||
|
${PAGER:-less} "$newsFileAll"
|
||||||
|
;;
|
||||||
|
--unread)
|
||||||
|
${PAGER:-less} "$newsFileUnread"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
errorEcho "Unknown argument $1"
|
||||||
|
return 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
# shellcheck disable=2154
|
||||||
|
if [[ -s "$newsUnreadIdsFile" ]]; then
|
||||||
|
local newsReadIdsFile
|
||||||
|
newsReadIdsFile="$(newsReadIdsFile)"
|
||||||
|
cat "$newsUnreadIdsFile" >> "$newsReadIdsFile"
|
||||||
|
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 " -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 " --cores NUM"
|
||||||
|
echo " --keep-failed"
|
||||||
|
echo " --keep-going"
|
||||||
|
echo " --max-jobs NUM"
|
||||||
|
echo " --option NAME VALUE"
|
||||||
|
echo " --show-trace"
|
||||||
|
echo " --(no-)substitute"
|
||||||
|
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"
|
||||||
|
echo
|
||||||
|
echo " remove-generations ID..."
|
||||||
|
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=()
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
opt="$1"
|
||||||
|
shift
|
||||||
|
case $opt in
|
||||||
|
build|instantiate|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
|
||||||
|
COMMAND="$opt"
|
||||||
|
;;
|
||||||
|
-A)
|
||||||
|
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-I)
|
||||||
|
EXTRA_NIX_PATH+=("$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-b)
|
||||||
|
export HOME_MANAGER_BACKUP_EXT="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-f|--file)
|
||||||
|
HOME_MANAGER_CONFIG="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
doHelp
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-n|--dry-run)
|
||||||
|
export DRY_RUN=1
|
||||||
|
;;
|
||||||
|
--option)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--max-jobs|--cores)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--keep-failed|--keep-going|--show-trace\
|
||||||
|
|--substitute|--no-substitute)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt")
|
||||||
|
;;
|
||||||
|
-v|--verbose)
|
||||||
|
export VERBOSE=1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
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
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z $COMMAND ]]; then
|
||||||
|
doHelp >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $COMMAND in
|
||||||
|
edit)
|
||||||
|
doEdit
|
||||||
|
;;
|
||||||
|
build)
|
||||||
|
doBuild
|
||||||
|
;;
|
||||||
|
instantiate)
|
||||||
|
doInstantiate
|
||||||
|
;;
|
||||||
|
switch)
|
||||||
|
doSwitch
|
||||||
|
;;
|
||||||
|
generations)
|
||||||
|
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
|
||||||
|
;;
|
||||||
|
packages)
|
||||||
|
doListPackages
|
||||||
|
;;
|
||||||
|
news)
|
||||||
|
doShowNews --all
|
||||||
|
;;
|
||||||
|
uninstall)
|
||||||
|
doUninstall
|
||||||
|
;;
|
||||||
|
help)
|
||||||
|
doHelp
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
errorEcho "Unknown command: $COMMAND"
|
||||||
|
doHelp >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
88
third_party/home-manager/home-manager/home-manager.nix
vendored
Normal file
88
third_party/home-manager/home-manager/home-manager.nix
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {}
|
||||||
|
, confPath
|
||||||
|
, confAttr ? null
|
||||||
|
, check ? true
|
||||||
|
, newsReadIdsFile ? null
|
||||||
|
}:
|
||||||
|
|
||||||
|
with pkgs.lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
env = import ../modules {
|
||||||
|
configuration =
|
||||||
|
if confAttr == "" || confAttr == null
|
||||||
|
then confPath
|
||||||
|
else (import confPath).${confAttr};
|
||||||
|
pkgs = pkgs;
|
||||||
|
check = check;
|
||||||
|
};
|
||||||
|
|
||||||
|
newsReadIds =
|
||||||
|
if newsReadIdsFile == null
|
||||||
|
then {}
|
||||||
|
else
|
||||||
|
let
|
||||||
|
ids = splitString "\n" (fileContents newsReadIdsFile);
|
||||||
|
in
|
||||||
|
builtins.listToAttrs (map (id: { name = id; value = null; }) ids);
|
||||||
|
|
||||||
|
newsIsRead = entry: builtins.hasAttr entry.id newsReadIds;
|
||||||
|
|
||||||
|
newsFiltered =
|
||||||
|
let
|
||||||
|
pred = entry: entry.condition && ! newsIsRead entry;
|
||||||
|
in
|
||||||
|
filter pred env.newsEntries;
|
||||||
|
|
||||||
|
newsNumUnread = length newsFiltered;
|
||||||
|
|
||||||
|
newsFileUnread = pkgs.writeText "news-unread.txt" (
|
||||||
|
concatMapStringsSep "\n\n" (entry:
|
||||||
|
let
|
||||||
|
time = replaceStrings ["T"] [" "] (removeSuffix "+00:00" entry.time);
|
||||||
|
in
|
||||||
|
''
|
||||||
|
* ${time}
|
||||||
|
|
||||||
|
${replaceStrings ["\n"] ["\n "] entry.message}
|
||||||
|
''
|
||||||
|
) newsFiltered
|
||||||
|
);
|
||||||
|
|
||||||
|
newsFileAll = pkgs.writeText "news-all.txt" (
|
||||||
|
concatMapStringsSep "\n\n" (entry:
|
||||||
|
let
|
||||||
|
flag = if newsIsRead entry then "read" else "unread";
|
||||||
|
time = replaceStrings ["T"] [" "] (removeSuffix "+00:00" entry.time);
|
||||||
|
in
|
||||||
|
''
|
||||||
|
* ${time} [${flag}]
|
||||||
|
|
||||||
|
${replaceStrings ["\n"] ["\n "] entry.message}
|
||||||
|
''
|
||||||
|
) env.newsEntries
|
||||||
|
);
|
||||||
|
|
||||||
|
# File where each line corresponds to an unread news entry
|
||||||
|
# identifier. If non-empty then the file ends in "\n".
|
||||||
|
newsUnreadIdsFile = pkgs.writeText "news-unread-ids" (
|
||||||
|
let
|
||||||
|
text = concatMapStringsSep "\n" (entry: entry.id) newsFiltered;
|
||||||
|
in
|
||||||
|
text + optionalString (text != "") "\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
newsInfo = pkgs.writeText "news-info.sh" ''
|
||||||
|
local newsNumUnread=${toString newsNumUnread}
|
||||||
|
local newsDisplay="${env.newsDisplay}"
|
||||||
|
local newsFileAll="${newsFileAll}"
|
||||||
|
local newsFileUnread="${newsFileUnread}"
|
||||||
|
local newsUnreadIdsFile="${newsUnreadIdsFile}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit (env) activationPackage;
|
||||||
|
inherit newsInfo;
|
||||||
|
}
|
84
third_party/home-manager/home-manager/install.nix
vendored
Normal file
84
third_party/home-manager/home-manager/install.nix
vendored
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
{ home-manager, runCommand }:
|
||||||
|
|
||||||
|
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
|
||||||
|
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"
|
||||||
|
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 = "20.09";
|
||||||
|
}
|
||||||
|
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
|
||||||
|
''
|
396
third_party/home-manager/modules/accounts/email.nix
vendored
Normal file
396
third_party/home-manager/modules/accounts/email.nix
vendored
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
{ 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);
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
62
third_party/home-manager/modules/default.nix
vendored
Normal file
62
third_party/home-manager/modules/default.nix
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{ configuration
|
||||||
|
, pkgs
|
||||||
|
, lib ? pkgs.stdenv.lib
|
||||||
|
|
||||||
|
# Whether to check that each option has a matching declaration.
|
||||||
|
, check ? true
|
||||||
|
}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
collectFailed = cfg:
|
||||||
|
map (x: x.message) (filter (x: !x.assertion) cfg.assertions);
|
||||||
|
|
||||||
|
showWarnings = res:
|
||||||
|
let
|
||||||
|
f = w: x: builtins.trace "[1;31mwarning: ${w}[0m" x;
|
||||||
|
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 ./.;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module = showWarnings (
|
||||||
|
let
|
||||||
|
failed = collectFailed rawModule.config;
|
||||||
|
failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed);
|
||||||
|
in
|
||||||
|
if failed == []
|
||||||
|
then rawModule
|
||||||
|
else throw "\nFailed assertions:\n${failedStr}"
|
||||||
|
);
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
inherit (module) options config;
|
||||||
|
|
||||||
|
activationPackage = module.config.home.activationPackage;
|
||||||
|
|
||||||
|
# For backwards compatibility. Please use activationPackage instead.
|
||||||
|
activation-script = module.config.home.activationPackage;
|
||||||
|
|
||||||
|
newsDisplay = rawModule.config.news.display;
|
||||||
|
newsEntries =
|
||||||
|
sort (a: b: a.time > b.time) (
|
||||||
|
filter (a: a.condition) rawModule.config.news.entries
|
||||||
|
);
|
||||||
|
}
|
331
third_party/home-manager/modules/files.nix
vendored
Normal file
331
third_party/home-manager/modules/files.nix
vendored
Normal file
|
@ -0,0 +1,331 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.home.file;
|
||||||
|
|
||||||
|
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; };
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
home.file = mkOption {
|
||||||
|
description = "Attribute set of files to link into the user home.";
|
||||||
|
default = {};
|
||||||
|
type = fileType "<envar>HOME</envar>" homeDirectory;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-files = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
internal = true;
|
||||||
|
description = "Package to contain all home files";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
lib.file.mkOutOfStoreSymlink = path:
|
||||||
|
let
|
||||||
|
pathStr = toString path;
|
||||||
|
name = hm.strings.storeFileName (baseNameOf pathStr);
|
||||||
|
in
|
||||||
|
pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out'';
|
||||||
|
|
||||||
|
# This verifies that the links we are about to create will not
|
||||||
|
# overwrite an existing file.
|
||||||
|
home.activation.checkLinkTargets = hm.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
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -v collision ]] ; then
|
||||||
|
errorEcho "Please move the above files and try again or use -b <ext> to move automatically."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
''
|
||||||
|
function checkNewGenCollision() {
|
||||||
|
local newGenFiles
|
||||||
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
|
find "$newGenFiles" \( -type f -or -type l \) \
|
||||||
|
-exec bash ${check} "$newGenFiles" {} +
|
||||||
|
}
|
||||||
|
|
||||||
|
checkNewGenCollision || exit 1
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
# This activation script will
|
||||||
|
#
|
||||||
|
# 1. Remove files from the old generation that are not in the new
|
||||||
|
# generation.
|
||||||
|
#
|
||||||
|
# 2. Switch over the Home Manager gcroot and current profile
|
||||||
|
# links.
|
||||||
|
#
|
||||||
|
# 3. Symlink files from the new generation into $HOME.
|
||||||
|
#
|
||||||
|
# This order is needed to ensure that we always know which links
|
||||||
|
# belong to which generation. Specifically, if we're moving from
|
||||||
|
# generation A to generation B having sets of home file links FA
|
||||||
|
# and FB, respectively then cleaning before linking produces state
|
||||||
|
# transitions similar to
|
||||||
|
#
|
||||||
|
# FA → FA ∩ FB → (FA ∩ FB) ∪ FB = FB
|
||||||
|
#
|
||||||
|
# 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"] (
|
||||||
|
let
|
||||||
|
link = pkgs.writeText "link" ''
|
||||||
|
newGenFiles="$1"
|
||||||
|
shift
|
||||||
|
for sourcePath in "$@" ; do
|
||||||
|
relativePath="''${sourcePath#$newGenFiles/}"
|
||||||
|
targetPath="$HOME/$relativePath"
|
||||||
|
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
|
||||||
|
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."
|
||||||
|
else
|
||||||
|
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath"
|
||||||
|
|
||||||
|
# Recursively delete empty parent directories.
|
||||||
|
targetDir="$(dirname "$relativePath")"
|
||||||
|
if [[ "$targetDir" != "." ]] ; then
|
||||||
|
pushd "$HOME" > /dev/null
|
||||||
|
|
||||||
|
# Call rmdir with a relative path excluding $HOME.
|
||||||
|
# Otherwise, it might try to delete $HOME and exit
|
||||||
|
# with a permission error.
|
||||||
|
$DRY_RUN_CMD rmdir $VERBOSE_ARG \
|
||||||
|
-p --ignore-fail-on-non-empty \
|
||||||
|
"$targetDir"
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
''
|
||||||
|
function linkNewGen() {
|
||||||
|
echo "Creating home file links in $HOME"
|
||||||
|
|
||||||
|
local newGenFiles
|
||||||
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
|
find "$newGenFiles" \( -type f -or -type l \) \
|
||||||
|
-exec bash ${link} "$newGenFiles" {} +
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanOldGen() {
|
||||||
|
if [[ ! -v oldGenPath ]] ; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cleaning up orphan links from $HOME"
|
||||||
|
|
||||||
|
local newGenFiles oldGenFiles
|
||||||
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
|
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
||||||
|
|
||||||
|
# Apply the cleanup script on each leaf in the old
|
||||||
|
# generation. The find command below will print the
|
||||||
|
# relative path of the entry.
|
||||||
|
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \
|
||||||
|
| xargs -0 bash ${cleanup} "$newGenFiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanOldGen
|
||||||
|
|
||||||
|
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" "$newGenGcPath"
|
||||||
|
else
|
||||||
|
echo "No change so reusing latest profile generation $oldGenNum"
|
||||||
|
fi
|
||||||
|
|
||||||
|
linkNewGen
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
|
||||||
|
''
|
||||||
|
declare -A changedFiles
|
||||||
|
'' + concatMapStrings (v: ''
|
||||||
|
cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \
|
||||||
|
&& changedFiles["${v.target}"]=0 \
|
||||||
|
|| changedFiles["${v.target}"]=1
|
||||||
|
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||||
|
);
|
||||||
|
|
||||||
|
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))
|
||||||
|
);
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
(''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
# Needed in case /nix is a symbolic link.
|
||||||
|
realOut="$(realpath -m "$out")"
|
||||||
|
|
||||||
|
function insertFile() {
|
||||||
|
local source="$1"
|
||||||
|
local relTarget="$2"
|
||||||
|
local executable="$3"
|
||||||
|
local recursive="$4"
|
||||||
|
|
||||||
|
# Figure out the real absolute path to the target.
|
||||||
|
local target
|
||||||
|
target="$(realpath -m "$realOut/$relTarget")"
|
||||||
|
|
||||||
|
# Target path must be within $HOME.
|
||||||
|
if [[ ! $target == $realOut* ]] ; then
|
||||||
|
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$target")"
|
||||||
|
if [[ -d $source ]]; then
|
||||||
|
if [[ $recursive ]]; then
|
||||||
|
mkdir -p "$target"
|
||||||
|
lndir -silent "$source" "$target"
|
||||||
|
else
|
||||||
|
ln -s "$source" "$target"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
[[ -x $source ]] && isExecutable=1 || isExecutable=""
|
||||||
|
|
||||||
|
# Link the file into the home file directory if possible,
|
||||||
|
# i.e., if the executable bit of the source is the same we
|
||||||
|
# expect for the target. Otherwise, we copy the file and
|
||||||
|
# set the executable bit to the expected value.
|
||||||
|
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||||
|
ln -s "$source" "$target"
|
||||||
|
else
|
||||||
|
cp "$source" "$target"
|
||||||
|
|
||||||
|
if [[ $executable == inherit ]]; then
|
||||||
|
# Don't change file mode if it should match the source.
|
||||||
|
:
|
||||||
|
elif [[ $executable ]]; then
|
||||||
|
chmod +x "$target"
|
||||||
|
else
|
||||||
|
chmod -x "$target"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
'' + concatStrings (
|
||||||
|
mapAttrsToList (n: v: ''
|
||||||
|
insertFile ${
|
||||||
|
escapeShellArgs [
|
||||||
|
(sourceStorePath v)
|
||||||
|
v.target
|
||||||
|
(if v.executable == null
|
||||||
|
then "inherit"
|
||||||
|
else toString v.executable)
|
||||||
|
(toString v.recursive)
|
||||||
|
]}
|
||||||
|
'') cfg
|
||||||
|
));
|
||||||
|
};
|
||||||
|
}
|
577
third_party/home-manager/modules/home-environment.nix
vendored
Normal file
577
third_party/home-manager/modules/home-environment.nix
vendored
Normal file
|
@ -0,0 +1,577 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.home;
|
||||||
|
|
||||||
|
languageSubModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
base = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use unless overridden by a more specific option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
ctype = 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).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
monetary = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for formatting currencies and money amounts.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
description = ''
|
||||||
|
The language to use for paper sizes.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for personal names.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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";
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
model = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
example = "presario";
|
||||||
|
description = ''
|
||||||
|
Keyboard model.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
options = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = ["grp:caps_toggle" "grp_led:scroll"];
|
||||||
|
description = ''
|
||||||
|
X keyboard options; layout switching goes here.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
variant = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default =
|
||||||
|
if versionAtLeast config.home.stateVersion "19.09"
|
||||||
|
then null
|
||||||
|
else "";
|
||||||
|
defaultText = literalExample "null";
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "home" "sessionVariableSetter" ] ''
|
||||||
|
Session variables are now always set through the shell. This is
|
||||||
|
done automatically if the shell configuration is managed by Home
|
||||||
|
Manager. If not, then you must source the
|
||||||
|
|
||||||
|
~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||||
|
|
||||||
|
file yourself.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
home.username = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
defaultText = literalExample ''
|
||||||
|
"$USER" for state version < 20.09,
|
||||||
|
undefined for state version ≥ 20.09
|
||||||
|
'';
|
||||||
|
example = "jane.doe";
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.language = mkOption {
|
||||||
|
type = languageSubModule;
|
||||||
|
default = {};
|
||||||
|
description = "Language configuration.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.keyboard = mkOption {
|
||||||
|
type = types.nullOr keyboardSubModule;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Keyboard configuration. Set to <literal>null</literal> to
|
||||||
|
disable Home Manager keyboard management.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.sessionVariables = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrs;
|
||||||
|
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
||||||
|
description = ''
|
||||||
|
Environment variables to always set at login.
|
||||||
|
</para><para>
|
||||||
|
The values may refer to other environment variables using
|
||||||
|
POSIX.2 style variable references. For example, a variable
|
||||||
|
<varname>parameter</varname> may be referenced as
|
||||||
|
<code>$parameter</code> or <code>''${parameter}</code>. A
|
||||||
|
default value <literal>foo</literal> may be given as per
|
||||||
|
<code>''${parameter:-foo}</code> and, similarly, an alternate
|
||||||
|
value <literal>bar</literal> can be given as per
|
||||||
|
<code>''${parameter:+bar}</code>.
|
||||||
|
</para><para>
|
||||||
|
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>
|
||||||
|
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.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 = [];
|
||||||
|
description = "The set of packages to appear in the user environment.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.extraOutputsToInstall = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "doc" "info" "devdoc" ];
|
||||||
|
description = ''
|
||||||
|
List of additional package outputs of the packages
|
||||||
|
<varname>home.packages</varname> that should be installed into
|
||||||
|
the user environment.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.path = mkOption {
|
||||||
|
internal = true;
|
||||||
|
description = "The derivation installing the user packages.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.emptyActivationPath = mkOption {
|
||||||
|
internal = true;
|
||||||
|
default = false;
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.activation = mkOption {
|
||||||
|
type = hm.types.dagOf types.str;
|
||||||
|
default = {};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||||
|
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
|
||||||
|
''${builtins.toPath ./link-me-directly} $HOME
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
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.
|
||||||
|
|
||||||
|
</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.
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.activationPackage = mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = types.package;
|
||||||
|
description = "The package containing the complete activation script.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.extraBuilderCommands = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
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 = {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = config.home.username != "";
|
||||||
|
message = "Username could not be determined";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = config.home.homeDirectory != "";
|
||||||
|
message = "Home directory could not be determined";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
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.sessionVariables =
|
||||||
|
let
|
||||||
|
maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
||||||
|
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_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);
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
# Provide a file holding all session variables.
|
||||||
|
(
|
||||||
|
pkgs.writeTextFile {
|
||||||
|
name = "hm-session-vars.sh";
|
||||||
|
destination = "/etc/profile.d/hm-session-vars.sh";
|
||||||
|
text = ''
|
||||||
|
# Only source this once.
|
||||||
|
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi
|
||||||
|
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 "";
|
||||||
|
|
||||||
|
# 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
|
||||||
|
''
|
||||||
|
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
home.activationPackage =
|
||||||
|
let
|
||||||
|
mkCmd = res: ''
|
||||||
|
noteEcho Activating ${res.name}
|
||||||
|
${res.data}
|
||||||
|
'';
|
||||||
|
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||||
|
activationCmds =
|
||||||
|
if sortedCommands ? result then
|
||||||
|
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||||
|
else
|
||||||
|
abort ("Dependency cycle in activation script: "
|
||||||
|
+ builtins.toJSON sortedCommands);
|
||||||
|
|
||||||
|
# Programs that always should be available on the activation
|
||||||
|
# script's PATH.
|
||||||
|
activationBinPaths = lib.makeBinPath [
|
||||||
|
pkgs.bash
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.diffutils # For `cmp` and `diff`.
|
||||||
|
pkgs.findutils
|
||||||
|
pkgs.gnugrep
|
||||||
|
pkgs.gnused
|
||||||
|
pkgs.ncurses # For `tput`.
|
||||||
|
]
|
||||||
|
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||||
|
|
||||||
|
activationScript = pkgs.writeScript "activation-script" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
cd $HOME
|
||||||
|
|
||||||
|
export PATH="${activationBinPaths}"
|
||||||
|
|
||||||
|
. ${./lib-bash/color-echo.sh}
|
||||||
|
|
||||||
|
${builtins.readFile ./lib-bash/activation-init.sh}
|
||||||
|
|
||||||
|
${activationCmds}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.runCommand
|
||||||
|
"home-manager-generation"
|
||||||
|
{
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
}
|
||||||
|
''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
cp ${activationScript} $out/activate
|
||||||
|
|
||||||
|
substituteInPlace $out/activate \
|
||||||
|
--subst-var-by GENERATION_DIR $out
|
||||||
|
|
||||||
|
ln -s ${config.home-files} $out/home-files
|
||||||
|
ln -s ${cfg.path} $out/home-path
|
||||||
|
|
||||||
|
${cfg.extraBuilderCommands}
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.path = pkgs.buildEnv {
|
||||||
|
name = "home-manager-path";
|
||||||
|
|
||||||
|
paths = cfg.packages;
|
||||||
|
inherit (cfg) extraOutputsToInstall;
|
||||||
|
|
||||||
|
postBuild = cfg.extraProfileCommands;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Environment of packages installed through home-manager";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
85
third_party/home-manager/modules/lib-bash/activation-init.sh
vendored
Executable file
85
third_party/home-manager/modules/lib-bash/activation-init.sh
vendored
Executable file
|
@ -0,0 +1,85 @@
|
||||||
|
#!/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 greatestGenNum
|
||||||
|
greatestGenNum=$( \
|
||||||
|
nix-env --list-generations --profile "$genProfilePath" \
|
||||||
|
| tail -1 \
|
||||||
|
| sed -E 's/ *([[:digit:]]+) .*/\1/')
|
||||||
|
|
||||||
|
if [[ -n $greatestGenNum ]] ; then
|
||||||
|
oldGenNum=$greatestGenNum
|
||||||
|
newGenNum=$((oldGenNum + 1))
|
||||||
|
else
|
||||||
|
newGenNum=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e $profilesPath/home-manager ]] ; then
|
||||||
|
oldGenPath="$(readlink -e "$profilesPath/home-manager")"
|
||||||
|
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 " '${oldGenNum:-}' and '${oldGenPath:-}'"
|
||||||
|
errorEcho "If you don't mind losing previous profile generations then"
|
||||||
|
errorEcho "the easiest solution is probably to run"
|
||||||
|
errorEcho " rm $profilesPath/home-manager*"
|
||||||
|
errorEcho " rm $gcPath/current-home"
|
||||||
|
errorEcho "and trying home-manager switch again. Good luck!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
export VERBOSE_ECHO=echo
|
||||||
|
export VERBOSE_ARG="--verbose"
|
||||||
|
else
|
||||||
|
export VERBOSE_ECHO=true
|
||||||
|
export VERBOSE_ARG=""
|
||||||
|
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
|
||||||
|
echo "This is a dry run"
|
||||||
|
export DRY_RUN_CMD=echo
|
||||||
|
else
|
||||||
|
$VERBOSE_ECHO "This is a live run"
|
||||||
|
export DRY_RUN_CMD=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
echo -n "Using Nix version: "
|
||||||
|
nix-env --version
|
||||||
|
fi
|
||||||
|
|
||||||
|
$VERBOSE_ECHO "Activation variables:"
|
||||||
|
if [[ -v oldGenNum ]] ; then
|
||||||
|
$VERBOSE_ECHO " oldGenNum=$oldGenNum"
|
||||||
|
$VERBOSE_ECHO " oldGenPath=$oldGenPath"
|
||||||
|
else
|
||||||
|
$VERBOSE_ECHO " oldGenNum undefined (first run?)"
|
||||||
|
$VERBOSE_ECHO " oldGenPath undefined (first run?)"
|
||||||
|
fi
|
||||||
|
$VERBOSE_ECHO " newGenPath=$newGenPath"
|
||||||
|
$VERBOSE_ECHO " newGenNum=$newGenNum"
|
||||||
|
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
|
||||||
|
$VERBOSE_ECHO " genProfilePath=$genProfilePath"
|
37
third_party/home-manager/modules/lib-bash/color-echo.sh
vendored
Normal file
37
third_party/home-manager/modules/lib-bash/color-echo.sh
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# The check for terminal output and color support is heavily inspired
|
||||||
|
# by https://unix.stackexchange.com/a/10065.
|
||||||
|
|
||||||
|
function setupColors() {
|
||||||
|
normalColor=""
|
||||||
|
errorColor=""
|
||||||
|
warnColor=""
|
||||||
|
noteColor=""
|
||||||
|
|
||||||
|
# Check if stdout is a terminal.
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
# See if it supports colors.
|
||||||
|
local ncolors
|
||||||
|
ncolors=$(tput colors)
|
||||||
|
|
||||||
|
if [[ -n "$ncolors" && "$ncolors" -ge 8 ]]; then
|
||||||
|
normalColor="$(tput sgr0)"
|
||||||
|
errorColor="$(tput bold)$(tput setaf 1)"
|
||||||
|
warnColor="$(tput setaf 3)"
|
||||||
|
noteColor="$(tput bold)$(tput setaf 6)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setupColors
|
||||||
|
|
||||||
|
function errorEcho() {
|
||||||
|
echo "${errorColor}$*${normalColor}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function warnEcho() {
|
||||||
|
echo "${warnColor}$*${normalColor}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function noteEcho() {
|
||||||
|
echo "${noteColor}$*${normalColor}"
|
||||||
|
}
|
117
third_party/home-manager/modules/lib/dag.nix
vendored
Normal file
117
third_party/home-manager/modules/lib/dag.nix
vendored
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# A generalization of Nixpkgs's `strings-with-deps.nix`.
|
||||||
|
#
|
||||||
|
# The main differences from the Nixpkgs version are
|
||||||
|
#
|
||||||
|
# - not specific to strings, i.e., any payload is OK,
|
||||||
|
#
|
||||||
|
# - the addition of the function `dagEntryBefore` indicating a
|
||||||
|
# "wanted by" relationship.
|
||||||
|
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
emptyDag = { };
|
||||||
|
|
||||||
|
isDag = 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
|
||||||
|
# topologically sorted list of entries.
|
||||||
|
#
|
||||||
|
# Internally this function uses the `toposort` function in
|
||||||
|
# `<nixpkgs/lib/lists.nix>` and its value is accordingly.
|
||||||
|
#
|
||||||
|
# Specifically, the result on success is
|
||||||
|
#
|
||||||
|
# { result = [{name = ?; data = ?;} …] }
|
||||||
|
#
|
||||||
|
# For example
|
||||||
|
#
|
||||||
|
# nix-repl> dagTopoSort {
|
||||||
|
# a = dagEntryAnywhere "1";
|
||||||
|
# b = dagEntryAfter ["a" "c"] "2";
|
||||||
|
# c = dagEntryBefore ["d"] "3";
|
||||||
|
# d = dagEntryBefore ["e"] "4";
|
||||||
|
# e = dagEntryAnywhere "5";
|
||||||
|
# } == {
|
||||||
|
# result = [
|
||||||
|
# { data = "1"; name = "a"; }
|
||||||
|
# { data = "3"; name = "c"; }
|
||||||
|
# { data = "2"; name = "b"; }
|
||||||
|
# { data = "4"; name = "d"; }
|
||||||
|
# { data = "5"; name = "e"; }
|
||||||
|
# ];
|
||||||
|
# }
|
||||||
|
# true
|
||||||
|
#
|
||||||
|
# And the result on error is
|
||||||
|
#
|
||||||
|
# {
|
||||||
|
# cycle = [ {after = ?; name = ?; data = ?} … ];
|
||||||
|
# loops = [ {after = ?; name = ?; data = ?} … ];
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# For example
|
||||||
|
#
|
||||||
|
# nix-repl> dagTopoSort {
|
||||||
|
# a = dagEntryAnywhere "1";
|
||||||
|
# b = dagEntryAfter ["a" "c"] "2";
|
||||||
|
# c = dagEntryAfter ["d"] "3";
|
||||||
|
# d = dagEntryAfter ["b"] "4";
|
||||||
|
# e = dagEntryAnywhere "5";
|
||||||
|
# } == {
|
||||||
|
# cycle = [
|
||||||
|
# { after = ["a" "c"]; data = "2"; name = "b"; }
|
||||||
|
# { after = ["d"]; data = "3"; name = "c"; }
|
||||||
|
# { after = ["b"]; data = "4"; name = "d"; }
|
||||||
|
# ];
|
||||||
|
# loops = [
|
||||||
|
# { after = ["a" "c"]; data = "2"; name = "b"; }
|
||||||
|
# ];
|
||||||
|
# } == {}
|
||||||
|
# true
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# Applies a function to each element of the given DAG.
|
||||||
|
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
|
||||||
|
|
||||||
|
# Create a DAG entry with no particular dependency information.
|
||||||
|
dagEntryAnywhere = data: {
|
||||||
|
inherit data;
|
||||||
|
before = [ ];
|
||||||
|
after = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
dagEntryBetween = before: after: data: { inherit data before after; };
|
||||||
|
|
||||||
|
dagEntryAfter = after: data: {
|
||||||
|
inherit data after;
|
||||||
|
before = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
dagEntryBefore = before: data: {
|
||||||
|
inherit data before;
|
||||||
|
after = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
26
third_party/home-manager/modules/lib/default.nix
vendored
Normal file
26
third_party/home-manager/modules/lib/default.nix
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
dag =
|
||||||
|
let
|
||||||
|
d = import ./dag.nix { inherit lib; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
empty = d.emptyDag;
|
||||||
|
isDag = d.isDag;
|
||||||
|
topoSort = d.dagTopoSort;
|
||||||
|
map = d.dagMap;
|
||||||
|
entryAnywhere = d.dagEntryAnywhere;
|
||||||
|
entryBetween = d.dagEntryBetween;
|
||||||
|
entryAfter = d.dagEntryAfter;
|
||||||
|
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; };
|
||||||
|
}
|
112
third_party/home-manager/modules/lib/file-type.nix
vendored
Normal file
112
third_party/home-manager/modules/lib/file-type.nix
vendored
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
{ homeDirectory, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
# Constructs a type suitable for a `home.file` like option. The
|
||||||
|
# target path may be either absolute or relative, in which case it
|
||||||
|
# is relative the `basePath` argument (which itself must be an
|
||||||
|
# absolute path).
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# - basePathDesc docbook compatible description of the base path
|
||||||
|
# - basePath the file base path
|
||||||
|
fileType = basePathDesc: basePath: types.attrsOf (types.submodule (
|
||||||
|
{ name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
target = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
apply = p:
|
||||||
|
let
|
||||||
|
absPath = if hasPrefix "/" p then p else "${basePath}/${p}";
|
||||||
|
in
|
||||||
|
removePrefix (homeDirectory + "/") absPath;
|
||||||
|
defaultText = literalExample "<name>";
|
||||||
|
description = ''
|
||||||
|
Path to target file relative to ${basePathDesc}.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
executable = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Set the execute bit. If <literal>null</literal>, defaults to the mode
|
||||||
|
of the <varname>source</varname> file or to <literal>false</literal>
|
||||||
|
for files created through the <varname>text</varname> option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
recursive = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
If the file source is a directory, then this option
|
||||||
|
determines whether the directory should be recursively
|
||||||
|
linked to the target location. This option has no effect
|
||||||
|
if the source is a file.
|
||||||
|
</para><para>
|
||||||
|
If <literal>false</literal> (the default) then the target
|
||||||
|
will be a symbolic link to the source directory. If
|
||||||
|
<literal>true</literal> then the target will be a
|
||||||
|
directory structure matching the source's but whose leafs
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = {
|
||||||
|
target = mkDefault name;
|
||||||
|
source = mkIf (config.text != null) (
|
||||||
|
mkDefault (pkgs.writeTextFile {
|
||||||
|
inherit (config) executable text;
|
||||||
|
name = hm.strings.storeFileName name;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
156
third_party/home-manager/modules/lib/gvariant.nix
vendored
Normal file
156
third_party/home-manager/modules/lib/gvariant.nix
vendored
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
# 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
34
third_party/home-manager/modules/lib/maintainers.nix
vendored
Normal file
34
third_party/home-manager/modules/lib/maintainers.nix
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# 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;
|
||||||
|
};
|
||||||
|
}
|
11
third_party/home-manager/modules/lib/shell.nix
vendored
Normal file
11
third_party/home-manager/modules/lib/shell.nix
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# Produces a Bourne shell like variable export statement.
|
||||||
|
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
|
||||||
|
# statement for each set entry.
|
||||||
|
exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars);
|
||||||
|
}
|
7
third_party/home-manager/modules/lib/stdlib-extended.nix
vendored
Normal file
7
third_party/home-manager/modules/lib/stdlib-extended.nix
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# 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; }; })
|
22
third_party/home-manager/modules/lib/strings.nix
vendored
Normal file
22
third_party/home-manager/modules/lib/strings.nix
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ 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;
|
||||||
|
}
|
99
third_party/home-manager/modules/lib/types-dag.nix
vendored
Normal file
99
third_party/home-manager/modules/lib/types-dag.nix
vendored
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
{ 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; };
|
||||||
|
};
|
||||||
|
}
|
90
third_party/home-manager/modules/lib/types.nix
vendored
Normal file
90
third_party/home-manager/modules/lib/types.nix
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
{ 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 8";
|
||||||
|
description = ''
|
||||||
|
The family name and size of the font within the package.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
30
third_party/home-manager/modules/lib/zsh.nix
vendored
Normal file
30
third_party/home-manager/modules/lib/zsh.nix
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{ 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);
|
||||||
|
}
|
68
third_party/home-manager/modules/manual.nix
vendored
Normal file
68
third_party/home-manager/modules/manual.nix
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.manual;
|
||||||
|
|
||||||
|
docs = import ../doc { inherit lib pkgs; };
|
||||||
|
|
||||||
|
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;
|
||||||
|
example = false;
|
||||||
|
description = ''
|
||||||
|
Whether to install the configuration manual page. The manual can
|
||||||
|
be reached by <command>man home-configuration.nix</command>.
|
||||||
|
</para><para>
|
||||||
|
When looking at the manual page pretend that all references to
|
||||||
|
NixOS stuff are actually references to Home Manager stuff.
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
73
third_party/home-manager/modules/misc/dconf.nix
vendored
Normal file
73
third_party/home-manager/modules/misc/dconf.nix
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
{ 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 != {}) {
|
||||||
|
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
|
||||||
|
''
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
26
third_party/home-manager/modules/misc/debug.nix
vendored
Normal file
26
third_party/home-manager/modules/misc/debug.nix
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
105
third_party/home-manager/modules/misc/fontconfig.nix
vendored
Normal file
105
third_party/home-manager/modules/misc/fontconfig.nix
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.fonts.fontconfig;
|
||||||
|
|
||||||
|
profileDirectory = config.home.profileDirectory;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
|
||||||
|
"fonts"
|
||||||
|
"fontconfig"
|
||||||
|
"enable"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
fonts.fontconfig = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable fontconfig configuration. This will, for
|
||||||
|
example, allow fontconfig to discover fonts and
|
||||||
|
configurations installed through
|
||||||
|
<varname>home.packages</varname> and
|
||||||
|
<command>nix-env</command>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
<?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>
|
||||||
|
</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>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
164
third_party/home-manager/modules/misc/gtk.nix
vendored
Normal file
164
third_party/home-manager/modules/misc/gtk.nix
vendored
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.gtk;
|
||||||
|
cfg2 = config.gtk.gtk2;
|
||||||
|
cfg3 = config.gtk.gtk3;
|
||||||
|
|
||||||
|
toGtk3Ini = generators.toINI {
|
||||||
|
mkKeyValue = key: value:
|
||||||
|
let
|
||||||
|
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'}";
|
||||||
|
|
||||||
|
themeType = types.submodule {
|
||||||
|
options = {
|
||||||
|
package = mkOption {
|
||||||
|
type = types.nullOr types.package;
|
||||||
|
default = null;
|
||||||
|
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
|
||||||
|
is assumed to already be available in your profile.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "Adwaita";
|
||||||
|
description = "The name of the theme within the package.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "gtk" "gtk3" "waylandSupport" ] ''
|
||||||
|
This options is not longer needed and can be removed.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
gtk = {
|
||||||
|
enable = mkEnableOption "GTK 2/3 configuration";
|
||||||
|
|
||||||
|
font = mkOption {
|
||||||
|
type = types.nullOr hm.types.fontType;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The font to use in GTK+ 2/3 applications.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
iconTheme = mkOption {
|
||||||
|
type = types.nullOr themeType;
|
||||||
|
default = null;
|
||||||
|
description = "The icon theme to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
theme = mkOption {
|
||||||
|
type = types.nullOr themeType;
|
||||||
|
default = null;
|
||||||
|
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>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk3 = {
|
||||||
|
bookmarks = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "file:///home/jane/Documents" ];
|
||||||
|
description = "Bookmarks in the sidebar of the GTK file browser";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf (either bool (either int str));
|
||||||
|
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>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = 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 = cfg.font.name; }
|
||||||
|
// 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 {
|
||||||
|
home.packages = optionalPackage cfg.font ++ optionalPackage cfg.theme
|
||||||
|
++ optionalPackage cfg.iconTheme;
|
||||||
|
|
||||||
|
home.file.".gtkrc-2.0".text =
|
||||||
|
concatStringsSep "\n" (mapAttrsToList formatGtk2Option ini) + "\n"
|
||||||
|
+ cfg2.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;
|
||||||
|
});
|
||||||
|
}
|
14
third_party/home-manager/modules/misc/lib.nix
vendored
Normal file
14
third_party/home-manager/modules/misc/lib.nix
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
lib = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
This option allows modules to define helper functions,
|
||||||
|
constants, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
1725
third_party/home-manager/modules/misc/news.nix
vendored
Normal file
1725
third_party/home-manager/modules/misc/news.nix
vendored
Normal file
File diff suppressed because it is too large
Load diff
152
third_party/home-manager/modules/misc/nixpkgs.nix
vendored
Normal file
152
third_party/home-manager/modules/misc/nixpkgs.nix
vendored
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
# Adapted from Nixpkgs.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, pkgsPath, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
isConfig = x:
|
||||||
|
builtins.isAttrs x || builtins.isFunction x;
|
||||||
|
|
||||||
|
optCall = f: x:
|
||||||
|
if builtins.isFunction f
|
||||||
|
then f x
|
||||||
|
else f;
|
||||||
|
|
||||||
|
mergeConfig = lhs_: rhs_:
|
||||||
|
let
|
||||||
|
lhs = optCall lhs_ { inherit pkgs; };
|
||||||
|
rhs = optCall rhs_ { inherit pkgs; };
|
||||||
|
in
|
||||||
|
lhs // rhs //
|
||||||
|
optionalAttrs (lhs ? packageOverrides) {
|
||||||
|
packageOverrides = pkgs:
|
||||||
|
optCall lhs.packageOverrides pkgs //
|
||||||
|
optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs;
|
||||||
|
} //
|
||||||
|
optionalAttrs (lhs ? perlPackageOverrides) {
|
||||||
|
perlPackageOverrides = pkgs:
|
||||||
|
optCall lhs.perlPackageOverrides pkgs //
|
||||||
|
optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
configType = mkOptionType {
|
||||||
|
name = "nixpkgs-config";
|
||||||
|
description = "nixpkgs config";
|
||||||
|
check = x:
|
||||||
|
let traceXIfNot = c:
|
||||||
|
if c x then true
|
||||||
|
else lib.traceSeqN 1 x false;
|
||||||
|
in traceXIfNot isConfig;
|
||||||
|
merge = args: fold (def: mergeConfig def.value) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
overlayType = mkOptionType {
|
||||||
|
name = "nixpkgs-overlay";
|
||||||
|
description = "nixpkgs overlay";
|
||||||
|
check = builtins.isFunction;
|
||||||
|
merge = lib.mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
_pkgs = import pkgsPath (
|
||||||
|
filterAttrs (n: v: v != null) config.nixpkgs
|
||||||
|
);
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.nixpkgs = {
|
||||||
|
config = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = { allowBroken = true; };
|
||||||
|
type = types.nullOr configType;
|
||||||
|
description = ''
|
||||||
|
The configuration of the Nix Packages collection. (For
|
||||||
|
details, see the Nixpkgs documentation.) It allows you to set
|
||||||
|
package configuration options.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
If <literal>null</literal>, then configuration is taken from
|
||||||
|
the fallback location, for example,
|
||||||
|
<filename>~/.config/nixpkgs/config.nix</filename>.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
Note, this option will not apply outside your Home Manager
|
||||||
|
configuration like when installing manually through
|
||||||
|
<command>nix-env</command>. If you want to apply it both
|
||||||
|
inside and outside Home Manager you can put it in a separate
|
||||||
|
file and include something like
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
nixpkgs.config = import ./nixpkgs-config.nix;
|
||||||
|
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
in your Home Manager configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
overlays = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = literalExample
|
||||||
|
''
|
||||||
|
[ (self: super: {
|
||||||
|
openssh = super.openssh.override {
|
||||||
|
hpnSupport = true;
|
||||||
|
withKerberos = true;
|
||||||
|
kerberos = self.libkrb5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
) ]
|
||||||
|
'';
|
||||||
|
type = types.nullOr (types.listOf overlayType);
|
||||||
|
description = ''
|
||||||
|
List of overlays to use with the Nix Packages collection. (For
|
||||||
|
details, see the Nixpkgs documentation.) It allows you to
|
||||||
|
override packages globally. This is a function that takes as
|
||||||
|
an argument the <emphasis>original</emphasis> Nixpkgs. The
|
||||||
|
first argument should be used for finding dependencies, and
|
||||||
|
the second should be used for overriding recipes.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
If <literal>null</literal>, then the overlays are taken from
|
||||||
|
the fallback location, for example,
|
||||||
|
<filename>~/.config/nixpkgs/overlays</filename>.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
Like <varname>nixpkgs.config</varname> this option only
|
||||||
|
applies within the Home Manager configuration. See
|
||||||
|
<varname>nixpkgs.config</varname> for a suggested setup that
|
||||||
|
works both internally and externally.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "i686-linux";
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Specifies the Nix platform type for which the user environment
|
||||||
|
should be built. If unset, it defaults to the platform type of
|
||||||
|
your host system. Specifying this option is useful when doing
|
||||||
|
distributed multi-platform deployment, or when building
|
||||||
|
virtual machines.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
_module.args = {
|
||||||
|
pkgs = mkOverride modules.defaultPriority _pkgs;
|
||||||
|
pkgs_i686 =
|
||||||
|
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
|
||||||
|
then _pkgs.pkgsi686Linux
|
||||||
|
else { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
31
third_party/home-manager/modules/misc/numlock.nix
vendored
Normal file
31
third_party/home-manager/modules/misc/numlock.nix
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{ 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" ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
32
third_party/home-manager/modules/misc/pam.nix
vendored
Normal file
32
third_party/home-manager/modules/misc/pam.nix
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
vars = config.pam.sessionVariables;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
pam.sessionVariables = mkOption {
|
||||||
|
default = { };
|
||||||
|
type = types.attrs;
|
||||||
|
example = { EDITOR = "vim"; };
|
||||||
|
description = ''
|
||||||
|
Environment variables that will be set for the PAM session.
|
||||||
|
The variable values must be as described in
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>pam_env.conf</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum>
|
||||||
|
</citerefentry>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (vars != { }) {
|
||||||
|
home.file.".pam_environment".text = concatStringsSep "\n"
|
||||||
|
(mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') vars) + "\n";
|
||||||
|
};
|
||||||
|
}
|
68
third_party/home-manager/modules/misc/qt.nix
vendored
Normal file
68
third_party/home-manager/modules/misc/qt.nix
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ 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>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.enable && cfg.platformTheme != null) {
|
||||||
|
home.sessionVariables.QT_QPA_PLATFORMTHEME =
|
||||||
|
if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
|
||||||
|
|
||||||
|
home.packages = if cfg.platformTheme == "gnome" then
|
||||||
|
[ pkgs.qgnomeplatform ]
|
||||||
|
else
|
||||||
|
[ pkgs.libsForQt5.qtstyleplugins ];
|
||||||
|
|
||||||
|
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ];
|
||||||
|
|
||||||
|
# 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+
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
32
third_party/home-manager/modules/misc/submodule-support.nix
vendored
Normal file
32
third_party/home-manager/modules/misc/submodule-support.nix
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ 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>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
49
third_party/home-manager/modules/misc/tmpfiles.nix
vendored
Normal file
49
third_party/home-manager/modules/misc/tmpfiles.nix
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
24
third_party/home-manager/modules/misc/version.nix
vendored
Normal file
24
third_party/home-manager/modules/misc/version.nix
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
home.stateVersion = mkOption {
|
||||||
|
type = types.enum [ "18.09" "19.03" "19.09" "20.03" "20.09" ];
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
51
third_party/home-manager/modules/misc/vte.nix
vendored
Normal file
51
third_party/home-manager/modules/misc/vte.nix
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
88
third_party/home-manager/modules/misc/xdg-mime-apps.nix
vendored
Normal file
88
third_party/home-manager/modules/misc/xdg-mime-apps.nix
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
55
third_party/home-manager/modules/misc/xdg-mime.nix
vendored
Normal file
55
third_party/home-manager/modules/misc/xdg-mime.nix
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
110
third_party/home-manager/modules/misc/xdg-user-dirs.nix
vendored
Normal file
110
third_party/home-manager/modules/misc/xdg-user-dirs.nix
vendored
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
{ 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.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
xdg.configFile."user-dirs.dirs".text = let
|
||||||
|
options = {
|
||||||
|
XDG_DESKTOP_DIR = cfg.desktop;
|
||||||
|
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||||
|
XDG_DOWNLOAD_DIR = cfg.download;
|
||||||
|
XDG_MUSIC_DIR = cfg.music;
|
||||||
|
XDG_PICTURES_DIR = cfg.pictures;
|
||||||
|
XDG_PUBLICSHARE_DIR = cfg.publicShare;
|
||||||
|
XDG_TEMPLATES_DIR = cfg.templates;
|
||||||
|
XDG_VIDEOS_DIR = cfg.videos;
|
||||||
|
} // cfg.extraConfig;
|
||||||
|
|
||||||
|
# For some reason, these need to be wrapped with quotes to be valid.
|
||||||
|
wrapped = mapAttrs (_: value: ''"${value}"'') options;
|
||||||
|
in generators.toKeyValue { } wrapped;
|
||||||
|
|
||||||
|
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||||||
|
};
|
||||||
|
}
|
114
third_party/home-manager/modules/misc/xdg.nix
vendored
Normal file
114
third_party/home-manager/modules/misc/xdg.nix
vendored
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
{ options, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg;
|
||||||
|
|
||||||
|
dag = config.lib.dag;
|
||||||
|
|
||||||
|
fileType = (import ../lib/file-type.nix {
|
||||||
|
inherit (config.home) homeDirectory;
|
||||||
|
inherit lib pkgs;
|
||||||
|
}).fileType;
|
||||||
|
|
||||||
|
defaultCacheHome = "${config.home.homeDirectory}/.cache";
|
||||||
|
defaultConfigHome = "${config.home.homeDirectory}/.config";
|
||||||
|
defaultDataHome = "${config.home.homeDirectory}/.local/share";
|
||||||
|
|
||||||
|
getXdgDir = name: fallback:
|
||||||
|
let
|
||||||
|
value = builtins.getEnv name;
|
||||||
|
in
|
||||||
|
if value != "" then value else fallback;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.xdg = {
|
||||||
|
enable = mkEnableOption "management of XDG base directories";
|
||||||
|
|
||||||
|
cacheHome = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
defaultText = "~/.cache";
|
||||||
|
description = ''
|
||||||
|
Absolute path to directory holding application caches.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = mkOption {
|
||||||
|
type = fileType "<varname>xdg.configHome</varname>" cfg.configHome;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Attribute set of files to link into the user's XDG
|
||||||
|
configuration home.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configHome = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
defaultText = "~/.config";
|
||||||
|
description = ''
|
||||||
|
Absolute path to directory holding application configurations.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataFile = mkOption {
|
||||||
|
type = fileType "<varname>xdg.dataHome</varname>" cfg.dataHome;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Attribute set of files to link into the user's XDG
|
||||||
|
data home.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataHome = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
defaultText = "~/.local/share";
|
||||||
|
description = ''
|
||||||
|
Absolute path to directory holding application data.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf cfg.enable {
|
||||||
|
xdg.cacheHome = mkDefault defaultCacheHome;
|
||||||
|
xdg.configHome = mkDefault defaultConfigHome;
|
||||||
|
xdg.dataHome = mkDefault defaultDataHome;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
XDG_CACHE_HOME = cfg.cacheHome;
|
||||||
|
XDG_CONFIG_HOME = cfg.configHome;
|
||||||
|
XDG_DATA_HOME = cfg.dataHome;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
# Legacy non-deterministic setup.
|
||||||
|
(mkIf (!cfg.enable && versionOlder config.home.stateVersion "20.09") {
|
||||||
|
xdg.cacheHome = getXdgDir "XDG_CACHE_HOME" defaultCacheHome;
|
||||||
|
xdg.configHome = getXdgDir "XDG_CONFIG_HOME" defaultConfigHome;
|
||||||
|
xdg.dataHome = getXdgDir "XDG_DATA_HOME" defaultDataHome;
|
||||||
|
})
|
||||||
|
|
||||||
|
# "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 = ""; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
227
third_party/home-manager/modules/modules.nix
vendored
Normal file
227
third_party/home-manager/modules/modules.nix
vendored
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
{ 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
|
||||||
|
}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
hostPlatform = pkgs.stdenv.hostPlatform;
|
||||||
|
|
||||||
|
loadModule = file: { condition ? true }: {
|
||||||
|
inherit file condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
allModules = [
|
||||||
|
(loadModule ./accounts/email.nix { })
|
||||||
|
(loadModule ./files.nix { })
|
||||||
|
(loadModule ./home-environment.nix { })
|
||||||
|
(loadModule ./manual.nix { })
|
||||||
|
(loadModule ./misc/dconf.nix { })
|
||||||
|
(loadModule ./misc/debug.nix { })
|
||||||
|
(loadModule ./misc/fontconfig.nix { })
|
||||||
|
(loadModule ./misc/gtk.nix { })
|
||||||
|
(loadModule ./misc/lib.nix { })
|
||||||
|
(loadModule ./misc/news.nix { })
|
||||||
|
(loadModule ./misc/nixpkgs.nix { condition = useNixpkgsModule; })
|
||||||
|
(loadModule ./misc/numlock.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./misc/pam.nix { })
|
||||||
|
(loadModule ./misc/qt.nix { })
|
||||||
|
(loadModule ./misc/submodule-support.nix { })
|
||||||
|
(loadModule ./misc/tmpfiles.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./misc/version.nix { })
|
||||||
|
(loadModule ./misc/vte.nix { })
|
||||||
|
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./misc/xdg.nix { })
|
||||||
|
(loadModule ./programs/abook.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./programs/afew.nix { })
|
||||||
|
(loadModule ./programs/alacritty.nix { })
|
||||||
|
(loadModule ./programs/alot.nix { })
|
||||||
|
(loadModule ./programs/aria2.nix { })
|
||||||
|
(loadModule ./programs/astroid.nix { })
|
||||||
|
(loadModule ./programs/autojump.nix { })
|
||||||
|
(loadModule ./programs/autorandr.nix { })
|
||||||
|
(loadModule ./programs/bash.nix { })
|
||||||
|
(loadModule ./programs/bat.nix { })
|
||||||
|
(loadModule ./programs/beets.nix { })
|
||||||
|
(loadModule ./programs/broot.nix { })
|
||||||
|
(loadModule ./programs/browserpass.nix { })
|
||||||
|
(loadModule ./programs/chromium.nix { })
|
||||||
|
(loadModule ./programs/command-not-found/command-not-found.nix { })
|
||||||
|
(loadModule ./programs/dircolors.nix { })
|
||||||
|
(loadModule ./programs/direnv.nix { })
|
||||||
|
(loadModule ./programs/eclipse.nix { })
|
||||||
|
(loadModule ./programs/emacs.nix { })
|
||||||
|
(loadModule ./programs/feh.nix { })
|
||||||
|
(loadModule ./programs/firefox.nix { })
|
||||||
|
(loadModule ./programs/fish.nix { })
|
||||||
|
(loadModule ./programs/fzf.nix { })
|
||||||
|
(loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./programs/gh.nix { })
|
||||||
|
(loadModule ./programs/git.nix { })
|
||||||
|
(loadModule ./programs/gnome-terminal.nix { })
|
||||||
|
(loadModule ./programs/go.nix { })
|
||||||
|
(loadModule ./programs/gpg.nix { })
|
||||||
|
(loadModule ./programs/home-manager.nix { })
|
||||||
|
(loadModule ./programs/htop.nix { })
|
||||||
|
(loadModule ./programs/i3status.nix { })
|
||||||
|
(loadModule ./programs/info.nix { })
|
||||||
|
(loadModule ./programs/irssi.nix { })
|
||||||
|
(loadModule ./programs/lieer.nix { })
|
||||||
|
(loadModule ./programs/jq.nix { })
|
||||||
|
(loadModule ./programs/kakoune.nix { })
|
||||||
|
(loadModule ./programs/keychain.nix { })
|
||||||
|
(loadModule ./programs/kitty.nix { })
|
||||||
|
(loadModule ./programs/lesspipe.nix { })
|
||||||
|
(loadModule ./programs/lf.nix { })
|
||||||
|
(loadModule ./programs/lsd.nix { })
|
||||||
|
(loadModule ./programs/man.nix { })
|
||||||
|
(loadModule ./programs/matplotlib.nix { })
|
||||||
|
(loadModule ./programs/mbsync.nix { })
|
||||||
|
(loadModule ./programs/mcfly.nix { })
|
||||||
|
(loadModule ./programs/mercurial.nix { })
|
||||||
|
(loadModule ./programs/mpv.nix { })
|
||||||
|
(loadModule ./programs/msmtp.nix { })
|
||||||
|
(loadModule ./programs/mu.nix { })
|
||||||
|
(loadModule ./programs/ncmpcpp.nix { })
|
||||||
|
(loadModule ./programs/ne.nix { })
|
||||||
|
(loadModule ./programs/neomutt.nix { })
|
||||||
|
(loadModule ./programs/neovim.nix { })
|
||||||
|
(loadModule ./programs/newsboat.nix { })
|
||||||
|
(loadModule ./programs/noti.nix { })
|
||||||
|
(loadModule ./programs/notmuch.nix { })
|
||||||
|
(loadModule ./programs/nushell.nix { })
|
||||||
|
(loadModule ./programs/obs-studio.nix { })
|
||||||
|
(loadModule ./programs/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/rtorrent.nix { })
|
||||||
|
(loadModule ./programs/skim.nix { })
|
||||||
|
(loadModule ./programs/starship.nix { })
|
||||||
|
(loadModule ./programs/ssh.nix { })
|
||||||
|
(loadModule ./programs/taskwarrior.nix { })
|
||||||
|
(loadModule ./programs/termite.nix { })
|
||||||
|
(loadModule ./programs/texlive.nix { })
|
||||||
|
(loadModule ./programs/tmux.nix { })
|
||||||
|
(loadModule ./programs/urxvt.nix { })
|
||||||
|
(loadModule ./programs/vim.nix { })
|
||||||
|
(loadModule ./programs/vscode.nix { })
|
||||||
|
(loadModule ./programs/vscode/haskell.nix { })
|
||||||
|
(loadModule ./programs/waybar.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./programs/z-lua.nix { })
|
||||||
|
(loadModule ./programs/zathura.nix { })
|
||||||
|
(loadModule ./programs/zoxide.nix { })
|
||||||
|
(loadModule ./programs/zplug.nix { })
|
||||||
|
(loadModule ./programs/zsh.nix { })
|
||||||
|
(loadModule ./programs/zsh/prezto.nix { })
|
||||||
|
(loadModule ./services/blueman-applet.nix { })
|
||||||
|
(loadModule ./services/cbatticon.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/clipmenu.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/compton.nix { })
|
||||||
|
(loadModule ./services/dropbox.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/dunst.nix { })
|
||||||
|
(loadModule ./services/dwm-status.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/emacs.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/flameshot.nix { })
|
||||||
|
(loadModule ./services/fluidsynth.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/gammastep.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/getmail.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/gnome-keyring.nix { })
|
||||||
|
(loadModule ./services/gpg-agent.nix { })
|
||||||
|
(loadModule ./services/grobi.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/hound.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/kanshi.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/kbfs.nix { })
|
||||||
|
(loadModule ./services/kdeconnect.nix { })
|
||||||
|
(loadModule ./services/keepassx.nix { })
|
||||||
|
(loadModule ./services/keybase.nix { })
|
||||||
|
(loadModule ./services/keynav.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/lieer.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/lorri.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/mako.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/mbsync.nix { })
|
||||||
|
(loadModule ./services/mpd.nix { })
|
||||||
|
(loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/muchsync.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/network-manager-applet.nix { })
|
||||||
|
(loadModule ./services/nextcloud-client.nix { })
|
||||||
|
(loadModule ./services/owncloud-client.nix { })
|
||||||
|
(loadModule ./services/parcellite.nix { })
|
||||||
|
(loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/pasystray.nix { })
|
||||||
|
(loadModule ./services/picom.nix { })
|
||||||
|
(loadModule ./services/polybar.nix { })
|
||||||
|
(loadModule ./services/pulseeffects.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./services/random-background.nix { })
|
||||||
|
(loadModule ./services/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/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.nix { condition = hostPlatform.isDarwin; })
|
||||||
|
(loadModule ./targets/generic-linux.nix { condition = hostPlatform.isLinux; })
|
||||||
|
(loadModule ./xcursor.nix { })
|
||||||
|
(loadModule ./xresources.nix { })
|
||||||
|
(loadModule ./xsession.nix { })
|
||||||
|
(loadModule (pkgs.path + "/nixos/modules/misc/assertions.nix") { })
|
||||||
|
(loadModule (pkgs.path + "/nixos/modules/misc/meta.nix") { })
|
||||||
|
];
|
||||||
|
|
||||||
|
modules = map (getAttr "file") (filter (getAttr "condition") allModules);
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
modules ++ [ pkgsModule ]
|
40
third_party/home-manager/modules/programs/abook.nix
vendored
Normal file
40
third_party/home-manager/modules/programs/abook.nix
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ 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}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
52
third_party/home-manager/modules/programs/afew.nix
vendored
Normal file
52
third_party/home-manager/modules/programs/afew.nix
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{ 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}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
59
third_party/home-manager/modules/programs/alacritty.nix
vendored
Normal file
59
third_party/home-manager/modules/programs/alacritty.nix
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.alacritty;
|
||||||
|
|
||||||
|
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 = types.attrs;
|
||||||
|
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 != { }) {
|
||||||
|
text =
|
||||||
|
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
58
third_party/home-manager/modules/programs/alot-accounts.nix
vendored
Normal file
58
third_party/home-manager/modules/programs/alot-accounts.nix
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
237
third_party/home-manager/modules/programs/alot.nix
vendored
Normal file
237
third_party/home-manager/modules/programs/alot.nix
vendored
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
# alot config loader is sensitive to leading space !
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.alot;
|
||||||
|
|
||||||
|
alotAccounts =
|
||||||
|
filter (a: a.notmuch.enable) (attrValues config.accounts.email.accounts);
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
61
third_party/home-manager/modules/programs/aria2.nix
vendored
Normal file
61
third_party/home-manager/modules/programs/aria2.nix
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{ 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);
|
||||||
|
};
|
||||||
|
}
|
32
third_party/home-manager/modules/programs/astroid-accounts.nix
vendored
Normal file
32
third_party/home-manager/modules/programs/astroid-accounts.nix
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ 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.attrs;
|
||||||
|
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");
|
||||||
|
};
|
||||||
|
}
|
113
third_party/home-manager/modules/programs/astroid-config-template.json
vendored
Normal file
113
third_party/home-manager/modules/programs/astroid-config-template.json
vendored
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
127
third_party/home-manager/modules/programs/astroid.nix
vendored
Normal file
127
third_party/home-manager/modules/programs/astroid.nix
vendored
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
with builtins;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.astroid;
|
||||||
|
|
||||||
|
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
|
||||||
|
configFile = mailAccounts:
|
||||||
|
let
|
||||||
|
template = fromJSON (readFile ./astroid-config-template.json);
|
||||||
|
astroidConfig = foldl' recursiveUpdate template [
|
||||||
|
{
|
||||||
|
astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc";
|
||||||
|
accounts = mapAttrs (n: accountAttr) astroidAccounts;
|
||||||
|
crypto.gpg.path = "${pkgs.gnupg}/bin/gpg";
|
||||||
|
}
|
||||||
|
cfg.extraConfig
|
||||||
|
cfg.externalEditor
|
||||||
|
];
|
||||||
|
in builtins.toJSON astroidConfig;
|
||||||
|
|
||||||
|
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 = types.attrs;
|
||||||
|
default = { };
|
||||||
|
example = { 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 = pkgs.runCommand "out.json" {
|
||||||
|
json = configFile astroidAccounts;
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
} ''
|
||||||
|
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.configFile."astroid/poll.sh" = {
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
# Generated by Home Manager
|
||||||
|
|
||||||
|
${cfg.pollScript}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
56
third_party/home-manager/modules/programs/autojump.nix
vendored
Normal file
56
third_party/home-manager/modules/programs/autojump.nix
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
364
third_party/home-manager/modules/programs/autorandr.nix
vendored
Normal file
364
third_party/home-manager/modules/programs/autorandr.nix
vendored
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
{ 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 ];
|
||||||
|
}
|
220
third_party/home-manager/modules/programs/bash.nix
vendored
Normal file
220
third_party/home-manager/modules/programs/bash.nix
vendored
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.bash;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "programs" "bash" "enableAutojump" ] [
|
||||||
|
"programs"
|
||||||
|
"autojump"
|
||||||
|
"enable"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
programs.bash = {
|
||||||
|
enable = mkEnableOption "GNU Bourne-Again SHell";
|
||||||
|
|
||||||
|
historySize = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 10000;
|
||||||
|
description = "Number of history lines to keep in memory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
historyFile = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/.bash_history";
|
||||||
|
description = "Location of the bash history file.";
|
||||||
|
};
|
||||||
|
|
||||||
|
historyFileSize = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 100000;
|
||||||
|
description = "Number of history lines to keep on file.";
|
||||||
|
};
|
||||||
|
|
||||||
|
historyControl = mkOption {
|
||||||
|
type = types.listOf (types.enum [
|
||||||
|
"erasedups"
|
||||||
|
"ignoredups"
|
||||||
|
"ignorespace"
|
||||||
|
]);
|
||||||
|
default = [];
|
||||||
|
description = "Controlling how commands are saved on the history list.";
|
||||||
|
};
|
||||||
|
|
||||||
|
historyIgnore = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "ls" "cd" "exit" ];
|
||||||
|
description = "List of commands that should not be saved to the history list.";
|
||||||
|
};
|
||||||
|
|
||||||
|
shellOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [
|
||||||
|
# Append to history file rather than replacing it.
|
||||||
|
"histappend"
|
||||||
|
|
||||||
|
# check the window size after each command and, if
|
||||||
|
# necessary, update the values of LINES and COLUMNS.
|
||||||
|
"checkwinsize"
|
||||||
|
|
||||||
|
# Extended globbing.
|
||||||
|
"extglob"
|
||||||
|
"globstar"
|
||||||
|
|
||||||
|
# Warn if closing shell with running jobs.
|
||||||
|
"checkjobs"
|
||||||
|
];
|
||||||
|
description = "Shell options to set.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sessionVariables = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrs;
|
||||||
|
example = { MAILCHECK = 30; };
|
||||||
|
description = ''
|
||||||
|
Environment variables that will be set for the Bash session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
shellAliases = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
profileExtra = mkOption {
|
||||||
|
default = "";
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Extra commands that should be run when initializing a login
|
||||||
|
shell.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
description = ''
|
||||||
|
Extra commands that should be run when initializing an
|
||||||
|
interactive shell.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
shoptsStr = concatStringsSep "\n" (
|
||||||
|
map (v: "shopt -s ${v}") cfg.shellOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
|
||||||
|
|
||||||
|
historyControlStr =
|
||||||
|
concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") (
|
||||||
|
{
|
||||||
|
HISTFILE = "\"${cfg.historyFile}\"";
|
||||||
|
HISTFILESIZE = toString cfg.historyFileSize;
|
||||||
|
HISTSIZE = toString cfg.historySize;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.historyControl != []) {
|
||||||
|
HISTCONTROL = concatStringsSep ":" cfg.historyControl;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.historyIgnore != []) {
|
||||||
|
HISTIGNORE = concatStringsSep ":" cfg.historyIgnore;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
in mkIf cfg.enable {
|
||||||
|
programs.bash.bashrcExtra = ''
|
||||||
|
# Commands that should be applied only for interactive shells.
|
||||||
|
if [[ $- == *i* ]]; then
|
||||||
|
${historyControlStr}
|
||||||
|
|
||||||
|
${shoptsStr}
|
||||||
|
|
||||||
|
${aliasesStr}
|
||||||
|
|
||||||
|
${cfg.initExtra}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".bash_profile".text = ''
|
||||||
|
# -*- mode: sh -*-
|
||||||
|
|
||||||
|
# include .profile if it exists
|
||||||
|
[[ -f ~/.profile ]] && . ~/.profile
|
||||||
|
|
||||||
|
# include .bashrc if it exists
|
||||||
|
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".profile".text = ''
|
||||||
|
# -*- mode: sh -*-
|
||||||
|
|
||||||
|
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
|
||||||
|
|
||||||
|
${sessionVarsStr}
|
||||||
|
|
||||||
|
${cfg.profileExtra}
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".bashrc".text = ''
|
||||||
|
# -*- mode: sh -*-
|
||||||
|
|
||||||
|
${cfg.bashrcExtra}
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
|
||||||
|
text = ''
|
||||||
|
# -*- mode: sh -*-
|
||||||
|
|
||||||
|
${cfg.logoutExtra}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
58
third_party/home-manager/modules/programs/bat.nix
vendored
Normal file
58
third_party/home-manager/modules/programs/bat.nix
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{ 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; }; }));
|
||||||
|
};
|
||||||
|
}
|
58
third_party/home-manager/modules/programs/beets.nix
vendored
Normal file
58
third_party/home-manager/modules/programs/beets.nix
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.beets;
|
||||||
|
|
||||||
|
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 = types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Configuration written to
|
||||||
|
<filename>~/.config/beets/config.yaml</filename>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
|
xdg.configFile."beets/config.yaml".text =
|
||||||
|
builtins.toJSON config.programs.beets.settings;
|
||||||
|
};
|
||||||
|
}
|
256
third_party/home-manager/modules/programs/broot.nix
vendored
Normal file
256
third_party/home-manager/modules/programs/broot.nix
vendored
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.broot;
|
||||||
|
|
||||||
|
configFile = config:
|
||||||
|
pkgs.runCommand "conf.toml" {
|
||||||
|
buildInputs = [ pkgs.remarshal ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
} ''
|
||||||
|
remarshal -if json -of toml \
|
||||||
|
< ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \
|
||||||
|
> $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
brootConf = {
|
||||||
|
verbs =
|
||||||
|
mapAttrsToList (name: value: value // { invocation = name; }) 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; attrsOf (attrsOf (either bool str));
|
||||||
|
default = {
|
||||||
|
"p" = { execution = ":parent"; };
|
||||||
|
"edit" = {
|
||||||
|
shortcut = "e";
|
||||||
|
execution = "$EDITOR {file}";
|
||||||
|
};
|
||||||
|
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
|
||||||
|
"view" = { execution = "less {file}"; };
|
||||||
|
};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"p" = { execution = ":parent"; };
|
||||||
|
"edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; };
|
||||||
|
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
|
||||||
|
"view" = { execution = "less {file}"; };
|
||||||
|
"blop {name}\\.{type}" = {
|
||||||
|
execution = "/bin/mkdir {parent}/{type} && /usr/bin/nvim {parent}/{type}/{name}.{type}";
|
||||||
|
from_shell = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Define new verbs. The attribute name indicates how the verb is
|
||||||
|
called by the user, with placeholders for arguments.
|
||||||
|
</para><para>
|
||||||
|
The possible attributes are:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>execution</literal> (mandatory)</term>
|
||||||
|
<listitem><para>how the verb is executed</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>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = [ pkgs.broot ];
|
||||||
|
|
||||||
|
xdg.configFile."broot/conf.toml".source = configFile 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
76
third_party/home-manager/modules/programs/browserpass.nix
vendored
Normal file
76
third_party/home-manager/modules/programs/browserpass.nix
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let browsers = [ "chrome" "chromium" "firefox" "vivaldi" ];
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
programs.browserpass = {
|
||||||
|
enable = mkEnableOption "the browserpass extension host application";
|
||||||
|
|
||||||
|
browsers = mkOption {
|
||||||
|
type = types.listOf (types.enum browsers);
|
||||||
|
default = browsers;
|
||||||
|
example = [ "firefox" ];
|
||||||
|
description = "Which browsers to install browserpass for";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.programs.browserpass.enable {
|
||||||
|
home.file = foldl' (a: b: a // b) { } (concatMap (x:
|
||||||
|
with pkgs.stdenv;
|
||||||
|
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";
|
||||||
|
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 == "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";
|
||||||
|
}]
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
92
third_party/home-manager/modules/programs/chromium.nix
vendored
Normal file
92
third_party/home-manager/modules/programs/chromium.nix
vendored
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
browserModule = defaultPkg: name: visible:
|
||||||
|
let browser = (builtins.parseDrvName defaultPkg.name).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.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extensions = mkOption {
|
||||||
|
inherit visible;
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample ''
|
||||||
|
[
|
||||||
|
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
|
||||||
|
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
|
||||||
|
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
|
||||||
|
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
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>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
browserConfig = cfg:
|
||||||
|
let
|
||||||
|
|
||||||
|
browser = (builtins.parseDrvName cfg.package.name).name;
|
||||||
|
|
||||||
|
darwinDirs = {
|
||||||
|
chromium = "Chromium";
|
||||||
|
google-chrome = "Google/Chrome";
|
||||||
|
google-chrome-beta = "Google/Chrome Beta";
|
||||||
|
google-chrome-dev = "Google/Chrome Dev";
|
||||||
|
};
|
||||||
|
|
||||||
|
configDir = if pkgs.stdenv.isDarwin then
|
||||||
|
"Library/Application Support/${getAttr browser darwinDirs}"
|
||||||
|
else
|
||||||
|
"${config.xdg.configHome}/${browser}";
|
||||||
|
|
||||||
|
extensionJson = ext: {
|
||||||
|
name = "${configDir}/External Extensions/${ext}.json";
|
||||||
|
value.text = builtins.toJSON {
|
||||||
|
external_update_url =
|
||||||
|
"https://clients2.google.com/service/update2/crx";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
home.file = listToAttrs (map extensionJson cfg.extensions);
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(browserConfig config.programs.chromium)
|
||||||
|
(browserConfig config.programs.google-chrome)
|
||||||
|
(browserConfig config.programs.google-chrome-beta)
|
||||||
|
(browserConfig config.programs.google-chrome-dev)
|
||||||
|
];
|
||||||
|
}
|
59
third_party/home-manager/modules/programs/command-not-found/command-not-found.nix
vendored
Normal file
59
third_party/home-manager/modules/programs/command-not-found/command-not-found.nix
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# Adapted from Nixpkgs.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.command-not-found;
|
||||||
|
commandNotFound = pkgs.substituteAll {
|
||||||
|
name = "command-not-found";
|
||||||
|
dir = "bin";
|
||||||
|
src = ./command-not-found.pl;
|
||||||
|
isExecutable = true;
|
||||||
|
inherit (pkgs) perl;
|
||||||
|
inherit (cfg) dbPath;
|
||||||
|
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [
|
||||||
|
pkgs.perlPackages.DBI
|
||||||
|
pkgs.perlPackages.DBDSQLite
|
||||||
|
pkgs.perlPackages.StringShellQuote
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
shInit = commandNotFoundHandlerName: ''
|
||||||
|
# This function is called whenever a command is not found.
|
||||||
|
${commandNotFoundHandlerName}() {
|
||||||
|
local p=${commandNotFound}/bin/command-not-found
|
||||||
|
if [ -x $p -a -f ${cfg.dbPath} ]; then
|
||||||
|
# Run the helper program.
|
||||||
|
$p "$@"
|
||||||
|
else
|
||||||
|
echo "$1: command not found" >&2
|
||||||
|
return 127
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
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";
|
||||||
|
description = ''
|
||||||
|
Absolute path to <filename>programs.sqlite</filename>. By
|
||||||
|
default this file will be provided by your channel
|
||||||
|
(nixexprs.tar.xz).
|
||||||
|
'';
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
programs.bash.initExtra = shInit "command_not_found_handle";
|
||||||
|
programs.zsh.initExtra = shInit "command_not_found_handler";
|
||||||
|
|
||||||
|
home.packages = [ commandNotFound ];
|
||||||
|
};
|
||||||
|
}
|
44
third_party/home-manager/modules/programs/command-not-found/command-not-found.pl
vendored
Normal file
44
third_party/home-manager/modules/programs/command-not-found/command-not-found.pl
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#! @perl@/bin/perl -w @perlFlags@
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use DBI;
|
||||||
|
use DBD::SQLite;
|
||||||
|
use String::ShellQuote;
|
||||||
|
use Config;
|
||||||
|
|
||||||
|
my $program = $ARGV[0];
|
||||||
|
|
||||||
|
my $dbPath = "@dbPath@";
|
||||||
|
|
||||||
|
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
|
||||||
|
or die "cannot open database `$dbPath'";
|
||||||
|
$dbh->{RaiseError} = 0;
|
||||||
|
$dbh->{PrintError} = 0;
|
||||||
|
|
||||||
|
my $system = $ENV{"NIX_SYSTEM"} // $Config{myarchname};
|
||||||
|
|
||||||
|
my $res = $dbh->selectall_arrayref(
|
||||||
|
"select package from Programs where system = ? and name = ?",
|
||||||
|
{ Slice => {} }, $system, $program);
|
||||||
|
|
||||||
|
if (!defined $res || scalar @$res == 0) {
|
||||||
|
print STDERR "$program: command not found\n";
|
||||||
|
} elsif (scalar @$res == 1) {
|
||||||
|
my $package = @$res[0]->{package};
|
||||||
|
if ($ENV{"NIX_AUTO_RUN"} // "") {
|
||||||
|
exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV));
|
||||||
|
} else {
|
||||||
|
print STDERR <<EOF;
|
||||||
|
The program ‘$program’ is currently not installed. You can install it by typing:
|
||||||
|
nix-env -iA nixos.$package
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print STDERR <<EOF;
|
||||||
|
The program ‘$program’ is currently not installed. It is provided by
|
||||||
|
several packages. You can install it by typing one of the following:
|
||||||
|
EOF
|
||||||
|
print STDERR " nix-env -iA nixos.$_->{package}\n" foreach @$res;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit 127;
|
223
third_party/home-manager/modules/programs/dircolors.nix
vendored
Normal file
223
third_party/home-manager/modules/programs/dircolors.nix
vendored
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
{ 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" ([ ]
|
||||||
|
++ optional (cfg.extraConfig != "") cfg.extraConfig
|
||||||
|
++ mapAttrsToList formatLine cfg.settings) + "\n";
|
||||||
|
|
||||||
|
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)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
107
third_party/home-manager/modules/programs/direnv.nix
vendored
Normal file
107
third_party/home-manager/modules/programs/direnv.nix
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.direnv;
|
||||||
|
configFile = config:
|
||||||
|
pkgs.runCommand "config.toml" {
|
||||||
|
buildInputs = [ pkgs.remarshal ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
} ''
|
||||||
|
remarshal -if json -of toml \
|
||||||
|
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
|
||||||
|
> $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
options.programs.direnv = {
|
||||||
|
enable = mkEnableOption "direnv, the environment switcher";
|
||||||
|
|
||||||
|
config = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
enableNixDirenvIntegration = mkEnableOption ''
|
||||||
|
<link
|
||||||
|
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
|
||||||
|
a fast, persistent use_nix implementation for direnv'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.direnv ];
|
||||||
|
|
||||||
|
xdg.configFile."direnv/config.toml" =
|
||||||
|
mkIf (cfg.config != { }) { source = configFile cfg.config; };
|
||||||
|
|
||||||
|
xdg.configFile."direnv/direnvrc" = let
|
||||||
|
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
|
||||||
|
++ optional cfg.enableNixDirenvIntegration
|
||||||
|
"source ${pkgs.nix-direnv}/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 ''
|
||||||
|
eval (${pkgs.direnv}/bin/direnv hook fish)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
60
third_party/home-manager/modules/programs/eclipse.nix
vendored
Normal file
60
third_party/home-manager/modules/programs/eclipse.nix
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.eclipse;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
programs.eclipse = {
|
||||||
|
enable = mkEnableOption "Eclipse";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.eclipses.eclipse-platform;
|
||||||
|
defaultText = literalExample "pkgs.eclipses.eclipse-platform";
|
||||||
|
example = literalExample "pkgs.eclipses.eclipse-java";
|
||||||
|
description = ''
|
||||||
|
The Eclipse package to install.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
enableLombok = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
Whether to enable the Lombok Java Agent in Eclipse. This is
|
||||||
|
necessary to use the Lombok class annotations.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
jvmArgs = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "JVM arguments to use for the Eclipse process.";
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [ ];
|
||||||
|
description = "Plugins that should be added to Eclipse.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [
|
||||||
|
(pkgs.eclipses.eclipseWithPlugins {
|
||||||
|
eclipse = cfg.package;
|
||||||
|
jvmArgs = cfg.jvmArgs ++ optional cfg.enableLombok
|
||||||
|
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
|
||||||
|
plugins = cfg.plugins;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
73
third_party/home-manager/modules/programs/emacs.nix
vendored
Normal file
73
third_party/home-manager/modules/programs/emacs.nix
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.emacs;
|
||||||
|
|
||||||
|
# Copied from all-packages.nix, with modifications to support
|
||||||
|
# overrides.
|
||||||
|
emacsPackages = let epkgs = pkgs.emacsPackagesFor cfg.package;
|
||||||
|
in epkgs.overrideScope' cfg.overrides;
|
||||||
|
|
||||||
|
emacsWithPackages = emacsPackages.emacsWithPackages;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
programs.emacs = {
|
||||||
|
enable = mkEnableOption "Emacs";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.emacs;
|
||||||
|
defaultText = literalExample "pkgs.emacs";
|
||||||
|
example = literalExample "pkgs.emacs25-nox";
|
||||||
|
description = "The Emacs package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraPackages = mkOption {
|
||||||
|
default = self: [ ];
|
||||||
|
type = hm.types.selectorFunction;
|
||||||
|
defaultText = "epkgs: []";
|
||||||
|
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
|
||||||
|
description = ''
|
||||||
|
Extra packages available to Emacs. To get a list of
|
||||||
|
available packages run:
|
||||||
|
<command>nix-env -f '<nixpkgs>' -qaP -A emacsPackages</command>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
overrides = mkOption {
|
||||||
|
default = self: super: { };
|
||||||
|
type = hm.types.overlayFunction;
|
||||||
|
defaultText = "self: super: {}";
|
||||||
|
example = literalExample ''
|
||||||
|
self: super: rec {
|
||||||
|
haskell-mode = self.melpaPackages.haskell-mode;
|
||||||
|
# ...
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Allows overriding packages within the Emacs package set.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
finalPackage = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
visible = false;
|
||||||
|
readOnly = true;
|
||||||
|
description = ''
|
||||||
|
The Emacs package including any overrides and extra packages.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.finalPackage ];
|
||||||
|
programs.emacs.finalPackage = emacsWithPackages cfg.extraPackages;
|
||||||
|
};
|
||||||
|
}
|
81
third_party/home-manager/modules/programs/feh.nix
vendored
Normal file
81
third_party/home-manager/modules/programs/feh.nix
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.feh;
|
||||||
|
|
||||||
|
bindingsOf = t: with types; attrsOf (nullOr (either t (listOf t)));
|
||||||
|
|
||||||
|
renderBindings = bindings:
|
||||||
|
let
|
||||||
|
enabled = filterAttrs (n: v: v != null) bindings;
|
||||||
|
disabled = filterAttrs (n: v: v == null) bindings;
|
||||||
|
render = mapAttrsToList renderBinding;
|
||||||
|
in concatStringsSep "\n" (render disabled ++ render enabled);
|
||||||
|
|
||||||
|
renderBinding = func: key:
|
||||||
|
if key == null then
|
||||||
|
func
|
||||||
|
else if isList key then
|
||||||
|
concatStringsSep " " ([ func ] ++ map toString key)
|
||||||
|
else
|
||||||
|
"${func} ${toString key}";
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.programs.feh = {
|
||||||
|
enable = mkEnableOption "feh - a fast and light image viewer";
|
||||||
|
|
||||||
|
buttons = mkOption {
|
||||||
|
default = { };
|
||||||
|
type = with types; bindingsOf (either str int);
|
||||||
|
example = {
|
||||||
|
zoom_in = 4;
|
||||||
|
zoom_out = "C-4";
|
||||||
|
prev_img = [ 3 "C-3" ];
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Override feh's default mouse button mapping. If you want to disable an
|
||||||
|
action, set its value to null. If you want to bind multiple buttons to
|
||||||
|
an action, set its value to a list.
|
||||||
|
See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for
|
||||||
|
default bindings and available commands.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
keybindings = mkOption {
|
||||||
|
default = { };
|
||||||
|
type = bindingsOf types.str;
|
||||||
|
example = {
|
||||||
|
zoom_in = "plus";
|
||||||
|
zoom_out = "minus";
|
||||||
|
prev_img = [ "h" "Left" ];
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Override feh's default keybindings. If you want to disable a keybinding
|
||||||
|
set its value to null. If you want to bind multiple keys to an action,
|
||||||
|
set its value to a list.
|
||||||
|
See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for
|
||||||
|
default bindings and available commands.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [{
|
||||||
|
assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == { });
|
||||||
|
message =
|
||||||
|
"To disable a keybinding, use `null` instead of an empty string.";
|
||||||
|
}];
|
||||||
|
|
||||||
|
home.packages = [ pkgs.feh ];
|
||||||
|
|
||||||
|
xdg.configFile."feh/buttons" =
|
||||||
|
mkIf (cfg.buttons != { }) { text = renderBindings cfg.buttons + "\n"; };
|
||||||
|
|
||||||
|
xdg.configFile."feh/keys" = mkIf (cfg.keybindings != { }) {
|
||||||
|
text = renderBindings cfg.keybindings + "\n";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
331
third_party/home-manager/modules/programs/firefox.nix
vendored
Normal file
331
third_party/home-manager/modules/programs/firefox.nix
vendored
Normal file
|
@ -0,0 +1,331 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||||
|
|
||||||
|
cfg = config.programs.firefox;
|
||||||
|
|
||||||
|
mozillaConfigPath =
|
||||||
|
if isDarwin
|
||||||
|
then "Library/Application Support/Mozilla"
|
||||||
|
else ".mozilla";
|
||||||
|
|
||||||
|
firefoxConfigPath =
|
||||||
|
if isDarwin
|
||||||
|
then "Library/Application Support/Firefox"
|
||||||
|
else "${mozillaConfigPath}/firefox";
|
||||||
|
|
||||||
|
profilesPath =
|
||||||
|
if isDarwin
|
||||||
|
then "${firefoxConfigPath}/Profiles"
|
||||||
|
else firefoxConfigPath;
|
||||||
|
|
||||||
|
# The extensions path shared by all profiles; will not be supported
|
||||||
|
# by future Firefox versions.
|
||||||
|
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
|
||||||
|
|
||||||
|
extensionsEnvPkg = pkgs.buildEnv {
|
||||||
|
name = "hm-firefox-extensions";
|
||||||
|
paths = cfg.extensions;
|
||||||
|
};
|
||||||
|
|
||||||
|
profiles =
|
||||||
|
flip mapAttrs' cfg.profiles (_: profile:
|
||||||
|
nameValuePair "Profile${toString profile.id}" {
|
||||||
|
Name = profile.name;
|
||||||
|
Path =
|
||||||
|
if isDarwin
|
||||||
|
then "Profiles/${profile.path}"
|
||||||
|
else profile.path;
|
||||||
|
IsRelative = 1;
|
||||||
|
Default = if profile.isDefault then 1 else 0;
|
||||||
|
}
|
||||||
|
) // {
|
||||||
|
General = {
|
||||||
|
StartWithLastProfile = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
profilesIni = generators.toINI {} profiles;
|
||||||
|
|
||||||
|
mkUserJs = prefs: extraPrefs: ''
|
||||||
|
// Generated by Home Manager.
|
||||||
|
|
||||||
|
${concatStrings (mapAttrsToList (name: value: ''
|
||||||
|
user_pref("${name}", ${builtins.toJSON value});
|
||||||
|
'') prefs)}
|
||||||
|
|
||||||
|
${extraPrefs}
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule ["programs" "firefox" "enableGoogleTalk"]
|
||||||
|
"Support for this option has been removed.")
|
||||||
|
(mkRemovedOptionModule ["programs" "firefox" "enableIcedTea"]
|
||||||
|
"Support for this option has been removed.")
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
programs.firefox = {
|
||||||
|
enable = mkEnableOption "Firefox";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default =
|
||||||
|
if versionAtLeast config.home.stateVersion "19.09"
|
||||||
|
then pkgs.firefox
|
||||||
|
else pkgs.firefox-unwrapped;
|
||||||
|
defaultText = literalExample "pkgs.firefox";
|
||||||
|
description = ''
|
||||||
|
The Firefox package to use. If state version ≥ 19.09 then
|
||||||
|
this should be a wrapped Firefox package. For earlier state
|
||||||
|
versions it should be an unwrapped Firefox package.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extensions = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [];
|
||||||
|
example = literalExample ''
|
||||||
|
with pkgs.nur.repos.rycee.firefox-addons; [
|
||||||
|
https-everywhere
|
||||||
|
privacy-badger
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
List of Firefox add-on packages to install. Some
|
||||||
|
pre-packaged add-ons are accessible from NUR,
|
||||||
|
<link xlink:href="https://github.com/nix-community/NUR"/>.
|
||||||
|
Once you have NUR installed run
|
||||||
|
|
||||||
|
<screen language="console">
|
||||||
|
<prompt>$</prompt> <userinput>nix-env -f '<nixpkgs>' -qaP -A nur.repos.rycee.firefox-addons</userinput>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
to list the available Firefox add-ons.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
Note that it is necessary to manually enable these
|
||||||
|
extensions inside Firefox after the first installation.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
Extensions listed here will only be available in Firefox
|
||||||
|
profiles managed through the
|
||||||
|
<link linkend="opt-programs.firefox.profiles">programs.firefox.profiles</link>
|
||||||
|
option. This is due to recent changes in the way Firefox
|
||||||
|
handles extension side-loading.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
profiles = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule ({config, name, ...}: {
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = "Profile name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
id = mkOption {
|
||||||
|
type = types.ints.unsigned;
|
||||||
|
default = 0;
|
||||||
|
description = ''
|
||||||
|
Profile ID. This should be set to a unique number per profile.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = with types; attrsOf (either bool (either int str));
|
||||||
|
default = {};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"browser.startup.homepage" = "https://nixos.org";
|
||||||
|
"browser.search.region" = "GB";
|
||||||
|
"browser.search.isUS" = false;
|
||||||
|
"distribution.searchplugins.defaultLocale" = "en-GB";
|
||||||
|
"general.useragent.locale" = "en-GB";
|
||||||
|
"browser.bookmarks.showMobileBookmarks" = true;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = "Attribute set of Firefox preferences.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Extra preferences to add to <filename>user.js</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
userChrome = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = "Custom Firefox user chrome CSS.";
|
||||||
|
example = ''
|
||||||
|
/* Hide tab bar in FF Quantum */
|
||||||
|
@-moz-document url("chrome://browser/content/browser.xul") {
|
||||||
|
#TabsToolbar {
|
||||||
|
visibility: collapse !important;
|
||||||
|
margin-bottom: 21px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"] #sidebar-header {
|
||||||
|
visibility: collapse !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
userContent = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = "Custom Firefox user content CSS.";
|
||||||
|
example = ''
|
||||||
|
/* Hide scrollbar in FF Quantum */
|
||||||
|
*{scrollbar-width:none !important}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
path = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = "Profile path.";
|
||||||
|
};
|
||||||
|
|
||||||
|
isDefault = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = config.id == 0;
|
||||||
|
defaultText = "true if profile ID is 0";
|
||||||
|
description = "Whether this is a default profile.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
default = {};
|
||||||
|
description = "Attribute set of Firefox profiles.";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableAdobeFlash = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable the unfree Adobe Flash plugin.";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableGnomeExtensions = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable the GNOME Shell native host connector. Note, you
|
||||||
|
also need to set the NixOS option
|
||||||
|
<literal>services.gnome3.chrome-gnome-shell.enable</literal> to
|
||||||
|
<literal>true</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
(
|
||||||
|
let
|
||||||
|
defaults =
|
||||||
|
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
|
||||||
|
in {
|
||||||
|
assertion = cfg.profiles == {} || length defaults == 1;
|
||||||
|
message =
|
||||||
|
"Must have exactly one default Firefox profile but found "
|
||||||
|
+ toString (length defaults)
|
||||||
|
+ optionalString (length defaults > 1)
|
||||||
|
(", namely " + concatStringsSep ", " defaults);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
let
|
||||||
|
duplicates =
|
||||||
|
filterAttrs (_: v: length v != 1)
|
||||||
|
(zipAttrs
|
||||||
|
(mapAttrsToList (n: v: { "${toString v.id}" = n; })
|
||||||
|
(cfg.profiles)));
|
||||||
|
|
||||||
|
mkMsg = n: v: " - ID ${n} is used by ${concatStringsSep ", " v}";
|
||||||
|
in {
|
||||||
|
assertion = duplicates == {};
|
||||||
|
message =
|
||||||
|
"Must not have Firefox profiles with duplicate IDs but\n"
|
||||||
|
+ concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages =
|
||||||
|
let
|
||||||
|
# The configuration expected by the Firefox wrapper.
|
||||||
|
fcfg = {
|
||||||
|
enableAdobeFlash = cfg.enableAdobeFlash;
|
||||||
|
enableGnomeExtensions = cfg.enableGnomeExtensions;
|
||||||
|
};
|
||||||
|
|
||||||
|
# A bit of hackery to force a config into the wrapper.
|
||||||
|
browserName = cfg.package.browserName
|
||||||
|
or (builtins.parseDrvName cfg.package.name).name;
|
||||||
|
|
||||||
|
# The configuration expected by the Firefox wrapper builder.
|
||||||
|
bcfg = setAttrByPath [browserName] fcfg;
|
||||||
|
|
||||||
|
package =
|
||||||
|
if isDarwin then
|
||||||
|
cfg.package
|
||||||
|
else if versionAtLeast config.home.stateVersion "19.09" then
|
||||||
|
cfg.package.override { cfg = fcfg; }
|
||||||
|
else
|
||||||
|
(pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
|
||||||
|
in
|
||||||
|
[ package ];
|
||||||
|
|
||||||
|
home.file = mkMerge (
|
||||||
|
[{
|
||||||
|
"${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != []) {
|
||||||
|
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
"${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) {
|
||||||
|
text = profilesIni;
|
||||||
|
};
|
||||||
|
}]
|
||||||
|
++ flip mapAttrsToList cfg.profiles (_: profile: {
|
||||||
|
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
|
||||||
|
mkIf (profile.userChrome != "") {
|
||||||
|
text = profile.userChrome;
|
||||||
|
};
|
||||||
|
|
||||||
|
"${profilesPath}/${profile.path}/chrome/userContent.css" =
|
||||||
|
mkIf (profile.userContent != "") {
|
||||||
|
text = profile.userContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
"${profilesPath}/${profile.path}/user.js" =
|
||||||
|
mkIf (profile.settings != {} || profile.extraConfig != "") {
|
||||||
|
text = mkUserJs profile.settings profile.extraConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
"${profilesPath}/${profile.path}/extensions" = mkIf (cfg.extensions != []) {
|
||||||
|
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
|
||||||
|
recursive = true;
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
460
third_party/home-manager/modules/programs/fish.nix
vendored
Normal file
460
third_party/home-manager/modules/programs/fish.nix
vendored
Normal file
|
@ -0,0 +1,460 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.fish;
|
||||||
|
|
||||||
|
pluginModule = types.submodule ({ config, ... }: {
|
||||||
|
options = {
|
||||||
|
src = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Path to the plugin folder.
|
||||||
|
</para><para>
|
||||||
|
Relevant pieces will be added to the fish function path and
|
||||||
|
the completion path. The <filename>init.fish</filename> and
|
||||||
|
<filename>key_binding.fish</filename> files are sourced if
|
||||||
|
they exist.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The name of the plugin.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
functionModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
body = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
The function body.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
argumentNames = mkOption {
|
||||||
|
type = with types; nullOr (either str (listOf str));
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Assigns the value of successive command line arguments to the names
|
||||||
|
given.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
description = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
A description of what the function does, suitable as a completion
|
||||||
|
description.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
wraps = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Causes the function to inherit completions from the given wrapped
|
||||||
|
command.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onEvent = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Tells fish to run this function when the specified named event is
|
||||||
|
emitted. Fish internally generates named events e.g. when showing the
|
||||||
|
prompt.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onVariable = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Tells fish to run this function when the specified variable changes
|
||||||
|
value.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onJobExit = mkOption {
|
||||||
|
type = with types; nullOr (either str int);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Tells fish to run this function when the job with the specified group
|
||||||
|
ID exits. Instead of a PID, the stringer <literal>caller</literal> can
|
||||||
|
be specified. This is only legal when in a command substitution, and
|
||||||
|
will result in the handler being triggered by the exit of the job
|
||||||
|
which created this command substitution.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onProcessExit = mkOption {
|
||||||
|
type = with types; nullOr (either str int);
|
||||||
|
default = null;
|
||||||
|
example = "$fish_pid";
|
||||||
|
description = ''
|
||||||
|
Tells fish to run this function when the fish child process with the
|
||||||
|
specified process ID exits. Instead of a PID, for backwards
|
||||||
|
compatibility, <literal>%self</literal> can be specified as an alias
|
||||||
|
for <literal>$fish_pid</literal>, and the function will be run when
|
||||||
|
the current fish instance exits.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onSignal = mkOption {
|
||||||
|
type = with types; nullOr (either str int);
|
||||||
|
default = null;
|
||||||
|
example = [ "SIGHUP" "HUP" 1 ];
|
||||||
|
description = ''
|
||||||
|
Tells fish to run this function when the specified signal is
|
||||||
|
delievered. The signal can be a signal number or signal name.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
noScopeShadowing = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Allows the function to access the variables of calling functions.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
inheritVariable = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Snapshots the value of the specified variable and defines a local
|
||||||
|
variable with that same name and value when the function is defined.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
abbrsStr = concatStringsSep "\n"
|
||||||
|
(mapAttrsToList (k: v: "abbr --add --global -- ${k} ${escapeShellArg v}")
|
||||||
|
cfg.shellAbbrs);
|
||||||
|
|
||||||
|
aliasesStr = concatStringsSep "\n"
|
||||||
|
(mapAttrsToList (k: v: "alias ${k} ${escapeShellArg v}") cfg.shellAliases);
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
programs.fish = {
|
||||||
|
enable = mkEnableOption "fish, the friendly interactive shell";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.fish;
|
||||||
|
defaultText = literalExample "pkgs.fish";
|
||||||
|
description = ''
|
||||||
|
The fish package to install. May be used to change the version.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
shellAliases = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
shellAbbrs = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
l = "less";
|
||||||
|
gco = "git checkout";
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
An attribute set that maps aliases (the top level attribute names
|
||||||
|
in this option) to abbreviations. Abbreviations are expanded with
|
||||||
|
the longer phrase after they are entered.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
shellInit = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Shell script code called during fish shell
|
||||||
|
initialisation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
loginShellInit = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Shell script code called during fish login shell
|
||||||
|
initialisation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
interactiveShellInit = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Shell script code called during interactive fish shell
|
||||||
|
initialisation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
promptInit = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Shell script code used to initialise fish prompt.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish.plugins = mkOption {
|
||||||
|
type = types.listOf pluginModule;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample ''
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name = "z";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "jethrokuan";
|
||||||
|
repo = "z";
|
||||||
|
rev = "ddeb28a7b6a1f0ec6dae40c636e5ca4908ad160a";
|
||||||
|
sha256 = "0c5i7sdrsp0q3vbziqzdyqn4fmp235ax4mn4zslrswvn8g3fvdyh";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# oh-my-fish plugins are stored in their own repositories, which
|
||||||
|
# makes them simple to import into home-manager.
|
||||||
|
{
|
||||||
|
name = "fasd";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "oh-my-fish";
|
||||||
|
repo = "plugin-fasd";
|
||||||
|
rev = "38a5b6b6011106092009549e52249c6d6f501fba";
|
||||||
|
sha256 = "06v37hqy5yrv5a6ssd1p3cjd9y3hnp19d3ab7dag56fs1qmgyhbs";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
The plugins to source in
|
||||||
|
<filename>conf.d/99plugins.fish</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish.functions = mkOption {
|
||||||
|
type = with types; attrsOf (either lines functionModule);
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
__fish_command_not_found_handler = {
|
||||||
|
body = "__fish_default_command_not_found_handler $argv[1]";
|
||||||
|
onEvent = "fish_command_not_found";
|
||||||
|
};
|
||||||
|
|
||||||
|
gitignore = "curl -sL https://www.gitignore.io/api/$argv";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Basic functions to add to fish. For more information see
|
||||||
|
<link xlink:href="https://fishshell.com/docs/current/cmds/function.html"/>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
|
{
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
|
xdg.dataFile."fish/home-manager_generated_completions".source = let
|
||||||
|
# paths later in the list will overwrite those already linked
|
||||||
|
destructiveSymlinkJoin = args_@{ name, paths, preferLocalBuild ? true
|
||||||
|
, allowSubstitutes ? false, postBuild ? "", ... }:
|
||||||
|
let
|
||||||
|
args = removeAttrs args_ [ "name" "postBuild" ] // {
|
||||||
|
# pass the defaults
|
||||||
|
inherit preferLocalBuild allowSubstitutes;
|
||||||
|
};
|
||||||
|
in pkgs.runCommand name args ''
|
||||||
|
mkdir -p $out
|
||||||
|
for i in $paths; do
|
||||||
|
if [ -z "$(find $i -prune -empty)" ]; then
|
||||||
|
cp -srf $i/* $out
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
${postBuild}
|
||||||
|
'';
|
||||||
|
|
||||||
|
generateCompletions = package:
|
||||||
|
pkgs.runCommand "${package.name}-fish-completions" {
|
||||||
|
src = package;
|
||||||
|
nativeBuildInputs = [ pkgs.python2 ];
|
||||||
|
buildInputs = [ cfg.package ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
} ''
|
||||||
|
mkdir -p $out
|
||||||
|
if [ -d $src/share/man ]; then
|
||||||
|
find $src/share/man -type f \
|
||||||
|
| xargs python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out \
|
||||||
|
> /dev/null
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in destructiveSymlinkJoin {
|
||||||
|
name = "${config.home.username}-fish-completions";
|
||||||
|
paths =
|
||||||
|
let cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
|
||||||
|
in map generateCompletions (sort cmp config.home.packages);
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish.interactiveShellInit = ''
|
||||||
|
# add completions generated by Home Manager to $fish_complete_path
|
||||||
|
begin
|
||||||
|
set -l joined (string join " " $fish_complete_path)
|
||||||
|
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
|
||||||
|
set -l post_joined (string replace $prev_joined "" $joined)
|
||||||
|
set -l prev (string split " " (string trim $prev_joined))
|
||||||
|
set -l post (string split " " (string trim $post_joined))
|
||||||
|
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.configFile."fish/config.fish".text = ''
|
||||||
|
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated
|
||||||
|
# automatically by home-manager.
|
||||||
|
|
||||||
|
# if we haven't sourced the general config, do it
|
||||||
|
if not set -q __fish_general_config_sourced
|
||||||
|
|
||||||
|
set -p fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions
|
||||||
|
fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null
|
||||||
|
set -e fish_function_path[1]
|
||||||
|
|
||||||
|
${cfg.shellInit}
|
||||||
|
# and leave a note so we don't source this config section again from
|
||||||
|
# this very shell (children will source the general config anew)
|
||||||
|
set -g __fish_general_config_sourced 1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# if we haven't sourced the login config, do it
|
||||||
|
status --is-login; and not set -q __fish_login_config_sourced
|
||||||
|
and begin
|
||||||
|
|
||||||
|
# Login shell initialisation
|
||||||
|
${cfg.loginShellInit}
|
||||||
|
|
||||||
|
# and leave a note so we don't source this config section again from
|
||||||
|
# this very shell (children will source the general config anew)
|
||||||
|
set -g __fish_login_config_sourced 1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# if we haven't sourced the interactive config, do it
|
||||||
|
status --is-interactive; and not set -q __fish_interactive_config_sourced
|
||||||
|
and begin
|
||||||
|
|
||||||
|
# Abbreviations
|
||||||
|
${abbrsStr}
|
||||||
|
|
||||||
|
# Aliases
|
||||||
|
${aliasesStr}
|
||||||
|
|
||||||
|
# Prompt initialisation
|
||||||
|
${cfg.promptInit}
|
||||||
|
|
||||||
|
# Interactive shell intialisation
|
||||||
|
${cfg.interactiveShellInit}
|
||||||
|
|
||||||
|
# and leave a note so we don't source this config section again from
|
||||||
|
# this very shell (children will source the general config anew,
|
||||||
|
# allowing configuration changes in, e.g, aliases, to propagate)
|
||||||
|
set -g __fish_interactive_config_sourced 1
|
||||||
|
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
xdg.configFile = mapAttrs' (name: def: {
|
||||||
|
name = "fish/functions/${name}.fish";
|
||||||
|
value = {
|
||||||
|
text = let
|
||||||
|
modifierStr = n: v: optional (v != null) ''--${n}="${toString v}"'';
|
||||||
|
modifierStrs = n: v: optional (v != null) "--${n}=${toString v}";
|
||||||
|
modifierBool = n: v: optional (v != null && v) "--${n}";
|
||||||
|
|
||||||
|
mods = with def;
|
||||||
|
modifierStr "description" description ++ modifierStr "wraps" wraps
|
||||||
|
++ modifierStr "on-event" onEvent
|
||||||
|
++ modifierStr "on-variable" onVariable
|
||||||
|
++ modifierStr "on-job-exit" onJobExit
|
||||||
|
++ modifierStr "on-process-exit" onProcessExit
|
||||||
|
++ modifierStr "on-signal" onSignal
|
||||||
|
++ modifierBool "no-scope-shadowing" noScopeShadowing
|
||||||
|
++ modifierStr "inherit-variable" inheritVariable
|
||||||
|
++ modifierStrs "argument-names" argumentNames;
|
||||||
|
|
||||||
|
modifiers = if isAttrs def then " ${toString mods}" else "";
|
||||||
|
body = if isAttrs def then def.body else def;
|
||||||
|
in ''
|
||||||
|
function ${name}${modifiers}
|
||||||
|
${body}
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}) cfg.functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Each plugin gets a corresponding conf.d/plugin-NAME.fish file to load
|
||||||
|
# in the paths and any initialization scripts.
|
||||||
|
(mkIf (length cfg.plugins > 0) {
|
||||||
|
xdg.configFile = mkMerge ((map (plugin: {
|
||||||
|
"fish/conf.d/plugin-${plugin.name}.fish".text = ''
|
||||||
|
# Plugin ${plugin.name}
|
||||||
|
set -l plugin_dir ${plugin.src}
|
||||||
|
|
||||||
|
# Set paths to import plugin components
|
||||||
|
if test -d $plugin_dir/functions
|
||||||
|
set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1]
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -d $plugin_dir/completions
|
||||||
|
set fish_complete_path $fish_complete_path[1] $plugin_dir/completions $fish_complete_path[2..-1]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Source initialization code if it exists.
|
||||||
|
if test -d $plugin_dir/conf.d
|
||||||
|
for f in $plugin_dir/conf.d/*.fish
|
||||||
|
source $f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -f $plugin_dir/key_bindings.fish
|
||||||
|
source $plugin_dir/key_bindings.fish
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -f $plugin_dir/init.fish
|
||||||
|
source $plugin_dir/init.fish
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
}) cfg.plugins));
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
146
third_party/home-manager/modules/programs/fzf.nix
vendored
Normal file
146
third_party/home-manager/modules/programs/fzf.nix
vendored
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.fzf;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.programs.fzf = {
|
||||||
|
enable = mkEnableOption "fzf - a command-line fuzzy finder";
|
||||||
|
|
||||||
|
defaultCommand = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "fd --type f";
|
||||||
|
description = ''
|
||||||
|
The command that gets executed as the default source for fzf
|
||||||
|
when running.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "--height 40%" "--border" ];
|
||||||
|
description = ''
|
||||||
|
Extra command line options given to fzf by default.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
fileWidgetCommand = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "fd --type f";
|
||||||
|
description = ''
|
||||||
|
The command that gets executed as the source for fzf for the
|
||||||
|
CTRL-T keybinding.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
fileWidgetOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "--preview 'head {}'" ];
|
||||||
|
description = ''
|
||||||
|
Command line options for the CTRL-T keybinding.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
changeDirWidgetCommand = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "fd --type d";
|
||||||
|
description = ''
|
||||||
|
The command that gets executed as the source for fzf for the
|
||||||
|
ALT-C keybinding.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
changeDirWidgetOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "--preview 'tree -C {} | head -200'" ];
|
||||||
|
description = ''
|
||||||
|
Command line options for the ALT-C keybinding.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
historyWidgetCommand = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The command that gets executed as the source for fzf for the
|
||||||
|
CTRL-R keybinding.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
historyWidgetOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "--sort" "--exact" ];
|
||||||
|
description = ''
|
||||||
|
Command line options for the CTRL-R keybinding.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = [ pkgs.fzf ];
|
||||||
|
|
||||||
|
home.sessionVariables = mapAttrs (n: v: toString v)
|
||||||
|
(filterAttrs (n: v: v != [ ] && v != null) {
|
||||||
|
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
|
||||||
|
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
|
||||||
|
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
|
||||||
|
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
|
||||||
|
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
|
||||||
|
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
|
||||||
|
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
|
||||||
|
FZF_DEFAULT_OPTS = cfg.defaultOptions;
|
||||||
|
});
|
||||||
|
|
||||||
|
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||||
|
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||||
|
. ${pkgs.fzf}/share/fzf/completion.bash
|
||||||
|
. ${pkgs.fzf}/share/fzf/key-bindings.bash
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||||
|
if [[ $options[zle] = on ]]; then
|
||||||
|
. ${pkgs.fzf}/share/fzf/completion.zsh
|
||||||
|
. ${pkgs.fzf}/share/fzf/key-bindings.zsh
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||||
|
source ${pkgs.fzf}/share/fzf/key-bindings.fish && fzf_key_bindings
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
49
third_party/home-manager/modules/programs/getmail-accounts.nix
vendored
Normal file
49
third_party/home-manager/modules/programs/getmail-accounts.nix
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options.getmail = {
|
||||||
|
enable = mkEnableOption "the getmail mail retriever for this account";
|
||||||
|
|
||||||
|
destinationCommand = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "\${pkgs.maildrop}/bin/maildrop";
|
||||||
|
description = ''
|
||||||
|
Specify a command delivering the incoming mail to your maildir.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mailboxes = mkOption {
|
||||||
|
type = types.nonEmptyListOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "INBOX" "INBOX.spam" ];
|
||||||
|
description = ''
|
||||||
|
A non-empty list of mailboxes. To download all mail you can
|
||||||
|
use the <literal>ALL</literal> mailbox.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
delete = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable if you want to delete read messages from the server. Most
|
||||||
|
users should either enable <literal>delete</literal> or disable
|
||||||
|
<literal>readAll</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
readAll = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Enable if you want to fetch all, even the read messages from the
|
||||||
|
server. Most users should either enable <literal>delete</literal> or
|
||||||
|
disable <literal>readAll</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
63
third_party/home-manager/modules/programs/getmail.nix
vendored
Normal file
63
third_party/home-manager/modules/programs/getmail.nix
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
accounts =
|
||||||
|
filter (a: a.getmail.enable) (attrValues config.accounts.email.accounts);
|
||||||
|
|
||||||
|
renderAccountConfig = account:
|
||||||
|
with account;
|
||||||
|
let
|
||||||
|
passCmd = concatMapStringsSep ", " (x: "'${x}'") passwordCommand;
|
||||||
|
renderedMailboxes =
|
||||||
|
concatMapStringsSep ", " (x: "'${x}'") getmail.mailboxes;
|
||||||
|
retrieverType = if imap.tls.enable then
|
||||||
|
"SimpleIMAPSSLRetriever"
|
||||||
|
else
|
||||||
|
"SimpleIMAPRetriever";
|
||||||
|
destination = if getmail.destinationCommand != null then {
|
||||||
|
destinationType = "MDA_external";
|
||||||
|
destinationPath = getmail.destinationCommand;
|
||||||
|
} else {
|
||||||
|
destinationType = "Maildir";
|
||||||
|
destinationPath = "${maildir.absPath}/";
|
||||||
|
};
|
||||||
|
renderGetmailBoolean = v: if v then "true" else "false";
|
||||||
|
in ''
|
||||||
|
# Generated by Home-Manager.
|
||||||
|
[retriever]
|
||||||
|
type = ${retrieverType}
|
||||||
|
server = ${imap.host}
|
||||||
|
${optionalString (imap.port != null) "port = ${toString imap.port}"}
|
||||||
|
username = ${userName}
|
||||||
|
password_command = (${passCmd})
|
||||||
|
mailboxes = ( ${renderedMailboxes} )
|
||||||
|
|
||||||
|
[destination]
|
||||||
|
type = ${destination.destinationType}
|
||||||
|
path = ${destination.destinationPath}
|
||||||
|
|
||||||
|
[options]
|
||||||
|
delete = ${renderGetmailBoolean getmail.delete}
|
||||||
|
read_all = ${renderGetmailBoolean getmail.readAll}
|
||||||
|
'';
|
||||||
|
getmailEnabled = length (filter (a: a.getmail.enable) accounts) > 0;
|
||||||
|
# Watch out! This is used by the getmail.service too!
|
||||||
|
renderConfigFilepath = a:
|
||||||
|
".getmail/getmail${if a.primary then "rc" else a.name}";
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
accounts.email.accounts = mkOption {
|
||||||
|
type = with types; attrsOf (submodule (import ./getmail-accounts.nix));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf getmailEnabled {
|
||||||
|
home.file = foldl' (a: b: a // b) { }
|
||||||
|
(map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; })
|
||||||
|
accounts);
|
||||||
|
};
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue