Compare commits

...

168 Commits

Author SHA1 Message Date
Robert Helgesson
b78b5fa4a0 firefox: force extension file linking
(cherry picked from commit b9d4f55228)
2020-04-09 11:42:55 +02:00
Andrei Shumailov
7aa2bd5bf4 firefox: backport extensions fix to release-19.09 2020-04-09 11:42:09 +02:00
Robert Helgesson
57f3b72d3a files: add force flag
Enabling this flag for a `home.file` entry causes the target to be
unconditionally overwritten. The option is not visible in
documentation for now and shouldn't be relied on for general use.

(cherry picked from commit 37694e9f51)
2020-04-09 11:29:54 +02:00
Robert Helgesson
0d1ca254d0 readline: fix example
(cherry picked from commit a4a07ba996)
2020-02-16 18:10:00 +01:00
Robert Helgesson
3166ae7993 readline: add variables option
Also add a basic test case.

(cherry picked from commit 284b8d94d4)
2020-02-16 18:08:26 +01:00
Vojtěch Káně
2b71762384 readline: add module
Add basic readline configuration (~/.inputrc) management.

(cherry picked from commit bb5dea02b9)
2020-02-16 18:08:07 +01:00
dind
1261ffee91 termite: fix scrollbar position option description
Signed-off-by: dind <lewdavatar@gmail.com>
(cherry picked from commit d8d5f85ab7)
2020-02-16 18:05:32 +01:00
Robert Helgesson
f5c9303ced mpv: allow string values in scripts list
Fixes #976

(cherry picked from commit 297ed97166)
2020-01-18 23:53:20 +01:00
Ross A. Baker
8d663335eb lorri: add gitMinimal to daemon path
Fixes https://github.com/target/lorri/issues/255 when the service is
installed through home-manager.

PR #975

(cherry picked from commit 0fce533e70)
2020-01-11 17:24:16 +01:00
Robert Helgesson
72400b2c29 contributing.md: minor update
This elaborates the instructions for the news entry of new modules.

(cherry picked from commit ef6674d1d1)
2020-01-11 17:24:15 +01:00
risson
1d38ffc372 neovim: un-deprecate the configure option (#978)
The `programs.neovim.configure` option is consistent with NixOS's
`wrapNeovim` and offers features not supported by the `extraConfig`
and `plugins` option pair.

Closes #971

(cherry picked from commit 1b7b1bc294)

Co-authored-by: Wael Nasreddine <wael.nasreddine@gmail.com>
2020-01-09 15:08:26 +01:00
oxalica
10d2c4e7e4 home-manager: fix pass-through option passing
This resolves, e.g., the errors occurring when passing empty arguments
like `--option builders ''`.

Closes #967

(cherry picked from commit 7c30831e8f)
2020-01-06 11:28:39 +01:00
Robert Helgesson
b646623a39 kakoune: prepend extra configuration with newline (#870)
Fixes #869

(cherry picked from commit 1b987952b5)
2020-01-06 11:28:06 +01:00
Robert Helgesson
af2303526d install: add state version to initial configuration
This sets the state version in recent installs to the latest released
version. It is beneficial for people to be aware of this option and it
is also good to help new users get a more recent setup.

(cherry picked from commit 54f367b119)
2019-12-31 09:31:24 +01:00
Gregory Oakes
11f8b1c1ce random-background: add bgSupport documentation
On NixOS it is necessary to set `bgSupport = true` when creating a
Home Manager desktop manager session. Otherwise NixOS will add code
that sets the background, overriding the effort made by the
`random-background` module.

Fixes #955
Pull request #956

(cherry picked from commit a12a8f7977)
2019-12-31 09:31:09 +01:00
Robert Helgesson
94c0367dd8 blueman-applet: minor cleanup of enable option
In particular use proper DocBook format in description.

(cherry picked from commit 8d14ffbe88)
2019-12-28 09:46:24 +01:00
Cabia Rangris
24c6d8dfc5 blueman: update advice for removing error message
The old method for hiding the error no longer works in NixOS 19.09,
and ends up breaking blueman-applet entirely. Enable the NixOS service
instead.

Pull request #950

(cherry picked from commit a5d3d6f665)
2019-12-28 09:46:23 +01:00
arcnmx
8fb1ed5919 systemd: fix degraded warning
(cherry picked from commit 8abaa025ec)
2019-12-28 09:45:23 +01:00
Robert Helgesson
829b688827 mbsync: skip maildir creation if no account is defined
Fixes #937

(cherry picked from commit 621c98f15a)
2019-12-28 09:45:22 +01:00
adisbladis
9e69b0d8b9 emacs: Don't use emacsPackagesNg
It's deprecated and since Nixos 19.09 it's an alias to `emacsPackages`.

(cherry picked from commit 49852220f9)
2019-12-28 09:44:22 +01:00
Robert Helgesson
9bdfdfe14e lorri: restrict news entry to Linux
(cherry picked from commit 9e716025b6)
2019-12-10 21:00:02 +01:00
Tobias Happ
b41fc9e6e8 lorri: add service
(cherry picked from commit 286dd9b308)

Fixes #944
2019-12-10 20:59:29 +01:00
Robert Helgesson
5e7a4c55ed gpg: remove dummy gnupg package from test
It caused evaluation issues related to systemd.

Fixes #934

(cherry picked from commit ed9a6e34ad)
2019-12-08 23:05:44 +01:00
leotaku
22076437f3 mpdris2: improve service description
In particular, make sure the systemd service actually starts.

(cherry picked from commit 34dc4a5e03)
2019-12-08 23:04:48 +01:00
Philip Stears
0d7b515a65 files: additional support for symlinked /nix
In the case where `/nix` is a link, for example, on macOS Catalina,
`builtins.storeDir` returns `/nix`, not the canonical location.

This causes tests on existing files to result in Home Manager thinking
those files are outside of the store.

This change uses `readlink` on the store path so that the tests work
as intended.

(cherry picked from commit 0e9b7aab3c)
2019-12-08 23:04:39 +01:00
Robert Helgesson
eafc8897e6 systemd: perform reload even in degraded state
This fixes #355, fixes #798, and fixes #909.

(cherry picked from commit 9781f3766d)
2019-12-08 23:04:38 +01:00
Anton Plotnikov
415f12bae5 files: update script to support linked Nix store
(cherry picked from commit b1dd373f5a)
2019-12-08 23:04:20 +01:00
pacien
06f1b13c21 Revert "astroid: require notmuch synchronize flags"
The Astroid program can work without this option,
which should be disabled when synchronising emails with muchsync for example.

This reverts commit fa3d1f98e0.

(cherry picked from commit 24dbac8da7)
2019-12-08 23:03:45 +01:00
pacien
a0653a7fb0 astroid: fix maildir folder paths
Using the absolute path of maildir folders is required for Astroid to save
messages in those.

(cherry picked from commit 18dc4153c7)
2019-12-08 23:03:44 +01:00
Robert Helgesson
dff5f07952 tests: reduce number of downloads
This replaces some derivation outputs by simple strings rather than
full Nix store paths. This removes the need to download the whole
derivation when all we need is a static string.

(cherry picked from commit 797c77a00a)
2019-10-29 23:11:09 +01:00
Robert Helgesson
b905de5833 doc: update version number in some places
(cherry picked from commit 6b6f759e7a)
2019-10-29 23:10:42 +01:00
Robert Helgesson
ecf333d27a faq: describe how to install Nixpkgs unstable packages
(cherry picked from commit a93d01fb4d)
2019-10-29 23:10:33 +01:00
dnsdhrj
e413a1408e getmail: fix port option type mismatch
Fixed type mismatch in commit 410f573226.
Added test case to ensure it works well.

(cherry picked from commit a177d0282f)
2019-10-29 23:10:23 +01:00
SoonHo Seo
06ae8792e7 getmail: add port option (#882)
Fixed bug where "accounts.email.accounts.<name>.imap.port" option was being ignored in getmail.

(cherry picked from commit 410f573226)
2019-10-29 23:10:15 +01:00
Robert Helgesson
f856c78a4a doc: finalize the 19.09 release notes
(cherry picked from commit ad52dbe044)
2019-10-09 21:08:09 +02:00
Robert Helgesson
31e84945d5 gitlab-ci: activate 19.09 branch 2019-10-07 20:06:52 +02:00
Robert Helgesson
8bddc1adab redshift: add assertion on latitude and longitude
These two options must be set if the provider is set to "manual".

Closes #841
2019-10-02 23:17:57 +02:00
David Wood
e8dbc35613 ssh: sockets forwards; remote and dynamic forwards
This commit adds support for forwarding paths rather than just
addresses/ports. It also adds options for specifying remote and
dynamic forwards.
2019-10-02 20:42:29 +02:00
Robert Helgesson
3d546e0d01 starship: use [[ in bash init 2019-10-01 21:56:56 +02:00
Robert Helgesson
a5999a62cd starship: fix fish syntax
Fixes #858
2019-10-01 21:21:36 +02:00
Robert Helgesson
761b3d0c12 rtorrent: add news entry 2019-09-26 23:47:41 +02:00
Mario Rodas
bdb4cf6c59 rtorrent: add module 2019-09-26 23:42:52 +02:00
Mario Rodas
7205d3b2d2 starship: add module 2019-09-26 23:19:39 +02:00
Mario Rodas
bb5c29107e git: add attributes support 2019-09-26 22:11:01 +09:00
Tobias Happ
3f45630180 xdg-mime-apps: add legacy mimeapps.list path
Although `.local/share/applications/mimeapps.list` is deprecated, this
file is still being read by some applications. To ensure compatibility
duplicate the file as recommended in
https://wiki.archlinux.org/index.php/XDG_MIME_Applications#mimeapps.list
2019-09-20 20:15:47 +02:00
Nazarii Bardiuk
51581b7e43 sxhkd: add service 2019-09-17 21:42:05 +02:00
Robert Helgesson
b0544c8cde mpd: allow path literal values in options
This allows specifying, for example, the music directory using path
literals without causing the directory to be copied to the Nix store.

Suggested-by: Silvan Mosberger <infinisil@icloud.com>
2019-09-16 21:43:53 +02:00
pacien
e347e932af xdg-mime-apps: add module 2019-09-15 17:21:42 +02:00
Robert Helgesson
0dfa1eef25 xsession: remove bashisms in start scripts
Fixes #836
2019-09-12 21:28:36 +02:00
pacien
aa5ba177cc xdg-user-dirs: add module 2019-09-11 20:03:32 +02:00
Bjarki Ágúst Guðmundsson
41f918499b gpg: sane default for throw-keyids option
The [throw-keyids](https://www.gnupg.org/gph/en/manual/r2110.html)
option "hides the receiver of the encrypted data as a countermeasure
against traffic analysis." However, it also slows down decryption, and
even breaks some applications; see e.g.
https://github.com/open-keychain/open-keychain/issues/626

I think the sane default would be to leave it off, just as it is off
by default in gpg. The typical user will probably not need this level
of security, and will probably prefer a better user experience (faster
decryption and compatibility with a wider range of applications).

Closes #838
2019-09-11 19:30:26 +02:00
Bruno Bigras
d3e316eec5 imapnotify: pkgs.mbsync -> pkgs.isync 2019-09-11 19:27:04 +02:00
Robert Helgesson
45ec65e1cc doc: convert some DocBook files to AsciiDoc 2019-09-07 09:29:24 +02:00
Hugo Geoffroy
05d91c5f50 mpd: use systemd journal instead of syslog
MPD is using syslog for its logging output, while it could directly
log to systemd's journal, as this daemon is primarily used as a
systemd user service. This change makes MPD log to standard output,
which is captured by systemd.

See https://github.com/NixOS/nixpkgs/pull/57608, which does the same
thing to NixOS's MPD service.
2019-09-05 22:38:35 +02:00
Robert Helgesson
d6b36f12ff keyboard: make the model option optional
Also, actually use it in the call to setxkbmap.
2019-09-05 01:56:14 +02:00
Robert Helgesson
824d31a21c keyboard: make layout and variant optional
Also default these options to `null` for state version ≥ 19.09.

Fixes #811

Suggested-by: Sean Marshallsay <srm.1708@gmail.com>
2019-09-05 01:56:06 +02:00
Robert Helgesson
0083087e01 xsession: verify setxkbmap service in test 2019-09-05 01:32:53 +02:00
Robert Helgesson
1923ac3358 rofi: add test to verify assertion 2019-09-04 12:52:14 +02:00
Robert Helgesson
698d0f0a44 polybar: restart service on failure 2019-09-03 23:51:23 +02:00
Alex Rice
ec0459e139 rofi: string -> str 2019-09-03 01:25:24 +01:00
dawidsowa
d5e73c39fc mpv: add scripts option 2019-09-02 18:23:17 +02:00
Robert Helgesson
a144c723a1 doc: surround name? with fancier characters 2019-09-01 21:28:40 +02:00
Robert Helgesson
a28614e65d git: deprecate extraConfig as string 2019-08-30 14:50:10 +02:00
Robert Helgesson
8ab1d22a82 home-manager: support --option argument
Fixes #784
2019-08-30 00:52:09 +02:00
Tobias Happ
b6289f7022 vim: always add sensible plugin 2019-08-29 23:18:11 +02:00
Robert Helgesson
875eea1330 systemd: fix unit examples
Closes #823
2019-08-29 19:12:39 +02:00
Robert Helgesson
7c76ae1814 manual: add nmd as a generation dependency
This is to allow network-less rebuilding of a generation after a
garbage collection.

Fixes #819
2019-08-28 20:36:11 +02:00
Tobias Happ
c142e5264d neovim: add extraConfig and plugins options 2019-08-28 12:35:48 +02:00
Tobias Happ
5d7eabb93f neovim: add finalPackage option as readOnly 2019-08-28 12:25:06 +02:00
Tobias Happ
f1146a1fef vim: allow packages to be passed as plugins
This change allows to pass custom packages into the `vim.plugins`
option.

Additionally this adds a deprecation warning and an error message if a
vim plugin is not present. This is an improvement because the user
gets instant feedback, when a plugin is not found.
2019-08-28 12:18:24 +02:00
Robert Helgesson
55b71223d4 Fix option defaultText when referencing packages
By using `literalExample` the documentation will show the option
default without surrounding quotes.
2019-08-28 00:14:22 +02:00
Robert Helgesson
db86bd6c01 doc: update nmd
Also perform scrubbing of `pkgs` since nmd no longer does this
automatically.
2019-08-27 23:40:52 +02:00
Robert Helgesson
13fa61744c doc: minor grammar fix 2019-08-26 23:14:51 +02:00
Robert Helgesson
8fe4e0879c home-manager: support a few extra pass-through options
These options will be passed through to the `nix-build` tool.
2019-08-26 23:06:36 +02:00
Robert Helgesson
6bec9547c6 home-manager: exit directly after printing help 2019-08-26 23:06:36 +02:00
Robert Helgesson
bfc28cacbe random-background: disable creation of ~/.fehbg file 2019-08-26 20:07:07 +02:00
Michael Fellinger
b2a787ca69 random-background: add option enableXinerama 2019-08-26 16:42:00 +02:00
Robert Helgesson
eb1b86a5ec Replace use of stdenv.shell by runtimeShell 2019-08-22 08:35:06 +02:00
Robert Helgesson
7159c293af gitlab-ci: fix deployment of manual 2019-08-21 23:00:04 +02:00
Robert Helgesson
eb0ccf7286 docs: use nmd for generating documentation
The nmd library is an external library for generating Nix-centric
documentation.
2019-08-21 20:35:59 +02:00
Robert Helgesson
35752e07fa kakoune: add missing period at end of description 2019-08-21 20:34:43 +02:00
Robert Helgesson
57925c50bf nixpkgs: improve description formatting slightly 2019-08-21 20:20:08 +02:00
Tobias Happ
0e871b490e ssh: add localForwards option for matchBlocks 2019-08-20 12:11:00 +02:00
Robert Helgesson
ed4f66185f Use types.port where applicable
This changes the type of all options that specify ports to
`types.port`. This type restricts values to between 0 and 65535.
2019-08-19 20:37:48 +02:00
leotaku
3d645c0ce1 kdeconnect: fix incorrect path to kdeconnectd 2019-08-18 23:35:53 +02:00
Robert Helgesson
8830b8d082 gitlab-ci: only run a single test
Unfortunately the full test suite seems to run out of memory on the
GitLab CI runner.
2019-08-18 21:33:56 +02:00
Robert Helgesson
73641e492c firefox: use wrapped package
This makes the

    programs.firefox.package

option take a pre-wrapped Firefox package as value if state version is
set to "19.09" or later. This should make the Firefox module work with
a wider range of Firefox packages.
2019-08-18 18:04:04 +02:00
Robert Helgesson
c2429ca0cf nix-darwin: pass on warnings to the system configuration 2019-08-18 17:37:26 +02:00
Robert Helgesson
7834ffbbf1 nixos: pass on warnings to the system configuration
Fixes #804
2019-08-18 17:35:42 +02:00
Robert Helgesson
fa82ced414 nixos: use non-deprecated fontconfig option 2019-08-18 17:35:41 +02:00
Tobias Happ
9cc30b18f7 nixos: add backup file extension and verbosity options 2019-08-18 17:19:39 +02:00
Tobias Happ
db0dfb4b08 dwm-status: add module 2019-08-18 16:23:31 +02:00
Robert Helgesson
5eed33ef08 emacs: document how to list available extra packages 2019-08-18 13:34:26 +02:00
pacien
31ae1bc2ff alot: fix account extraConfig section 2019-08-18 12:00:38 +02:00
Robert Helgesson
6932e6330e muchsync: add news entry 2019-08-17 14:25:15 +02:00
pacien
a124dae35a muchsync: add module 2019-08-17 20:08:11 +09:00
Tobias Happ
5203340b64 zsh: add envExtra option 2019-08-16 17:00:08 +09:00
Tobias Happ
ed0e40dee8 zsh: add initExtraBeforeCompInit config option
The new initExtraBeforeCompInit option enables the user to inject
commands in zshrc before compinit is executed.
2019-08-16 16:57:52 +09:00
Tobias Happ
8b759c24e6 bash: add logoutExtra option 2019-08-16 16:46:38 +09:00
paumr
1499b85ac6 alot: added send/draf_box to configuration file 2019-08-16 16:27:28 +09:00
Robert Helgesson
fcdab6a62d install: restrict to nix-shell
This commit adds a "build" command to the install derivation that
tells the user that `nix-shell` should be used.

A derivation attribute `shellHookOnly = true` is also added with the
intent to indicate that the shell hook is the entire point of the
derivation.
2019-08-15 23:23:43 +02:00
Tobias Happ
5c94538c7d numlock: set RemainAfterExit for numlockx.service 2019-08-15 11:53:34 +02:00
Tobias Happ
2eae9daae7 xsession: set RemainAfterExit for setxkbmap.service 2019-08-15 11:53:34 +02:00
Robert Helgesson
55c962fda2 gitlab-ci: trigger NUR update
This will trigger a CI job at

    https://gitlab.com/rycee/nur-expressions

that will update Home Manager in NUR.
2019-08-14 21:57:22 +02:00
Robert Helgesson
eb7f39f0aa gitlab-ci: add test stage 2019-08-14 17:38:47 +02:00
Nikita Uvarov
7310cfc557 zsh: fix completion when oh-my-zsh is enabled
enableCompletion option not only calls compinit but also adds
nix-zsh-completions package to home.packages which should still happen
even if oh-my-zsh is enabled.

The double compinit call will still be eliminated by moving guarding condition
down to the compinit call itself.

Fixes #771.
2019-08-09 15:02:31 +02:00
Nikita Uvarov
42ad0effdd zsh: create oh-my-zsh cache directory
Fixes #761.
2019-08-09 14:53:03 +02:00
paumr
bce63e4dff msmtp: add account option tls.fingerprint 2019-08-08 14:12:34 +02:00
Robert Helgesson
9302523d34 modules: fix module order 2019-08-08 13:53:22 +02:00
adisbladis
a9ecef1fa9 hound: add module 2019-08-08 13:52:27 +02:00
Evan Stoll
e59b8b0c37 numlock: add module
This adds an option `xsession.numlock` that enable the Num Lock key
when starting a graphical session.

Fixes #651
2019-08-08 13:25:01 +02:00
paumr
3743e8995a mbsync: fix use of certificatesFile
The `tls.certificatesFile` option may be set to a path but the
`CertificateFile` attribute should be a string.
2019-08-08 00:50:52 +02:00
Tobias Happ
4c9b40ca0e systemd-activate.rb: add start/stop/restart sockets 2019-08-07 23:12:30 +02:00
Robert Helgesson
d625186ce5 Remove use of network-online.target
This target is only available at the system level and has no effect on
user services.
2019-07-28 14:17:28 +02:00
Olli Helenius
caf3349f01 dconf: assume empty list value is a list of strings
Fixes #769.
2019-07-28 13:01:29 +03:00
Brian Hicks
6239ce20af nix-darwin: add docs 2019-07-26 23:45:05 +02:00
Robert Helgesson
54de0e1d79 xdg: create cache directory using keep file
We can avoid the activation block by instead creating a hidden file in
the directory.
2019-07-26 23:23:51 +02:00
Robert Helgesson
056443ccbd vscode: fix configuration path for Darwin
Fixes #737
2019-07-22 12:44:52 +02:00
Sebastian Zivota
7d68c46feb kakoune: add module 2019-07-17 22:40:26 +02:00
Shanon McQuay
734128930f skim: correctly name default options
skim uses SKIM_DEFAULT_OPTIONS rather than SKIM_DEFAULT_OPTS.
2019-07-17 21:53:30 +02:00
pacien
cc0cd538e6 taskwarrior-sync: add service module 2019-07-17 21:34:53 +02:00
Robert Helgesson
ca4f22be85 mbsync: use full path to mu in example 2019-07-17 10:02:35 +02:00
Robert Helgesson
c3520bfa52 mbsync: put extra config at the beginning
If it is at the end it will just end up applying to the last defined
section.

Fixes #748
2019-07-05 22:16:15 +02:00
Andreas Fehn
2029e104d4 xsuspender: write all options to config 2019-07-05 18:44:28 +02:00
Andreas Fehn
7c76f4a71f xsuspender: correctly name default section 2019-07-05 18:44:28 +02:00
arcnmx
95382060eb git: support nested section options
Closes #614
2019-07-04 16:51:28 +02:00
arcnmx
472d7731d6 git: support multiple values
Closes #614
2019-07-04 16:51:24 +02:00
Alexandre Héaumé
28f2dd612e broot: add module 2019-07-02 11:28:31 +02:00
Robert Helgesson
8467e7e10a getmail: restrict tests to Linux 2019-06-28 05:56:42 +02:00
Robert Helgesson
8f7cd53204 getmail: restrict platform to Linux
Need to limit this module to Linux since it uses systemd.
2019-06-27 20:04:18 +02:00
Róman Joost
68fe8623ad Address code review comments for getmail service
This patch started by addresssing the code review comments to close
https://github.com/rycee/home-manager/pull/290. However initiating a new
pull request it became clear, that home-manager changed significantly
since then.

This changes the initial pull request to be consistent with the email
account management in home-manager now. It also adds a simple test and support
for multiple accounts.
2019-06-27 07:48:09 +02:00
Mats Rauhala
8243cc0a5d getmail: add module 2019-06-27 07:48:09 +02:00
Robert Helgesson
95d55b8da1 xsession: add option importedVariables
This option lists the environment variables to be imported into the
systemd user session.

Also add a basic test of the xsession module.
2019-06-23 14:06:29 +02:00
Kai Wohlfahrt
f83c49baa3 gpg-agent: add sshcontrol configuration
This lets gpg-agent serve specific keys with authentication capability
as SSH keys
2019-06-18 13:37:19 +01:00
Jonas Holst Damtoft
cf0aad391c emacs: fix merging of extraPackages and overrides
Because `extraPackages` and `overrides` expect functions as values it
has not been possible to perform merges. This adds suitable types for
these options that allow reasonable merging.
2019-06-10 22:56:47 +02:00
Robert Helgesson
42732990cd home-manager: rewrite argument parsing
This rewrite allows "long options" but unfortunately does not allow
merged options such as `-vn`.

Also improve the home-manager manual page, with this it should include
all sub-commands and arguments.

Finally, include the home-manager manual page in the generated HTML
documentation.
2019-06-09 22:19:03 +02:00
Judson
f82246171b files: backup file collisions
When a configuration file would be written to an existing file, rather
than failing switch (and having the user have to move or delete those
files), move the files automatically to a new path.

Closes #585
2019-06-09 14:26:12 +02:00
Robert Helgesson
5b50eb18fc network-manager-applet: fix indentation 2019-06-09 12:13:11 +02:00
Sebastián Estrella
29824a8cf6 tmux: Disable confirmation prompt 2019-06-05 13:05:10 +09:00
Jaka Hudoklin
0db26fc3ab gpg: add module 2019-06-03 23:50:50 +02:00
Florian Klink
8991fe2e90 screen-locker: fix systemd unit
In particular, don't add trailing backslashes introduced by
`xautolockExtraOptions`. Systemd's unit file parser seems to have
gotten a bit stricter and with systemd 242, the trailing backslash
caused the next non-empty line to be ignored.

In that case, this was `[Section]`, so all subsequent settings were
mistakenly added to `[Service]`, causing them to be ignored entirely.

Simplify and fix this by using `concatStringsSep` to build a single
`ExecStart` line.
2019-06-02 23:29:37 +02:00
Sam Boosalis
2211770d8b home-manager: add Bash completion 2019-06-01 14:00:38 +02:00
Tad Fisher
e25113bcf0 browserpass: fix host/policy link sources 2019-06-01 12:24:30 +02:00
Robert Helgesson
e1535d2bd8 vscode: add example for extensions option 2019-05-31 21:37:28 +02:00
Robert Helgesson
d5bf68d77d xsuspender: limit module to Linux 2019-05-30 23:25:30 +02:00
Jaka Hudoklin
5b95fd0521 firefox: add profile options 2019-05-30 22:58:36 +02:00
Jaka Hudoklin
fcacba268d xsuspender: add module 2019-05-30 19:53:10 +02:00
Richard Marko
d7eaeaf636 random-background: add option display
This option parameterizes the `--bg-*` argument for feh.
2019-05-30 13:40:15 +02:00
Jaka Hudoklin
2e13c3cdfd nixos: use usercfg.home.username for username
Use `usercfg.home.username` for username instead of attribute name,
as this way we can change username regardless of the name of the attribute.
2019-05-25 14:26:49 +02:00
Robert Helgesson
d726afd9e4 imapnotify: specify notmuch configuration path 2019-05-19 01:08:06 +02:00
Roman Volosatovs
1480a6ca14 nix-darwin: actually install packages
Also apply assertions when using the nix-darwin module.

Closes #702
2019-05-19 00:36:35 +02:00
kalium
02a07f19a1 zsh: add autocd option 2019-05-17 09:39:26 +02:00
Tadeo Kondrak
d2ed39f103 alacritty: don't create file if settings is empty
Also add a few test cases for the alacritty module.
2019-05-14 23:53:10 +02:00
Tadeo Kondrak
8b15f18993 mpv: add module 2019-05-08 00:42:18 +02:00
Robert Helgesson
b256e3a44f fontconfig: fix build error
This fixes a build error occurring when building a configuration
having fontconfig enabled and `home.packages` only containing one
package installing things to `/lib`.

Also adds a number of test cases to verify the fontconfig cache
generation functionality.

Fixes #703
2019-05-06 00:44:23 +02:00
Robert Helgesson
939274281a tests: bump nmt version 2019-05-06 00:17:30 +02:00
Jos van Bakel
be4b100ae5 rsibreak: add module 2019-05-05 01:56:53 +02:00
Robert Helgesson
f99d4ba7c4 flameshot: fix service description 2019-05-01 13:13:38 +02:00
Robert Helgesson
1f4e9681f7 fontconfig: fix error on missing cachedir file
Fixes #699
2019-04-30 18:43:58 +02:00
Will Dietz
f56256f488 files: fix find invocation broken in c94eaa0e
Add parens to expression so the `-exec` includes files matching both.

Otherwise (before this change) the `-exec` is only invoked for
links (`-type l`):

    file or (link -> doexec)
      =>
    (file or link) -> doexec
2019-04-30 15:07:47 +02:00
Robert Helgesson
f18e2933d4 fontconfig: generate font cache files
Also deprecates the `fonts.fontconfig.enableProfileFonts` option. The
configuration is now always generated if `fonts.fontconfig.enable` is
set.

Fixes #520
2019-04-30 00:28:07 +02:00
Nick Hu
2f819d1647 imapnotify: add service 2019-04-29 00:05:02 +02:00
Mario Rodas
821df406c9 z-lua: add module 2019-04-28 23:57:31 +02:00
Robert Helgesson
3bb7c75db3 home-manager: add uninstall command 2019-04-28 18:40:41 +02:00
Robert Helgesson
c94eaa0e6c files: replace unnecessary use of xargs 2019-04-27 13:48:57 +02:00
Robert Helgesson
a16439e38e firefox: deprecate Google Talk and IcedTea options 2019-04-27 10:01:30 +02:00
Robert Helgesson
b6e613c771 Fix type of various sessionVariables options
Unfortunately, using `attrsOf` is not possible since it results in too
eager evaluation. In particular, the

    home.sessionVariables = {
      FOO = "Hello";
      BAR = "${config.home.sessionVariables.FOO} World!";
    };

example will cause an infinite recursion.

This commit restores the option type of

- `home.sessionVariables`,
- `pam.sessionVariables`,
- `programs.bash.sessionVariables`, and
- `programs.zsh.sessionVariables`

to `attrs`. It also adds test cases for the above options to avoid
regressions.

Fixes #659
2019-04-27 01:07:09 +02:00
Robert Hensing
c5f230e682 vscode.haskell: add module
- Haskell IDE Engine integration
- Syntax highlighting
2019-04-27 01:00:57 +02:00
198 changed files with 6766 additions and 1414 deletions

View File

@@ -1,6 +1,18 @@
image: nixos/nix:latest
stages:
- test
- deploy
Run tests:
stage: test
script:
- nix-shell tests -A run.files-text
only:
- release-19.09
pages:
stage: deploy
script:
- mkdir -p ~/.config/nixpkgs
- echo '{ manual.html.enable = true; }' > ~/.config/nixpkgs/home.nix
@@ -12,3 +24,14 @@ pages:
- public
only:
- master
Deploy NUR:
stage: deploy
variables:
HM_BRANCH: $CI_COMMIT_REF_NAME
HM_COMMIT_SHA: $CI_COMMIT_SHA
trigger:
project: rycee/nur-expressions
branch: master
only:
- release-19.09

View File

@@ -139,15 +139,18 @@ If you do have a change worthy of a news entry then please add one in
> use 'services.myservice.bar' instead.
- A new module, say `foo.nix`, should always include a news entry
(without any condition) that has a message along the lines of
that has a message along the lines of
> A new service is available: 'services.foo'.
> A new module is available: 'services.foo'.
or
If the module is platform specific, e.g., a service module using
systemd, then a condition like
> A new program configuration is available: 'program.foo'.
```
condition = hostPlatform.isLinux;
```
depending on the type of module.
should be added.
[open issues]: https://github.com/rycee/home-manager/issues
[new issue]: https://github.com/rycee/home-manager/issues/new

30
FAQ.md
View File

@@ -119,3 +119,33 @@ The solution on NixOS is to add
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 then you can import the
unstable Nixpkgs and refer to its packages within your configuration.
Something like
```nix
{ pkgs, config, ... }:
let
pkgsUnstable = import <nixpkgs-unstable> {};
in
{
home.packages = [
pkgsUnstable.foo
];
# …
}
```
should work provided you have a Nix channel called `nixpkgs-unstable`.
Note, the package will not be affected by any package overrides,
overlays, etc.

View File

@@ -19,7 +19,7 @@ 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 19.03 (the
Home Manager targets [NixOS][] unstable and NixOS version 19.09 (the
current stable version), it may or may not work on other Linux
distributions and NixOS versions.
@@ -72,11 +72,11 @@ Currently the easiest way to install Home Manager is as follows:
if you are following Nixpkgs master or an unstable channel and
```console
$ nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager
$ nix-channel --add https://github.com/rycee/home-manager/archive/release-19.09.tar.gz home-manager
$ nix-channel --update
```
if you follow a Nixpkgs version 19.03 channel.
if you follow a Nixpkgs version 19.09 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

View File

@@ -1,328 +1,72 @@
{ pkgs, options, config, version, revision, extraSources ? [] }:
with pkgs;
{ pkgs }:
let
lib = pkgs.lib;
# Remove invisible and internal options.
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
nmdSrc = pkgs.fetchFromGitLab {
name = "nmd";
owner = "rycee";
repo = "nmd";
rev = "9751ca5ef6eb2ef27470010208d4c0a20e89443d";
sha256 = "0rbx10n8kk0bvp1nl5c8q79lz1w0p1b8103asbvwps3gmqd070hi";
};
# Replace functions by the string <function>
substFunction = x:
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
else if builtins.isList x then map substFunction x
else if lib.isFunction x then "<function>"
else x;
nmd = import nmdSrc { inherit pkgs; };
# Generate DocBook documentation for a list of packages. This is
# what `relatedPackages` option of `mkOption` from
# ../../../lib/options.nix influences.
#
# Each element of `relatedPackages` can be either
# - a string: that will be interpreted as an attribute name from `pkgs`,
# - a list: that will be interpreted as an attribute path from `pkgs`,
# - an attrset: that can specify `name`, `path`, `package`, `comment`
# (either of `name`, `path` is required, the rest are optional).
genRelatedPackages = packages:
let
unpack = p: if lib.isString p then { name = p; }
else if lib.isList p then { path = p; }
else p;
describe = args:
let
name = args.name or (lib.concatStringsSep "." args.path);
path = args.path or [ args.name ];
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
in "<listitem>"
+ "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
+ ": ${package.meta.description or "???"}.</para>"
+ lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
# Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
+ lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
+ "</listitem>";
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
# 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 { };
};
}
];
};
optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
# Clean up declaration sites to not refer to the NixOS source tree.
declarations = map stripAnyPrefixes opt.declarations;
}
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
// lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
hmModulesDocs = nmd.buildModulesDocs {
modules =
import ../modules/modules.nix { inherit lib pkgs; }
++ [ scrubbedPkgsModule ];
moduleRootPaths = [ ./.. ];
mkModuleUrl = path:
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
channelName = "home-manager";
docBook.id = "home-manager-options";
};
# We need to strip references to /nix/store/* from options,
# including any `extraSources` if some modules came from elsewhere,
# or else the build will fail.
#
# E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
# you'd need to include `extraSources = [ pkgs.customModules ]`
prefixesToStrip = map (p: "${toString p}/") ([ ./.. ] ++ extraSources);
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
# Custom "less" that pushes up all the things ending in ".enable*"
# and ".package*"
optionLess = a: b:
let
ise = lib.hasPrefix "enable";
isp = lib.hasPrefix "package";
cmp = lib.splitByAndCompare ise lib.compare
(lib.splitByAndCompare isp lib.compare lib.compare);
in lib.compareLists cmp a.loc b.loc < 0;
# Customly sort option list for the man page.
optionsList = lib.sort optionLess optionsListDesc;
# Convert the list of options into an XML file.
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
optionsDocBook = runCommand "options-db.xml"
{
nativeBuildInputs = [ buildPackages.libxslt.bin ];
}
''
optionsXML=${optionsXML}
xsltproc \
--stringparam program 'home-manager' \
--stringparam revision '${revision}' \
-o $out ${./options-to-docbook.xsl} $optionsXML
'';
sources = lib.sourceFilesBySuffices ./. [".xml"];
modulesDoc = builtins.toFile "modules.xml" ''
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules">
${(lib.concatMapStrings (path: ''
<xi:include href="${path}" />
'') (lib.catAttrs "value" config.meta.doc))}
</section>
'';
generatedSources = runCommand "generated-docbook" {} ''
mkdir $out
ln -s ${modulesDoc} $out/modules.xml
ln -s ${optionsDocBook} $out/options-db.xml
printf "%s" "${version}" > $out/version
'';
copySources =
''
cp -prd $sources/* . # */
ln -s ${generatedSources} ./generated
chmod -R u+w .
'';
toc = builtins.toFile "toc.xml"
''
<toc role="chunk-toc">
docs = nmd.buildDocBookDocs {
pathName = "home-manager";
modulesDocs = [ hmModulesDocs ];
documentsDirectory = ./.;
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>
'';
};
manualXsltprocOptions = toString [
"--param section.autolabel 1"
"--param section.label.includes.component.label 1"
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
"--param xref.with.number.and.title 1"
"--param toc.section.depth 3"
"--stringparam admon.style ''"
"--stringparam callout.graphics.extension .svg"
"--stringparam current.docid manual"
"--param chunk.section.depth 0"
"--param chunk.first.sections 1"
"--param use.id.as.filename 1"
"--stringparam generate.toc 'book toc appendix toc'"
"--stringparam chunk.toc ${toc}"
];
in
manual-combined = runCommand "home-manager-manual-combined"
{ inherit sources;
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
meta.description = "The Home Manager manual as plain docbook XML";
}
''
${copySources}
{
inherit nmdSrc;
xmllint --xinclude --output ./manual-combined.xml ./manual.xml
xmllint --xinclude --noxincludenode \
--output ./man-pages-combined.xml ./man-pages.xml
options = {
json = hmModulesDocs.json.override {
path = "share/doc/home-manager/options.json";
};
};
# outputs the context of an xmllint error output
# LEN lines around the failing line are printed
function context {
# length of context
local LEN=6
# lines to print before error line
local BEFORE=4
# xmllint output lines are:
# file.xml:1234: there was an error on line 1234
while IFS=':' read -r file line rest; do
echo
if [[ -n "$rest" ]]; then
echo "$file:$line:$rest"
local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1))
# number lines & filter context
nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p"
else
if [[ -n "$line" ]]; then
echo "$file:$line"
else
echo "$file"
fi
fi
done
}
function lintrng {
xmllint --debug --noout --nonet \
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
"$1" \
2>&1 | context 1>&2
# ^ redirect assumes xmllint doesnt print to stdout
}
lintrng manual-combined.xml
lintrng man-pages-combined.xml
mkdir $out
cp manual-combined.xml $out/
cp man-pages-combined.xml $out/
'';
olinkDB = runCommand "manual-olinkdb"
{ inherit sources;
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
}
''
xsltproc \
${manualXsltprocOptions} \
--stringparam collect.xref.targets only \
--stringparam targets.filename "$out/manual.db" \
--nonet \
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
${manual-combined}/manual-combined.xml
cat > "$out/olinkdb.xml" <<EOF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE targetset SYSTEM
"file://${docbook5_xsl}/xml/xsl/docbook/common/targetdatabase.dtd" [
<!ENTITY manualtargets SYSTEM "file://$out/manual.db">
]>
<targetset>
<targetsetinfo>
Allows for cross-referencing olinks between the manpages
and manual.
</targetsetinfo>
<document targetdoc="manual">&manualtargets;</document>
</targetset>
EOF
'';
in rec {
inherit generatedSources;
# The Home Manager options in JSON format.
optionsJSON = runCommand "options-json"
{ meta.description = "List of Home Manager options in JSON format";
}
''
# Export list of options in different format.
dst=$out/share/doc/home-manager
mkdir -p $dst
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
} $dst/options.json
mkdir -p $out/nix-support
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
''; # */
# Generate the Home Manager manual.
manual = runCommand "home-manager-manual"
{ inherit sources;
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
meta.description = "The Home Manager manual in HTML format";
allowedReferences = ["out"];
}
''
# Generate the HTML manual.
dst=$out/share/doc/home-manager
mkdir -p $dst
xsltproc \
${manualXsltprocOptions} \
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
--nonet --output $dst/ \
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
${manual-combined}/manual-combined.xml
mkdir -p $dst/images/callouts
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
cp ${./style.css} $dst/style.css
cp ${./overrides.css} $dst/overrides.css
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
mkdir -p $out/nix-support
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
echo "doc manual $dst" >> $out/nix-support/hydra-build-products
''; # */
manualEpub = runCommand "home-manager-manual-epub"
{ inherit sources;
buildInputs = [ libxml2.bin libxslt.bin zip ];
}
''
# Generate the epub manual.
dst=$out/share/doc/home-manager
xsltproc \
${manualXsltprocOptions} \
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
--nonet --xinclude --output $dst/epub/ \
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
${manual-combined}/manual-combined.xml
mkdir -p $dst/epub/OEBPS/images/callouts
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
echo "application/epub+zip" > mimetype
manual="$dst/home-manager-manual.epub"
zip -0Xq "$manual" mimetype
cd $dst/epub && zip -Xr9D "$manual" *
rm -rf $dst/epub
mkdir -p $out/nix-support
echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products
'';
# Generate the Home Manager manpages.
manpages = runCommand "home-manager-manpages"
{ inherit sources;
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
allowedReferences = ["out"];
}
''
# Generate manpages.
mkdir -p $out/share/man
xsltproc --nonet \
--param man.output.in.separate.dir 1 \
--param man.output.base.dir "'$out/share/man/'" \
--param man.endnotes.are.numbered 0 \
--param man.break.after.slash 1 \
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
${manual-combined}/man-pages-combined.xml
'';
manPages = docs.manPages;
manual = {
inherit (docs) html htmlOpenTool;
};
}

View File

@@ -79,11 +79,11 @@
if you are following Nixpkgs master or an unstable channel and
</para>
<screen>
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager</userinput>
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.09.tar.gz home-manager</userinput>
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 19.03 channel.
if you follow a Nixpkgs version 19.09 channel.
</para>
<para>
On NixOS you may need to log out and back in for the channel to become
@@ -169,12 +169,12 @@ $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
</para>
<screen>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.09.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 19.03 channel.
if you follow a Nixpkgs version 19.09 channel.
</para>
<para>
@@ -230,7 +230,81 @@ home-manager.useUserPackages = true;
<title>nix-darwin module</title>
<para>
To be done.
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>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/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/rycee/home-manager/archive/release-19.09.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 19.09 channel.
</para>
<para>
It is then possible to add
</para>
<programlisting language="nix">
imports = [ &lt;home-manager/nix-darwin&gt; ];
</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>
</section>
</chapter>

View File

@@ -26,7 +26,7 @@
You can use the following options in
<filename>home-configuration.nix</filename>:
</para>
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
<xi:include href="./nmd-result/home-manager-options.xml" />
</refsection>
<refsection>
<title>See also</title>

View File

@@ -2,46 +2,141 @@
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>
<refentrytitle><command>home-manager</command>
</refentrytitle><manvolnum>1</manvolnum>
<refmiscinfo class="source">Home Manager</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta>
<refnamediv>
<refname><command>home-manager</command></refname>
<refpurpose>reconfigure a user environment</refpurpose>
<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">
<option>help</option>
build
</arg>
<arg choice="plain">
<option>build</option>
edit
</arg>
<arg choice="plain">
<option>switch</option>
expire-generations <replaceable>timestamp</replaceable>
</arg>
<arg choice="plain">
<option>generations</option>
generations
</arg>
<arg choice="plain">
<option>remove-generations</option>
help
</arg>
<arg choice="plain">
<option>packages</option>
news
</arg>
<arg choice="plain">
<option>news</option>
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>
<group choice="req">
<arg choice="plain">
-v
</arg>
<arg choice="plain">
--verbose
</arg>
</group>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection>
@@ -50,6 +145,321 @@
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>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>&lt;nixpkgs&gt;</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>-v</option>
</term>
<term>
<option>--verbose</option>
</term>
<listitem>
<para>
Activates verbose output.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection>
<title>Files</title>
@@ -77,12 +487,11 @@
</para>
</refsection>
<refsection>
<title>See also</title>
<para>
<citerefentry>
<refentrytitle>home-configuration.nix</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
</para>
<title>See also</title>
<para>
<citerefentry>
<refentrytitle>home-configuration.nix</refentrytitle>
<manvolnum>5</manvolnum> </citerefentry>
</para>
</refsection>
</refentry>

View File

@@ -28,7 +28,11 @@
<xi:include href="installation.xml" />
<appendix xml:id="ch-options">
<title>Configuration Options</title>
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
<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>

View File

@@ -1,239 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://docbook.org/ns/docbook"
extension-element-prefixes="str"
>
<xsl:output method='xml' encoding="UTF-8" />
<xsl:param name="revision" />
<xsl:param name="program" />
<xsl:template match="/expr/list">
<appendix>
<title>Configuration Options</title>
<variablelist xml:id="configuration-variable-list">
<xsl:for-each select="attrs">
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'), '?', '_'))" />
<varlistentry>
<term xlink:href="#{$id}">
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
<option>
<xsl:value-of select="attr[@name = 'name']/string/@value" />
</option>
</term>
<listitem>
<para>
<xsl:value-of disable-output-escaping="yes"
select="attr[@name = 'description']/string/@value" />
</para>
<xsl:if test="attr[@name = 'type']">
<para>
<emphasis>Type:</emphasis>
<xsl:text> </xsl:text>
<xsl:value-of select="attr[@name = 'type']/string/@value"/>
<xsl:if test="attr[@name = 'readOnly']/bool/@value = 'true'">
<xsl:text> </xsl:text>
<emphasis>(read only)</emphasis>
</xsl:if>
</para>
</xsl:if>
<xsl:if test="attr[@name = 'default']">
<para>
<emphasis>Default:</emphasis>
<xsl:text> </xsl:text>
<xsl:apply-templates select="attr[@name = 'default']" mode="top" />
</para>
</xsl:if>
<xsl:if test="attr[@name = 'example']">
<para>
<emphasis>Example:</emphasis>
<xsl:text> </xsl:text>
<xsl:choose>
<xsl:when test="attr[@name = 'example']/attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
<programlisting><xsl:value-of select="attr[@name = 'example']/attrs/attr[@name = 'text']/string/@value" /></programlisting>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="attr[@name = 'example']" mode="top" />
</xsl:otherwise>
</xsl:choose>
</para>
</xsl:if>
<xsl:if test="attr[@name = 'relatedPackages']">
<para>
<emphasis>Related packages:</emphasis>
<xsl:text> </xsl:text>
<xsl:value-of disable-output-escaping="yes"
select="attr[@name = 'relatedPackages']/string/@value" />
</para>
</xsl:if>
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
<para>
<emphasis>Declared by:</emphasis>
</para>
<xsl:apply-templates select="attr[@name = 'declarations']" />
</xsl:if>
<xsl:if test="count(attr[@name = 'definitions']/list/*) != 0">
<para>
<emphasis>Defined by:</emphasis>
</para>
<xsl:apply-templates select="attr[@name = 'definitions']" />
</xsl:if>
</listitem>
</varlistentry>
</xsl:for-each>
</variablelist>
</appendix>
</xsl:template>
<xsl:template match="*" mode="top">
<xsl:choose>
<xsl:when test="string[contains(@value, '&#010;')]">
<programlisting>
<xsl:text>''
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "&apos;&apos;${")' /><xsl:text>''</xsl:text></programlisting>
</xsl:when>
<xsl:otherwise>
<literal><xsl:apply-templates /></literal>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="null">
<xsl:text>null</xsl:text>
</xsl:template>
<xsl:template match="string">
<xsl:choose>
<xsl:when test="(contains(@value, '&quot;') or contains(@value, '\')) and not(contains(@value, '&#010;'))">
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "&apos;&apos;${")' /><xsl:text>''</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>"</xsl:text><xsl:value-of select="str:replace(str:replace(str:replace(str:replace(@value, '\', '\\'), '&quot;', '\&quot;'), '&#010;', '\n'), '$', '\$')" /><xsl:text>"</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="int">
<xsl:value-of select="@value" />
</xsl:template>
<xsl:template match="bool[@value = 'true']">
<xsl:text>true</xsl:text>
</xsl:template>
<xsl:template match="bool[@value = 'false']">
<xsl:text>false</xsl:text>
</xsl:template>
<xsl:template match="list">
[
<xsl:for-each select="*">
<xsl:apply-templates select="." />
<xsl:text> </xsl:text>
</xsl:for-each>
]
</xsl:template>
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
<xsl:value-of select="attr[@name = 'text']/string/@value" />
</xsl:template>
<xsl:template match="attrs">
{
<xsl:for-each select="attr">
<xsl:value-of select="@name" />
<xsl:text> = </xsl:text>
<xsl:apply-templates select="*" /><xsl:text>; </xsl:text>
</xsl:for-each>
}
</xsl:template>
<xsl:template match="derivation">
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
</xsl:template>
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
<simplelist>
<xsl:for-each select="list/string">
<member><filename>
<!-- Hyperlink the filename either to the NixOS Subversion
repository (if its a module and we have a revision number),
or to the local filesystem. -->
<xsl:choose>
<xsl:when test="not(starts-with(@value, '/'))">
<xsl:choose>
<xsl:when test="$program = 'home-manager'">
<xsl:attribute name="xlink:href">https://github.com/rycee/home-manager/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/>#blob-path</xsl:attribute>
</xsl:when>
<xsl:when test="$revision = 'local'">
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/master/<xsl:value-of select="@value"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$revision != 'local' and $program = 'nixops' and contains(@value, '/nix/')">
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="xlink:href">file://<xsl:value-of select="@value"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<!-- Print the filename and make it user-friendly by replacing the
/nix/store/<hash> prefix by the default location of nixos
sources. -->
<xsl:choose>
<xsl:when test="$program = 'home-manager'">
&lt;home-manager/<xsl:value-of select="@value"/>&gt;
</xsl:when>
<xsl:when test="not(starts-with(@value, '/'))">
&lt;nixpkgs/<xsl:value-of select="@value"/>&gt;
</xsl:when>
<xsl:when test="contains(@value, 'nixops') and contains(@value, '/nix/')">
&lt;nixops/<xsl:value-of select="substring-after(@value, '/nix/')"/>&gt;
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@value" />
</xsl:otherwise>
</xsl:choose>
</filename></member>
</xsl:for-each>
</simplelist>
</xsl:template>
<xsl:template match="function">
<xsl:text>λ</xsl:text>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,9 +0,0 @@
.docbook .xref img[src^=images\/callouts\/],
.screen img,
.programlisting img {
width: 1em;
}
.calloutlist img {
width: 1.5em;
}

View File

@@ -0,0 +1,4 @@
[[sec-release-18.09]]
== Release 18.09
The 18.09 release branch became the stable branch in September, 2018.

View File

@@ -1,11 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-18.09">
<title>Release 18.09</title>
<para>
The 18.09 release branch became the stable branch in September, 2018.
</para>
</section>

View 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.

View File

@@ -1,88 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.03">
<title>Release 19.03</title>
<para>
The 19.03 release branch became the stable branch in April, 2019.
</para>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.03-highlights">
<title>Highlights</title>
<para>
This release has the following notable changes:
</para>
<itemizedlist>
<listitem>
<para>
The <option>home.file.&lt;name?&gt;.source</option> now allows source
files to be hidden, that is, having a name starting with the
<literal>.</literal> 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
<programlisting>
home.file."my file".source = ./. + "/file with spaces!";
</programlisting>
</para>
</listitem>
<listitem>
<para>
The type used for the systemd unit options under
<option>systemd.user.services</option>,
<option>systemd.user.sockets</option>, 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.
</para>
<para>
In particular, if you get an error saying that a <quote>unique
option</quote> is <quote>defined multiple times</quote> then you need to
use the
<code xlink:href="https://nixos.org/nixos/manual/#sec-option-definitions-setting-priorities">mkForce</code>
function. For example,
<programlisting language="nix">
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
</programlisting>
becomes
<programlisting language="nix">
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
</programlisting>
We had to make this change because the old merging was causing too many
confusing situations for people.
</para>
</listitem>
</itemizedlist>
</section>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.03-state-version-changes">
<title>State Version Changes</title>
<para>
The state version in this release includes the changes below. These changes
are only active if the <option>home.stateVersion</option> option is set to
"19.03" or later.
</para>
<itemizedlist>
<listitem>
<para>
There is now an option <option>programs.beets.enable</option> that
defaults to <literal>false</literal>. Before the module would be active if
the <option>programs.beets.settings</option> option was non-empty.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View 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 <<opt-programs.firefox.enableGoogleTalk>> and
<<opt-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.

View File

@@ -1,12 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.09">
<title>Release 19.09 (unreleased)</title>
<para>
This is the current unstable branch and the information in this section is
therefore not final.
</para>
</section>

View File

@@ -1,271 +0,0 @@
/* Copied from http://bakefile.sourceforge.net/, which appears
licensed under the GNU GPL. */
/***************************************************************************
Basic headers and text:
***************************************************************************/
body
{
font-family: "Nimbus Sans L", sans-serif;
background: white;
margin: 2em 1em 2em 1em;
}
h1, h2, h3, h4
{
color: #005aa0;
}
h1 /* title */
{
font-size: 200%;
}
h2 /* chapters, appendices, subtitle */
{
font-size: 180%;
}
/* Extra space between chapters, appendices. */
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
{
margin-top: 1.5em;
}
div.section > div.titlepage h2 /* sections */
{
font-size: 150%;
margin-top: 1.5em;
}
h3 /* subsections */
{
font-size: 125%;
}
div.simplesect h2
{
font-size: 110%;
}
div.appendix h3
{
font-size: 150%;
margin-top: 1.5em;
}
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
{
margin-top: 1.4em;
font-size: 125%;
}
div.refsection h3
{
font-size: 110%;
}
/***************************************************************************
Examples:
***************************************************************************/
div.example
{
border: 1px solid #b0b0b0;
padding: 6px 6px;
margin-left: 1.5em;
margin-right: 1.5em;
background: #f4f4f8;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example p.title
{
margin-top: 0em;
}
div.example pre
{
box-shadow: none;
}
/***************************************************************************
Screen dumps:
***************************************************************************/
pre.screen, pre.programlisting
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
background: #f4f4f8;
font-family: monospace;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example pre.programlisting
{
border: 0px;
padding: 0 0;
margin: 0 0 0 0;
}
/***************************************************************************
Notes, warnings etc:
***************************************************************************/
.note, .warning
{
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
margin-bottom: 1em;
padding: 0.3em 0.3em 0.3em 0.3em;
background: #fffff5;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.note, div.warning
{
font-style: italic;
}
div.note h3, div.warning h3
{
color: red;
font-size: 100%;
padding-right: 0.5em;
display: inline;
}
div.note p, div.warning p
{
margin-bottom: 0em;
}
div.note h3 + p, div.warning h3 + p
{
display: inline;
}
div.note h3
{
color: blue;
font-size: 100%;
}
div.navfooter *
{
font-size: 90%;
}
/***************************************************************************
Links colors and highlighting:
***************************************************************************/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
a:link { color: #0048b3; }
a:visited { color: #002a6a; }
/***************************************************************************
Table of contents:
***************************************************************************/
div.toc
{
font-size: 90%;
}
div.toc dl
{
margin-top: 0em;
margin-bottom: 0em;
}
/***************************************************************************
Special elements:
***************************************************************************/
tt, code
{
color: #400000;
}
.term
{
font-weight: bold;
}
div.variablelist dd p, div.glosslist dd p
{
margin-top: 0em;
}
div.variablelist dd, div.glosslist dd
{
margin-left: 1.5em;
}
div.glosslist dt
{
font-style: italic;
}
.varname
{
color: #400000;
}
span.command strong
{
font-weight: normal;
color: #400000;
}
div.calloutlist table
{
box-shadow: none;
}
table
{
border-collapse: collapse;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
table.simplelist
{
text-align: left;
color: #005aa0;
border: 0;
padding: 5px;
background: #fffff5;
font-weight: normal;
font-style: italic;
box-shadow: none;
margin-bottom: 1em;
}
div.navheader table, div.navfooter table {
box-shadow: none;
}
div.affiliation
{
font-style: italic;
}

View 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" "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

View File

@@ -34,4 +34,7 @@ runCommand
--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
''

View File

@@ -10,6 +10,20 @@ function errorEcho() {
echo $* >&2
}
function setVerboseAndDryRun() {
if [[ -v VERBOSE ]]; then
export VERBOSE_ARG="--verbose"
else
export VERBOSE_ARG=""
fi
if [[ -v DRY_RUN ]] ; then
export DRY_RUN_CMD=echo
else
export DRY_RUN_CMD=""
fi
}
function setWorkDir() {
if [[ ! -v WORK_DIR ]]; then
WORK_DIR="$(mktemp --tmpdir -d home-manager-build.XXXXXXXXXX)"
@@ -79,12 +93,14 @@ function doBuildAttr() {
nix build \
-f "<home-manager/home-manager/home-manager.nix>" \
$extraArgs \
"${PASSTHROUGH_OPTS[@]}" \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
else
nix-build \
"<home-manager/home-manager/home-manager.nix>" \
$extraArgs \
"${PASSTHROUGH_OPTS[@]}" \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
fi
@@ -216,17 +232,7 @@ function doListGens() {
# Removes linked generations. Takes as arguments identifiers of
# generations to remove.
function doRmGenerations() {
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
setVerboseAndDryRun
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
@@ -246,6 +252,11 @@ function doRmGenerations() {
popd > /dev/null
}
function doRmAllGenerations() {
$DRY_RUN_CMD rm $VERBOSE_ARG \
"/nix/var/nix/profiles/per-user/$USER/home-manager"*
}
function doExpireGenerations() {
local profileDir="/nix/var/nix/profiles/per-user/$USER"
@@ -347,6 +358,56 @@ function doShowNews() {
fi
}
function doUninstall() {
setVerboseAndDryRun
echo "This will remove Home Manager from your system."
if [[ -v DRY_RUN ]]; then
echo "This is a dry run, nothing will actually be uninstalled."
fi
local confirmation
read -r -n 1 -p "Really uninstall Home Manager? [y/n] " confirmation
echo
case $confirmation in
y|Y)
echo "Switching to empty Home Manager configuration..."
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
echo "{}" > "$HOME_MANAGER_CONFIG"
doSwitch
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/var/nix/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
@@ -357,10 +418,20 @@ function doHelp() {
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
echo "Commands"
echo
echo " help Print this help"
@@ -385,63 +456,84 @@ function doHelp() {
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"
}
EXTRA_NIX_PATH=()
HOME_MANAGER_CONFIG_ATTRIBUTE=""
PASSTHROUGH_OPTS=()
COMMAND=""
COMMAND_ARGS=()
# As a special case, if the user has given --help anywhere on the
# command line then print help and exit.
for arg in "$@"; do
if [[ $arg == "--help" ]]; then
doHelp
exit 0
fi
done
while getopts 2f:I:A:vnh opt; do
while [[ $# -gt 0 ]]; do
opt="$1"
shift
case $opt in
2)
build|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
COMMAND="$opt"
;;
-2)
USE_NIX2_COMMAND=1
;;
f)
HOME_MANAGER_CONFIG="$OPTARG"
-A)
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
shift
;;
I)
EXTRA_NIX_PATH+=("$OPTARG")
-I)
EXTRA_NIX_PATH+=("$1")
shift
;;
A)
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
-b)
export HOME_MANAGER_BACKUP_EXT="$1"
shift
;;
v)
export VERBOSE=1
-f|--file)
HOME_MANAGER_CONFIG="$1"
shift
;;
n)
export DRY_RUN=1
;;
h)
-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)
PASSTHROUGH_OPTS+=("$opt")
;;
-v|--verbose)
export VERBOSE=1
;;
*)
doHelp >&2
exit 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
# Get rid of the options.
shift "$((OPTIND-1))"
if [[ $# -eq 0 ]]; then
if [[ -z $COMMAND ]]; then
doHelp >&2
exit 1
fi
cmd="$1"
shift 1
case "$cmd" in
case $COMMAND in
edit)
doEdit
;;
@@ -455,10 +547,15 @@ case "$cmd" in
doListGens
;;
remove-generations)
doRmGenerations "$@"
doRmGenerations "${COMMAND_ARGS[@]}"
;;
expire-generations)
doExpireGenerations "$@"
if [[ ${#COMMAND_ARGS[@]} != 1 ]]; then
errorEcho "expire-generations expects one argument, got ${#COMMAND_ARGS[@]}."
exit 1
else
doExpireGenerations "${COMMAND_ARGS[@]}"
fi
;;
packages)
doListPackages
@@ -466,11 +563,14 @@ case "$cmd" in
news)
doShowNews --all
;;
help|--help)
uninstall)
doUninstall
;;
help)
doHelp
;;
*)
errorEcho "Unknown command: $cmd"
errorEcho "Unknown command: $COMMAND"
doHelp >&2
exit 1
;;

View File

@@ -6,6 +6,7 @@ runCommand
propagatedBuildInputs = [ home-manager ];
preferLocalBuild = true;
allowSubstitutes = false;
shellHookOnly = true;
shellHook = ''
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
@@ -20,6 +21,16 @@ runCommand
{
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
# 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 = "19.09";
}
EOF
fi
@@ -53,4 +64,7 @@ runCommand
fi
'';
}
""
''
echo This derivation is not buildable, instead run it using nix-shell.
exit 1
''

View File

@@ -95,7 +95,7 @@ let
};
port = mkOption {
type = types.nullOr types.ints.positive;
type = types.nullOr types.port;
default = null;
example = 993;
description = ''
@@ -125,7 +125,7 @@ let
};
port = mkOption {
type = types.nullOr types.ints.positive;
type = types.nullOr types.port;
default = null;
example = 465;
description = ''
@@ -388,6 +388,7 @@ in
mailAccountOpts
(import ../programs/alot-accounts.nix pkgs)
(import ../programs/astroid-accounts.nix)
(import ../programs/getmail-accounts.nix)
(import ../programs/mbsync-accounts.nix)
(import ../programs/msmtp-accounts.nix)
(import ../programs/notmuch-accounts.nix)

View File

@@ -23,10 +23,6 @@ let
then file.source
else builtins.path { path = file.source; name = sourceName; };
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*";
in
{
@@ -49,23 +45,57 @@ in
# overwrite an existing file.
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
let
# Paths that should be forcibly overwritten by Home Manager.
# Caveat emptor!
forcedPaths =
concatMapStringsSep " " (p: ''"$HOME/${p}"'')
(mapAttrsToList (n: v: v.target)
(filterAttrs (n: v: v.force) cfg));
check = pkgs.writeText "check" ''
. ${./lib-bash/color-echo.sh}
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
forcedPaths=(${forcedPaths})
newGenFiles="$1"
shift
for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" \
&& ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
errorEcho "Existing file '$targetPath' is in the way"
collision=1
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, will be moved to '$backup'"
fi
else
errorEcho "Existing file '$targetPath' is in the way"
collision=1
fi
fi
done
if [[ -v collision ]] ; then
errorEcho "Please move the above files and try again"
errorEcho "Please move the above files and try again or use -b <ext> to move automatically."
exit 1
fi
'';
@@ -74,8 +104,8 @@ in
function checkNewGenCollision() {
local newGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
find "$newGenFiles" -type f -print0 -or -type l -print0 \
| xargs -0 bash ${check} "$newGenFiles"
find "$newGenFiles" \( -type f -or -type l \) \
-exec bash ${check} "$newGenFiles" {} +
}
checkNewGenCollision || exit 1
@@ -111,6 +141,10 @@ in
for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
$DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
fi
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath"
done
@@ -119,13 +153,17 @@ in
cleanup = pkgs.writeText "cleanup" ''
. ${./lib-bash/color-echo.sh}
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
newGenFiles="$1"
shift 1
for relativePath in "$@" ; do
targetPath="$HOME/$relativePath"
if [[ -e "$newGenFiles/$relativePath" ]] ; then
$VERBOSE_ECHO "Checking $targetPath: exists"
elif [[ ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
else
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
@@ -155,8 +193,8 @@ in
local newGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
find "$newGenFiles" -type f -print0 -or -type l -print0 \
| xargs -0 bash ${link} "$newGenFiles"
find "$newGenFiles" \( -type f -or -type l \) \
-exec bash ${link} "$newGenFiles" {} +
}
function cleanOldGen() {
@@ -222,6 +260,9 @@ in
(''
mkdir -p $out
# Needed in case /nix is a symbolic link.
realOut="$(realpath -m "$out")"
function insertFile() {
local source="$1"
local relTarget="$2"
@@ -230,10 +271,10 @@ in
# Figure out the real absolute path to the target.
local target
target="$(realpath -m "$out/$relTarget")"
target="$(realpath -m "$realOut/$relTarget")"
# Target path must be within $HOME.
if [[ ! $target == $out* ]] ; then
if [[ ! $target == $realOut* ]] ; then
echo "Error installing file '$relTarget' outside \$HOME" >&2
exit 1
fi

View File

@@ -55,16 +55,24 @@ let
keyboardSubModule = types.submodule {
options = {
layout = mkOption {
type = types.str;
default = "us";
type = with types; nullOr str;
default =
if versionAtLeast config.home.stateVersion "19.09"
then null
else "us";
defaultText = literalExample "null";
description = ''
Keyboard layout.
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 = types.str;
default = "pc104";
type = with types; nullOr str;
default = null;
example = "presario";
description = ''
Keyboard model.
@@ -81,11 +89,19 @@ let
};
variant = mkOption {
type = types.str;
default = "";
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.
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.
'';
};
};
@@ -149,7 +165,7 @@ in
home.sessionVariables = mkOption {
default = {};
type = with types; attrsOf (either int str);
type = types.attrs;
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
description = ''
Environment variables to always set at login.
@@ -167,19 +183,19 @@ in
variable may have a runtime dependency on another session
variable. In particular code like
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "$FOO World!";
};
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!";
};
home.sessionVariables = {
FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!";
};
</programlisting>
'';
};
@@ -370,7 +386,7 @@ in
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
activationScript = pkgs.writeScript "activation-script" ''
#!${pkgs.stdenv.shell}
#!${pkgs.runtimeShell}
set -eu
set -o pipefail

View File

@@ -86,6 +86,18 @@ in
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 = {

28
modules/lib/types.nix Normal file
View File

@@ -0,0 +1,28 @@
{ lib }:
with lib;
{
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;
};
}

View File

@@ -1,4 +1,4 @@
{ config, lib, pkgs, baseModules, ... }:
{ config, lib, pkgs, ... }:
with lib;
@@ -6,55 +6,7 @@ let
cfg = config.manual;
/* For the purpose of generating docs, evaluate options with each derivation
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
It isn't perfect, but it seems to cover a vast majority of use cases.
Caveat: even if the package is reached by a different means,
the path above will be shown and not e.g. `${config.services.foo.package}`. */
homeManagerManual = import ../doc {
inherit pkgs config;
version = "0.1";
revision = "master";
options =
let
scrubbedEval = evalModules {
modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules;
args = (config._module.args) // { modules = [ ]; };
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
};
scrubDerivations = namePrefix: pkgSet: mapAttrs
(name: value:
let wholeName = "${namePrefix}.${name}"; in
if isAttrs value then
scrubDerivations wholeName value
// (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
else value
)
pkgSet;
in scrubbedEval.options;
};
manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";
helpScript = pkgs.writeShellScriptBin "home-manager-help" ''
#!${pkgs.bash}/bin/bash -e
if [ -z "$BROWSER" ]; then
for candidate in xdg-open open w3m; do
BROWSER="$(type -P $candidate || true)"
if [ -x "$BROWSER" ]; then
break;
fi
done
fi
if [ -z "$BROWSER" ]; then
echo "$0: unable to start a web browser; please set \$BROWSER"
exit 1
fi
exec "$BROWSER" ${manualHtmlRoot}
'';
docs = import ../doc { inherit pkgs; };
in
@@ -100,15 +52,17 @@ in
config = {
home.packages = mkMerge [
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
(mkIf cfg.json.enable [ homeManagerManual.optionsJSON ])
(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
'';
};
# To fix error during manpage build.
meta = {
maintainers = [ maintainers.rycee ];
doc = builtins.toFile "nothingness" "";
};
}

View File

@@ -13,9 +13,15 @@ let
let
tweakVal = v:
if isString v then "'${v}'"
else if isList v then "[" + concatMapStringsSep "," tweakVal v + "]"
else if isList v then tweakList v
else if isBool v then (if v then "true" else "false")
else toString v;
# Assume empty list is a list of strings, see #769
tweakList = v:
if v == [] then "@as []"
else "[" + concatMapStringsSep "," tweakVal v + "]";
in
"${key}=${tweakVal value}";

View File

@@ -6,36 +6,100 @@ 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 = {
enableProfileFonts = mkOption {
enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Configure fontconfig to discover fonts installed through
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>.
</para><para>
Note, this is only necessary on non-NixOS systems.
'';
};
};
};
config = mkIf cfg.enableProfileFonts {
xdg.configFile."fontconfig/conf.d/10-nix-profile-fonts.conf".text = ''
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>${config.home.profileDirectory}/lib/X11/fonts</dir>
<dir>${config.home.profileDirectory}/share/fonts</dir>
<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>
'';
};
};
}

View File

@@ -1065,6 +1065,189 @@ in
A new module is available: 'programs.alacritty'.
'';
}
{
time = "2019-04-26T22:53:48+00:00";
condition = config.programs.vscode.enable;
message = ''
A new module is available: 'programs.vscode.haskell'.
Enable to add Haskell IDE Engine and syntax highlighting
support to your VSCode.
'';
}
{
time = "2019-05-04T23:56:39+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.rsibreak'.
'';
}
{
time = "2019-05-07T20:49:29+00:00";
message = ''
A new module is available: 'programs.mpv'.
'';
}
{
time = "2019-05-30T17:49:29+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.xsuspender'.
'';
}
{
time = "2019-06-03T21:47:10+00:00";
message = ''
A new module is available: 'programs.gpg'.
'';
}
{
time = "2019-06-09T12:19:18+00:00";
message = ''
Collisions between unmanaged and managed files can now be
automatically resolved by moving the target file to a new
path instead of failing the switch operation. To enable
this, use the new '-b' command line argument. For example,
home-manager -b bck switch
where 'bck' is the suffix to give the moved file. In this
case a colliding file 'foo.conf' will be moved to
'foo.conf.bck'.
'';
}
{
time = "2019-06-19T17:49:29+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: `services.getmail`.
'';
}
{
time = "2019-07-02T09:27:56+00:00";
message = ''
A new module is available: 'programs.broot'.
'';
}
{
time = "2019-07-17T19:30:29+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.taskwarrior-sync'.
'';
}
{
time = "2019-07-17T20:05:29+00:00";
message = ''
A new module is available: 'programs.kakoune'.
'';
}
{
time = "2019-08-08T11:49:35+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.hound'.
'';
}
{
time = "2019-08-17T12:24:58+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.muchsync'.
'';
}
{
time = "2019-08-18T14:22:41+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.dwm-status'.
'';
}
{
time = "2019-08-28T10:18:07+00:00";
condition = config.programs.vim.enable;
message = ''
The 'programs.vim.plugins' option now accepts packages.
Specifying them as strings is deprecated.
'';
}
{
time = "2019-09-17T19:33:49+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.sxhkd'.
'';
}
{
time = "2019-09-26T21:05:24+00:00";
message = ''
A new module is available: 'programs.starship'.
'';
}
{
time = "2019-09-26T21:47:13+00:00";
message = ''
A new module is available: 'programs.rtorrent'.
'';
}
{
time = "2019-12-10T19:58:00+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.lorri'.
'';
}
{
time = "2020-02-16T17:07:44+00:00";
message = ''
A new module is available: 'programs.readline'.
'';
}
{
time = "2020-03-15T16:55:28+00:00";
condition = config.programs.firefox.enable;
message = ''
In anticipation of Firefox dropping support for extension
sideloading[1], we now install extensions directly to
Firefox profiles managed through Home Manager's
'programs.firefox.profiles'
option.
Unfortunately this will most likely trigger an "Existing
file is in the way" error when activating your configuration
since Firefox keeps a copy of the add-on in the location
Home Manager wants to overwrite. If this is the case, remove
the listed '.xpi' files and try again.
This change also means that extensions installed through
Home Manager may disappear from unmanaged profiles in future
Firefox releases.
[1] https://blog.mozilla.org/addons/2019/10/31/firefox-to-discontinue-sideloaded-extensions/
'';
}
];
};
}

View File

@@ -82,8 +82,7 @@ in
<programlisting language="nix">
nixpkgs.config = import ./nixpkgs-config.nix;
xdg.configFile."nixpkgs/config.nix".source =
./nixpkgs-config.nix;
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
</programlisting>
in your Home Manager configuration.

35
modules/misc/numlock.nix Normal file
View File

@@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.xsession.numlock;
in
{
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" ];
};
};
};
}

View File

@@ -14,7 +14,7 @@ in
options = {
pam.sessionVariables = mkOption {
default = {};
type = with types; attrsOf (either int str);
type = types.attrs;
example = { EDITOR = "vim"; };
description = ''
Environment variables that will be set for the PAM session.

View File

@@ -65,8 +65,7 @@ in
then [ pkgs.qgnomeplatform ]
else [ pkgs.libsForQt5.qtstyleplugins ];
xsession.profileExtra =
"systemctl --user import-environment QT_QPA_PLATFORMTHEME";
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ];
# Enable GTK+ style for Qt4 in either case.
# It doesnt support the platform theme packages.

View File

@@ -25,7 +25,7 @@ with lib;
installed separately from the Home Manager activation script.
In NixOS, for example, this may be accomplished by installing
the packages through
<option>users.users.&lt;name?&gt;.packages</option>.
<option>users.users.name?.packages</option>.
'';
};
};

View File

@@ -0,0 +1,92 @@
{ 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.
home.file.".local/share/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;
};
};
}

View File

@@ -0,0 +1,100 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.xdg.userDirs;
in
{
meta.maintainers = with maintainers; [ pacien ];
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.";
};
publishShare = 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 = generators.toKeyValue {} (
{
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.publishShare;
XDG_TEMPLATES_DIR = cfg.templates;
XDG_VIDEOS_DIR = cfg.videos;
}
// cfg.extraConfig
);
};
}

View File

@@ -92,10 +92,13 @@ in
})
{
home.file = mkMerge [ cfg.configFile cfg.dataFile ];
home.activation.xdgCreateCache = dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir $VERBOSE_ARG -m0700 -p "${config.xdg.cacheHome}"
'';
home.file = mkMerge [
cfg.configFile
cfg.dataFile
{
"${config.xdg.cacheHome}/.keep".text = "";
}
];
}
];
}

View File

@@ -28,10 +28,13 @@ let
(loadModule ./misc/lib.nix { })
(loadModule ./misc/news.nix { })
(loadModule ./misc/nixpkgs.nix { })
(loadModule ./misc/numlock.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/pam.nix { })
(loadModule ./misc/qt.nix { })
(loadModule ./misc/submodule-support.nix { })
(loadModule ./misc/version.nix { })
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/xdg.nix { })
(loadModule ./programs/afew.nix { })
(loadModule ./programs/alacritty.nix { })
@@ -41,6 +44,7 @@ let
(loadModule ./programs/bash.nix { })
(loadModule ./programs/bat.nix { })
(loadModule ./programs/beets.nix { })
(loadModule ./programs/broot.nix { })
(loadModule ./programs/browserpass.nix { })
(loadModule ./programs/chromium.nix { condition = hostPlatform.isLinux; })
(loadModule ./programs/command-not-found/command-not-found.nix { })
@@ -51,14 +55,17 @@ let
(loadModule ./programs/firefox.nix { })
(loadModule ./programs/fish.nix { })
(loadModule ./programs/fzf.nix { })
(loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; })
(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/info.nix { })
(loadModule ./programs/irssi.nix { })
(loadModule ./programs/jq.nix { })
(loadModule ./programs/kakoune.nix { })
(loadModule ./programs/keychain.nix { })
(loadModule ./programs/lesspipe.nix { })
(loadModule ./programs/lsd.nix { })
@@ -66,6 +73,7 @@ let
(loadModule ./programs/matplotlib.nix { })
(loadModule ./programs/mbsync.nix { })
(loadModule ./programs/mercurial.nix { })
(loadModule ./programs/mpv.nix { })
(loadModule ./programs/msmtp.nix { })
(loadModule ./programs/neovim.nix { })
(loadModule ./programs/newsboat.nix { })
@@ -75,8 +83,11 @@ let
(loadModule ./programs/offlineimap.nix { })
(loadModule ./programs/opam.nix { })
(loadModule ./programs/pidgin.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 { })
@@ -85,22 +96,30 @@ let
(loadModule ./programs/urxvt.nix { })
(loadModule ./programs/vim.nix { })
(loadModule ./programs/vscode.nix { })
(loadModule ./programs/vscode/haskell.nix { })
(loadModule ./programs/z-lua.nix { })
(loadModule ./programs/zathura.nix { })
(loadModule ./programs/zsh.nix { })
(loadModule ./services/blueman-applet.nix { })
(loadModule ./services/compton.nix { })
(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/getmail.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/gnome-keyring.nix { })
(loadModule ./services/gpg-agent.nix { })
(loadModule ./services/hound.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/kbfs.nix { })
(loadModule ./services/kdeconnect.nix { })
(loadModule ./services/keepassx.nix { })
(loadModule ./services/keybase.nix { })
(loadModule ./services/lorri.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 { })
@@ -109,12 +128,15 @@ let
(loadModule ./services/polybar.nix { })
(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/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/window-managers/awesome.nix { })
@@ -123,6 +145,7 @@ let
(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 ./xcursor.nix { })
(loadModule ./xresources.nix { })

View File

@@ -41,10 +41,13 @@ in
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.alacritty ];
config = mkMerge [
(mkIf cfg.enable {
home.packages = [ pkgs.alacritty ];
xdg.configFile."alacritty/alacritty.yml".text =
replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings);
};
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != {}) {
text = replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings);
};
})
];
}

View File

@@ -21,6 +21,8 @@ let
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;
@@ -36,11 +38,10 @@ let
boolStr (signature.showSignature == "attach");
}
)
++ [ alot.extraConfig ]
++ [ "[[[abook]]]" ]
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion
)
+ "\n"
+ alot.extraConfig;
);
configFile =
let

View File

@@ -20,9 +20,9 @@ let
sendmail = astroid.sendMailCommand;
additional_sent_tags = "";
default = boolOpt primary;
save_drafts_to = folders.drafts;
save_drafts_to = "${maildir.absPath}/${folders.drafts}";
save_sent = "true";
save_sent_to = folders.sent;
save_sent_to = "${maildir.absPath}/${folders.sent}";
select_query = "";
}
// optionalAttrs (signature.showSignature != "none") {
@@ -106,14 +106,6 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion = config.programs.notmuch.maildir.synchronizeFlags;
message = "The astroid module requires"
+ " 'programs.notmuch.maildir.synchronizeFlags = true'.";
}
];
home.packages = [ pkgs.astroid ];
xdg.configFile."astroid/config".source =

View File

@@ -72,7 +72,7 @@ in
sessionVariables = mkOption {
default = {};
type = with types; attrsOf (either int str);
type = types.attrs;
example = { MAILCHECK = 30; };
description = ''
Environment variables that will be set for the Bash session.
@@ -123,6 +123,15 @@ in
interactive shell.
'';
};
logoutExtra = mkOption {
default = "";
type = types.lines;
description = ''
Extra commands that should be run when logging out of an
interactive shell.
'';
};
};
};
@@ -195,6 +204,14 @@ in
${cfg.bashrcExtra}
'';
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
text = ''
# -*- mode: sh -*-
${cfg.logoutExtra}
'';
};
home.packages =
optional (cfg.enableAutojump) pkgs.autojump;
}

261
modules/programs/broot.nix Normal file
View File

@@ -0,0 +1,261 @@
{ 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".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
'';
};
}

View File

@@ -32,11 +32,11 @@ in {
in [
{
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-host.json";
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
}
{
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-policy.json";
source = "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}
]
else if x == "chromium" then
@@ -46,11 +46,11 @@ in {
in [
{
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-host.json";
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
}
{
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-policy.json";
source = "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}
]
else if x == "firefox" then
@@ -59,7 +59,7 @@ in {
then "Library/Application Support/Mozilla/NativeMessagingHosts"
else ".mozilla/native-messaging-hosts")
+ "/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/lib/mozilla/native-messaging-hosts/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
@@ -68,11 +68,11 @@ in {
in [
{
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-host.json";
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
}
{
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-policy.json";
source = "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}
]
else throw "unknown browser ${x}") config.programs.browserpass.browsers);

View File

@@ -21,7 +21,7 @@ let
inherit visible;
type = types.package;
default = defaultPkg;
defaultText = "pkgs.${browser}";
defaultText = literalExample "pkgs.${browser}";
description = "The ${name} package to use.";
};

View File

@@ -4,13 +4,15 @@ with lib;
let
hmTypes = import ../lib/types.nix { inherit lib; };
cfg = config.programs.emacs;
# Copied from all-packages.nix, with modifications to support
# overrides.
emacsPackages =
let
epkgs = pkgs.emacsPackagesNgGen cfg.package;
epkgs = pkgs.emacsPackagesGen cfg.package;
in
epkgs.overrideScope' cfg.overrides;
emacsWithPackages = emacsPackages.emacsWithPackages;
@@ -27,20 +29,26 @@ in
package = mkOption {
type = types.package;
default = pkgs.emacs;
defaultText = "pkgs.emacs";
defaultText = literalExample "pkgs.emacs";
example = literalExample "pkgs.emacs25-nox";
description = "The Emacs package to use.";
};
extraPackages = mkOption {
default = self: [];
type = hmTypes.selectorFunction;
defaultText = "epkgs: []";
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
description = "Extra packages available to Emacs.";
description = ''
Extra packages available to Emacs. To get a list of
available packages run:
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A emacsPackages</command>.
'';
};
overrides = mkOption {
default = self: super: {};
type = hmTypes.overlayFunction;
defaultText = "self: super: {}";
example = literalExample ''
self: super: rec {

View File

@@ -6,8 +6,47 @@ let
cfg = config.programs.firefox;
mozillaConfigPath = ".mozilla";
firefoxConfigPath = "${mozillaConfigPath}/firefox";
profilesPath = 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 = 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
{
@@ -19,9 +58,16 @@ in
package = mkOption {
type = types.package;
default = pkgs.firefox-unwrapped;
defaultText = "pkgs.firefox-unwrapped";
description = "The unwrapped Firefox package to use.";
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 {
@@ -40,6 +86,84 @@ in
'';
};
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 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;
}
}
'';
};
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;
@@ -49,47 +173,122 @@ in
enableGoogleTalk = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the unfree Google Talk plugin.";
description = ''
Whether to enable the unfree Google Talk plugin. This option
is <emphasis>deprecated</emphasis> and will only work if
<programlisting language="nix">
programs.firefox.package = pkgs.firefox-esr-52-unwrapped;
</programlisting>
and the <option>plugin.load_flash_only</option> Firefox
option has been disabled.
'';
};
enableIcedTea = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the Java applet plugin.";
description = ''
Whether to enable the Java applet plugin. This option is
<emphasis>deprecated</emphasis> and will only work if
<programlisting language="nix">
programs.firefox.package = pkgs.firefox-esr-52-unwrapped;
</programlisting>
and the <option>plugin.load_flash_only</option> Firefox
option has been disabled.
'';
};
};
};
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
# A bit of hackery to force a config into the wrapper.
browserName = cfg.package.browserName
or (builtins.parseDrvName cfg.package.name).name;
fcfg = setAttrByPath [browserName] {
# The configuration expected by the Firefox wrapper.
fcfg = {
enableAdobeFlash = cfg.enableAdobeFlash;
enableGoogleTalkPlugin = cfg.enableGoogleTalk;
icedtea = cfg.enableIcedTea;
};
wrapper = pkgs.wrapFirefox.override {
config = fcfg;
};
in
[ (wrapper cfg.package { }) ];
# A bit of hackery to force a config into the wrapper.
browserName = cfg.package.browserName
or (builtins.parseDrvName cfg.package.name).name;
home.file.".mozilla/${extensionPath}" = mkIf (cfg.extensions != []) (
let
extensionsEnv = pkgs.buildEnv {
name = "hm-firefox-extensions";
paths = cfg.extensions;
};
# The configuration expected by the Firefox wrapper builder.
bcfg = setAttrByPath [browserName] fcfg;
package =
if versionAtLeast config.home.stateVersion "19.09"
then cfg.package.override { cfg = fcfg; }
else (pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
in
{
source = "${extensionsEnv}/share/mozilla/${extensionPath}";
[ 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}/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;
};
})
);
};
}

View File

@@ -23,7 +23,7 @@ in
package = mkOption {
default = pkgs.fish;
defaultText = "pkgs.fish";
defaultText = literalExample "pkgs.fish";
description = ''
The fish package to install. May be used to change the version.
'';

View 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>.
'';
};
};
}

View File

@@ -0,0 +1,60 @@
{ 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
{
config = mkIf getmailEnabled {
home.file = map (a:
{ target = renderConfigFilepath a;
text = renderAccountConfig a;
}) accounts;
};
}

View File

@@ -6,11 +6,53 @@ let
cfg = config.programs.git;
# create [section "subsection"] keys from "section.subsection" attrset names
mkSectionName = name:
let
containsQuote = strings.hasInfix ''"'' name;
sections = splitString "." name;
section = head sections;
subsections = tail sections;
subsection = concatStringsSep "." subsections;
in
if containsQuote || subsections == []
then name
else "${section} \"${subsection}\"";
# generation for multiple ini values
mkKeyValue = k: v:
let
mkKeyValue = generators.mkKeyValueDefault {} "=" k;
in
concatStringsSep "\n" (map mkKeyValue (toList v));
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
gitFlattenAttrs =
let
recurse = path: value:
if isAttrs value then
mapAttrsToList (name: value: recurse ([name] ++ path) value) value
else if length path > 1 then
{ ${concatStringsSep "." (reverseList (tail path))}.${head path} = value; }
else
{ ${head path} = value; };
in
attrs: foldl recursiveUpdate {} (flatten (recurse [] attrs));
gitToIni = attrs:
let
toIni = generators.toINI { inherit mkKeyValue mkSectionName; };
in
toIni (gitFlattenAttrs attrs);
gitIniType = with types;
let
primitiveType = either bool (either int str);
primitiveType = either str (either bool int);
multipleType = either primitiveType (listOf primitiveType);
sectionType = attrsOf multipleType;
supersectionType = attrsOf (either multipleType sectionType);
in
attrsOf (attrsOf primitiveType);
attrsOf supersectionType;
signModule = types.submodule {
options = {
@@ -64,7 +106,7 @@ let
};
config.path = mkIf (config.contents != {}) (
mkDefault (pkgs.writeText "contents" (generators.toINI {} config.contents))
mkDefault (pkgs.writeText "contents" (gitToIni config.contents))
);
});
@@ -80,7 +122,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.git;
defaultText = "pkgs.git";
defaultText = literalExample "pkgs.git";
description = ''
Git package to install. Use <varname>pkgs.gitAndTools.gitFull</varname>
to gain access to <command>git send-email</command> for instance.
@@ -117,8 +159,12 @@ in
default = {};
example = {
core = { whitespace = "trailing-space,space-before-tab"; };
url."ssh://git@host".insteadOf = "otherhost";
};
description = "Additional configuration to add.";
description = ''
Additional configuration to add. The use of string values is
deprecated and will be removed in the future.
'';
};
iniContent = mkOption {
@@ -133,6 +179,13 @@ in
description = "List of paths that should be globally ignored.";
};
attributes = mkOption {
type = types.listOf types.str;
default = [];
example = [ "*.pdf diff=pdf" ];
description = "List of defining attributes set globally.";
};
includes = mkOption {
type = types.listOf includeModule;
default = [];
@@ -175,11 +228,15 @@ in
};
xdg.configFile = {
"git/config".text = generators.toINI {} cfg.iniContent;
"git/config".text = gitToIni cfg.iniContent;
"git/ignore" = mkIf (cfg.ignores != []) {
text = concatStringsSep "\n" cfg.ignores + "\n";
};
"git/attributes" = mkIf (cfg.attributes != []) {
text = concatStringsSep "\n" cfg.attributes + "\n";
};
};
}
@@ -189,7 +246,7 @@ in
hasSmtp = name: account: account.smtp != null;
genIdentity = name: account: with account;
nameValuePair "sendemail \"${name}\"" ({
nameValuePair "sendemail.${name}" ({
smtpEncryption = if smtp.tls.enable then "tls" else "";
smtpServer = smtp.host;
smtpUser = userName;
@@ -220,23 +277,35 @@ in
})
(mkIf (lib.isString cfg.extraConfig) {
warnings = [
''
Using programs.git.extraConfig as a string option is
deprecated and will be removed in the future. Please
change to using it as an attribute set instead.
''
];
xdg.configFile."git/config".text = cfg.extraConfig;
})
(mkIf (cfg.includes != []) {
xdg.configFile."git/config".text = mkAfter
(concatMapStringsSep "\n"
(i: with i; ''
[${if (condition == null) then "include" else "includeIf \"${condition}\""}]
path = ${path}
'')
cfg.includes);
xdg.configFile."git/config".text =
let
include = i: with i;
if condition != null
then { includeIf.${condition}.path = "${path}"; }
else { include.path = "${path}"; };
in
mkAfter
(concatStringsSep "\n"
(map gitToIni
(map include cfg.includes)));
})
(mkIf cfg.lfs.enable {
home.packages = [ pkgs.git-lfs ];
programs.git.iniContent."filter \"lfs\"" =
programs.git.iniContent.filter.lfs =
let
skipArg = optional cfg.lfs.skipSmudge "--skip";
in

View File

@@ -18,7 +18,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.go;
defaultText = "pkgs.go";
defaultText = literalExample "pkgs.go";
description = "The Go package to use.";
};

61
modules/programs/gpg.nix Normal file
View File

@@ -0,0 +1,61 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.gpg;
cfgText =
concatStringsSep "\n"
(attrValues
(mapAttrs (key: value:
if isString value
then "${key} ${value}"
else optionalString value key)
cfg.settings));
in {
options.programs.gpg = {
enable = mkEnableOption "GnuPG";
settings = mkOption {
type = types.attrsOf (types.either types.str types.bool);
example = {
no-comments = false;
s2k-cipher-algo = "AES128";
};
description = ''
GnuPG configuration options. Available options are described
in the gpg manpage:
<link xlink:href="https://gnupg.org/documentation/manpage.html"/>.
'';
};
};
config = mkIf cfg.enable {
programs.gpg.settings = {
personal-cipher-preferences = mkDefault "AES256 AES192 AES";
personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256";
personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed";
default-preference-list = mkDefault "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
cert-digest-algo = mkDefault "SHA512";
s2k-digest-algo = mkDefault "SHA512";
s2k-cipher-algo = mkDefault "AES256";
charset = mkDefault "utf-8";
fixed-list-mode = mkDefault true;
no-comments = mkDefault true;
no-emit-version = mkDefault true;
keyid-format = mkDefault "0xlong";
list-options = mkDefault "show-uid-validity";
verify-options = mkDefault "show-uid-validity";
with-fingerprint = mkDefault true;
require-cross-certification = mkDefault true;
no-symkey-cache = mkDefault true;
use-agent = mkDefault true;
};
home.packages = [ pkgs.gnupg ];
home.file.".gnupg/gpg.conf".text = cfgText;
};
}

View File

@@ -101,7 +101,7 @@ let
};
port = mkOption {
type = types.int;
type = types.port;
default = 6667;
description = "Port of the chat server.";
};

View File

@@ -0,0 +1,575 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.kakoune;
hook = types.submodule {
options = {
name = mkOption {
type = types.enum [
"NormalBegin" "NormalIdle" "NormalEnd" "NormalKey"
"InsertBegin" "InsertIdle" "InsertEnd" "InsertKey"
"InsertChar" "InsertDelete" "InsertMove" "WinCreate"
"WinClose" "WinResize" "WinDisplay" "WinSetOption"
"BufSetOption" "BufNewFile" "BufOpenFile" "BufCreate"
"BufWritePre" "BufWritePost" "BufReload" "BufClose"
"BufOpenFifo" "BufReadFifo" "BufCloseFifo" "RuntimeError"
"ModeChange" "PromptIdle" "GlobalSetOption" "KakBegin"
"KakEnd" "FocusIn" "FocusOut" "RawKey"
"InsertCompletionShow" "InsertCompletionHide"
"InsertCompletionSelect"
];
example = "SetOption";
description = ''
The name of the hook. For a description, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc#default-hooks"/>.
'';
};
once = mkOption {
type = types.bool;
default = false;
description = ''
Remove the hook after running it once.
'';
};
group = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Add the hook to the named group.
'';
};
option = mkOption {
type = types.nullOr types.str;
default = null;
example = "filetype=latex";
description = ''
Additional option to pass to the hook.
'';
};
commands = mkOption {
type = types.lines;
default = "";
example = "set-option window indentwidth 2";
description = ''
Commands to run when the hook is activated.
'';
};
};
};
keyMapping = types.submodule {
options = {
mode = mkOption {
type = types.enum [
"insert"
"normal"
"prompt"
"menu"
"user"
"goto"
"view"
"object"
];
example = "user";
description = ''
The mode in which the mapping takes effect.
'';
};
docstring = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Optional documentation text to display in info boxes.
'';
};
key = mkOption {
type = types.str;
example = "<a-x>";
description = ''
The key to be mapped. See
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc#mappable-keys"/>
for possible values.
'';
};
effect = mkOption {
type = types.str;
example = ":wq<ret>";
description = ''
The sequence of keys to be mapped.
'';
};
};
};
configModule = types.submodule {
options = {
colorScheme = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Set the color scheme. To see available schemes, enter
<command>colorscheme</command> at the kakoune prompt.
'';
};
tabStop = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
description = ''
The width of a tab in spaces. The kakoune default is
<literal>6</literal>.
'';
};
indentWidth = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
description = ''
The width of an indentation in spaces.
The kakoune default is <literal>4</literal>.
If <literal>0</literal>, a tab will be used instead.
'';
};
incrementalSearch = mkOption {
type = types.bool;
default = true;
description = ''
Execute a search as it is being typed.
'';
};
alignWithTabs = mkOption {
type = types.bool;
default = false;
description = ''
Use tabs for the align command.
'';
};
autoInfo = mkOption {
type = types.nullOr (types.listOf (types.enum [ "command" "onkey" "normal" ]));
default = null;
example = [ "command" "normal" ];
description = ''
Contexts in which to display automatic information box.
The kakoune default is <literal>[ "command" "onkey" ]</literal>.
'';
};
autoComplete = mkOption {
type = types.nullOr(types.listOf (types.enum [ "insert" "prompt" ]));
default = null;
description = ''
Modes in which to display possible completions.
The kakoune default is <literal>[ "insert" "prompt" ]</literal>.
'';
};
autoReload = mkOption {
type = types.nullOr (types.enum [ "yes" "no" "ask" ]);
default = null;
description = ''
Reload buffers when an external modification is detected.
The kakoune default is <literal>"ask"</literal>.
'';
};
scrollOff = mkOption {
type = types.nullOr (types.submodule {
options = {
lines = mkOption {
type = types.ints.unsigned;
default = 0;
description = ''
The number of lines to keep visible around the cursor.
'';
};
columns = mkOption {
type = types.ints.unsigned;
default = 0;
description = ''
The number of columns to keep visible around the cursor.
'';
};
};
});
default = null;
description = ''
How many lines and columns to keep visible around the cursor.
'';
};
ui = mkOption {
type = types.nullOr (types.submodule {
options = {
setTitle = mkOption {
type = types.bool;
default = false;
description = ''
Change the title of the terminal emulator.
'';
};
statusLine = mkOption {
type = types.enum [ "top" "bottom" ];
default = "bottom";
description = ''
Where to display the status line.
'';
};
assistant = mkOption {
type = types.enum [ "clippy" "cat" "dilbert" "none" ];
default = "clippy";
description = ''
The assistant displayed in info boxes.
'';
};
enableMouse = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable mouse support.
'';
};
changeColors = mkOption {
type = types.bool;
default = true;
description = ''
Change color palette.
'';
};
wheelDownButton = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Button to send for wheel down events.
'';
};
wheelUpButton = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Button to send for wheel up events.
'';
};
shiftFunctionKeys = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
description = ''
Amount by which shifted function keys are offset. That
is, if the terminal sends F13 for Shift-F1, this
should be <literal>12</literal>.
'';
};
useBuiltinKeyParser = mkOption {
type = types.bool;
default = false;
description = ''
Bypass ncurses key parser and use an internal one.
'';
};
};
});
default = null;
description = ''
Settings for the ncurses interface.
'';
};
showMatching = mkOption {
type = types.bool;
default = false;
description = ''
Highlight the matching char of the character under the
selections' cursor using the <literal>MatchingChar</literal>
face.
'';
};
wrapLines = mkOption {
type = types.nullOr (types.submodule {
options = {
enable = mkEnableOption "the wrap lines highlighter";
word = mkOption {
type = types.bool;
default = false;
description = ''
Wrap at word boundaries instead of codepoint boundaries.
'';
};
indent = mkOption {
type = types.bool;
default = false;
description = ''
Preserve line indentation when wrapping.
'';
};
maxWidth = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
description = ''
Wrap text at maxWidth, even if the window is wider.
'';
};
marker = mkOption {
type = types.nullOr types.str;
default = null;
example = "";
description = ''
Prefix wrapped lines with marker text.
If not <literal>null</literal>,
the marker text will be displayed in the indentation if possible.
'';
};
};
});
default = null;
description = ''
Settings for the wrap lines highlighter.
'';
};
numberLines = mkOption {
type = types.nullOr (types.submodule {
options = {
enable = mkEnableOption "the number lines highlighter";
relative = mkOption {
type = types.bool;
default = false;
description = ''
Show line numbers relative to the main cursor line.
'';
};
highlightCursor = mkOption {
type = types.bool;
default = false;
description = ''
Highlight the cursor line with a separate face.
'';
};
separator = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
String that separates the line number column from the
buffer contents. The kakoune default is
<literal>"|"</literal>.
'';
};
};
});
default = null;
description = ''
Settings for the number lines highlighter.
'';
};
showWhitespace = mkOption {
type = types.nullOr (types.submodule {
options = {
enable = mkEnableOption "the show whitespace highlighter";
lineFeed = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The character to display for line feeds.
The kakoune default is <literal>"¬"</literal>.
'';
};
space = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The character to display for spaces.
The kakoune default is <literal>"·"</literal>.
'';
};
nonBreakingSpace = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The character to display for non-breaking spaces.
The kakoune default is <literal>""</literal>.
'';
};
tab = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The character to display for tabs.
The kakoune default is <literal>""</literal>.
'';
};
tabStop = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The character to append to tabs to reach the width of a tabstop.
The kakoune default is <literal>" "</literal>.
'';
};
};
});
default = null;
description = ''
Settings for the show whitespaces highlighter.
'';
};
keyMappings = mkOption {
type = types.listOf keyMapping;
default = [];
description = ''
User-defined key mappings. For documentation, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc"/>.
'';
};
hooks = mkOption {
type = types.listOf hook;
default = [];
description = ''
Global hooks. For documentation, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc"/>.
'';
};
};
};
configFile =
let
wrapOptions = with cfg.config.wrapLines; concatStrings [
"${optionalString word " -word"}"
"${optionalString indent " -indent"}"
"${optionalString (marker != null) " -marker ${marker}"}"
"${optionalString (maxWidth != null) " -width ${toString maxWidth}"}"
];
numberLinesOptions = with cfg.config.numberLines; concatStrings [
"${optionalString relative " -relative "}"
"${optionalString highlightCursor " -hlcursor"}"
"${optionalString (separator != null) " -separator ${separator}"}"
];
uiOptions = with cfg.config.ui; concatStringsSep " " [
"ncurses_set_title=${if setTitle then "true" else "false"}"
"ncurses_status_on_top=${if (statusLine == "top") then "true" else "false"}"
"ncurses_assistant=${assistant}"
"ncurses_enable_mouse=${if enableMouse then "true" else "false"}"
"ncurses_change_colors=${if changeColors then "true" else "false"}"
"${optionalString (wheelDownButton != null)
"ncurses_wheel_down_button=${wheelDownButton}"}"
"${optionalString (wheelUpButton != null)
"ncurses_wheel_up_button=${wheelUpButton}"}"
"${optionalString (shiftFunctionKeys != null)
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
"ncurses_builtin_key_parser=${if useBuiltinKeyParser then "true" else "false"}"
];
keyMappingString = km: concatStringsSep " " [
"map global"
"${km.mode} ${km.key} '${km.effect}'"
"${optionalString (km.docstring != null) "-docstring '${km.docstring}'"}"
];
hookString = h: concatStringsSep " " [
"hook" "${optionalString (h.group != null) "-group ${group}"}"
"${optionalString (h.once) "-once"}" "global"
"${h.name}" "${optionalString (h.option != null) h.option}"
"%{ ${h.commands} }"
];
cfgStr = with cfg.config; concatStringsSep "\n" (
[ "# Generated by home-manager" ]
++ optional (colorScheme != null) "colorscheme ${colorScheme}"
++ optional (tabStop != null) "set-option global tabstop ${toString tabStop}"
++ optional (indentWidth != null) "set-option global indentwidth ${toString indentWidth}"
++ optional (!incrementalSearch) "set-option global incsearch false"
++ optional (alignWithTabs) "set-option global aligntab true"
++ optional (autoInfo != null) "set-option global autoinfo ${concatStringsSep "|" autoInfo}"
++ optional (autoComplete != null) "set-option global autocomplete ${concatStringsSep "|" autoComplete}"
++ optional (autoReload != null) "set-option global/ autoreload ${autoReload}"
++ optional (wrapLines != null && wrapLines.enable) "add-highlighter global/ wrap${wrapOptions}"
++ optional (numberLines != null && numberLines.enable)
"add-highlighter global/ number-lines${numberLinesOptions}"
++ optional showMatching "add-highlighter global/ show-matching"
++ optional (scrollOff != null)
"set-option global scrolloff ${toString scrollOff.lines},${toString scrollOff.columns}"
++ [ "# UI options" ]
++ optional (ui != null) "set-option global ui_options ${uiOptions}"
++ [ "# Key mappings" ]
++ map keyMappingString keyMappings
++ [ "# Hooks" ]
++ map hookString hooks
);
in
pkgs.writeText "kakrc" (
optionalString (cfg.config != null) cfgStr
+ "\n"
+ cfg.extraConfig
);
in
{
options = {
programs.kakoune = {
enable = mkEnableOption "the kakoune text editor";
config = mkOption {
type = types.nullOr configModule;
default = {};
description = "kakoune configuration options.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add to
<filename>~/.config/kak/kakrc</filename>.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.kakoune ];
xdg.configFile."kak/kakrc".source = configFile;
};
}

View File

@@ -25,7 +25,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.keychain;
defaultText = "pkgs.keychain";
defaultText = literalExample "pkgs.keychain";
description = ''
Keychain package to install.
'';

View File

@@ -20,7 +20,7 @@ let
}
//
optionalAttrs (tls.enable && tls.certificatesFile != null) {
CertificateFile = tls.certificatesFile;
CertificateFile = toString tls.certificatesFile;
};
masterSlaveMapping = {
@@ -112,7 +112,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.isync;
defaultText = "pkgs.isync";
defaultText = literalExample "pkgs.isync";
example = literalExample "pkgs.isync";
description = "The package to use for the mbsync binary.";
};
@@ -173,16 +173,18 @@ in
in
concatStringsSep "\n" (
[ "# Generated by Home Manager.\n" ]
++ optional (cfg.extraConfig != "") cfg.extraConfig
++ accountsConfig
++ groupsConfig
++ optional (cfg.extraConfig != "") cfg.extraConfig
) + "\n";
home.activation.createMaildir =
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
}
'';
home.activation = mkIf (mbsyncAccounts != []) {
createMaildir =
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
}
'';
};
};
}

View File

@@ -17,7 +17,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.mercurial;
defaultText = "pkgs.mercurial";
defaultText = literalExample "pkgs.mercurial";
description = "Mercurial package to install.";
};

152
modules/programs/mpv.nix Normal file
View File

@@ -0,0 +1,152 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (builtins) typeOf stringLength;
cfg = config.programs.mpv;
mpvOption = with types; either str (either int (either bool float));
mpvOptions = with types; attrsOf mpvOption;
mpvProfiles = with types; attrsOf mpvOptions;
mpvBindings = with types; attrsOf str;
renderOption = option:
rec {
int = toString option;
float = int;
bool = if option then "yes" else "no";
string = option;
}.${typeOf option};
renderOptions = options:
concatStringsSep "\n"
(mapAttrsToList
(name: value:
let
rendered = renderOption value;
length = toString (stringLength rendered);
in
"${name}=%${length}%${rendered}")
options);
renderProfiles = profiles:
concatStringsSep "\n"
(mapAttrsToList
(name: value: ''
[${name}]
${renderOptions value}
'')
profiles);
renderBindings = bindings:
concatStringsSep "\n"
(mapAttrsToList
(name: value:
"${name} ${value}")
bindings);
in {
options = {
programs.mpv = {
enable = mkEnableOption "mpv";
scripts = mkOption {
type = with types; listOf (either package str);
default = [];
example = literalExample "[ pkgs.mpvScripts.mpris ]";
description = ''
List of scripts to use with mpv.
'';
};
config = mkOption {
description = ''
Configuration written to
<filename>~/.config/mpv/mpv.conf</filename>. See
<citerefentry>
<refentrytitle>mpv</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
for the full list of options.
'';
type = mpvOptions;
default = {};
example = literalExample ''
{
profile = "gpu-hq";
force-window = "yes";
ytdl-format = "bestvideo+bestaudio";
cache-default = 4000000;
}
'';
};
profiles = mkOption {
description = ''
Sub-configuration options for specific profiles written to
<filename>~/.config/mpv/mpv.conf</filename>. See
<option>programs.mpv.config</option> for more information.
'';
type = mpvProfiles;
default = {};
example = literalExample ''
{
fast = {
vo = "vdpau";
};
"protocol.dvd" = {
profile-desc = "profile for dvd:// streams";
alang = "en";
};
}
'';
};
bindings = mkOption {
description = ''
Input configuration written to
<filename>~/.config/mpv/input.conf</filename>. See
<citerefentry>
<refentrytitle>mpv</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
for the full list of options.
'';
type = mpvBindings;
default = {};
example = literalExample ''
{
WHEEL_UP = "seek 10";
WHEEL_DOWN = "seek -10";
"Alt+0" = "set window-scale 0.5";
}
'';
};
};
};
config = mkIf cfg.enable (mkMerge [
{
home.packages = [(
if cfg.scripts == []
then pkgs.mpv
else pkgs.mpv-with-scripts.override { scripts = cfg.scripts; }
)];
}
(mkIf (cfg.config != {} || cfg.profiles != {}) {
xdg.configFile."mpv/mpv.conf".text = ''
${optionalString (cfg.config != {}) (renderOptions cfg.config)}
${optionalString (cfg.profiles != {}) (renderProfiles cfg.profiles)}
'';
})
(mkIf (cfg.bindings != {}) {
xdg.configFile."mpv/input.conf".text = renderBindings cfg.bindings;
})
]);
meta.maintainers = with maintainers; [ tadeokondrak ];
}

View File

@@ -22,6 +22,17 @@ with lib;
'';
};
tls.fingerprint = mkOption {
type = types.nullOr (types.strMatching "([[:alnum:]]{2}\:)+[[:alnum:]]{2}");
default = null;
example = "my:SH:a2:56:ha:sh";
description = ''
Fingerprint of a trusted TLS certificate.
The fingerprint can be obtained by executing
<command>msmtp --serverinfo --tls --tls-certcheck=off</command>.
'';
};
extraConfig = mkOption {
type = types.attrsOf types.str;
default = { };

View File

@@ -24,6 +24,9 @@ let
tls_starttls = onOff smtp.tls.useStartTls;
tls_trust_file = smtp.tls.certificatesFile;
}
// optionalAttrs (msmtp.tls.fingerprint != null) {
tls_fingerprint = msmtp.tls.fingerprint;
}
// optionalAttrs (smtp.port != null) {
port = toString smtp.port;
}

View File

@@ -24,6 +24,14 @@ let
merge = mergeOneOption;
};
moduleConfigure =
optionalAttrs (cfg.extraConfig != "") {
customRC = cfg.extraConfig;
}
// optionalAttrs (cfg.plugins != []) {
packages.home-manager.start = cfg.plugins;
};
in
{
@@ -107,10 +115,17 @@ in
package = mkOption {
type = types.package;
default = pkgs.neovim-unwrapped;
defaultText = "pkgs.neovim-unwrapped";
defaultText = literalExample "pkgs.neovim-unwrapped";
description = "The package to use for the neovim binary.";
};
finalPackage = mkOption {
type = types.package;
visible = false;
readOnly = true;
description = "Resulting customized neovim package.";
};
configure = mkOption {
type = types.attrs;
default = {};
@@ -130,19 +145,63 @@ in
description = ''
Generate your init file from your list of plugins and custom commands,
and loads it from the store via <command>nvim -u /nix/store/hash-vimrc</command>
</para><para>
This option is mutually exclusive with <varname>extraConfig</varname>
and <varname>plugins</varname>.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
set nocompatible
set nobackup
'';
description = ''
Custom vimrc lines.
</para><para>
This option is mutually exclusive with <varname>configure</varname>.
'';
};
plugins = mkOption {
type = with types; listOf package;
default = [ ];
example = literalExample "[ pkgs.vimPlugins.yankring ]";
description = ''
List of vim plugins to install.
</para><para>
This option is mutually exclusive with <varname>configure</varname>.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [
(pkgs.wrapNeovim cfg.package {
inherit (cfg)
extraPython3Packages withPython3
extraPythonPackages withPython
withNodeJs withRuby viAlias vimAlias configure;
})
assertions = [
{
assertion = cfg.configure == { } || moduleConfigure == { };
message = "The programs.neovim option configure is mutually exclusive"
+ " with extraConfig and plugins.";
}
];
home.packages = [ cfg.finalPackage ];
programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package {
inherit (cfg)
extraPython3Packages withPython3
extraPythonPackages withPython
withNodeJs withRuby viAlias vimAlias;
configure = cfg.configure // moduleConfigure;
};
};
}

View File

@@ -188,7 +188,7 @@ in
{
target = "${notmuchIni.database.path}/.notmuch/hooks/${name}";
source = pkgs.writeScript name ''
#!${pkgs.stdenv.shell}
#!${pkgs.runtimeShell}
export PATH="${pkgs.notmuch}/bin''${PATH:+:}$PATH"
export NOTMUCH_CONFIG="${config.xdg.configHome}/notmuch/notmuchrc"

View File

@@ -17,7 +17,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.opam;
defaultText = "pkgs.opam";
defaultText = literalExample "pkgs.opam";
description = "Opam package to install.";
};

View File

@@ -18,7 +18,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.pidgin;
defaultText = "pkgs.pidgin";
defaultText = literalExample "pkgs.pidgin";
description = "The Pidgin package to use.";
};

View File

@@ -0,0 +1,78 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.readline;
mkSetVariableStr = n: v:
let
mkValueStr = v:
if v == true then "on"
else if v == false then "off"
else if isInt v then toString v
else if isString v then v
else abort ("values ${toPretty v} is of unsupported type");
in
"set ${n} ${mkValueStr v}";
mkBindingStr = k: v: "\"${k}\": ${v}";
in
{
options.programs.readline = {
enable = mkEnableOption "readline";
bindings = mkOption {
default = {};
type = types.attrsOf types.str;
example = literalExample ''
{ "\\C-h" = "backward-kill-word"; }
'';
description = "Readline bindings.";
};
variables = mkOption {
type = with types; attrsOf (either str (either int bool));
default = {};
example = { expand-tilde = true; };
description = ''
Readline customization variable assignments.
'';
};
includeSystemConfig = mkOption {
type = types.bool;
default = true;
description = "Whether to include the system-wide configuration.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Configuration lines appended unchanged to the end of the
<filename>~/.inputrc</filename> file.
'';
};
};
config = mkIf cfg.enable {
home.file.".inputrc".text =
let
configStr = concatStringsSep "\n" (
optional cfg.includeSystemConfig "$include /etc/inputrc"
++ mapAttrsToList mkSetVariableStr cfg.variables
++ mapAttrsToList mkBindingStr cfg.bindings
);
in
''
# Generated by Home Manager.
${configStr}
${cfg.extraConfig}
'';
};
}

View File

@@ -270,7 +270,7 @@ in
theme = mkOption {
default = null;
type = with types; nullOr (either string path);
type = with types; nullOr (either str path);
example = "Arc";
description = ''
Name of theme or path to theme file in rasi format. Available

View File

@@ -0,0 +1,37 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.rtorrent;
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.rtorrent = {
enable = mkEnableOption "rTorrent";
settings = mkOption {
type = types.lines;
default = "";
description = ''
Configuration written to
<filename>~/.config/rtorrent/rtorrent.rc</filename>. See
<link xlink:href="https://github.com/rakshasa/rtorrent/wiki/Config-Guide" />
for explanation about possible values.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.rtorrent ];
xdg.configFile."rtorrent/rtorrent.rc" = mkIf (cfg.settings != "") {
text = cfg.settings;
};
};
}

View File

@@ -107,7 +107,7 @@ in
SKIM_CTRL_T_COMMAND = cfg.fileWidgetCommand;
SKIM_CTRL_T_OPTS = cfg.fileWidgetOptions;
SKIM_DEFAULT_COMMAND = cfg.defaultCommand;
SKIM_DEFAULT_OPTS = cfg.defaultOptions;
SKIM_DEFAULT_OPTIONS = cfg.defaultOptions;
}
);

View File

@@ -6,10 +6,56 @@ let
cfg = config.programs.ssh;
isPath = x: builtins.substring 0 1 (toString x) == "/";
addressPort = entry:
if isPath entry.address
then " ${entry.address}"
else " [${entry.address}]:${toString entry.port}";
yn = flag: if flag then "yes" else "no";
unwords = builtins.concatStringsSep " ";
bindOptions = {
address = mkOption {
type = types.str;
default = "localhost";
example = "example.org";
description = "The address where to bind the port.";
};
port = mkOption {
type = types.port;
example = 8080;
description = "Specifies port number to bind on bind address.";
};
};
dynamicForwardModule = types.submodule {
options = bindOptions;
};
forwardModule = types.submodule {
options = {
bind = bindOptions;
host = {
address = mkOption {
type = types.str;
example = "example.org";
description = "The address where to forward the traffic to.";
};
port = mkOption {
type = types.port;
example = 80;
description = "Specifies port number to forward the traffic to.";
};
};
};
};
matchBlockModule = types.submodule ({ name, ... }: {
options = {
host = mkOption {
@@ -21,7 +67,7 @@ let
};
port = mkOption {
type = types.nullOr types.int;
type = types.nullOr types.port;
default = null;
description = "Specifies port number to connect on remote host.";
};
@@ -152,6 +198,63 @@ let
'';
};
localForwards = mkOption {
type = types.listOf forwardModule;
default = [];
example = literalExample ''
[
{
bind.port = 8080;
host.address = "10.0.0.13";
host.port = 80;
}
];
'';
description = ''
Specify local port forwardings. See
<citerefentry>
<refentrytitle>ssh_config</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for <literal>LocalForward</literal>.
'';
};
remoteForwards = mkOption {
type = types.listOf forwardModule;
default = [];
example = literalExample ''
[
{
bind.port = 8080;
host.address = "10.0.0.13";
host.port = 80;
}
];
'';
description = ''
Specify remote port forwardings. See
<citerefentry>
<refentrytitle>ssh_config</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for <literal>RemoteForward</literal>.
'';
};
dynamicForwards = mkOption {
type = types.listOf dynamicForwardModule;
default = [];
example = literalExample ''
[ { port = 8080; } ];
'';
description = ''
Specify dynamic port forwardings. See
<citerefentry>
<refentrytitle>ssh_config</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for <literal>DynamicForward</literal>.
'';
};
extraOptions = mkOption {
type = types.attrsOf types.str;
default = {};
@@ -181,6 +284,9 @@ let
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}"
++ optional (cf.proxyJump != null) " ProxyJump ${cf.proxyJump}"
++ map (file: " IdentityFile ${file}") cf.identityFile
++ map (f: " LocalForward" + addressPort f.bind + addressPort f.host) cf.localForwards
++ map (f: " RemoteForward" + addressPort f.bind + addressPort f.host) cf.remoteForwards
++ map (f: " DynamicForward" + addressPort f) cf.dynamicForwards
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
);
@@ -308,6 +414,25 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion =
let
# `builtins.any`/`lib.lists.any` does not return `true` if there are no elements.
any' = pred: items: if items == [] then true else any pred items;
# Check that if `entry.address` is defined, and is a path, that `entry.port` has not
# been defined.
noPathWithPort = entry: entry ? address && isPath entry.address -> !(entry ? port);
checkDynamic = block: any' noPathWithPort block.dynamicForwards;
checkBindAndHost = fwd: noPathWithPort fwd.bind && noPathWithPort fwd.host;
checkLocal = block: any' checkBindAndHost block.localForwards;
checkRemote = block: any' checkBindAndHost block.remoteForwards;
checkMatchBlock = block: all (fn: fn block) [ checkLocal checkRemote checkDynamic ];
in any' checkMatchBlock (builtins.attrValues cfg.matchBlocks);
message = "Forwarded paths cannot have ports.";
}
];
home.file.".ssh/config".text = ''
${concatStringsSep "\n" (
mapAttrsToList (n: v: "${n} ${v}") cfg.extraOptionOverrides)}

View File

@@ -0,0 +1,91 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.starship;
configFile = config:
pkgs.runCommand "config.toml"
{
buildInputs = [ pkgs.remarshal ];
preferLocalBuild = true;
allowSubstitutes = false;
}
''
remarshal -if json -of toml \
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
> $out
'';
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.starship = {
enable = mkEnableOption "starship";
settings = mkOption {
type = types.attrs;
default = {};
description = ''
Configuration written to
<filename>~/.config/starship.toml</filename>.
</para><para>
See <link xlink:href="https://starship.rs/config/" /> for the full list
of options.
'';
};
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.starship ];
xdg.configFile."starship.toml" = mkIf (cfg.settings != {}) {
source = configFile cfg.settings;
};
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ -z $INSIDE_EMACS ]]; then
eval "$(${pkgs.starship}/bin/starship init bash)"
fi
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
if [ -z "$INSIDE_EMACS" ]; then
eval "$(${pkgs.starship}/bin/starship init zsh)"
fi
'';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
if test -z "$INSIDE_EMACS"
eval (${pkgs.starship}/bin/starship init fish)
end
'';
};
}

View File

@@ -178,7 +178,7 @@ in
scrollbar = mkOption {
default = null;
type = types.nullOr (types.enum [ "off" "left" "right" ]);
description = "Scroll to the bottom when the shell generates output.";
description = "Scrollbar position.";
};
backgroundColor = mkOption {

View File

@@ -65,6 +65,11 @@ let
bind C-${cfg.shortcut} last-window
''}
${optionalString cfg.disableConfirmationPrompt ''
bind-key & kill-window
bind-key x kill-pane
''}
setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
set -s escape-time ${toString cfg.escapeTime}
@@ -109,6 +114,14 @@ in
'';
};
disableConfirmationPrompt = mkOption {
default = false;
type = types.bool;
description = ''
Disable confirmation prompt before killing a pane or window
'';
};
enable = mkEnableOption "tmux";
escapeTime = mkOption {
@@ -156,7 +169,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.tmux;
defaultText = "pkgs.tmux";
defaultText = literalExample "pkgs.tmux";
example = literalExample "pkgs.tmux";
description = "The tmux package to install";
};

View File

@@ -15,7 +15,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.rxvt_unicode;
defaultText = "pkgs.rxvt_unicode";
defaultText = literalExample "pkgs.rxvt_unicode";
description = "rxvt-unicode package to install.";
};

View File

@@ -5,7 +5,7 @@ with lib;
let
cfg = config.programs.vim;
defaultPlugins = [ "sensible" ];
defaultPlugins = [ pkgs.vimPlugins.sensible ];
knownSettings = {
background = types.enum [ "dark" "light" ];
@@ -55,6 +55,16 @@ let
in
optionalString (value != null) ("set " + v);
plugins =
let
vpkgs = pkgs.vimPlugins;
getPkg = p:
if isDerivation p
then [ p ]
else optional (isString p && hasAttr p vpkgs) vpkgs.${p};
in
concatMap getPkg cfg.plugins;
in
{
@@ -63,12 +73,16 @@ in
enable = mkEnableOption "Vim";
plugins = mkOption {
type = types.listOf types.str;
type = with types; listOf (either str package);
default = defaultPlugins;
example = [ "YankRing" ];
example = literalExample ''[ pkgs.vimPlugins.YankRing ]'';
description = ''
List of vim plugins to install. To get a list of supported plugins run:
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A vimPlugins</command>.
</para><para>
Note: String values are deprecated, please use actual packages.
'';
};
@@ -135,16 +149,43 @@ in
vim = pkgs.vim_configurable.customize {
name = "vim";
vimrcConfig.customRC = customRC;
vimrcConfig.vam.knownPlugins = pkgs.vimPlugins;
vimrcConfig.vam.pluginDictionaries = [
{ names = defaultPlugins ++ cfg.plugins; }
];
};
vimrcConfig = {
inherit customRC;
in mkIf cfg.enable {
programs.vim.package = vim;
home.packages = [ cfg.package ];
}
packages.home-manager.start = plugins;
};
};
in
mkIf cfg.enable {
assertions =
let
packagesNotFound = filter (p: isString p && (!hasAttr p pkgs.vimPlugins)) cfg.plugins;
in
[
{
assertion = packagesNotFound == [];
message = "Following VIM plugin not found in pkgs.vimPlugins: ${
concatMapStringsSep ", " (p: ''"${p}"'') packagesNotFound
}";
}
];
warnings =
let
stringPlugins = filter isString cfg.plugins;
in
optional (stringPlugins != []) ''
Specifying VIM plugins using strings is deprecated, found ${
concatMapStringsSep ", " (p: ''"${p}"'') stringPlugins
} as strings.
'';
home.packages = [ cfg.package ];
programs.vim = {
package = vim;
plugins = defaultPlugins;
};
}
);
}

View File

@@ -6,6 +6,12 @@ let
cfg = config.programs.vscode;
configFilePath =
if pkgs.stdenv.hostPlatform.isDarwin then
"Library/Application Support/Code/User/settings.json"
else
"${config.xdg.configHome}/Code/User/settings.json";
in
{
@@ -23,14 +29,15 @@ in
}
'';
description = ''
Configuration written to
<filename>~/.config/Code/User/settings.json</filename>.
Configuration written to Visual Studio Code's
<filename>settings.json</filename>.
'';
};
extensions = mkOption {
type = types.listOf types.package;
default = [];
example = literalExample "[ pkgs.vscode-extensions.bbenoist.Nix ]";
description = ''
The extensions Visual Studio Code should be started with.
These will override but not delete manually installed ones.
@@ -46,7 +53,6 @@ in
})
];
xdg.configFile."Code/User/settings.json".text =
builtins.toJSON cfg.userSettings;
home.file."${configFilePath}".text = builtins.toJSON cfg.userSettings;
};
}

View File

@@ -0,0 +1,66 @@
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.programs.vscode.haskell;
defaultHieNixExe = hie-nix.hies + "/bin/hie-wrapper";
defaultHieNixExeText = literalExample
"\"\${pkgs.hie-nix.hies}/bin/hie-wrapper\"";
hie-nix = pkgs.hie-nix or (abort ''
vscode.haskell: pkgs.hie-nix missing. Please add an overlay such as:
${exampleOverlay}
'');
exampleOverlay = ''
nixpkgs.overlays = [
(self: super: { hie-nix = import ~/src/hie-nix {}; })
]
'';
in
{
options.programs.vscode.haskell = {
enable = mkEnableOption "Haskell integration for Visual Studio Code";
hie.enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable Haskell IDE engine integration.";
};
hie.executablePath = mkOption {
type = types.path;
default = defaultHieNixExe;
defaultText = defaultHieNixExeText;
description = ''
The path to the Haskell IDE Engine executable.
</para><para>
Because hie-nix is not packaged in Nixpkgs, you need to add it as an
overlay or set this option. Example overlay configuration:
<programlisting language="nix">${exampleOverlay}</programlisting>
'';
example = literalExample ''
(import ~/src/haskell-ide-engine {}).hies + "/bin/hie-wrapper";
'';
};
};
config = mkIf cfg.enable {
programs.vscode.userSettings = mkIf cfg.hie.enable {
"languageServerHaskell.enableHIE" = true;
"languageServerHaskell.hieExecutablePath" = cfg.hie.executablePath;
};
programs.vscode.extensions =
[
pkgs.vscode-extensions.justusadam.language-haskell
]
++ lib.optional cfg.hie.enable
pkgs.vscode-extensions.alanz.vscode-hie-server;
};
}

View File

@@ -0,0 +1,86 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.z-lua;
aliases = {
zz = "z -c"; # restrict matches to subdirs of $PWD
zi = "z -i"; # cd with interactive selection
zf = "z -I"; # use fzf to select in multiple matches
zb = "z -b"; # quickly cd to the parent directory
zh = "z -I -t ."; # fzf
};
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.z-lua = {
enable = mkEnableOption "z.lua";
options = mkOption {
type = types.listOf types.str;
default = [];
example = [ "enhanced" "once" "fzf" ];
description = ''
List of options to pass to z.lua.
'';
};
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.
'';
};
enableAliases = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable recommended z.lua aliases.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.z-lua ];
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
eval "$(${pkgs.z-lua}/bin/z --init bash ${concatStringsSep " " cfg.options})"
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${pkgs.z-lua}/bin/z --init zsh ${concatStringsSep " " cfg.options})"
'';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
source (${pkgs.z-lua}/bin/z --init fish ${concatStringsSep " " cfg.options} | psub)
'';
programs.bash.shellAliases = mkIf cfg.enableAliases aliases;
programs.zsh.shellAliases = mkIf cfg.enableAliases aliases;
};
}

View File

@@ -149,6 +149,14 @@ in
programs.zsh = {
enable = mkEnableOption "Z shell (Zsh)";
autocd = mkOption {
default = null;
description = ''
Automatically enter into a directory if typed directly into shell.
'';
type = types.nullOr types.bool;
};
dotDir = mkOption {
default = null;
example = ".config/zsh";
@@ -202,17 +210,29 @@ in
sessionVariables = mkOption {
default = {};
type = with types; attrsOf (either int str);
type = types.attrs;
example = { MAILCHECK = 30; };
description = "Environment variables that will be set for zsh session.";
};
initExtraBeforeCompInit = mkOption {
default = "";
type = types.lines;
description = "Extra commands that should be added to <filename>.zshrc</filename> before compinit.";
};
initExtra = mkOption {
default = "";
type = types.lines;
description = "Extra commands that should be added to <filename>.zshrc</filename>.";
};
envExtra = mkOption {
default = "";
type = types.lines;
description = "Extra commands that should be added to <filename>.zshenv</filename>.";
};
profileExtra = mkOption {
default = "";
type = types.lines;
@@ -279,6 +299,10 @@ in
};
config = mkIf cfg.enable (mkMerge [
(mkIf (cfg.envExtra != "") {
home.file."${relToDotDir ".zshenv"}".text = cfg.envExtra;
})
(mkIf (cfg.profileExtra != "") {
home.file."${relToDotDir ".zprofile"}".text = cfg.profileExtra;
})
@@ -294,7 +318,7 @@ in
(mkIf cfg.oh-my-zsh.enable {
home.file."${relToDotDir ".zshenv"}".text = ''
ZSH="${pkgs.oh-my-zsh}/share/oh-my-zsh";
ZSH_CACHE_DIR="''${XDG_CACHE_HOME:-''$HOME/.cache}/oh-my-zsh";
ZSH_CACHE_DIR="${config.xdg.cacheHome}/oh-my-zsh";
'';
})
@@ -333,12 +357,20 @@ in
${localVarsStr}
${cfg.initExtraBeforeCompInit}
${concatStrings (map (plugin: ''
path+="$HOME/${pluginsDir}/${plugin.name}"
fpath+="$HOME/${pluginsDir}/${plugin.name}"
'') cfg.plugins)}
${optionalString cfg.enableCompletion "autoload -U compinit && compinit"}
# Oh-My-Zsh calls compinit during initialization,
# calling it twice causes sight start up slowdown
# as all $fpath entries will be traversed again.
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable)
"autoload -U compinit && compinit"
}
${optionalString cfg.enableAutosuggestions
"source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
}
@@ -378,6 +410,7 @@ in
${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}
${cfg.initExtra}
@@ -387,10 +420,9 @@ in
}
(mkIf cfg.oh-my-zsh.enable {
# Oh-My-Zsh calls compinit during initialization,
# calling it twice causes sight start up slowdown
# as all $fpath entries will be traversed again.
programs.zsh.enableCompletion = mkForce false;
# Make sure we create a cache directory since some plugins expect it to exist
# See: https://github.com/rycee/home-manager/issues/761
home.file."${config.xdg.cacheHome}/oh-my-zsh/.keep".text = "";
})
(mkIf (cfg.plugins != []) {

View File

@@ -5,15 +5,18 @@ with lib;
{
options = {
services.blueman-applet = {
enable = mkEnableOption ''
Blueman applet.
Note, for the applet to work, 'blueman' package should also be installed system-wide
since it requires running 'blueman-mechanism' service activated via dbus.
You can add it to the dbus packages in system configuration:
services.dbus.packages = [ pkgs.blueman ];
'';
enable = mkEnableOption "" // {
description = ''
Whether to enable the Blueman applet.
</para><para>
Note, for the applet to work, the 'blueman' service should
be enabled system-wide. You can enable it in the system
configuration using
<programlisting language="nix">
services.blueman.enable = true;
</programlisting>
'';
};
};
};

View File

@@ -263,7 +263,7 @@ in {
package = mkOption {
type = types.package;
default = pkgs.compton;
defaultText = "pkgs.compton";
defaultText = literalExample "pkgs.compton";
example = literalExample "pkgs.compton";
description = ''
Compton derivation to use.

View File

@@ -0,0 +1,70 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.dwm-status;
features = [ "audio" "backlight" "battery" "cpu_load" "network" "time" ];
configText = builtins.toJSON ({ inherit (cfg) order; } // cfg.extraConfig);
configFile = pkgs.writeText "dwm-status.json" configText;
in
{
options = {
services.dwm-status = {
enable = mkEnableOption "dwm-status user service";
package = mkOption {
type = types.package;
default = pkgs.dwm-status;
defaultText = literalExample "pkgs.dwm-status";
example = "pkgs.dwm-status.override { enableAlsaUtils = false; }";
description = "Which dwm-status package to use.";
};
order = mkOption {
type = types.listOf (types.enum features);
description = "List of enabled features in order.";
};
extraConfig = mkOption {
type = types.attrs;
default = {};
example = literalExample ''
{
separator = "#";
battery = {
notifier_levels = [ 2 5 10 15 20 ];
};
time = {
format = "%H:%M";
};
}
'';
description = "Extra config of dwm-status.";
};
};
};
config = mkIf cfg.enable {
systemd.user.services.dwm-status = {
Unit = {
Description = "DWM status service";
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${cfg.package}/bin/dwm-status ${configFile}";
};
};
};
}

View File

@@ -35,7 +35,7 @@ in
};
Service = {
ExecStart = "${pkgs.stdenv.shell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
ExecStart = "${pkgs.runtimeShell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs)'";
Restart = "on-failure";
};

View File

@@ -23,7 +23,7 @@ in
systemd.user.services.flameshot = {
Unit = {
Description = "Powerful yet simple to use screenshot software";
Description = "Flameshot screenshot tool";
After = [
"graphical-session-pre.target"
"polybar.service"

View File

@@ -0,0 +1,61 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.getmail;
accounts = filter (a: a.getmail.enable)
(attrValues config.accounts.email.accounts);
# Note: The getmail service does not expect a path, but just the filename!
renderConfigFilepath = a: if a.primary then "getmailrc" else "getmail${a.name}";
configFiles = concatMapStringsSep " " (a: " --rcfile ${renderConfigFilepath a}") accounts;
in
{
options = {
services.getmail = {
enable = mkEnableOption "the getmail systemd service to automatically retrieve mail";
frequency = mkOption {
type = types.str;
default = "*:0/5";
example = "hourly";
description = ''
The refresh frequency. Check <literal>man systemd.time</literal> for
more information on the syntax. If you use a gpg-agent in
combination with the passwordCommand, keep the poll
frequency below the cache-ttl value (as set by the
<literal>default</literal>) to avoid pinentry asking
permanently for a password.
'';
};
};
};
config = mkIf cfg.enable {
systemd.user.services.getmail = {
Unit = {
Description = "getmail email fetcher";
};
Service = {
ExecStart = "${pkgs.getmail}/bin/getmail ${configFiles}";
};
};
systemd.user.timers.getmail = {
Unit = {
Description = "getmail email fetcher";
};
Timer = {
OnCalendar = "${cfg.frequency}";
Unit = "getmail.service";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}

View File

@@ -70,6 +70,14 @@ in
'';
};
sshKeys = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
Which GPG keys (by keygrip) to expose as SSH keys.
'';
};
enableExtraSocket = mkOption {
type = types.bool;
default = false;
@@ -157,6 +165,11 @@ in
programs.zsh.initExtra = gpgInitStr;
}
(mkIf (cfg.sshKeys != null) {
# Trailing newlines are important
home.file.".gnupg/sshcontrol".text = concatMapStrings (s: "${s}\n") cfg.sshKeys;
})
# The systemd units below are direct translations of the
# descriptions in the
#

View File

@@ -0,0 +1,84 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.hound;
configFile = pkgs.writeText "hound-config.json" (
builtins.toJSON {
max-concurrent-indexers = cfg.maxConcurrentIndexers;
dbpath = cfg.databasePath;
repos = cfg.repositories;
health-check-url = "/healthz";
}
);
houndOptions = [
"--addr ${cfg.listenAddress}"
"--conf ${configFile}"
];
in
{
meta.maintainers = [ maintainers.adisbladis ];
options.services.hound = {
enable = mkEnableOption "hound";
maxConcurrentIndexers = mkOption {
type = types.ints.positive;
default = 2;
description = "Limit the amount of concurrent indexers.";
};
databasePath = mkOption {
type = types.path;
default = "${config.xdg.dataHome}/hound";
defaultText = "\$XDG_DATA_HOME/hound";
description = "The Hound database path.";
};
listenAddress = mkOption {
type = types.str;
default = "localhost:6080";
description = "Listen address of the Hound daemon.";
};
repositories = mkOption {
type = types.attrsOf (types.uniq types.attrs);
default = {};
example = literalExample ''
{
SomeGitRepo = {
url = "https://www.github.com/YourOrganization/RepoOne.git";
ms-between-poll = 10000;
exclude-dot-files = true;
};
}
'';
description = "The repository configuration.";
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.hound ];
systemd.user.services.hound = {
Unit = {
Description = "Hound source code search engine";
};
Install = {
WantedBy = [ "default.target" ];
};
Service = {
Environment = "PATH=${makeBinPath [ pkgs.mercurial pkgs.git ]}";
ExecStart = "${pkgs.hound}/bin/houndd ${concatStringsSep " " houndOptions}";
};
};
};
}

View File

@@ -0,0 +1,30 @@
{ lib, ... }:
with lib;
{
options.imapnotify = {
enable = mkEnableOption "imapnotify";
onNotify = mkOption {
type = with types; either str (attrsOf str);
default = "";
example = "\${pkgs.isync}/bin/mbsync test-%s";
description = "Shell commands to run on any event.";
};
onNotifyPost = mkOption {
type = with types; either str (attrsOf str);
default = "";
example = { mail = "\${pkgs.notmuch}/bin/notmuch new && \${pkgs.libnotify}/bin/notify-send 'New mail arrived'"; };
description = "Shell commands to run after onNotify event.";
};
boxes = mkOption {
type = types.listOf types.str;
default = [];
example = [ "Inbox" "[Gmail]/MyLabel" ];
description = "IMAP folders to watch.";
};
};
}

View File

@@ -0,0 +1,107 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.imapnotify;
safeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""];
imapnotifyAccounts =
filter (a: a.imapnotify.enable)
(attrValues config.accounts.email.accounts);
genAccountUnit = account:
let
name = safeName account.name;
in
{
name = "imapnotify-${name}";
value = {
Unit = {
Description = "imapnotify for ${name}";
};
Service = {
ExecStart = "${pkgs.imapnotify}/bin/imapnotify -c ${genAccountConfig account}";
} // optionalAttrs account.notmuch.enable {
Environment = "NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc";
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
genAccountConfig = account:
pkgs.writeText "imapnotify-${safeName account.name}-config.js" (
let
port =
if account.imap.port != null then account.imap.port
else if account.imap.tls.enable then 993
else 143;
toJSON = builtins.toJSON;
in
''
var child_process = require('child_process');
function getStdout(cmd) {
var stdout = child_process.execSync(cmd);
return stdout.toString().trim();
}
exports.host = ${toJSON account.imap.host}
exports.port = ${toJSON port};
exports.tls = ${toJSON account.imap.tls.enable};
exports.username = ${toJSON account.userName};
exports.password = getStdout("${toString account.passwordCommand}");
exports.onNotify = ${toJSON account.imapnotify.onNotify};
exports.onNotifyPost = ${toJSON account.imapnotify.onNotifyPost};
exports.boxes = ${toJSON account.imapnotify.boxes};
''
);
in
{
meta.maintainers = [ maintainers.nickhu ];
options = {
services.imapnotify = {
enable = mkEnableOption "imapnotify";
};
accounts.email.accounts = mkOption {
type = with types; attrsOf (submodule (
import ./imapnotify-accounts.nix
));
};
};
config = mkIf cfg.enable {
assertions =
let
checkAccounts = pred: msg:
let
badAccounts = filter pred imapnotifyAccounts;
in
{
assertion = badAccounts == [];
message = "imapnotify: Missing ${msg} for accounts: "
+ concatMapStringsSep ", " (a: a.name) badAccounts;
};
in
[
(checkAccounts (a: a.maildir == null) "maildir configuration")
(checkAccounts (a: a.imap == null) "IMAP configuration")
(checkAccounts (a: a.passwordCommand == null) "password command")
(checkAccounts (a: a.userName == null) "username")
];
systemd.user.services =
listToAttrs (map genAccountUnit imapnotifyAccounts);
};
}

View File

@@ -42,7 +42,7 @@ in
Service = {
Environment = "PATH=${config.home.profileDirectory}/bin";
ExecStart = "${package}/lib/libexec/kdeconnectd";
ExecStart = "${package}/libexec/kdeconnectd";
Restart = "on-abort";
};
};

View File

@@ -0,0 +1,58 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.lorri;
in
{
meta.maintainers = [ maintainers.gerschtli ];
options = {
services.lorri.enable = mkEnableOption "lorri build daemon";
};
config = mkIf cfg.enable {
home.packages = [ pkgs.lorri ];
systemd.user = {
services.lorri = {
Unit = {
Description = "lorri build daemon";
Requires = "lorri.socket";
After = "lorri.socket";
RefuseManualStart = true;
};
Service = {
ExecStart = "${pkgs.lorri}/bin/lorri daemon";
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = "read-only";
Restart = "on-failure";
Environment =
let path = with pkgs; makeSearchPath "bin" [ nix gitMinimal gnutar gzip ];
in "PATH=${path}";
};
};
sockets.lorri = {
Unit = {
Description = "Socket for lorri build daemon";
};
Socket = {
ListenStream = "%t/lorri/daemon.socket";
RuntimeDirectory = "lorri";
};
Install = {
WantedBy = [ "sockets.target" ];
};
};
};
};
}

View File

@@ -22,7 +22,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.isync;
defaultText = "pkgs.isync";
defaultText = literalExample "pkgs.isync";
example = literalExample "pkgs.isync";
description = "The package to use for the mbsync binary.";
};
@@ -71,7 +71,7 @@ in
postExec = mkOption {
type = types.nullOr types.str;
default = null;
example = "mu index";
example = "\${pkgs.mu}/bin/mu index";
description = ''
An optional command to run after mbsync executes successfully.
This is useful for running mailbox indexing tools.
@@ -83,7 +83,6 @@ in
systemd.user.services.mbsync = {
Unit = {
Description = "mbsync mailbox synchronization";
PartOf = [ "network-online.target" ];
};
Service = {

View File

@@ -16,7 +16,6 @@ let
''}
state_file "${cfg.dataDir}/state"
sticker_file "${cfg.dataDir}/sticker.sql"
log_file "syslog"
${optionalString (cfg.network.listenAddress != "any")
''bind_to_address "${cfg.network.listenAddress}"''}
@@ -46,6 +45,7 @@ in {
type = types.path;
default = "${config.home.homeDirectory}/music";
defaultText = "$HOME/music";
apply = toString; # Prevent copies to Nix store.
description = ''
The directory where mpd reads music from.
'';
@@ -55,6 +55,7 @@ in {
type = types.path;
default = "${cfg.dataDir}/playlists";
defaultText = ''''${dataDir}/playlists'';
apply = toString; # Prevent copies to Nix store.
description = ''
The directory where mpd stores playlists.
'';
@@ -79,6 +80,7 @@ in {
type = types.path;
default = "${config.xdg.dataHome}/${name}";
defaultText = "$XDG_DATA_HOME/mpd";
apply = toString; # Prevent copies to Nix store.
description = ''
The directory where MPD stores its state, tag cache,
playlists etc.
@@ -98,7 +100,7 @@ in {
};
port = mkOption {
type = types.ints.positive;
type = types.port;
default = 6600;
description = ''
The TCP port on which the the daemon will listen.

View File

@@ -42,7 +42,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.mpdris2;
defaultText = "pkgs.mpdris2";
defaultText = literalExample "pkgs.mpdris2";
description = "The mpDris2 package to use.";
};
@@ -56,7 +56,7 @@ in
};
port = mkOption {
type = types.ints.positive;
type = types.port;
default = config.services.mpd.network.port;
defaultText = "config.services.mpd.network.port";
description = ''
@@ -86,15 +86,21 @@ in
xdg.configFile."mpDris2/mpDris2.conf".text = toIni mpdris2Conf;
systemd.user.services.mpdris2 = {
Install = {
WantedBy = [ "default.target" ];
};
Unit = {
Description = "MPRIS 2 support for MPD";
After = [ "graphical-session-pre.target" "mpd.service" ];
PartOf = [ "graphical-session.target" ];
After = [ "mpd.service" ];
};
Service = {
Type = "simple";
Restart = "on-failure";
RestartSec = "5s";
ExecStart = "${cfg.package}/bin/mpDris2";
BusName = "org.mpris.MediaPlayer2.mpd";
};
};
};

View File

@@ -0,0 +1,211 @@
{ config, lib, pkgs, ... }:
with lib;
# Documentation was partially copied from the muchsync manual.
# See http://www.muchsync.org/muchsync.html
let
cfg = config.services.muchsync;
syncOptions = {
options = {
frequency = mkOption {
type = types.str;
default = "*:0/5";
description = ''
How often to run <command>muchsync</command>. This
value is passed to the systemd timer configuration as the
<literal>OnCalendar</literal> option. See
<citerefentry>
<refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum>
</citerefentry>
for more information about the format.
'';
};
sshCommand = mkOption {
type = types.str;
default = "${pkgs.openssh}/bin/ssh -CTaxq";
defaultText = "ssh -CTaxq";
description = ''
Specifies a command line to pass to <command>/bin/sh</command>
to execute a command on another machine.
</para><para>
Note that because this string is passed to the shell,
special characters including spaces may need to be escaped.
'';
};
upload = mkOption {
type = types.bool;
default = true;
description = ''
Whether to propagate local changes to the remote.
'';
};
local = {
checkForModifiedFiles = mkOption {
type = types.bool;
default = false;
description = ''
Check for locally modified files.
Without this option, muchsync assumes that files in a maildir are
never edited.
</para><para>
<option>checkForModifiedFiles</option> disables certain
optimizations so as to make muchsync at least check the timestamp on
every file, which will detect modified files at the cost of a longer
startup time.
</para><para>
This option is useful if your software regularly modifies the
contents of mail files (e.g., because you are running offlineimap
with "synclabels = yes").
'';
};
importNew = mkOption {
type = types.bool;
default = true;
description = ''
Whether to begin the synchronisation by running
<command>notmuch new</command> locally.
'';
};
};
remote = {
host = mkOption {
type = types.str;
description = ''
Remote SSH host to synchronize with.
'';
};
muchsyncPath = mkOption {
type = types.str;
default = "";
defaultText = "$PATH/muchsync";
description = ''
Specifies the path to muchsync on the server.
Ordinarily, muchsync should be in the default PATH on the server
so this option is not required.
However, this option is useful if you have to install muchsync in
a non-standard place or wish to test development versions of the
code.
'';
};
checkForModifiedFiles = mkOption {
type = types.bool;
default = false;
description = ''
Check for modified files on the remote side.
Without this option, muchsync assumes that files in a maildir are
never edited.
</para><para>
<option>checkForModifiedFiles</option> disables certain
optimizations so as to make muchsync at least check the timestamp on
every file, which will detect modified files at the cost of a longer
startup time.
</para><para>
This option is useful if your software regularly modifies the
contents of mail files (e.g., because you are running offlineimap
with "synclabels = yes").
'';
};
importNew = mkOption {
type = types.bool;
default = true;
description = ''
Whether to begin the synchronisation by running
<command>notmuch new</command> on the remote side.
'';
};
};
};
};
in {
meta.maintainers = with maintainers; [ pacien ];
options.services.muchsync = {
remotes = mkOption {
type = with types; attrsOf (submodule syncOptions);
default = { };
example = literalExample ''
{
server = {
frequency = "*:0/10";
remote.host = "server.tld";
};
}
'';
description = ''
Muchsync remotes to synchronise with.
'';
};
};
config = let
mapRemotes = gen: with attrsets; mapAttrs'
(name: remoteCfg: nameValuePair "muchsync-${name}" (gen name remoteCfg))
cfg.remotes;
in mkIf (cfg.remotes != { }) {
assertions = [
{
assertion = config.programs.notmuch.enable;
message = ''
The muchsync module requires 'programs.notmuch.enable = true'.
'';
}
];
systemd.user.services = mapRemotes (name: remoteCfg: {
Unit = {
Description = "muchsync sync service (${name})";
};
Service = {
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
Environment = [
''"PATH=${pkgs.notmuch}/bin"''
''"NOTMUCH_CONFIG=${config.home.sessionVariables.NOTMUCH_CONFIG}"''
''"NMBGIT=${config.home.sessionVariables.NMBGIT}"''
];
ExecStart = concatStringsSep " " (
[ "${pkgs.muchsync}/bin/muchsync" ]
++ [ "-s ${escapeShellArg remoteCfg.sshCommand}" ]
++ optional (!remoteCfg.upload) "--noup"
# local configuration
++ optional remoteCfg.local.checkForModifiedFiles "-F"
++ optional (!remoteCfg.local.importNew) "--nonew"
# remote configuration
++ [ (escapeShellArg remoteCfg.remote.host) ]
++ optional (remoteCfg.remote.muchsyncPath != "")
"-r ${escapeShellArg remoteCfg.remote.muchsyncPath}"
++ optional remoteCfg.remote.checkForModifiedFiles "-F"
++ optional (!remoteCfg.remote.importNew) "--nonew"
);
};
});
systemd.user.timers = mapRemotes (name: remoteCfg: {
Unit = {
Description = "muchsync periodic sync (${name})";
};
Timer = {
Unit = "muchsync-${name}.service";
OnCalendar = remoteCfg.frequency;
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
});
};
}

View File

@@ -19,24 +19,24 @@ in
config = mkIf cfg.enable {
systemd.user.services.network-manager-applet = {
Unit = {
Description = "Network Manager applet";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Unit = {
Description = "Network Manager applet";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
ExecStart = toString (
[
"${pkgs.networkmanagerapplet}/bin/nm-applet"
"--sm-disable"
] ++ optional config.xsession.preferStatusNotifierItems "--indicator"
);
};
Service = {
ExecStart = toString (
[
"${pkgs.networkmanagerapplet}/bin/nm-applet"
"--sm-disable"
] ++ optional config.xsession.preferStatusNotifierItems "--indicator"
);
};
};
};
}

View File

@@ -37,7 +37,7 @@ in
package = mkOption {
type = types.package;
default = pkgs.polybar;
defaultText = "pkgs.polybar";
defaultText = literalExample "pkgs.polybar";
description = "Polybar package to install.";
example = literalExample ''
pkgs.polybar.override {
@@ -131,6 +131,7 @@ in
scriptPkg = pkgs.writeShellScriptBin "polybar-start" cfg.script;
in
"${scriptPkg}/bin/polybar-start";
Restart = "on-failure";
};
Install = {

View File

@@ -6,6 +6,15 @@ let
cfg = config.services.random-background;
flags = lib.concatStringsSep " " (
[
"--bg-${cfg.display}"
"--no-fehbg"
"--randomize"
]
++ lib.optional (!cfg.enableXinerama) "--no-xinerama"
);
in
{
@@ -13,7 +22,17 @@ in
options = {
services.random-background = {
enable = mkEnableOption "random desktop background";
enable = mkEnableOption "" // {
description = ''
Whether to enable random desktop background.
</para><para>
Note, if you are using NixOS and have set up a custom
desktop manager session for Home Manager, then the session
configuration must have the <option>bgSupport</option>
option set to <literal>true</literal> or the background
image set by this module may be overwritten.
'';
};
imageDirectory = mkOption {
type = types.str;
@@ -25,6 +44,12 @@ in
'';
};
display = mkOption {
type = types.enum [ "center" "fill" "max" "scale" "tile" ];
default = "fill";
description = "Display background images according to this option.";
};
interval = mkOption {
default = null;
type = types.nullOr types.str;
@@ -35,6 +60,16 @@ in
as a duration understood by systemd.
'';
};
enableXinerama = mkOption {
default = true;
type = types.bool;
description = ''
Will place a separate image per screen when enabled,
otherwise a single image will be stretched across all
screens.
'';
};
};
};
@@ -50,7 +85,7 @@ in
Service = {
Type = "oneshot";
ExecStart = "${pkgs.feh}/bin/feh --randomize --bg-fill ${cfg.imageDirectory}";
ExecStart = "${pkgs.feh}/bin/feh ${flags} ${cfg.imageDirectory}";
IOSchedulingClass = "idle";
};

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