Compare commits

...

236 Commits

Author SHA1 Message Date
Symphorien Gibol
e6f96b6aa3 unison: fix escaping of arguments
The `ExecStart=` option of systemd must take arguments fully quoted.
That is,

    "-sshargs=-i somekey"

and not

    -ssargs="-i somekey"

Additionally, inside arguments passed to unison, `=` characters must
be quoted. After unquotation by systemd, one must have

    -sshargs=-o Foo\=4

instead of

    -sshargs=-o Foo=4

(cherry picked from commit 92c682cd10)

Fixes #1500
2020-09-18 00:51:16 +02:00
jD91mZM2
4a8d628054 xdg-user-dirs: fix erroneous dirs file
Before this change,

```rust
fn main() {
    println!("{:?}", glib::get_user_special_dir(glib::UserDirectory::Documents));
}
```

would return `None` even though `~/Documents` is available and
`xdg.userDirs.enable = true`. Checking the differences between
`xdg-user-dirs-update` shows that the latter has quotes around each
thing.

PR #1440

(cherry picked from commit fceef469c2)
2020-08-23 23:13:45 +02:00
Damien Cassou
318bc0754e direnv: add support for nix-direnv
PR #1297

(cherry picked from commit b33802ca7f)
2020-07-05 21:08:04 +02:00
Damien Cassou
3a8e036f4a direnv: add initial test for bash integration
(cherry picked from commit 575cd4b8ba)
2020-07-05 21:08:03 +02:00
Justin Lovinger
d8fdbbdf03 dircolors: fix usage together with zsh.oh-my-zsh
PR #1280

(cherry picked from commit 3a80ece9fa)
2020-06-17 00:00:52 +02:00
Justin Lovinger
12620f7fd4 dircolors: add module
PR #1219

(cherry picked from commit e9945ee6ee)
2020-06-17 00:00:28 +02:00
Damien Cassou
1710db409d firefox: show how to get pre-packaged add-ons
PR #1296

(cherry picked from commit ca6fcc92a1)
2020-06-16 23:48:25 +02:00
Robert Helgesson
ab911f44e6 xdg-mime: fix issue on WSL1
This change stops update-mime-database from running unless the
`share/mime/packages` directory is writable. For some reason it
appears to be read-only on WSL1.

Fixes #1192

(cherry picked from commit 8e8210b441)
2020-06-16 23:47:56 +02:00
Finn Behrens
3797004203 nixos: add mount check for home directory
PR #1271

(cherry picked from commit 5ba71ef91f)
2020-06-16 23:47:01 +02:00
Robert Helgesson
96fcf3b017 sway: fix config.keybindings example
(cherry picked from commit f90b86b577)
2020-05-24 13:05:32 +02:00
Robert Helgesson
db21f23943 i3: fix config.keybindings example
(cherry picked from commit 1c71bd1242)
2020-05-24 13:05:31 +02:00
Robert Helgesson
b49ababba0 lorri: make system environment attribute a list
It should be a list to allow inclusions of additional variables.

(cherry picked from commit a0d9a58616)
2020-05-24 13:05:30 +02:00
Matthew Bauer
7c0774ba0e readme: remove firefox "enableIcedTea" option
This option was actually removed in commit
3461ceebc0.

(cherry picked from commit d99f54b51b)
2020-05-24 13:05:29 +02:00
Andrew McDermott
cc69c3115f gnome-terminal: allow for 'system' theme variant
PR #1228

(cherry picked from commit 40b1c5c448)
2020-05-20 23:45:52 +02:00
Robert Helgesson
9fea5ac54f xdg.mimeApps: use xdg.dataFile instead of home.file
The former honors the data home path set by the user.

(cherry picked from commit b886cbea0b)
2020-05-20 23:44:55 +02:00
Robert Helgesson
22d03f20fb git: escape string values in configuration
This should handle the special characters that typically occur.

Fixes #1206

(cherry picked from commit 642d9ffe24)
2020-05-20 23:44:29 +02:00
Robert Helgesson
c91b2f4556 home-manager: add activation sanity check of Nix
This adds an empty `nix-build` command to verify that the user is
having a good Nix install. It also, as a side effect, will create the
necessary per-user `profiles` and `gcroots` directories.

Fixes #1246

(cherry picked from commit dcbe0f2a31)
2020-05-20 23:43:33 +02:00
Robert Helgesson
25ddbf4824 home-manager: use nix-env to list generations
Using the `nix-env` command is far more robust. It also has the
benefit that if the per-user `profiles` and `gcroots` directories do
not exist then they will be created with the correct permissions.

Because of the second point this commit also removes the `mkdir` step
of the installation instructions.

PR #1239
Closes #474, #948, #1091

(cherry picked from commit 9ec9f004e1)
2020-05-20 23:43:24 +02:00
Robert Helgesson
a378bccd60 Revert "vscode: fix extension path symlink error"
This reverts commit fe145b12cd.

Turns out the change does not apply to Nixpkgs 20.03 [1].

[1] https://github.com/rycee/home-manager/pull/1100#issuecomment-621506706
2020-04-30 09:44:00 +02:00
Bruno Bigras
98fa8f63b8 spotifyd: user -> username
PR #1168

(cherry picked from commit 2d88cbe496)
2020-04-23 23:54:18 +02:00
Cole Helbling
9b5133529e systemd: don't page failed user units
Otherwise, the pager (typically `less`) pauses execution of
`home-manager switch` until the pager is dismissed, if the content is
larger than would fit on the screen.

PR #1175

(cherry picked from commit 8369624512)
2020-04-23 23:43:00 +02:00
Paul
2dd4c20f49 keynav: use correct ExecStart command
When the change requested in

  https://github.com/rycee/home-manager/pull/1082#discussion_r392715440

was applied, the service `ExecStart` attribute was not updated to use
`pkgs.keynav`.

Fixes #1177
PR #1184

(cherry picked from commit ee1c40e5c5)
2020-04-23 23:42:59 +02:00
Robert Helgesson
42e4eef749 Update documentation for release 20.03 2020-04-23 00:29:11 +02:00
Robert Helgesson
7613fd12ec doc: document dagOf and gvariant types 2020-04-22 23:59:10 +02:00
Robert Helgesson
f735fac91b doc: bump nmd revision
Also convert `release-notes.xml` to AsciiDoc.
2020-04-22 23:59:09 +02:00
Robin Stumm
f0710115c5 kakoune: add missing hook name
PR #1185
2020-04-22 23:18:23 +02:00
nurelin
8c920682e6 sway: remove restart command from sway configuration (#1155)
The restart command does not exists in sway, only reload.
See https://github.com/swaywm/sway/blob/1.4/sway/sway.5.scd
2020-04-22 02:31:07 +02:00
Terje Larsen
9905ab5087 fish: fix fish plugins complete path update
PR #1178
2020-04-22 01:02:10 +02:00
dawidsowa
b3bbc8b769 xdg-user-dirs: add user-dirs.conf
PR #1143
2020-04-22 00:52:39 +02:00
Lisa Ugray
3a5cd90631 bat: add custom themes
Add the ability to add custom theme files to bat.

Co-Authored-By: Robert Helgesson <robert@rycee.net>
2020-04-21 18:26:13 -04:00
Bruno Bigras
3e3de8cee2 i3/sway: fix typo in fonts option (#1152) 2020-04-21 08:18:38 +02:00
Robert Helgesson
687395ebda home-manager: remove unsupported -2 option
This option used to make the `home-manager` command use the `nix` tool
from Nix 2. Unfortunately the `nix` tool is a bit experimental and it
is best to await its stabilization before supporting it in Home
Manager.
2020-04-18 11:37:06 +02:00
Robert Helgesson
e5325c2274 home-manager: fix shellcheck warning 2020-04-18 11:37:05 +02:00
Robert Helgesson
3461ceebc0 firefox: remove options removed upstream
Fixes #1166
2020-04-18 11:24:11 +02:00
Robert Helgesson
133badb297 ssh: deprecate the list form of match block
Configurations depending on specific block order should use the DAG
functions instead of lists.
2020-04-16 23:27:40 +02:00
Robin Stumm
86ccd8fecb kakoune: implement whitespace highlighter config
The options under `programs.kakoune.config.showWhitespace` existed
but were not implemented.

PR #1162
2020-04-16 22:34:31 +02:00
Robert Helgesson
f6afd95ef8 tmux: fix broken test case 2020-04-15 23:25:16 +02:00
Robert Helgesson
022228e0aa ssh: switch type of matchBlocks to listOrDagOf
This switches the type of `matchBlocks` from `loaOf` to `listOrDagOf`.
The former has been deprecated in Nixpkgs. The latter allows
dependencies between entries to be expressed using the DAG functions.
2020-04-13 23:24:40 +02:00
Robert Helgesson
8ad4bd6c1b types: improve dagOf and listOrDagOf
In particular, improve the behavior of these types if the element type
is a submodule.
2020-04-13 22:01:20 +02:00
Piotr Bogdan
9f223e98b7 gnome-terminal: add cursorBlinkMode option 2020-04-10 17:10:26 +02:00
Robert Helgesson
2102b4e7b3 home-environment: minor fix of DocBook code 2020-04-10 16:16:46 +02:00
Robert Helgesson
ebdfa06685 tests: update nmt 2020-04-10 01:01:20 +02:00
Robert Helgesson
41094aa3c7 neovim: fix docbook syntax in option descriptions 2020-04-09 19:27:57 +02:00
Jonathan Ringer
09abc29b73 neovim: add vimdiffAlias 2020-04-09 19:20:19 +02:00
Terje Larsen
5b7b9821e0 qutebrowser: add support for list values in settings 2020-04-09 19:13:07 +02:00
Robert Helgesson
ee18288eeb codeowners: add entry for mako 2020-04-09 11:28:22 +02:00
Jonas Heinrich
f856da6690 mako: add module
PR #1113
2020-04-09 11:21:22 +02:00
Robert Helgesson
5cdbfc9064 Add code owners and pull request template 2020-04-08 19:29:57 +02:00
Robert Helgesson
068ff76a10 gitlab-ci: improve NUR update trigger
Specifically, trigger NUR updates for all release branches by default.

Also updates the GitLab CI definition to use the new `rules` attribute
rather than the deprecated `only` attribute.
2020-04-08 16:13:01 +02:00
Justin Lovinger
b7737f1732 qutebrowser: add module
PR #1132
2020-04-08 14:50:59 +02:00
Tobias Happ
d06bcf4c97 targets.genericLinux: add module
PR #797
2020-04-08 13:36:25 +02:00
Robert Helgesson
dd538c2969 home-environment: add option sessionVariablesExtra
This is an internal option for adding additional code to
`hm-session-vars.sh`.
2020-04-08 13:23:02 +02:00
Robert Helgesson
f56c4187a4 screen-locker: add option enableDetectSleep
Fixes #1125
2020-04-06 19:41:13 +02:00
Diep Pham
1fd874b7ea go: add goPrivate option
This option configures the `GOPRIVATE` variable. See

   https://golang.org/cmd/go/#hdr-Module_configuration_for_non_public_modules

for more information.

PR #1126
2020-04-06 19:28:31 +02:00
Griffin Smith
5ff245790d gtk: add bookmarks option
Add a new 'bookmarks' option, for managing `~/.config/gtk3/bookmarks`,
a list of URIs to display as bookmarks in the sidebar of GTK file
browsers.

PR #1129
2020-04-06 15:52:46 +02:00
Robert Helgesson
1cfc0a3203 sxhkd: add dummy package in tests 2020-04-06 12:55:58 +02:00
Robert Helgesson
a128e35927 Update nixfmt and apply to a few more files 2020-04-06 12:51:11 +02:00
Matthieu Coudron
dd93c300bb vim: avoid using alias of vim-sensible 2020-03-30 21:55:10 +02:00
Michael Millwood
14f83a46d0 kakoune: fix set option
The old `set-option global/ autoreload` code causes an error.

PR #1117
2020-03-30 21:33:24 +02:00
Timo Kaufmann
5969551a5c home-manager: add instantiate subcommand
It can be useful to simply instantiate a Home Manager configuration
without actually building it, for example for the purpose of
pre-building it with some custom command.

PR #1099
2020-03-25 21:16:43 +01:00
Carlos Tomé
7fa890462d zsh: support extra settings in oh-my-zsh plugins (#1106)
Co-Authored-By: Robert Helgesson <robert@rycee.net>
2020-03-25 15:40:42 +01:00
Ruby Iris Juric
78a0bbb38b picom: add module
Nixpkgs no longer packages compton, and instead packages picom, a
(mostly) compatible fork of compton, providing an alias from compton
to picom. Because some configuration options have been changed, and
all references to "compton" have been made deprecated and replaced
with "picom", 'services.compton' has been deprecated in favor of the
new 'services.picom'.

Resolves #878
PR #1101
2020-03-24 23:50:22 +01:00
Erik Arvstedt
e2414c4a4f systemd: improve systemd-activate.rb script
- Pass arguments verbatim to the `systemctl` subprocess, obviating the
  need for shell escaping.

- Use open3 for capturing subprocess output.

- Fix printing of commands during dry run.

- Simplify `X-RestartIfChanged` regular expression.

  1. Use \s to match whitespace, \b to match a word boundary.

  2. Rename variable to conform to Ruby's underscore naming
     conventions.

- Remove no-op set operation. Specifically, 'no_restart' and 'to_stop'
  are disjunct since

  1. After reloading the daemon with the new generation, units in
     'to_stop' (i.e. units from the old gen that are missing in the
     new gen) are not registered anymore in the systemd daemon.

  2. Hence, 'systemctl cat' returns no output for these units.

  3. Because this output is needed to detect 'no_restart' units,
     'no_restart' includes no units from 'to_stop'.

  So 'to_stop -= to_restart' is a no-op.

- Only notify about units that would otherwise be restarted. That is,
  exclude units that are started but not restarted.

- Previously, all inactive units, like short-running services, were
  handled as failed units.

  Now systemd activation doesn't fail for oneshot services like
  'setxkbmap' while 'servicesStartTimeoutMs' is set.

- Don't start unchanged oneshot services.

PR #1110
2020-03-24 00:00:44 +01:00
Robert Helgesson
d11803d7b4 syncthing: install man pages to user profile 2020-03-22 21:15:25 +01:00
Robert Helgesson
19dd9866da dunst: install man pages 2020-03-22 21:15:23 +01:00
Robert Helgesson
f080f29292 faq: outline how to override packages
Fixes #1107
2020-03-22 13:16:59 +01:00
Cole Helbling
8571e568e0 sway: fix onChange when defunct sockets exist
Fixes `..../generation/activate: line 181: [: too many arguments`
when, for whatever reason, the user has multiple `sway-ipc` sockets.

PR #1086
2020-03-21 18:00:26 +01:00
Bill Sun
fe145b12cd vscode: fix extension path symlink error
Fix extension path symlink error caused by [1], which removes
`/share/{wrappedPkgName}/extensions` from the extension install path.

[1] https://github.com/NixOS/nixpkgs/pull/71251

PR #1100
2020-03-21 17:47:32 +01:00
Robert Helgesson
0f11a79e02 dconf: make settings have type gvariant
Closes #835, #1094, #1095
2020-03-21 01:02:41 +01:00
Robert Helgesson
ac9e44a831 lib: add GVariant datatype and functions 2020-03-21 00:28:50 +01:00
Desetude
3673107bc4 termite: fix the key for bold foreground color
PR #1097
2020-03-17 23:47:36 +01:00
Robert Helgesson
b9d4f55228 firefox: force extension file linking 2020-03-17 23:42:27 +01:00
Robert Helgesson
37694e9f51 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.
2020-03-17 23:42:26 +01:00
William Carroll
2cd168467e keynav: add module
PR #1082
2020-03-17 22:59:15 +01:00
Robert Helgesson
cc386e4b3b firefox: prepare for updated sideloading behavior
Co-Authored-By: Cole Helbling <cole.e.helbling@outlook.com>
2020-03-15 19:48:07 +01:00
Joshua Fern
2681568f2b firefox: support user content CSS
The `userContent.css` file is similar to `userChrome.css`, it's a CSS
file that you can use to change the way web sites and e-mails look.

See http://kb.mozillazine.org/index.php?title=UserContent.css

PR #1079
2020-03-15 18:26:37 +01:00
Robert Helgesson
5c1e7349bb lieer: remove package dependency in tests 2020-03-08 12:02:35 +01:00
Tad Fisher
9f46d516fa services.lieer: add module
Add 'services.lieer', which generates systemd timer and service units
to synchronize a Gmail account with lieer. Per-account configuration
lives in 'accounts.email.accounts.<name>.lieer.sync'.
2020-03-07 15:13:50 +01:00
Tad Fisher
60a939bd01 programs.lieer: add module
Add 'programs.lieer', a tool for synchronizing a Gmail account with a
local maildir and notmuch database. Per-account configuration lives in
'accounts.email.accounts.<name>.lieer'.
2020-03-07 15:13:15 +01:00
Maximilian Bosch
0056a5aea1 debug: add module
This one is fairly similar to `environment.enableDebugInfo`[1] (hence
the name). It ensures that the `debug`-output of packages defined in
`home.packages` is installed if available and ensures that
`gdb`/`elfutils` find those symbols by adding
`~/.nix-profile/lib/debug` to the `NIX_DEBUG_INFO_DIRS`[2] variable.

[1] https://github.com/NixOS/nixpkgs/blob/release-19.09/nixos/modules/config/debug-info.nix
[2] https://github.com/NixOS/nixpkgs/blob/release-19.09/pkgs/development/tools/misc/gdb/debug-info-from-env.patch

PR #1040
2020-03-07 15:03:44 +01:00
Robert Helgesson
b36d3e0261 news: fix condition
The news entry for the new Fish functions functionality was
accidentally conditioned for people using zsh.
2020-03-07 14:33:13 +01:00
Erik Arvstedt
efbe1383e6 nixos integration: add option 'useGlobalPkgs'
PR #1059
2020-03-07 14:25:00 +01:00
Erik Arvstedt
c7b43786ad README: add link to main manual page
The main manual page is highly relevant and should be easily
discoverable from the README.

PR #1059
Fixes #1048
2020-03-07 13:32:36 +01:00
Cole Helbling
a11cf1decd fish: allow arguments to functions
This allows the ability to provide arguments to a function, such as
`--on-event` in order to trigger a function on the
`fish_command_not_found` event, for example.

PR #1063
2020-03-07 12:51:37 +01:00
zimbatm
9a1feb5b10 git: fix the config output formatting
When setting values using the `git config --set` command, git formats
the file a bit differently. This changes the output so it maps to that
format.

Differences:

* each `key = value` in a section is prefixed by a tab character
* the `=` between the key and the value is surrounded by spaces

PR #1069
2020-03-07 12:02:20 +01:00
William Carroll
71c7aaee83 fzf: support fish integration
Create the `enableFishIntegration` option to install the fzf
key-bindings for people who use fish shell.

PR #1074
2020-03-07 11:52:54 +01:00
Robert Helgesson
faa2945606 tests: remove package dependencies on rofi and abook 2020-03-06 00:27:21 +01:00
Robert Helgesson
1a4c10e950 ci: run tests with --pure 2020-03-06 00:14:09 +01:00
Robert Helgesson
f3fbb50b68 polybar: add test case 2020-03-04 21:26:35 +01:00
Alex Rice
a6657d6b21 sway: fix floating modifier description
PR #1054
2020-03-04 21:09:36 +01:00
MmeQuignon
0a1ce53990 abook: add module
PR #1058
2020-03-04 19:58:05 +01:00
Robert Helgesson
2678fb3441 format: pin Nixpkgs version
This is to make sure that we get a consistent version of nixfmt.
2020-03-04 19:36:07 +01:00
Robert Helgesson
6fc6c736f9 tests: bump nmt version 2020-03-02 23:47:39 +01:00
Robert Helgesson
28401ddd91 systemd: skip services taking an instance parameter
Fixes #730
2020-03-02 20:33:20 +01:00
Robert Helgesson
7bd043e9ee xresources: give properties option more specific type
This more readily allows merging configurations.
2020-02-29 22:32:52 +01:00
Robert Helgesson
acf106ced0 starship: give settings option more specific type
This more readily allows merging configurations.

Fixes #1023
2020-02-29 22:17:47 +01:00
Robert Helgesson
2f726bbd1c bash, fish, zsh: fix shellAliases example
Unfortunately the document generator is not smart enough to quote the
`..` alias in the documentation which is very misleading. By making it
a literal example the quotes stay.
2020-02-26 22:44:54 +01:00
Alex Rice
02d6040003 sway: add module
PR #829
2020-02-26 22:37:15 +01:00
Robert Helgesson
2fcdf3df34 contributing: add section about tests 2020-02-26 22:13:48 +01:00
Robert Helgesson
aedde6dcde contributing: add note about news entry for new modules 2020-02-26 21:59:36 +01:00
Martin Potier
ef148ab3cb newsboat: show queries before urls
PR #1047
2020-02-26 21:38:07 +01:00
Robert Helgesson
03b622b356 Bump copyright year 2020-02-25 19:27:54 +01:00
Chris Hodapp
9ab59dd6ac home-manager: handle args with spaces to doBuildAttr
Presently, if you pass an argument with spaces in it to `doBuildAttr`,
it will be split it into multiple arguments to `nix build` or
`nix-build`. This situation arises, for example, on systems with
spaces in `XDG_DATA_HOME`.

Specifically, the `home-manager` script errors out in trying to
address the `read-news` state file. With this change, argument
separation should be preserved properly in `doBuildAttr`.

PR #1044
2020-02-24 23:51:36 +01:00
Vojtěch Káně
9ab4e70d17 readme: add notes on release policy
PR #1046
2020-02-24 23:09:18 +01:00
Robert Helgesson
91c7059d98 udiskie: fix formatting 2020-02-24 23:07:58 +01:00
Robert Helgesson
d90ae6dffa udiskie: remove obsolete -2 command line argument
Fixes #1042
2020-02-24 20:45:54 +01:00
ivann
9ab0d2305c kitty: add module
PR #1000
2020-02-23 11:28:53 +01:00
ivann
9bddef74df types: create fontType option type 2020-02-23 11:18:59 +01:00
Wael Nasreddine
4e50809c78 modules: remove unused checkPlatform function
PR #1041
2020-02-21 21:56:51 +01:00
Evan Stoll
7f748f27bc neomutt: add reverse sort options (#1036) 2020-02-21 15:24:52 +01:00
Robert Helgesson
543118ac70 fish: apply nixfmt 2020-02-20 00:16:01 +01:00
Robert Helgesson
57bd27b3e7 Merge PR #635 2020-02-20 00:07:04 +01:00
Cole Helbling
5ca224f75b fish: consistency is key and other style changes
I like my empty sets with spaces between them.
2020-02-20 00:03:29 +01:00
Cole Helbling
89239d554d fish: prepend fenv functions dir
Instead of concatenating the `fish_function_path` with the fenv
functions path, just prepend it. Functionally the same, but looks
cleaner (IMO).
2020-02-20 00:03:28 +01:00
Cole Helbling
a08dabf015 fish: escape abbrs and aliases
Some of my aliases have apostrophes in them, so shell-escaping them is a
must.
2020-02-20 00:03:27 +01:00
Cole Helbling
9a258edc10 fish: fix sourcing of .fish files
Turns out, the quotes were messing things up.
2020-02-20 00:03:26 +01:00
Ryan Orendorff
111011b2c2 fish: add some tests
- If a function is defined, check that the function file exists and
  that the contents matches a given string.

- If no functions exists, the functions folder should not exist.

- Verify plugin functionality.
2020-02-20 00:03:26 +01:00
Ryan Orendorff
108259925a fish: plugins separated into conf.d files
This was done to make it easier for the generated files to be understood.
2020-02-20 00:03:25 +01:00
Ryan Orendorff
639f6fea8c fish: plugins concated to 99plugins.fish
This change allows the entire repo to be imported directly. Some plugins (such
as oh-my-fish's vi-mode) have extra files that are referenced by the plugin
itself. This means we cannot create a generic plugin file structure out of the
plugins that exist currently.
2020-02-20 00:03:24 +01:00
Ryan Orendorff
f5b24635b6 fish: whitespace and style fixes (camel case) 2020-02-20 00:03:23 +01:00
Ryan Orendorff
0522c7c1f6 fish: plugins uses pluginModule type, add example 2020-02-20 00:03:22 +01:00
Ryan Orendorff
2f51b9e418 fish: add pluginModule type
Similar to zsh's `pluginModule` type, but without an initialization
file.
2020-02-20 00:03:21 +01:00
Ryan Orendorff
4f532948f7 fish: shell{Abbrs,Aliases} has more specific type
Converted attrs to attrsOf str.
2020-02-20 00:03:20 +01:00
Ryan Orendorff
0740c257b1 fish: remove fileType function
Replaced by types that are more common. This additionally reflects in the
manpages, which should have types the reader is familiar with.
2020-02-20 00:03:19 +01:00
Ryan Orendorff
490f5fc585 fish: remove completions
They are not currently handled in the code, hence they are removed for now.
2020-02-20 00:03:18 +01:00
Ryan Orendorff
642bd67126 fish: add comma to program slogan
Matches what is on the fish website
2020-02-20 00:03:18 +01:00
Ryan Orendorff
4833a8b532 fish: add section headers to generated config
The section headers help show where each section came from when looking at the
generated config. Added a note about how the config was generated in the
generated file.
2020-02-20 00:03:17 +01:00
Ryan Orendorff
d45e1c4adc fish: functions type to attrsOf lines, load by text
Functions in fish are now defined in terms of adding the appropriate
files and `files.text` sets to `xdg.configFile`.
2020-02-20 00:02:58 +01:00
Ryan Orendorff
3de8102e7f fish: revamp descriptions to match bash style 2020-02-19 23:42:54 +01:00
Ryan Orendorff
665766f8bb fish: add examples for shellAliases, shellAbbrs 2020-02-19 23:42:53 +01:00
Ryan Orendorff
2eb1cb077d fish: move type declarations to top of mkOptions
A closer match to the style of the definitions in the bash program.
2020-02-19 23:42:52 +01:00
Jonas Holst Damtoft
c22f3e1d29 fish: basic completions support 2020-02-19 23:42:51 +01:00
Jonas Holst Damtoft
b18d302d44 fish: add plugin functionality 2020-02-19 23:42:51 +01:00
Robert Helgesson
5be9aa417a neomutt: fix sendMailCommand when msmtp is enabled
This resolves the error

    The option `accounts.email.accounts.xyz.neomutt.sendMailCommand`
    is defined both null and not null, in
    `…/home-manager/modules/accounts/email.nix' and
    `…/home-manager/modules/accounts/email.nix'.

that would occur previously when both neomutt and msmtp were enabled
for an account.
2020-02-16 23:08:37 +01:00
Robert Helgesson
7a3e2cc063 files: use nix-env to create profile links 2020-02-15 23:53:39 +01:00
Robert Helgesson
e1153f4d2e home-manager: make sure all files are uninstalled
This forces the `home.file` option to be completely empty when
switching to the uninstall configuration. This is necessary to guard
against files are added by default in Home Manager, such as
`$XDG_CACHE_HOME/.keep`.
2020-02-15 19:26:23 +01:00
brettm12345
7b7499dd70 starship: use promptInit for fish 2020-02-14 21:07:50 +01:00
Robert Helgesson
f0fe18cd22 systemd: start timers as well
Fixes #1019
2020-02-09 22:59:36 +01:00
Jonathan Ringer
f487b527ec compton: add inactiveDim option
PR #1016
2020-02-05 20:13:20 +01:00
Gregory C. Oakes
6cc4fd6ede screen-locker: made xss-lock a systemd service.
Takes advantage of the new `--session` xss-lock parameter to allow
xss-lock be made into a systemd service.

PR #1015
2020-02-02 01:33:36 +01:00
Robert Helgesson
115e76ae12 Merge PR #1006 2020-02-02 01:26:45 +01:00
Robert Helgesson
a4a07ba996 readline: fix example 2020-02-02 01:20:05 +01:00
Robert Helgesson
70af3b126a ci: add format script and use in CI pipeline
The format script can be used to automatically format the Nix source
files and also verify that the files are formatted using the `-c`
command argument.

At the moment some files are exempt from the formatting to avoid
causing merge conflicts in active pull requests.

Finally, update the contribution guidelines to note that `nixfmt`
should be used.
2020-02-02 01:19:35 +01:00
Robert Helgesson
45abf3d38a Apply nixfmt on many files 2020-02-02 01:07:28 +01:00
Michael Hoang
9799d3de2d feh: add buttons option
Use `null` to disable keybindings or button mappings.
2020-02-01 10:04:52 +01:00
Owen Shepherd
a591e8f9e4 zsh: add 'ignoreSpace' option
This option sets HIST_IGNORE_SPACE, which determines whether commands starting with a
space are put in the history or not.
2020-01-26 21:36:03 +01:00
Robert Helgesson
de8033747c tests: clean up tests
- Move all module tests to their own directories.

- Avoid duplication of `// import`.
2020-01-26 21:11:23 +01:00
Matthieu Coudron
fba87f8998 neomutt: add module
PR #1002
2020-01-26 20:46:44 +01:00
dind
d8d5f85ab7 termite: fix scrollbar position option description
Signed-off-by: dind <lewdavatar@gmail.com>
2020-01-26 16:31:41 +00:00
Marius Bergmann
b4e8d9869f grobi: add module
This adds a service module for [grobi](https://github.com/fd0/grobi),
which can be used to automatically configure monitors/outputs for Xorg
via RANDR.
2020-01-26 13:57:49 +01:00
Néfix Estrada
b270fcef2f bspwm: add module
PR #362, #981

Co-authored-by: Vincent Breitmoser <look@my.amazin.horse>
2020-01-26 13:43:13 +01:00
arcnmx
244d795325 nixpkgs: add indirection to _module.args.pkgs
This allows pkgs to be overridden in such a way that `<nixpkgs>` is
never imported, allowing home-manager to be used in environments where
`NIX_PATH` is not set.

PR #993
2020-01-26 13:03:23 +01:00
eyeinsky
e5fb259872 readme: add more prominent link to the manual
PR #996
2020-01-26 12:04:43 +01:00
Robert Helgesson
ba097beb17 tests: remove unnecessary user of import 2020-01-26 11:30:32 +01:00
Robert Helgesson
1397570eea tests: use lib.hm.types instead of explicit import 2020-01-26 11:28:34 +01:00
Robert Helgesson
57ede1369f emacs: use lib.hm.types instead of explicit import 2020-01-26 11:26:33 +01:00
Robert Helgesson
95c8007b8f xresources: improve properties option example
Fixes #1001
2020-01-21 22:27:57 +01:00
Ashish SHUKLA
805d82e1be ssh: make certificateFile similar to identityFile
PR #998
2020-01-21 21:10:11 +01:00
Robert Helgesson
6e4b9af080 Switch to extended Nixpkg's lib
This change makes use of the `extend` function inside `lib` to inject
a new `hm` field containing the Home Manager library functions. This
simplifies use of the Home Manager library in the modules and reduces
the risk of accidental infinite recursion.

PR #994
2020-01-21 20:47:04 +01:00
0x6d6178
c8323a0bf1 xdg-user-dirs: fix typo in option name
Fixes #985
PR #987
2020-01-17 23:55:27 +01:00
Robert Helgesson
4b04050953 Merge PR #991 2020-01-16 00:29:57 +01:00
Robert Helgesson
f65510b1d1 home-environment: make home.activation public
Also improve documentation and add an example.
2020-01-16 00:16:35 +01:00
Robert Helgesson
7f87329fca home-environment: use DAG type in activation option 2020-01-16 00:16:35 +01:00
Robert Helgesson
6c127efb2d lib: add type generators dagOf and listOrDagOf
Given an inner type, the former function generates a type that expect
DAG option values. The latter function is only present to temporarily
allow the `programs.ssh.matchBlocks` to keep accepting list values.
2020-01-16 00:16:09 +01:00
arcnmx
b053dc8697 modules: use pkgs.path instead of <nixpkgs>
PR #992
2020-01-15 20:58:15 +01:00
Robert Helgesson
bff499113e manual: note deprecation of list values for file options
In particular, this entry notes that assigning lists to `home.file`,
`xdg.configFile`, and `xdg.dataFile` is deprecated and will be removed
in the next release.
2020-01-13 22:34:38 +01:00
Robert Helgesson
ee01d24a45 notmuch: use writeShellScript 2020-01-13 21:45:20 +01:00
Robert Helgesson
e9beef31eb getmail: use attribute set to define files
To avoid warning message concerning deprecation of the `loaOf` type.
2020-01-13 21:45:19 +01:00
Robert Helgesson
cff9ee7cce zsh: use attribute set to define files
To avoid warning message concerning deprecation of the `loaOf` type.
2020-01-13 21:45:18 +01:00
Robert Helgesson
07dc3e5425 notmuch: use attribute set to define files
To avoid warning message concerning deprecation of the `loaOf` type.
2020-01-13 21:45:17 +01:00
Robert Helgesson
e857249d86 go: use attribute set to define files
To avoid warning message concerning deprecation of the `loaOf` type.
2020-01-13 21:45:17 +01:00
Robert Helgesson
8ace1ab1b0 browserpass: use attribute set to define files
To avoid warning message concerning deprecation of the `loaOf` type.
2020-01-13 21:45:16 +01:00
Robert Helgesson
00e26ceffe chromium: use attribute set to define files
To avoid warning message concerning deprecation of the `loaOf` type.
2020-01-13 21:45:15 +01:00
Vojtěch Káně
4ad3fe78f9 go: adds an option extraGoPaths
PR #946
2020-01-13 21:44:13 +01:00
Robert Helgesson
297ed97166 mpv: allow string values in scripts list
Fixes #976
2020-01-11 17:44:04 +01:00
Ross A. Baker
0fce533e70 lorri: add gitMinimal to daemon path
Fixes https://github.com/target/lorri/issues/255 when the service is
installed through home-manager.

PR #975
2020-01-11 17:19:10 +01:00
Philipp Middendorf
3a3657b107 cbatticon: add module (#963) 2020-01-11 13:08:56 +01:00
Denys Pavlov
d677556e62 spotifyd: update flags (#979)
Following nixos/nixpkgs@54433c4
2020-01-09 15:10:16 +01:00
Wael M. Nasreddine
1b7b1bc294 neovim: un-deprecate the configure option
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
2020-01-06 07:02:37 -08:00
Robert Helgesson
ef6674d1d1 contributing.md: minor update
This elaborates the instructions for the news entry of new modules.
2020-01-06 11:31:37 +01:00
YVT
e70912df26 lsd: add shell aliases for fish 2020-01-06 15:09:51 +09:00
Robert Helgesson
0bb2d87cfd gitlab-ci: pin Nixpkgs version 2020-01-01 13:52:01 +01:00
jD91mZM2
ebf1df58da gpg-agent: fix GnuPG by adding pinentry flavor option
See https://github.com/NixOS/nixpkgs/pull/71095.

Fixes #908
2020-01-01 13:26:21 +01:00
oxalica
7c30831e8f home-manager: fix pass-through option passing
This resolves, e.g., the errors occurring when passing empty arguments
like `--option builders ''`.

Closes #967
2020-01-01 12:27:29 +01:00
Michael Hoang
df4db50632 i3: update default i3 key bindings
Update to match the default i3 key bindings

  https://github.com/i3/i3/blob/master/etc/config

PR #957
2019-12-31 11:19:20 +01:00
Robert Helgesson
54f367b119 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.
2019-12-31 09:27:37 +01:00
cmacrae
f66cc1b851 firefox: add darwin support 2019-12-31 00:08:20 +01:00
jD91mZM2
a0ab0b16fe keychain: add xsession integration 2019-12-28 17:29:57 +01:00
Julien Tanguy
5992c1b469 keychain: add fish shell integration
The shell command is added in the interactiveShellInit, as it is the
equivalent of initExtra in bash or zsh.
2019-12-27 10:58:03 +01:00
Robert Helgesson
8d14ffbe88 blueman-applet: minor cleanup of enable option
In particular use proper DocBook format in description.
2019-12-25 22:00:54 +01:00
Cabia Rangris
a5d3d6f665 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
2019-12-25 21:52:49 +01:00
Gregory Oakes
a12a8f7977 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
2019-12-25 21:44:23 +01:00
Bernardo Meurer
0f1c9f25cf beets: allow custom package (#952) 2019-12-18 01:25:52 +01:00
arcnmx
8abaa025ec systemd: fix degraded warning 2019-12-15 14:58:43 -08:00
Robert Helgesson
621c98f15a mbsync: skip maildir creation if no account is defined
Fixes #937
2019-12-08 21:46:30 +01:00
Robert Helgesson
bcfc52cb85 tests: move git and files tests to directories 2019-12-08 21:40:22 +01:00
David Wood
5c9ec0d8e9 starship: add package option 2019-12-08 21:24:04 +01:00
Robert Helgesson
284b8d94d4 readline: add variables option
Also add a basic test case.
2019-12-08 21:13:58 +01:00
Vojtěch Káně
bb5dea02b9 readline: add module
Add basic readline configuration (~/.inputrc) management.
2019-12-08 20:49:00 +01:00
Konrad Borowski
711109d468 vscode: correct VSCodium extension directory path 2019-12-07 15:04:11 +01:00
Robert Helgesson
ed9a6e34ad gpg: remove dummy gnupg package from test
It caused evaluation issues related to systemd.

Fixes #934
2019-12-02 21:16:44 +01:00
Sebastian Ullrich
571989f564 xdg-mime: add module 2019-12-01 23:11:49 +01:00
Robin Stumm
fdd65e5fad parcellite: remove obsolete backward compatibility fixes
This also fixes that the `gtk.theme` option was not picked up due to
hardcoded XDG_DATA_DIRS.
2019-12-01 20:03:05 +01:00
Robert Helgesson
7c2532d9f9 home-manager: add --(no-)substitute options
Fixes #312
2019-12-01 10:43:39 +01:00
pacien
94d183eaaa unison: add module 2019-11-29 23:49:00 +01:00
pacien
9d09738e4d password-store: add modules 2019-11-29 23:03:15 +01:00
worldofpeace
ef11164c0c vscode: don't create an empty settings.json
If I enable this module without using the userSettings option it will
create an empty settings.json. We use mkIf to prevent this on the default
value.
2019-11-28 16:01:58 -05:00
leotaku
34dc4a5e03 mpdris2: improve service description
In particular, make sure the systemd service actually starts.
2019-11-27 22:46:02 +01:00
Philip Stears
0e9b7aab3c 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.
2019-11-26 22:22:19 +01:00
Robert Helgesson
9781f3766d systemd: perform reload even in degraded state
This fixes #355, fixes #798, and fixes #909.
2019-11-24 18:55:01 +01:00
Robert Helgesson
9e716025b6 lorri: restrict news entry to Linux 2019-11-24 18:53:44 +01:00
Kloenk
eee6ae33e8 spotifyd: add module 2019-11-24 18:52:52 +01:00
Anton Plotnikov
b1dd373f5a files: update script to support linked Nix store 2019-11-22 20:16:42 +01:00
Tobias Happ
286dd9b308 lorri: add service 2019-11-17 20:36:27 +01:00
Pasquale
595150be86 vscode: correct base path from which to pull extensions 2019-11-15 23:18:12 +01:00
HerrMAzik
08094f3cc2 vscode: fix configDir for VSCodium 2019-11-15 23:15:00 +01:00
pacien
24dbac8da7 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.
2019-11-15 23:11:27 +01:00
pacien
18dc4153c7 astroid: fix maildir folder paths
Using the absolute path of maildir folders is required for Astroid to save
messages in those.
2019-11-15 18:14:58 +01:00
Nikita Uvarov
4505710565 zsh: fix history.path issues
- Default value is set to static '$HOME/.zsh_history' -- dotDir is not
prepended anymore
- $HOME is not prepended to the option value
- Ensure history path directory exists

Fixes #886, replaces #427.
2019-11-05 23:04:06 +01:00
Mario Rodas
05dabb7239 pazi: add module 2019-11-04 21:57:15 +01:00
adisbladis
49852220f9 emacs: Don't use emacsPackagesNg
It's deprecated and since Nixos 19.09 it's an alias to `emacsPackages`.
2019-11-04 11:16:06 +00:00
Robert Helgesson
6b6f759e7a doc: update version number in some places 2019-10-29 23:08:46 +01:00
Nikita Uvarov
149c0593ab version: add 20.03 2019-10-28 22:08:51 +01:00
Nikita Uvarov
26defdf205 tests: fix i3-keybindings test 2019-10-28 22:05:09 +01:00
wedens
5161dd3b2e i3: add workspaceAutoBackAndForth option 2019-10-28 11:31:51 +01:00
Robert Helgesson
a93d01fb4d faq: describe how to install Nixpkgs unstable packages 2019-10-26 16:43:14 +02:00
Robert Helgesson
797c77a00a 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.
2019-10-26 13:07:04 +02:00
dnsdhrj
a177d0282f getmail: fix port option type mismatch
Fixed type mismatch in commit 410f573226.
Added test case to ensure it works well.
2019-10-26 10:58:31 +02:00
Robert Helgesson
1b987952b5 kakoune: prepend extra configuration with newline (#870)
Fixes #869
2019-10-23 20:39:52 +09:00
SoonHo Seo
410f573226 getmail: add port option (#882)
Fixed bug where "accounts.email.accounts.<name>.imap.port" option was being ignored in getmail.
2019-10-23 20:17:04 +09:00
Pasquale
024d1aa227 vscode: add package option and link extensions 2019-10-20 21:49:17 +02:00
Wael Nasreddine
b1d8c0f9c3 termite: use vte-ng at pkgs.termite.vte-ng (#865) 2019-10-12 11:39:33 -07:00
Robert Helgesson
90bf989002 newsboat: support feed titles
Fixes #861
2019-10-11 21:41:05 +02:00
Robert Helgesson
79c16b9a90 doc: fix section ID for 20.03 release notes 2019-10-09 22:41:56 +02:00
Robert Helgesson
83018ac54a doc: add preliminary release notes for 20.03 2019-10-09 21:07:43 +02:00
Robert Helgesson
ad52dbe044 doc: finalize the 19.09 release notes 2019-10-09 21:03:04 +02:00
326 changed files with 11286 additions and 4963 deletions

163
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,163 @@
* @rycee
/modules/home-environment.nix @rycee
/modules/misc/dconf.nix @gnidorah @rycee
/modules/misc/fontconfig.nix @rycee
/tests/modules/misc/fontconfig @rycee
/modules/misc/gtk.nix @rycee
/modules/misc/news.nix @rycee
/modules/misc/pam.nix @rycee
/tests/modules/misc/pam @rycee
/modules/misc/qt.nix @rycee
/modules/misc/submodule-support.nix @rycee
/modules/misc/xdg-mime-apps.nix @pacien
/modules/misc/xdg-user-dirs.nix @pacien
/modules/programs/autorandr.nix @uvNikita
/modules/programs/bash.nix @rycee
/modules/programs/bat.nix @marsam
/modules/programs/beets.nix @rycee
/modules/programs/broot.nix @aheaume
/modules/programs/dircolors.nix @JustinLovinger
/modules/programs/direnv.nix @rycee
/modules/programs/eclipse.nix @rycee
/modules/programs/emacs.nix @rycee
/modules/programs/firefox.nix @rycee
/modules/programs/git.nix @rycee
/modules/programs/gnome-terminal.nix @rycee
/modules/programs/go.nix @rvolosatovs
/modules/programs/home-manager.nix @rycee
/modules/programs/keychain.nix @marsam
/modules/programs/lesspipe.nix @rycee
/modules/programs/lieer.nix @tadfisher
/modules/programs/lsd.nix @marsam
/modules/programs/matplotlib.nix @rprospero
/modules/programs/mpv.nix @tadeokondrak
/modules/programs/noti.nix @marsam
/modules/programs/obs-studio.nix @adisbladis
/modules/programs/opam.nix @marsam
/modules/programs/openssh.nix @rycee
/modules/programs/password-store.nix @pacien
/modules/programs/pazi.nix @marsam
/modules/programs/pidgin.nix @rycee
/modules/programs/rtorrent.nix @marsam
/modules/programs/ssh.nix @rycee
/modules/programs/starship.nix @marsam
/modules/programs/texlive.nix @rycee
/modules/programs/z-lua.nix @marsam
/modules/programs/zathura.nix @rprospero
/modules/services/cbatticon.nix @pmiddend
/modules/services/dunst.nix @rycee
/modules/services/flameshot.nix @moredhel
/modules/services/gnome-keyring.nix @rycee
/modules/services/gpg-agent.nix @rycee
/modules/services/grobi.nix @mbrgm
/modules/services/hound.nix @adisbladis
/modules/services/imapnotify.nix @nickhu
/modules/services/kdeconnect.nix @adisbladis
/modules/services/keepassx.nix @rycee
/modules/services/lieer.nix @tadfisher
/modules/services/lorri.nix @Gerschtli
/modules/services/mako.nix @onny
/modules/services/mbsync.nix @pjones
/modules/services/mpdris2.nix @pjones
/modules/services/muchsync.nix @pacien
/modules/services/network-manager-applet.nix @rycee
/modules/services/parcellite.nix @gleber
/modules/services/password-store-sync.nix @pacien
/modules/services/pasystray.nix @pltanton
/modules/services/random-background.nix @rycee
/modules/services/redshift.nix @rycee
/modules/services/status-notifier-watcher.nix @pltanton
/modules/services/syncthing.nix @rycee
/modules/services/taffybar.nix @rycee
/modules/services/tahoe-lafs.nix @rycee
/modules/services/taskwarrior-sync.nix @minijackson @pacien
/modules/services/udiskie.nix @rycee
/modules/services/unison.nix @pacien
/modules/services/xcape.nix @nickhu
/modules/services/xembed-sni-proxy.nix @rycee
/modules/services/xscreensaver.nix @rycee
/modules/services/xsuspender.nix @offlinehacker
/modules/systemd.nix @rycee
/modules/xcursor.nix @league
/modules/xresources.nix @rycee
/modules/xsession.nix @rycee

34
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,34 @@
<!--
Please fill the description and checklist to the best of your
ability.
-->
### Description
### Checklist
- [ ] Code formatted with `./format`.
- [ ] Code tested through `nix-shell --pure tests -A run.all`.
- [ ] Test cases updated/added. See [example](https://github.com/rycee/home-manager/commit/f3fbb50b68df20da47f9b0def5607857fcc0d021#diff-b61a6d542f9036550ba9c401c80f00ef).
- [ ] Commit messages are formatted like
```
{component}: {description}
{long description}
```
See [CONTRIBUTING](https://github.com/rycee/home-manager/blob/master/CONTRIBUTING.md#commits) for more information and [recent commit messages](https://github.com/rycee/home-manager/commits/master) for examples.
- If this PR adds a new module
- [ ] Added myself as module maintainer. See [example](https://github.com/rycee/home-manager/blob/068ff76a10e95820f886ac46957edcff4e44621d/modules/programs/lesspipe.nix#L6).
- [ ] Added myself and the module files to `.github/CODEOWNERS`.

View File

@@ -1,5 +1,9 @@
image: nixos/nix:latest
variables:
# Pinned 2020-01-01.
NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/b0bbacb52134a7e731e549f4c0a7a2a39ca6b481.tar.gz"
stages:
- test
- deploy
@@ -8,8 +12,9 @@ Run tests:
stage: test
script:
- nix-shell tests -A run.files-text
only:
- master
rules:
- if: $CI_COMMIT_BRANCH == "master"
when: always
pages:
stage: deploy
@@ -22,8 +27,9 @@ pages:
artifacts:
paths:
- public
only:
- master
rules:
- if: $CI_COMMIT_BRANCH == "master"
when: always
Deploy NUR:
stage: deploy
@@ -33,5 +39,6 @@ Deploy NUR:
trigger:
project: rycee/nur-expressions
branch: master
only:
- master
rules:
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH =~ /^release-/
when: always

View File

@@ -4,9 +4,7 @@ os:
- linux
- osx
before_script:
- mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
script:
- ./format -c
- nix-shell . -A install
- nix-shell tests -A run.all
- nix-shell --pure --max-jobs 10 tests -A run.all

View File

@@ -91,12 +91,15 @@ In addition to the above commit message guidelines, try to follow the
### Style guidelines ###
The code in Home Manager should follow the [Nixpkgs syntax
guidelines][]. Note, we prefer `lowerCamelCase` for variable and
attribute names with the accepted exception of variables directly
referencing packages in Nixpkgs which use a hyphenated style. For
example, the Home Manager option `services.gpg-agent.enableSshSupport`
references the `gpg-agent` package in Nixpkgs.
The code in Home Manager is formatted by the [nixfmt][] tool and the
formatting is checked in the pull request tests. Run the `format` tool
inside the project repository before submitting your pull request.
Note, we prefer `lowerCamelCase` for variable and attribute names with
the accepted exception of variables directly referencing packages in
Nixpkgs which use a hyphenated style. For example, the Home Manager
option `services.gpg-agent.enableSshSupport` references the
`gpg-agent` package in Nixpkgs.
### News ###
@@ -139,15 +142,48 @@ 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. If you contribute a module then you don't need to
add this entry, the merger will create an entry for you.
### Tests ###
Home Manager includes a basic test suite and it is highly recommended
to include at least one test when adding a module. Tests are typically
in the form of "golden tests" where, for example, a generated
configuration file is compared to a known correct file.
It is relatively easy to create tests by modeling the existing tests,
found in the `tests` project directory.
The full Home Manager test suite can be run by executing
```console
$ nix-shell --pure tests -A run.all
```
in the project root. List all test cases through
```console
$ nix-shell --pure tests -A list
```
and run an individual test, for example `alacritty-empty-settings`,
through
```console
$ nix-shell --pure tests -A run.alacritty-empty-settings
```
[open issues]: https://github.com/rycee/home-manager/issues
[new issue]: https://github.com/rycee/home-manager/issues/new
@@ -155,4 +191,4 @@ If you do have a change worthy of a news entry then please add one in
[create a pull request]: https://help.github.com/articles/creating-a-pull-request/
[seven rules]: https://chris.beams.io/posts/git-commit/#seven-rules
[`news.nix`]: https://github.com/rycee/home-manager/blob/master/modules/misc/news.nix
[Nixpkgs syntax guidelines]: https://nixos.org/nixpkgs/manual/#sec-syntax
[nixfmt]: https://github.com/serokell/nixfmt/

77
FAQ.md
View File

@@ -119,3 +119,80 @@ 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.
How do I override the package used by a module?
-----------------------------------------------
By default Home Manager will install the package provided by your
chosen `nixpkgs` channel but occasionally you might end up needing to
change this package. This can typically be done in two ways.
1. If the module provides a `package` option, such as
`programs.beets.package`, then this is the recommended way to
perform the override. For example,
```
programs.beets.package = pkgs.beets.override { enableCheck = true; };
```
2. If no `package` option is available, then you can typically
override the relevant package using an [overlay][nixpkgs-overlays].
For example, if you want to use the `programs.skim` module but use
the `skim` package from Nixpkgs unstable, then a configuration like
```nix
{ pkgs, config, ... }:
let
pkgsUnstable = import <nixpkgs-unstable> {};
in
{
programs.skim.enable = true;
nixpkgs.overlays = [
(self: super: {
skim = pkgsUnstable.skim;
})
];
# …
}
```
should work OK.
[nixpkgs-overlays]: https://nixos.org/nixpkgs/manual/#chap-overlays

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-2019 Robert Helgesson and Home Manager contributors
Copyright (c) 2017-2020 Robert Helgesson and Home Manager contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -6,6 +6,9 @@ using the [Nix][] package manager together with the Nix libraries
found in [Nixpkgs][]. Before attempting to use Home Manager please
read the warning below.
For a more systematic overview of Home Manager and its available
options, please see the [Home Manager manual][manual].
Words of warning
----------------
@@ -19,7 +22,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 20.03 (the
current stable version), it may or may not work on other Linux
distributions and NixOS versions.
@@ -43,21 +46,12 @@ Installation
Currently the easiest way to install Home Manager is as follows:
1. Make sure you have a working Nix installation. If you are not
using NixOS then you may here have to run
```console
$ mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
```
since Home Manager uses these directories to manage your profile
generations. On NixOS these should already be available.
Also make sure that your user is able to build and install Nix
packages. For example, you should be able to successfully run a
command like `nix-instantiate '<nixpkgs>' -A hello` without having
to switch to the root user. For a multi-user install of Nix this
means that your user must be covered by the
1. Make sure you have a working Nix installation. Specifically, make
sure that your user is able to build and install Nix packages. For
example, you should be able to successfully run a command like
`nix-instantiate '<nixpkgs>' -A hello` without having to switch to
the root user. For a multi-user install of Nix this means that
your user must be covered by the
[`allowed-users`][nixAllowedUsers] Nix option. On NixOS you can
control this option using the
[`nix.allowedUsers`][nixosAllowedUsers] system option.
@@ -72,11 +66,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-20.03.tar.gz home-manager
$ nix-channel --update
```
if you follow a Nixpkgs version 19.03 channel.
if you follow a Nixpkgs version 20.03 channel.
On NixOS you may need to log out and back in for the channel to
become available. On non-NixOS you may have to add
@@ -155,7 +149,13 @@ To satisfy the above setup we should elaborate the
programs.firefox = {
enable = true;
enableIcedTea = true;
profiles = {
myprofile = {
settings = {
"general.smoothScroll" = false;
};
};
};
};
services.gpg-agent = {
@@ -300,6 +300,17 @@ in your system configuration and
in your Home Manager configuration.
Releases
--------
Home Manager is developed against `nixpkgs-unstable` branch, which
often causes it to contain tweaks for changes/packages not yet
released in stable NixOS. To avoid breaking users' configurations,
Home Manager is released in branches corresponding to NixOS releases
(e.g. `release-20.03`). These branches get fixes, but usually not new
modules. If you need a module to be backported, then feel free to open
an issue.
[Bash]: https://www.gnu.org/software/bash/
[Nix]: https://nixos.org/nix/
[NixOS]: https://nixos.org/
@@ -307,6 +318,7 @@ in your Home Manager configuration.
[nixAllowedUsers]: https://nixos.org/nix/manual/#conf-allowed-users
[nixosAllowedUsers]: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers
[Z shell]: http://zsh.sourceforge.net/
[manual]: https://rycee.gitlab.io/home-manager/
[configuration options]: https://rycee.gitlab.io/home-manager/options.html
[#home-manager]: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager
[freenode]: https://freenode.net/

View File

@@ -1,13 +1,10 @@
{ pkgs ? import <nixpkgs> {} }:
{ pkgs ? import <nixpkgs> { } }:
rec {
home-manager = pkgs.callPackage ./home-manager {
path = toString ./.;
};
home-manager = pkgs.callPackage ./home-manager { path = toString ./.; };
install = pkgs.callPackage ./home-manager/install.nix {
inherit home-manager;
};
install =
pkgs.callPackage ./home-manager/install.nix { inherit home-manager; };
nixos = import ./nixos;
}

View File

@@ -1,36 +1,35 @@
{ pkgs }:
{
# Note, this should be "the standard library" + HM extensions.
lib, pkgs }:
let
lib = pkgs.lib;
nmdSrc = pkgs.fetchFromGitLab {
name = "nmd";
owner = "rycee";
repo = "nmd";
rev = "9751ca5ef6eb2ef27470010208d4c0a20e89443d";
sha256 = "0rbx10n8kk0bvp1nl5c8q79lz1w0p1b8103asbvwps3gmqd070hi";
rev = "49567e3ff2824ac8ba457f439f384eafc1eb4547";
sha256 = "0x2lwcryvmnr128r497bzrawi4x1yyxb4riicppdaib95iwn8jck";
};
nmd = import nmdSrc { inherit pkgs; };
nmd = import nmdSrc { inherit lib pkgs; };
# Make sure the used package is scrubbed to avoid actually
# instantiating derivations.
scrubbedPkgsModule = {
imports = [
{
_module.args = {
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
pkgs_i686 = lib.mkForce { };
};
}
];
imports = [{
_module.args = {
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
pkgs_i686 = lib.mkForce { };
};
}];
};
hmModulesDocs = nmd.buildModulesDocs {
modules =
import ../modules/modules.nix { inherit lib pkgs; }
++ [ scrubbedPkgsModule ];
modules = import ../modules/modules.nix {
inherit lib pkgs;
check = false;
} ++ [ scrubbedPkgsModule ];
moduleRootPaths = [ ./.. ];
mkModuleUrl = path:
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
@@ -42,6 +41,7 @@ let
pathName = "home-manager";
modulesDocs = [ hmModulesDocs ];
documentsDirectory = ./.;
documentType = "book";
chunkToc = ''
<toc>
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-home-manager-manual"><?dbhtml filename="index.html"?>
@@ -53,9 +53,7 @@ let
'';
};
in
{
in {
inherit nmdSrc;
options = {
@@ -66,7 +64,5 @@ in
manPages = docs.manPages;
manual = {
inherit (docs) html htmlOpenTool;
};
manual = { inherit (docs) html htmlOpenTool; };
}

View File

@@ -44,22 +44,12 @@
<orderedlist>
<listitem>
<para>
Make sure you have a working Nix installation. If you are not using NixOS
then it may be necessary to run
</para>
<screen>
<prompt>$</prompt> <userinput>mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER</userinput>
</screen>
<para>
since Home Manager uses these directories to manage your profile
generations. On NixOS these should already be available.
</para>
<para>
Also make sure that your user is able to build and install Nix packages.
For example, you should be able to successfully run a command like
<literal>nix-instantiate '&lt;nixpkgs&gt;' -A hello</literal> without
having to switch to the root user. For a multi-user install of Nix this
means that your user must be covered by the
Make sure you have a working Nix installation. Specifically, make
sure that your user is able to build and install Nix packages.
For example, you should be able to successfully run a command
like <literal>nix-instantiate '&lt;nixpkgs&gt;' -A hello</literal>
without having to switch to the root user. For a multi-user
install of Nix this means that your user must be covered by the
<link xlink:href="https://nixos.org/nix/manual/#conf-allowed-users"><literal>allowed-users</literal></link>
Nix option. On NixOS you can control this option using the
<link xlink:href="https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers"><literal>nix.allowedUsers</literal></link>
@@ -79,11 +69,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-20.03.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 20.03 channel.
</para>
<para>
On NixOS you may need to log out and back in for the channel to become
@@ -169,12 +159,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-20.03.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 20.03 channel.
</para>
<para>
@@ -225,6 +215,23 @@ home-manager.useUserPackages = true;
become the default value in the future.
</para>
</note>
<note>
<para>
By default, Home Manager uses a private <literal>pkgs</literal> instance
that is configured via the <option>home-manager.users.&lt;name&gt;.nixpkgs</option> options.
To instead use the global <literal>pkgs</literal> that is configured via
the system level <option>nixpkgs</option> options, set
</para>
<programlisting language="nix">
home-manager.useGlobalPkgs = true;
</programlisting>
<para>
This saves an extra Nixpkgs evaluation, adds consistency, and removes the
dependency on <envar>NIX_PATH</envar>, which is otherwise used for
importing Nixpkgs.
</para>
</note>
</section>
<section xml:id="sec-install-nix-darwin-module">
<title>nix-darwin module</title>
@@ -251,12 +258,12 @@ home-manager.useUserPackages = true;
</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-20.03.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 20.03 channel.
</para>
<para>

View File

@@ -17,6 +17,10 @@
build
</arg>
<arg choice="plain">
instantiate
</arg>
<arg choice="plain">
edit
</arg>
@@ -126,6 +130,10 @@
--show-trace
</arg>
<arg>
--(no-)substitute
</arg>
<arg>
<group choice="req">
<arg choice="plain">
@@ -159,6 +167,16 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>instantiate</option>
</term>
<listitem>
<para>
Instantiate the configuration and print the resulting derivation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>edit</option>
@@ -446,6 +464,18 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--(no-)substitute</option>
</term>
<listitem>
<para>
Passed on to <citerefentry>
<refentrytitle>nix-build</refentrytitle>
<manvolnum>1</manvolnum> </citerefentry>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-v</option>

View File

@@ -4,7 +4,7 @@
<title>Home Manager Reference Pages</title>
<info>
<author><personname>Home Manager contributors</personname></author>
<copyright><year>20172019</year><holder>Home Manager contributors</holder>
<copyright><year>20172020</year><holder>Home Manager contributors</holder>
</copyright>
</info>
<xi:include href="man-configuration.xml" />

View File

@@ -26,6 +26,7 @@
</note>
</preface>
<xi:include href="installation.xml" />
<xi:include href="writing-modules.xml" />
<appendix xml:id="ch-options">
<title>Configuration Options</title>
<xi:include href="./nmd-result/home-manager-options.xml" />

View File

@@ -0,0 +1,17 @@
[[ch-release-notes]]
[appendix]
== Release Notes
This section lists the release notes for stable versions of Home Manager and the current unstable version.
:leveloffset: 1
include::rl-2003.adoc[]
include::rl-1909.adoc[]
include::rl-1903.adoc[]
include::rl-1809.adoc[]
:leveloffset: 0

View File

@@ -1,14 +0,0 @@
<appendix xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="ch-release-notes">
<title>Release Notes</title>
<para>
This section lists the release notes for stable versions of Home Manager and
the current unstable version.
</para>
<xi:include href="rl-1909.xml" />
<xi:include href="rl-1903.xml" />
<xi:include href="rl-1809.xml" />
</appendix>

View File

@@ -1,8 +1,20 @@
[[sec-release-19.09]]
== Release 19.09 (unreleased)
== Release 19.09
This is the current unstable branch and the information in this
section is therefore not final.
The 19.09 release branch became the stable branch in October, 2019.
[[sec-release-19.09-highlights]]
=== Highlights
This release has the following notable changes:
* The `programs.firefox.enableGoogleTalk` and
`programs.firefox.enableIcedTea` options are now deprecated
and will only work if Firefox ESR 52.x is used.
* The `home-manager` tool now provides an `uninstall` sub-command that
can be used to uninstall Home Manager, if used in the standalone
mode. That is, not as a NixOS module.
[[sec-release-19.09-state-version-changes]]
=== State Version Changes

View File

@@ -0,0 +1,126 @@
[[sec-release-20.03]]
== Release 20.03
The 20.03 release branch became the stable branch in April, 2020.
[[sec-release-20.03-highlights]]
=== Highlights
This release has the following notable changes:
* Assigning a list to the <<opt-home.file>>, <<opt-xdg.configFile>>,
and <<opt-xdg.dataFile>> options is now deprecated and will produce a
warning message if used. Specifically, if your configuration currently
contains something like
+
[source,nix]
----
home.file = [
{
target = ".config/foo.txt";
text = "bar";
}
]
----
+
then it should be updated to instead use the equivalent attribute set form
+
[source,nix]
----
home.file = {
".config/foo.txt".text = "bar";
}
----
+
Support for the list form will be removed in Home Manager version
20.09.
* The `lib` function attribute given to modules is now enriched with
an attribute `hm` containing extra library functions specific for Home
Manager. More specifically, `lib.hm` is now the same as `config.lib`
and should be the preferred choice since it is more robust.
+
Therefore, if your configuration makes use of, for example,
`config.lib.dag` to create activation script blocks, it is recommended
to change to `lib.hm.dag`.
+
Note, in the unlikely case that you are
+
** using Home Manager's NixOS or nix-darwin module,
** have made your own Home Manager module containing an top-level
option named `config` or `options`, and
** assign to this option in your system configuration inside a plain
attribute set, i.e., without a function argument,
+
then you must update your configuration to perform the option
assignment inside a `config` attribute. For example, instead of
+
[source,nix]
----
home-manager.users.jane = { config = "foo"; };
----
+
use
+
[source,nix]
----
home-manager.users.jane = { config.config = "foo"; };
----
* The `services.compton` module has been deprecated and instead the
new module `services.picom` should be used. This is because Nixpkgs no
longer packages compton, and instead packages the (mostly) compatible
fork called picom.
* The list form of the <<opt-programs.ssh.matchBlocks>> option has
been deprecated and configurations requiring match blocks in a defined
order should switch to using DAG entries instead. For example, a
configuration
+
[source,nix]
----
programs.ssh.matchBlocks = [
{
host = "alpha.foo.com";
user = "jd";
}
{
host = "*.foo.com";
user = "john.doe";
}
];
----
+
can be expressed along the lines of
+
[source,nix]
----
programs.ssh.matchBlocks = {
"*.example.com" = {
user = "john.doe";
}
"alpha.example.com" = lib.hm.dag.entryBefore ["*.example.com"] {
user = "jd";
}
};
----
+
Support for the list form will be removed in Home Manager version
20.09.
[[sec-release-20.03-state-version-changes]]
=== State Version Changes
The state version in this release includes the changes below. These
changes are only active if the `home.stateVersion` option is set to
"20.03" or later.
* The <<opt-programs.zsh.history.path>> option is no longer prepended
by `$HOME`, which allows specifying absolute paths, for example,
using the xdg module. Also, the default value is fixed to
`$HOME/.zsh_history` and `dotDir` path is not prepended to it
anymore.
* The newsboat module will now default in displaying `queries` before `urls` in
its main window. This makes sense in the case when one has a lot of URLs and
few queries.

180
doc/writing-modules.adoc Normal file
View File

@@ -0,0 +1,180 @@
[[ch-writing-modules]]
== Writing Home Manager Modules
:writing-nixos-modules: https://nixos.org/nixos/manual/index.html#sec-writing-modules
The module system in Home Manager is based entirely on the NixOS module system so we will here only highlight aspects that are specific for Home Manager. For information about the module system as such please refer to the {writing-nixos-modules}[Writing NixOS Modules] chapter of the NixOS manual.
[[sec-option-types]]
=== Option Types
:wikipedia-dag: https://en.wikipedia.org/w/index.php?title=Directed_acyclic_graph&oldid=939656095
:gvariant-description: https://developer.gnome.org/glib/stable/glib-GVariant.html#glib-GVariant.description
Overall the basic option types are the same in Home Manager as NixOS. A few Home Manager options, however, make use of custom types that are worth describing in more detail. These are the option types `dagOf` and `gvariant` that are used, for example, by <<opt-programs.ssh.matchBlocks>> and <<opt-dconf.settings>>.
`hm.types.dagOf`::
Options of this type have attribute sets as values where each member is a node in a {wikipedia-dag}[directed acyclic graph] (DAG). This allows the attribute set entries to express dependency relations among themselves. This can, for example, be used to control the order of match blocks in a OpenSSH client configuration or the order of activation script blocks in <<opt-home.activation>>.
+
A number of functions are provided to create DAG nodes. The functions are shown below with examples using an option `foo.bar` of type `hm.types.dagOf types.int`.
+
`hm.dag.entryAnywhere (value: T)`:::
Indicates that `value` can be placed anywhere within the DAG. This is also the default for plain attribute set entries, that is
+
[source,nix]
----
foo.bar = {
a = hm.dag.entryAnywhere 0;
}
----
+
and
+
[source,nix]
----
foo.bar = {
a = 0;
}
----
+
are equivalent.
+
`hm.dag.entryAfter (afters: list string) (value: T)`:::
Indicates that `value` must be placed _after_ each of the attribute names in the given list. For example
+
[source,nix]
----
foo.bar = {
a = 0;
b = hm.dag.entryAfter [ "a" ] 1;
}
----
+
would place `b` after `a` in the graph.
+
`hm.dag.entryBefore (befores: list string) (value: T)`:::
Indicates that `value` must be placed _before_ each of the attribute names in the given list. For example
+
[source,nix]
----
foo.bar = {
b = hm.dag.entryBefore [ "a" ] 1;
a = 0;
}
----
+
would place `b` before `a` in the graph.
+
`hm.dag.entryBetween (befores: list string) (afters: list string) (value: T)`:::
Indicates that `value` must be placed _before_ the attribute names in the first list and _after_ the attribute names in the second list. For example
+
[source,nix]
----
foo.bar = {
a = 0;
c = hm.dag.entryBetween [ "b" ] [ "a" ] 2;
b = 1;
}
----
+
would place `c` before `b` and after `a` in the graph.
`hm.types.gvariant`::
This type is useful for options representing {gvariant-description}[GVariant] values. The type accepts all primitive GVariant types as well as arrays and tuples. Dictionaries are not currently supported.
+
To create a GVariant value you can use a number of provided functions. Examples assume an option `foo.bar` of type `hm.types.gvariant`.
+
`hm.gvariant.mkBoolean (v: bool)`:::
Takes a Nix value `v` to a GVariant `boolean` value. Note, Nix booleans are automatically coerced using this function. That is,
+
[source,nix]
----
foo.bar = hm.gvariant.mkBoolean true;
----
+
is equivalent to
+
[source,nix]
----
foo.bar = true;
----
`hm.gvariant.mkString (v: string)`:::
Takes a Nix value `v` to a GVariant `string` value. Note, Nix strings are automatically coerced using this function. That is,
+
[source,nix]
----
foo.bar = hm.gvariant.mkString "a string";
----
+
is equivalent to
+
[source,nix]
----
foo.bar = "a string";
----
`hm.gvariant.mkObjectpath (v: string)`:::
Takes a Nix value `v` to a GVariant `objectpath` value.
`hm.gvariant.mkUchar (v: string)`:::
Takes a Nix value `v` to a GVariant `uchar` value.
`hm.gvariant.mkInt16 (v: int)`:::
Takes a Nix value `v` to a GVariant `int16` value.
`hm.gvariant.mkUint16 (v: int)`:::
Takes a Nix value `v` to a GVariant `uint16` value.
`hm.gvariant.mkInt32 (v: int)`:::
Takes a Nix value `v` to a GVariant `int32` value. Note, Nix integers are automatically coerced using this function. That is,
+
[source,nix]
----
foo.bar = hm.gvariant.mkInt32 7;
----
+
is equivalent to
+
[source,nix]
----
foo.bar = 7;
----
`hm.gvariant.mkUint32 (v: int)`:::
Takes a Nix value `v` to a GVariant `uint32` value.
`hm.gvariant.mkInt64 (v: int)`:::
Takes a Nix value `v` to a GVariant `int64` value.
`hm.gvariant.mkUint64 (v: int)`:::
Takes a Nix value `v` to a GVariant `uint64` value.
`hm.gvariant.mkDouble (v: double)`:::
Takes a Nix value `v` to a GVariant `double` value. Note, Nix floats are automatically coerced using this function. That is,
+
[source,nix]
----
foo.bar = hm.gvariant.mkDouble 3.14;
----
+
is equivalent to
+
[source,nix]
----
foo.bar = 3.14;
----
+
`hm.gvariant.mkArray type elements`:::
Builds a GVariant array containing the given list of elements, where each element is a GVariant value of the given type. The `type` value can be constructed using
+
--
- `hm.gvariant.type.string`
- `hm.gvariant.type.boolean`
- `hm.gvariant.type.uchar`
- `hm.gvariant.type.int16`
- `hm.gvariant.type.uint16`
- `hm.gvariant.type.int32`
- `hm.gvariant.type.uint32`
- `hm.gvariant.type.int64`
- `hm.gvariant.type.uint64`
- `hm.gvariant.type.double`
- `hm.gvariant.type.arrayOf type`
- `hm.gvariant.type.tupleOf types`
--
+
where `type` and `types` are themselve a type and list of types, respectively.
+
`hm.gvariant.mkEmptyArray type`:::
An alias of `hm.gvariant.mkArray type []`.
+
`hm.gvariant.mkTuple elements`:::
Builds a GVariant tuple containing the given list of elements, where each element is a GVariant value.

65
format Executable file
View File

@@ -0,0 +1,65 @@
#! /usr/bin/env nix-shell
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/05f0934825c2a0750d4888c4735f9420c906b388.tar.gz -i bash -p findutils nixfmt
CHECK_ARG=
case $1 in
-h)
echo "$0 [-c]"
;;
-c)
CHECK_ARG=-c
;;
esac
# The first block of excludes are files where nixfmt does a poor job,
# IMHO. The second block of excludes are files touched by open pull
# requests and we want to avoid merge conflicts.
find . -name '*.nix' \
! -path ./modules/programs/irssi.nix \
\
! -path ./home-manager/default.nix \
! -path ./home-manager/home-manager.nix \
! -path ./modules/default.nix \
! -path ./modules/files.nix \
! -path ./modules/home-environment.nix \
! -path ./modules/lib/default.nix \
! -path ./modules/lib/file-type.nix \
! -path ./modules/manual.nix \
! -path ./modules/misc/dconf.nix \
! -path ./modules/misc/gtk.nix \
! -path ./modules/misc/news.nix \
! -path ./modules/misc/nixpkgs.nix \
! -path ./modules/misc/xdg.nix \
! -path ./modules/modules.nix \
! -path ./modules/programs/afew.nix \
! -path ./modules/programs/alot.nix \
! -path ./modules/programs/bash.nix \
! -path ./modules/programs/emacs.nix \
! -path ./modules/programs/firefox.nix \
! -path ./modules/programs/gpg.nix \
! -path ./modules/programs/lesspipe.nix \
! -path ./modules/programs/neovim.nix \
! -path ./modules/programs/ssh.nix \
! -path ./modules/programs/tmux.nix \
! -path ./modules/programs/vscode.nix \
! -path ./modules/programs/zsh.nix \
! -path ./modules/services/gpg-agent.nix \
! -path ./modules/services/kbfs.nix \
! -path ./modules/services/keybase.nix \
! -path ./modules/services/mpd.nix \
! -path ./modules/services/sxhkd.nix \
! -path ./modules/services/window-managers/i3.nix \
! -path ./modules/systemd.nix \
! -path ./nix-darwin/default.nix \
! -path ./tests/default.nix \
! -path ./tests/modules/home-environment/default.nix \
! -path ./tests/modules/home-environment/session-variables.nix \
! -path ./tests/modules/programs/gpg/override-defaults.nix \
! -path ./tests/modules/programs/tmux/default.nix \
! -path ./tests/modules/programs/zsh/session-variables.nix \
! -path ./tests/modules/services/sxhkd/service.nix \
! -path ./tests/modules/systemd/default.nix \
! -path ./tests/modules/systemd/services.nix \
! -path ./tests/modules/systemd/session-variables.nix \
-exec nixfmt $CHECK_ARG {} +

View File

@@ -278,7 +278,7 @@ _home-manager_completions ()
#--------------------------#
local Subcommands
Subcommands=( "help" "edit" "build" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" )
Subcommands=( "help" "edit" "build" "instantiate" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" )
# ^ « home-manager »'s subcommands.

View File

@@ -74,36 +74,48 @@ function setHomeManagerNixPath() {
done
}
function doInstantiate() {
setConfigFile
setHomeManagerNixPath
local extraArgs=()
for p in "${EXTRA_NIX_PATH[@]}"; do
extraArgs=("${extraArgs[@]}" "-I" "$p")
done
if [[ -v VERBOSE ]]; then
extraArgs=("${extraArgs[@]}" "--show-trace")
fi
nix-instantiate \
"<home-manager/home-manager/home-manager.nix>" \
"${extraArgs[@]}" \
"${PASSTHROUGH_OPTS[@]}" \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
}
function doBuildAttr() {
setConfigFile
setHomeManagerNixPath
local extraArgs="$*"
local extraArgs=("$@")
for p in "${EXTRA_NIX_PATH[@]}"; do
extraArgs="$extraArgs -I $p"
extraArgs=("${extraArgs[@]}" "-I" "$p")
done
if [[ -v VERBOSE ]]; then
extraArgs="$extraArgs --show-trace"
extraArgs=("${extraArgs[@]}" "--show-trace")
fi
# shellcheck disable=2086
if [[ -v USE_NIX2_COMMAND ]]; then
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
nix-build \
"<home-manager/home-manager/home-manager.nix>" \
"${extraArgs[@]}" \
"${PASSTHROUGH_OPTS[@]}" \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
}
# Presents news to the user. Takes as argument the path to a "news
@@ -169,13 +181,8 @@ function doBuild() {
local exitCode
if [[ -v USE_NIX2_COMMAND ]]; then
doBuildAttr activationPackage \
&& exitCode=0 || exitCode=1
else
doBuildAttr --attr activationPackage \
&& exitCode=0 || exitCode=1
fi
doBuildAttr --attr activationPackage \
&& exitCode=0 || exitCode=1
presentNews "$newsInfo"
@@ -197,17 +204,10 @@ function doSwitch() {
# before activation completes.
generation="$WORK_DIR/generation"
if [[ -v USE_NIX2_COMMAND ]]; then
doBuildAttr \
--out-link "$generation" \
activationPackage \
&& "$generation/activate" || exitCode=1
else
doBuildAttr \
--out-link "$generation" \
--attr activationPackage \
&& "$generation/activate" || exitCode=1
fi
doBuildAttr \
--out-link "$generation" \
--attr activationPackage \
&& "$generation/activate" || exitCode=1
presentNews "$newsInfo"
@@ -307,23 +307,14 @@ function buildNews() {
local output
output="$WORK_DIR/news-info.sh"
if [[ -v USE_NIX2_COMMAND ]]; then
doBuildAttr \
--out-link "$output" \
--quiet \
--arg check false \
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
newsInfo
else
doBuildAttr \
--out-link "$output" \
--no-build-output \
--quiet \
--arg check false \
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
--attr newsInfo \
> /dev/null
fi
doBuildAttr \
--out-link "$output" \
--no-build-output \
--quiet \
--arg check false \
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
--attr newsInfo \
> /dev/null
echo "$output"
}
@@ -375,7 +366,7 @@ function doUninstall() {
y|Y)
echo "Switching to empty Home Manager configuration..."
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
echo "{}" > "$HOME_MANAGER_CONFIG"
echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG"
doSwitch
rm "$HOME_MANAGER_CONFIG"
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
@@ -431,6 +422,7 @@ function doHelp() {
echo " --max-jobs NUM"
echo " --option NAME VALUE"
echo " --show-trace"
echo " --(no-)substitute"
echo
echo "Commands"
echo
@@ -440,6 +432,8 @@ function doHelp() {
echo
echo " build Build configuration into result directory"
echo
echo " instantiate Instantiate the configuration and print the resulting derivation"
echo
echo " switch Build and activate configuration"
echo
echo " generations List all home environment generations"
@@ -470,12 +464,9 @@ while [[ $# -gt 0 ]]; do
opt="$1"
shift
case $opt in
build|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
build|instantiate|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
COMMAND="$opt"
;;
-2)
USE_NIX2_COMMAND=1
;;
-A)
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
shift
@@ -507,7 +498,8 @@ while [[ $# -gt 0 ]]; do
PASSTHROUGH_OPTS+=("$opt" "$1")
shift
;;
--keep-failed|--keep-going|--show-trace)
--keep-failed|--keep-going|--show-trace\
|--substitute|--no-substitute)
PASSTHROUGH_OPTS+=("$opt")
;;
-v|--verbose)
@@ -540,6 +532,9 @@ case $COMMAND in
build)
doBuild
;;
instantiate)
doInstantiate
;;
switch)
doSwitch
;;

View File

@@ -1,60 +1,67 @@
{ home-manager, runCommand }:
runCommand
"home-manager-install"
{
propagatedBuildInputs = [ home-manager ];
preferLocalBuild = true;
allowSubstitutes = false;
shellHookOnly = true;
shellHook = ''
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
if [[ ! -e $confFile ]]; then
echo
echo "Creating initial Home Manager configuration..."
mkdir -p "$(dirname "$confFile")"
cat > $confFile <<EOF
{ config, pkgs, ... }:
{
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
}
EOF
fi
runCommand "home-manager-install" {
propagatedBuildInputs = [ home-manager ];
preferLocalBuild = true;
allowSubstitutes = false;
shellHookOnly = true;
shellHook = ''
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
if [[ ! -e $confFile ]]; then
echo
echo "Creating initial Home Manager generation..."
echo
echo "Creating initial Home Manager configuration..."
if home-manager switch; then
cat <<EOF
mkdir -p "$(dirname "$confFile")"
cat > $confFile <<EOF
{ config, pkgs, ... }:
All done! The home-manager tool should now be installed and you
can edit
{
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
$confFile
# This value determines the Home Manager release that your
# configuration is compatible with. This helps avoid breakage
# when a new Home Manager release introduces backwards
# incompatible changes.
#
# You can update Home Manager without changing this value. See
# the Home Manager release notes for a list of state version
# changes in each release.
home.stateVersion = "20.03";
}
EOF
fi
to configure Home Manager. Run 'man home-configuration.nix' to
see all available options.
EOF
exit 0
else
cat <<EOF
echo
echo "Creating initial Home Manager generation..."
echo
Uh oh, the installation failed! Please create an issue at
if home-manager switch; then
cat <<EOF
https://github.com/rycee/home-manager/issues
All done! The home-manager tool should now be installed and you
can edit
if the error seems to be the fault of Home Manager.
EOF
exit 1
fi
'';
}
''
echo This derivation is not buildable, instead run it using nix-shell.
exit 1
''
$confFile
to configure Home Manager. Run 'man home-configuration.nix' to
see all available options.
EOF
exit 0
else
cat <<EOF
Uh oh, the installation failed! Please create an issue at
https://github.com/rycee/home-manager/issues
if the error seems to be the fault of Home Manager.
EOF
exit 1
fi
'';
} ''
echo This derivation is not buildable, instead run it using nix-shell.
exit 1
''

View File

@@ -106,7 +106,7 @@ let
tls = mkOption {
type = tlsModule;
default = {};
default = { };
description = ''
Configuration for secure connections.
'';
@@ -136,7 +136,7 @@ let
tls = mkOption {
type = tlsModule;
default = {};
default = { };
description = ''
Configuration for secure connections.
'';
@@ -209,7 +209,7 @@ let
aliases = mkOption {
type = types.listOf (types.strMatching ".*@.*");
default = [];
default = [ ];
example = [ "webmaster@example.org" "admin@example.org" ];
description = "Alternative email addresses of this account.";
};
@@ -276,7 +276,7 @@ let
};
};
};
default = {};
default = { };
description = ''
Standard email folders.
'';
@@ -292,7 +292,7 @@ let
signature = mkOption {
type = signatureModule;
default = {};
default = { };
description = ''
Signature configuration.
'';
@@ -332,9 +332,7 @@ let
(mkIf (config.flavor == "gmail.com") {
userName = mkDefault config.address;
imap = {
host = "imap.gmail.com";
};
imap = { host = "imap.gmail.com"; };
smtp = {
host = "smtp.gmail.com";
@@ -343,20 +341,14 @@ let
})
(mkIf (config.flavor == "runbox.com") {
imap = {
host = "mail.runbox.com";
};
imap = { host = "mail.runbox.com"; };
smtp = {
host = "mail.runbox.com";
};
smtp = { host = "mail.runbox.com"; };
})
];
};
in
{
in {
options.accounts.email = {
certificatesFile = mkOption {
type = types.path;
@@ -373,9 +365,7 @@ in
default = "${config.home.homeDirectory}/Maildir";
defaultText = "$HOME/Maildir";
apply = p:
if hasPrefix "/" p
then p
else "${config.home.homeDirectory}/${p}";
if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}";
description = ''
The base directory for account maildir directories. May be a
relative path, in which case it is relative the home
@@ -384,39 +374,35 @@ in
};
accounts = mkOption {
type = types.attrsOf (types.submodule [
type = types.attrsOf (types.submodule ([
mailAccountOpts
(import ../programs/alot-accounts.nix pkgs)
(import ../programs/astroid-accounts.nix)
(import ../programs/getmail-accounts.nix)
(import ../programs/lieer-accounts.nix)
(import ../programs/mbsync-accounts.nix)
(import ../programs/msmtp-accounts.nix)
(import ../programs/neomutt-accounts.nix)
(import ../programs/notmuch-accounts.nix)
(import ../programs/offlineimap-accounts.nix)
]);
default = {};
] ++ optionals pkgs.stdenv.hostPlatform.isLinux
[ (import ../services/lieer-accounts.nix) ]));
default = { };
description = "List of email accounts.";
};
};
config = mkIf (cfg.accounts != {}) {
config = mkIf (cfg.accounts != { }) {
assertions = [
(
let
primaries =
catAttrs "name"
(filter (a: a.primary)
(attrValues cfg.accounts));
in
{
assertion = length primaries == 1;
message =
"Must have exactly one primary mail account but found "
+ toString (length primaries)
+ optionalString (length primaries > 1)
(", namely " + concatStringsSep ", " primaries);
}
)
(let
primaries =
catAttrs "name" (filter (a: a.primary) (attrValues cfg.accounts));
in {
assertion = length primaries == 1;
message = "Must have exactly one primary mail account but found "
+ toString (length primaries) + optionalString (length primaries > 1)
(", namely " + concatStringsSep ", " primaries);
})
];
};
}

View File

@@ -19,10 +19,16 @@ let
in
fold f res res.config.warnings;
rawModule = lib.evalModules {
modules =
[ configuration ]
++ (import ./modules.nix { inherit check lib pkgs; });
extendedLib = import ./lib/stdlib-extended.nix pkgs.lib;
hmModules =
import ./modules.nix {
inherit check pkgs;
lib = extendedLib;
};
rawModule = extendedLib.evalModules {
modules = [ configuration ] ++ hmModules;
specialArgs = {
modulesPath = builtins.toString ./.;
};

View File

@@ -6,8 +6,6 @@ let
cfg = config.home.file;
dag = config.lib.dag;
homeDirectory = config.home.homeDirectory;
fileType = (import lib/file-type.nix {
@@ -23,10 +21,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
{
@@ -47,18 +41,42 @@ in
config = {
# This verifies that the links we are about to create will not
# overwrite an existing file.
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
let
# Paths that should be forcibly overwritten by Home Manager.
# Caveat emptor!
forcedPaths =
concatMapStringsSep " " (p: ''"$HOME/${p}"'')
(mapAttrsToList (n: v: v.target)
(filterAttrs (n: v: v.force) cfg));
check = pkgs.writeText "check" ''
. ${./lib-bash/color-echo.sh}
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
forcedPaths=(${forcedPaths})
newGenFiles="$1"
shift
for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" \
&& ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
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
@@ -113,7 +131,7 @@ in
# and a failure during the intermediate state FA ∩ FB will not
# result in lost links because this set of links are in both the
# source and target generation.
home.activation.linkGeneration = dag.entryAfter ["writeBoundary"] (
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
let
link = pkgs.writeText "link" ''
newGenFiles="$1"
@@ -133,13 +151,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)"
@@ -195,8 +217,7 @@ in
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
echo "Creating profile generation $newGenNum"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG $(basename "$newGenProfilePath") "$genProfilePath"
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
else
echo "No change so reusing latest profile generation $oldGenNum"
@@ -206,7 +227,7 @@ in
''
);
home.activation.checkFilesChanged = dag.entryBefore ["linkGeneration"] (
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
''
declare -A changedFiles
'' + concatMapStrings (v: ''
@@ -216,7 +237,7 @@ in
'') (filter (v: v.onChange != "") (attrValues cfg))
);
home.activation.onFilesChange = dag.entryAfter ["linkGeneration"] (
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
concatMapStrings (v: ''
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then
${v.onChange}
@@ -236,6 +257,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"
@@ -244,10 +268,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

@@ -6,8 +6,6 @@ let
cfg = config.home;
dag = config.lib.dag;
languageSubModule = types.submodule {
options = {
base = mkOption {
@@ -200,6 +198,16 @@ in
'';
};
home.sessionVariablesExtra = mkOption {
type = types.lines;
default = "";
internal = true;
description = ''
Extra configuration to add to the
<filename>hm-session-vars.sh</filename> file.
'';
};
home.packages = mkOption {
type = types.listOf types.package;
default = [];
@@ -228,23 +236,57 @@ in
type = types.bool;
description = ''
Whether the activation script should start with an empty
<envvar>PATH</envvar> variable. When <literal>false</literal>
then the user's <envvar>PATH</envvar> will be used.
<envar>PATH</envar> variable. When <literal>false</literal>
then the user's <envar>PATH</envar> will be used.
'';
};
home.activation = mkOption {
internal = true;
type = hm.types.dagOf types.str;
default = {};
type = types.attrs;
example = literalExample ''
{
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
''${builtins.toPath ./link-me-directly} $HOME
''';
}
'';
description = ''
Activation scripts for the home environment.
The activation scripts blocks to run when activating a Home
Manager generation. Any entry here should be idempotent,
meaning running twice or more times produces the same result
as running it once.
</para><para>
Any script should respect the <varname>DRY_RUN</varname>
variable, if it is set then no actual action should be taken.
If the script block produces any observable side effect, such
as writing or deleting files, then it
<emphasis>must</emphasis> be placed after the special
<literal>writeBoundary</literal> script block. Prior to the
write boundary one can place script blocks that verifies, but
does not modify, the state of the system and exits if an
unexpected state is found. For example, the
<literal>checkLinkTargets</literal> script block checks for
collisions between non-managed files and files defined in
<varname><link linkend="opt-home.file">home.file</link></varname>.
</para><para>
A script block should respect the <varname>DRY_RUN</varname>
variable, if it is set then the actions taken by the script
should be logged to standard out and not actually performed.
The variable <varname>DRY_RUN_CMD</varname> is set to
<code>echo</code> if dry run is enabled. Thus, many cases you
can use the idiom <code>$DRY_RUN_CMD rm -rf /</code>.
<command>echo</command> if dry run is enabled.
</para><para>
A script block should also respect the
<varname>VERBOSE</varname> variable, and if set print
information on standard out that may be useful for debugging
any issue that may arise. The variable
<varname>VERBOSE_ARG</varname> is set to
<option>--verbose</option> if verbose output is enabled.
'';
};
@@ -320,14 +362,14 @@ in
export __HM_SESS_VARS_SOURCED=1
${config.lib.shell.exportAll cfg.sessionVariables}
'';
'' + cfg.sessionVariablesExtra;
}
)
];
# A dummy entry acting as a boundary between the activation
# script's "check" and the "write" phases.
home.activation.writeBoundary = dag.entryAnywhere "";
home.activation.writeBoundary = hm.dag.entryAnywhere "";
# Install packages to the user environment.
#
@@ -344,7 +386,7 @@ in
# In case the user has moved from a user-install of Home Manager
# to a submodule managed one we attempt to uninstall the
# `home-manager-path` package if it is installed.
home.activation.installPackages = dag.entryAfter ["writeBoundary"] (
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
if config.submoduleSupport.externalPackageInstall
then
''
@@ -364,7 +406,7 @@ in
noteEcho Activating ${res.name}
${res.data}
'';
sortedCommands = dag.topoSort cfg.activation;
sortedCommands = hm.dag.topoSort cfg.activation;
activationCmds =
if sortedCommands ? result then
concatStringsSep "\n" (map mkCmd sortedCommands.result)

View File

@@ -3,13 +3,16 @@
function setupVars() {
local profilesPath="/nix/var/nix/profiles/per-user/$USER"
local gcPath="/nix/var/nix/gcroots/per-user/$USER"
local greatestGenNum
genProfilePath="$profilesPath/home-manager"
newGenPath="@GENERATION_DIR@";
newGenGcPath="$gcPath/current-home"
local greatestGenNum
greatestGenNum=$( \
find "$profilesPath" -name 'home-manager-*-link' \
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
| sort -rn \
| head -1)
nix-env --list-generations --profile "$genProfilePath" \
| tail -1 \
| sed -E 's/ *([[:digit:]]+) .*/\1/')
if [[ -n $greatestGenNum ]] ; then
oldGenNum=$greatestGenNum
@@ -18,15 +21,15 @@ function setupVars() {
newGenNum=1
fi
if [[ -e $gcPath/current-home ]] ; then
oldGenPath="$(readlink -e "$gcPath/current-home")"
if [[ -e $profilesPath/home-manager ]] ; then
oldGenPath="$(readlink -e "$profilesPath/home-manager")"
fi
$VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath"
if [[ -v oldGenNum && ! -v oldGenPath
|| ! -v oldGenNum && -v oldGenPath ]]; then
errorEcho "Invalid profile number and GC root values! These must be"
errorEcho "either both empty or both set but are now set to"
errorEcho "Invalid profile number and current profile values! These"
errorEcho "must be either both empty or both set but are now set to"
errorEcho " '${oldGenNum:-}' and '${oldGenPath:-}'"
errorEcho "If you don't mind losing previous profile generations then"
errorEcho "the easiest solution is probably to run"
@@ -35,12 +38,6 @@ function setupVars() {
errorEcho "and trying home-manager switch again. Good luck!"
exit 1
fi
genProfilePath="$profilesPath/home-manager"
newGenPath="@GENERATION_DIR@";
newGenProfilePath="$profilesPath/home-manager-$newGenNum-link"
newGenGcPath="$gcPath/current-home"
}
if [[ -v VERBOSE ]]; then
@@ -53,6 +50,11 @@ fi
echo "Starting home manager activation"
# Verify that we can connect to the Nix store and/or daemon. This will
# also create the necessary directories in profiles and gcroots.
$VERBOSE_ECHO "Sanity checking Nix"
nix-build --expr '{}' --no-out-link
setupVars
if [[ -v DRY_RUN ]] ; then
@@ -78,6 +80,5 @@ else
fi
$VERBOSE_ECHO " newGenPath=$newGenPath"
$VERBOSE_ECHO " newGenNum=$newGenNum"
$VERBOSE_ECHO " newGenProfilePath=$newGenProfilePath"
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
$VERBOSE_ECHO " genProfilePath=$genProfilePath"

View File

@@ -13,13 +13,11 @@ with lib;
rec {
emptyDag = {};
emptyDag = { };
isDag = dag:
let
isEntry = e: (e ? data) && (e ? after) && (e ? before);
in
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
let isEntry = e: (e ? data) && (e ? after) && (e ? before);
in builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
# Takes an attribute set containing entries built by
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
@@ -80,22 +78,19 @@ rec {
dagTopoSort = dag:
let
dagBefore = dag: name:
mapAttrsToList (n: v: n) (
filterAttrs (n: v: any (a: a == name) v.before) dag
);
normalizedDag =
mapAttrs (n: v: {
name = n;
data = v.data;
after = v.after ++ dagBefore dag n;
}) dag;
mapAttrsToList (n: v: n)
(filterAttrs (n: v: any (a: a == name) v.before) dag);
normalizedDag = mapAttrs (n: v: {
name = n;
data = v.data;
after = v.after ++ dagBefore dag n;
}) dag;
before = a: b: any (c: a.name == c) b.after;
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
in
if sorted ? result then
{ result = map (v: { inherit (v) name data; }) sorted.result; }
else
sorted;
in if sorted ? result then {
result = map (v: { inherit (v) name data; }) sorted.result;
} else
sorted;
# Applies a function to each element of the given DAG.
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
@@ -103,22 +98,20 @@ rec {
# Create a DAG entry with no particular dependency information.
dagEntryAnywhere = data: {
inherit data;
before = [];
after = [];
before = [ ];
after = [ ];
};
dagEntryBetween = before: after: data: {
inherit data before after;
};
dagEntryBetween = before: after: data: { inherit data before after; };
dagEntryAfter = after: data: {
inherit data after;
before = [];
before = [ ];
};
dagEntryBefore = before: data: {
inherit data before;
after = [];
after = [ ];
};
}

View File

@@ -1,6 +1,6 @@
{ lib }:
{
rec {
dag =
let
d = import ./dag.nix { inherit lib; };
@@ -16,7 +16,10 @@
entryBefore = d.dagEntryBefore;
};
gvariant = import ./gvariant.nix { inherit lib; };
strings = import ./strings.nix { inherit lib; };
types = import ./types.nix { inherit dag gvariant lib; };
shell = import ./shell.nix { inherit lib; };
zsh = import ./zsh.nix { inherit lib; };

View File

@@ -2,12 +2,6 @@
with lib;
let
stringsExtra = import ./strings.nix { inherit lib; };
in
{
# Constructs a type suitable for a `home.file` like option. The
# target path may be either absolute or relative, in which case it
@@ -86,6 +80,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 = {
@@ -93,7 +99,7 @@ in
source = mkIf (config.text != null) (
mkDefault (pkgs.writeTextFile {
inherit (config) executable text;
name = stringsExtra.storeFileName name;
name = hm.strings.storeFileName name;
})
);
};

141
modules/lib/gvariant.nix Normal file
View File

@@ -0,0 +1,141 @@
# A partial and basic implementation of GVariant formatted strings.
#
# Note, this API is not considered fully stable and it might therefore
# change in backwards incompatible ways without prior notice.
{ lib }:
with lib;
let
mkPrimitive = t: v: {
_type = "gvariant";
type = t;
value = v;
__toString = self: "@${self.type} ${toString self.value}";
};
type = {
arrayOf = t: "a${t}";
tupleOf = ts: "(${concatStrings ts})";
string = "s";
boolean = "b";
uchar = "y";
int16 = "n";
uint16 = "q";
int32 = "i";
uint32 = "u";
int64 = "x";
uint64 = "t";
double = "d";
};
# Returns the GVariant type of a given Nix value. If no type can be
# found for the value then the empty string is returned.
typeOf = v:
with type;
if builtins.isBool v then
boolean
else if builtins.isInt v then
int32
else if builtins.isFloat v then
double
else if builtins.isString v then
string
else if builtins.isList v then
let elemType = elemTypeOf v;
in if elemType == "" then "" else arrayOf elemType
else if builtins.isAttrs v && v ? type then
v.type
else
"";
elemTypeOf = vs:
if builtins.isList vs then
if vs == [ ] then "" else typeOf (head vs)
else
"";
in rec {
inherit type typeOf;
isArray = hasPrefix "a";
isTuple = hasPrefix "(";
# Returns the GVariant value that most closely matches the given Nix
# value. If no GVariant value can be found then `null` is returned.
#
# No support for dictionaries, maybe types, or variants.
mkValue = v:
if builtins.isBool v then
mkBoolean v
else if builtins.isInt v then
mkInt32 v
else if builtins.isFloat v then
mkDouble v
else if builtins.isString v then
mkString v
else if builtins.isList v then
if v == [ ] then mkArray type.string [ ] else mkArray (elemTypeOf v) v
else if builtins.isAttrs v && (v._type or "") == "gvariant" then
v
else
null;
mkArray = elemType: elems:
mkPrimitive (type.arrayOf elemType) (map mkValue elems) // {
__toString = self:
"@${self.type} [${concatMapStringsSep "," toString self.value}]";
};
mkEmptyArray = elemType: mkArray elemType [ ];
mkTuple = elems:
let
gvarElems = map mkValue elems;
tupleType = type.tupleOf (map (e: e.type) gvarElems);
in mkPrimitive tupleType gvarElems // {
__toString = self:
"@${self.type} (${concatMapStringsSep "," toString self.value})";
};
mkBoolean = v:
mkPrimitive type.boolean v // {
__toString = self: if self.value then "true" else "false";
};
mkString = v:
mkPrimitive type.string v // {
__toString = self: "'${escape [ "'" ] self.value}'";
};
mkObjectpath = v:
mkPrimitive type.string v // {
__toString = self: "objectpath '${escape [ "'" ] self.value}'";
};
mkUchar = mkPrimitive type.uchar;
mkInt16 = mkPrimitive type.int16;
mkUint16 = mkPrimitive type.uint16;
mkInt32 = v:
mkPrimitive type.int32 v // {
__toString = self: toString self.value;
};
mkUint32 = mkPrimitive type.uint32;
mkInt64 = mkPrimitive type.int64;
mkUint64 = mkPrimitive type.uint64;
mkDouble = v:
mkPrimitive type.double v // {
__toString = self: toString self.value;
};
}

View File

@@ -2,7 +2,7 @@
rec {
# Produces a Bourne shell like variable export statement.
export = n: v: "export ${n}=\"${toString v}\"";
export = n: v: ''export ${n}="${toString v}"'';
# Given an attribute set containing shell variable names and their
# assignment, this function produces a string containing an export

View File

@@ -0,0 +1,7 @@
# Just a convenience function that returns the given Nixpkgs standard
# library extended with the HM library.
nixpkgsLib:
let mkHmLib = import ./.;
in nixpkgsLib.extend (self: super: { hm = mkHmLib { lib = super; }; })

View File

@@ -9,19 +9,14 @@ with lib;
# All characters that are considered safe. Note "-" is not
# included to avoid "-" followed by digit being interpreted as a
# version.
safeChars =
[ "+" "." "_" "?" "=" ]
++ lowerChars
++ upperChars
safeChars = [ "+" "." "_" "?" "=" ] ++ lowerChars ++ upperChars
++ stringToCharacters "0123456789";
empties = l: genList (x: "") (length l);
unsafeInName = stringToCharacters (
replaceStrings safeChars (empties safeChars) path
);
unsafeInName =
stringToCharacters (replaceStrings safeChars (empties safeChars) path);
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
in
"hm_" + safeName;
in "hm_" + safeName;
}

99
modules/lib/types-dag.nix Normal file
View File

@@ -0,0 +1,99 @@
{ dag, lib }:
with lib;
let
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
dagContentType = elemType:
types.submodule ({ name, ... }: {
options = {
data = mkOption { type = elemType; };
after = mkOption { type = with types; uniq (listOf str); };
before = mkOption { type = with types; uniq (listOf str); };
};
config = mkIf (elemType.name == "submodule") {
data._module.args.dagName = name;
};
});
in rec {
# A directed acyclic graph of some inner type.
#
# Note, if the element type is a submodule then the `name` argument
# will always be set to the string "data" since it picks up the
# internal structure of the DAG values. To give access to the
# "actual" attribute name a new submodule argument is provided with
# the name `dagName`.
dagOf = elemType:
let
convertAllToDags = let
maybeConvert = n: v: if isDagEntry v then v else dag.entryAnywhere v;
in map (def: def // { value = mapAttrs maybeConvert def.value; });
attrEquivalent = types.attrsOf (dagContentType elemType);
in mkOptionType rec {
name = "dagOf";
description = "DAG of ${elemType.description}s";
check = isAttrs;
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
getSubModules = elemType.getSubModules;
substSubModules = m: dagOf (elemType.substSubModules m);
functor = (defaultFunctor name) // { wrapped = elemType; };
};
# A directed acyclic graph of some inner type OR a list of that
# inner type. This is a temporary hack for use by the
# `programs.ssh.matchBlocks` and is only guaranteed to be vaguely
# correct!
#
# In particular, adding a dependency on one of the "unnamed-N-M"
# entries generated by a list value is almost guaranteed to destroy
# the list's order.
#
# This function will be removed in version 20.09.
listOrDagOf = elemType:
let
paddedIndexStr = list: i:
let padWidth = stringLength (toString (length list));
in fixedWidthNumber padWidth i;
convertAll = loc: defs:
let
convertListValue = namePrefix: def:
let
vs = def.value;
pad = paddedIndexStr vs;
makeEntry = i: v: nameValuePair "${namePrefix}.${pad i}" v;
warning = ''
In file ${def.file}
a list is being assigned to the option '${
concatStringsSep "." loc
}'.
This will soon be an error due to the list form being deprecated.
Please use the attribute set form instead with DAG functions to
express the desired order of entries.
'';
in warn warning (listToAttrs (imap1 makeEntry vs));
convertValue = i: def:
if isList def.value then
convertListValue "unnamed-${paddedIndexStr defs i}" def
else
def.value;
in imap1 (i: def: def // { value = convertValue i def; }) defs;
dagType = dagOf elemType;
in mkOptionType rec {
name = "listOrDagOf";
description = "list or DAG of ${elemType.description}s";
check = x: isList x || dagType.check x;
merge = loc: defs: dagType.merge loc (convertAll loc defs);
getSubOptions = dagType.getSubOptions;
getSubModules = dagType.getSubModules;
substSubModules = m: listOrDagOf (elemType.substSubModules m);
functor = (defaultFunctor name) // { wrapped = elemType; };
};
}

View File

@@ -1,28 +1,88 @@
{ lib }:
{ lib, dag ? import ./dag.nix { inherit lib; }
, gvariant ? import ./gvariant.nix { inherit lib; } }:
with lib;
{
let
typesDag = import ./types-dag.nix { inherit dag lib; };
# Needed since the type is called gvariant and its merge attribute
# must refer back to the type.
gvar = gvariant;
in rec {
inherit (typesDag) dagOf listOrDagOf;
selectorFunction = mkOptionType {
name = "selectorFunction";
description =
"Function that takes an attribute set and returns a list"
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);
merge = _loc: defs: as: concatMap (select: select as) (getValues defs);
};
overlayFunction = mkOptionType {
name = "overlayFunction";
description =
"An overlay function, takes self and super and returns"
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;
merge = _loc: defs: self: super:
foldl' (res: def: mergeAttrs res (def.value self super)) { } defs;
};
fontType = types.submodule {
options = {
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExample "pkgs.dejavu_fonts";
description = ''
Package providing the font. This package will be installed
to your profile. If <literal>null</literal> then the font
is assumed to already be available in your profile.
'';
};
name = mkOption {
type = types.str;
example = "DejaVu Sans 8";
description = ''
The family name and size of the font within the package.
'';
};
};
};
gvariant = mkOptionType rec {
name = "gvariant";
description = "GVariant value";
check = v: gvar.mkValue v != null;
merge = loc: defs:
let
vdefs = map (d: d // { value = gvar.mkValue d.value; }) defs;
vals = map (d: d.value) vdefs;
defTypes = map (x: x.type) vals;
sameOrNull = x: y: if x == y then y else null;
# A bit naive to just check the first entry…
sharedDefType = foldl' sameOrNull (head defTypes) defTypes;
allChecked = all (x: check x) vals;
in if sharedDefType == null then
throw ("Cannot merge definitions of `${showOption loc}' with"
+ " mismatched GVariant types given in"
+ " ${showFiles (getFiles defs)}.")
else if gvar.isArray sharedDefType && allChecked then
(types.listOf gvariant).merge loc
(map (d: d // { value = d.value.value; }) vdefs)
else if gvar.isTuple sharedDefType && allChecked then
mergeOneOption loc defs
else if gvar.type.string == sharedDefType && allChecked then
types.str.merge loc defs
else if gvar.type.double == sharedDefType && allChecked then
types.float.merge loc defs
else
mergeDefaultOption loc defs;
};
}

View File

@@ -2,13 +2,15 @@
rec {
# Produces a Zsh shell like value
toZshValue = v: if builtins.isBool v then
if v then "true" else "false"
else if builtins.isString v then
"\"${v}\""
else if builtins.isList v then
"(${lib.concatStringsSep " " (map toZshValue v)})"
else "\"${toString v}\"";
toZshValue = v:
if builtins.isBool v then
if v then "true" else "false"
else if builtins.isString v then
''"${v}"''
else if builtins.isList v then
"(${lib.concatStringsSep " " (map toZshValue v)})"
else
''"${toString v}"'';
# Produces a Zsh shell like definition statement
define = n: v: "${n}=${toZshValue v}";

View File

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

View File

@@ -5,27 +5,11 @@ with lib;
let
cfg = config.dconf;
dag = config.lib.dag;
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
mkIniKeyValue = key: value:
let
tweakVal = v:
if isString v then "'${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}";
primitive = with types; either bool (either int (either float str));
"${key}=${toString (hm.gvariant.mkValue value)}";
in
@@ -44,8 +28,7 @@ in
};
settings = mkOption {
type = with types;
attrsOf (attrsOf (either primitive (listOf primitive)));
type = with types; attrsOf (attrsOf hm.types.gvariant);
default = {};
example = literalExample ''
{
@@ -54,6 +37,7 @@ in
show-thousands = true;
base = 10;
word-size = 64;
window-position = lib.hm.gvariant.mkTuple [100 100];
};
}
'';
@@ -65,7 +49,7 @@ in
};
config = mkIf (cfg.enable && cfg.settings != {}) {
home.activation.dconfSettings = dag.entryAfter ["installPackages"] (
home.activation.dconfSettings = hm.dag.entryAfter ["installPackages"] (
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
in

26
modules/misc/debug.nix Normal file
View File

@@ -0,0 +1,26 @@
{ config, pkgs, lib, ... }:
with lib;
{
options.home = {
enableDebugInfo = mkEnableOption "" // {
description = ''
Some Nix-packages provide debug symbols for
<command>gdb</command> in the <literal>debug</literal>-output.
This option ensures that those are automatically fetched from
the binary cache if available and <command>gdb</command> is
configured to find those symbols.
'';
};
};
config = mkIf config.home.enableDebugInfo {
home.extraOutputsToInstall = [ "debug" ];
home.sessionVariables = {
NIX_DEBUG_INFO_DIRS =
"$NIX_DEBUG_INFO_DIRS\${NIX_DEBUG_INFO_DIRS:+:}${config.home.profileDirectory}/lib/debug";
};
};
}

View File

@@ -8,15 +8,15 @@ let
profileDirectory = config.home.profileDirectory;
in
{
in {
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkRenamedOptionModule
[ "fonts" "fontconfig" "enableProfileFonts" ]
[ "fonts" "fontconfig" "enable" ])
(mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
"fonts"
"fontconfig"
"enable"
])
];
options = {

View File

@@ -27,29 +27,6 @@ let
in
"${n} = ${v'}";
fontType = types.submodule {
options = {
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExample "pkgs.dejavu_fonts";
description = ''
Package providing the font. This package will be installed
to your profile. If <literal>null</literal> then the font
is assumed to already be available in your profile.
'';
};
name = mkOption {
type = types.str;
example = "DejaVu Sans 8";
description = ''
The family name and size of the font within the package.
'';
};
};
};
themeType = types.submodule {
options = {
package = mkOption {
@@ -87,7 +64,7 @@ in
enable = mkEnableOption "GTK 2/3 configuration";
font = mkOption {
type = types.nullOr fontType;
type = types.nullOr hm.types.fontType;
default = null;
description = ''
The font to use in GTK+ 2/3 applications.
@@ -119,6 +96,13 @@ in
};
gtk3 = {
bookmarks = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "file:///home/jane/Documents" ];
description = "Bookmarks in the sidebar of the GTK file browser";
};
extraConfig = mkOption {
type = with types; attrsOf (either bool (either int str));
default = {};
@@ -182,6 +166,10 @@ in
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
xdg.configFile."gtk-3.0/bookmarks" = mkIf (cfg3.bookmarks != []) {
text = concatStringsSep "\n" cfg3.bookmarks;
};
dconf.settings."org/gnome/desktop/interface" = dconfIni;
}
);

View File

@@ -4,7 +4,7 @@
options = {
lib = lib.mkOption {
type = lib.types.attrsOf lib.types.attrs;
default = {};
default = { };
description = ''
This option allows modules to define helper functions,
constants, etc.

View File

@@ -1207,6 +1207,280 @@ in
A new module is available: 'programs.rtorrent'.
'';
}
{
time = "2019-11-04T20:56:29+00:00";
message = ''
A new module is available: 'programs.pazi'.
'';
}
{
time = "2019-11-05T21:54:04+00:00";
condition = config.programs.zsh.enable;
message = ''
The 'programs.zsh.history.path' option behavior and the
default value has changed for state version 20.03 and above.
Specifically, '$HOME' will no longer be prepended to the
option value, which allows specifying absolute paths (e.g.
using the xdg module). Also, the default value is fixed to
'$HOME/.zsh_history' and 'dotDir' path is not prepended to
it anymore.
'';
}
{
time = "2019-11-17T18:47:40+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.lorri'.
'';
}
{
time = "2019-11-24T17:46:57+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.spotifyd'.
'';
}
{
time = "2019-11-29T21:18:48+00:00";
message = ''
A new module is available: 'programs.password-store'.
'';
}
{
time = "2019-11-29T21:18:48+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.password-store-sync'.
'';
}
{
time = "2019-11-29T22:46:49+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.unison'.
'';
}
{
time = "2019-12-01T22:10:23+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'xdg.mime'.
If enabled, which it is by default, this module will create
the XDG mime database and desktop file database caches from
programs installed via Home Manager.
'';
}
{
time = "2019-12-08T19:48:26+00:00";
message = ''
A new module is available: 'programs.readline'.
'';
}
{
time = "2020-01-11T11:49:51+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.cbatticon'.
'';
}
{
time = "2020-01-26T12:42:33+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'xsession.windowManager.bspwm'.
'';
}
{
time = "2020-01-26T12:49:40+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.grobi'.
'';
}
{
time = "2020-01-26T19:37:57+00:00";
message = ''
A new module is available: 'programs.neomutt'.
'';
}
{
time = "2020-02-23T10:19:48+00:00";
message = ''
A new module is available: 'programs.kitty'.
'';
}
{
time = "2020-02-26T21:20:55+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'wayland.windowManager.sway'
'';
}
{
time = "2020-03-04T18:55:03+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'programs.abook'
'';
}
{
time = "2020-03-07T11:43:26+00:00";
condition = config.programs.fish.enable;
message = ''
The option 'programs.fish.functions' has been reworked in
order to support all available flags, such as
'--description', '--on-event', and more.
'';
}
{
time = "2020-03-07T13:11:43+00:00";
condition = hostPlatform.isLinux;
message = ''
The NixOS module has a new option: 'home-manager.useGlobalPkgs'.
This enables using the system configuration's 'pkgs'
argument in Home Manager.
To learn more, see the installation section of the manual
https://rycee.gitlab.io/home-manager/#sec-install-nixos-module
'';
}
{
time = "2020-03-07T14:12:50+00:00";
message = ''
A new module is available: 'programs.lieer'.
'';
}
{
time = "2020-03-07T14:12:50+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.lieer'.
'';
}
{
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/
'';
}
{
time = "2020-03-17T21:56:26+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.keynav'.
'';
}
{
time = "2020-03-24T22:17:20+00:00";
condition = config.services.compton.enable;
message = ''
The 'services.compton' module has been deprecated and
instead the new module 'services.picom' should be used. This
is because Nixpkgs no longer packages compton, and instead
packages the (mostly) compatible fork called picom.
The 'services.compton' and 'services.picom' modules have a
few differences:
- 'services.picom' has a new 'experimentalBackends'
option.
- 'vSync' is now a boolean value on 'services.picom', as
opposed to the string in 'services.compton'.
Migrating to the new picom service is simple - just change
all references to 'services.compton' to 'services.picom',
and adhere to the above changes.
The deprecated 'services.compton' will eventually be removed
in the future. Please update your configurations to use
'services.picom' as soon as possible.
'';
}
{
time = "2020-04-08T09:33:05+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'targets.genericLinux'.
When enabled, this module will configure various settings
and environment variables to make Home Manager and programs
installed through Nix work better on GNU/Linux distributions
other than NixOS.
It should not be enabled if your Home Manager configuration
is deployed on a NixOS host.
'';
}
{
time = "2020-04-08T11:51:15+00:00";
message = ''
A new module is available: 'programs.qutebrowser'
'';
}
{
time = "2020-04-09T09:19:38+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.mako'
'';
}
{
time = "2020-05-12T20:09:54+00:00";
message = ''
A new module is available: 'programs.dircolors'
'';
}
];
};
}

View File

@@ -142,7 +142,7 @@ in
config = {
_module.args = {
pkgs = _pkgs;
pkgs = mkOverride modules.defaultPriority _pkgs;
pkgs_i686 =
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
then _pkgs.pkgsi686Linux

View File

@@ -6,12 +6,8 @@ let
cfg = config.xsession.numlock;
in
{
options = {
xsession.numlock.enable = mkEnableOption "Num Lock";
};
in {
options = { xsession.numlock.enable = mkEnableOption "Num Lock"; };
config = mkIf cfg.enable {
systemd.user.services.numlockx = {
@@ -27,9 +23,7 @@ in
ExecStart = "${pkgs.numlockx}/bin/numlockx";
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Install = { WantedBy = [ "graphical-session.target" ]; };
};
};
}

View File

@@ -6,14 +6,12 @@ let
vars = config.pam.sessionVariables;
in
{
in {
meta.maintainers = [ maintainers.rycee ];
options = {
pam.sessionVariables = mkOption {
default = {};
default = { };
type = types.attrs;
example = { EDITOR = "vim"; };
description = ''
@@ -27,10 +25,8 @@ in
};
};
config = mkIf (vars != {}) {
home.file.".pam_environment".text =
concatStringsSep "\n" (
mapAttrsToList (n: v: "${n} OVERRIDE=\"${toString v}\"") vars
) + "\n";
config = mkIf (vars != { }) {
home.file.".pam_environment".text = concatStringsSep "\n"
(mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') vars) + "\n";
};
}

View File

@@ -5,21 +5,14 @@ with lib;
let
cfg = config.qt;
dag = config.lib.dag;
in
{
in {
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkChangedOptionModule
[ "qt" "useGtkTheme" ]
[ "qt" "platformTheme" ]
(mkChangedOptionModule [ "qt" "useGtkTheme" ] [ "qt" "platformTheme" ]
(config:
if getAttrFromPath [ "qt" "useGtkTheme" ] config
then "gtk"
else null))
if getAttrFromPath [ "qt" "useGtkTheme" ] config then "gtk" else null))
];
options = {
@@ -30,10 +23,8 @@ in
type = types.nullOr (types.enum [ "gtk" "gnome" ]);
default = null;
example = "gnome";
relatedPackages = [
"qgnomeplatform"
["libsForQt5" "qtstyleplugins"]
];
relatedPackages =
[ "qgnomeplatform" [ "libsForQt5" "qtstyleplugins" ] ];
description = ''
Selects the platform theme to use for Qt applications.</para>
<para>The options are
@@ -60,16 +51,16 @@ in
home.sessionVariables.QT_QPA_PLATFORMTHEME =
if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
home.packages =
if cfg.platformTheme == "gnome"
then [ pkgs.qgnomeplatform ]
else [ pkgs.libsForQt5.qtstyleplugins ];
home.packages = if cfg.platformTheme == "gnome" then
[ pkgs.qgnomeplatform ]
else
[ pkgs.libsForQt5.qtstyleplugins ];
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ];
# Enable GTK+ style for Qt4 in either case.
# It doesnt support the platform theme packages.
home.activation.useGtkThemeInQt4 = dag.entryAfter ["writeBoundary"] ''
home.activation.useGtkThemeInQt4 = hm.dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
--set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+
'';

View File

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

View File

@@ -9,9 +9,7 @@ let
strListOrSingleton = with types;
coercedTo (either (listOf str) str) toList (listOf str);
in
{
in {
meta.maintainers = with maintainers; [ pacien ];
options.xdg.mimeApps = {
@@ -76,17 +74,15 @@ in
config = mkIf cfg.enable {
# Deprecated but still used by some applications.
home.file.".local/share/applications/mimeapps.list".source =
xdg.dataFile."applications/mimeapps.list".source =
config.xdg.configFile."mimeapps.list".source;
xdg.configFile."mimeapps.list".text =
let
joinValues = mapAttrs (n: concatStringsSep ";");
in
generators.toINI {} {
"Added Associations" = joinValues cfg.associations.added;
"Removed Associations" = joinValues cfg.associations.removed;
"Default Applications" = joinValues cfg.defaultApplications;
};
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;
};
};
}

47
modules/misc/xdg-mime.nix Normal file
View File

@@ -0,0 +1,47 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.xdg.mime;
in {
options = {
xdg.mime.enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether to install programs and files to support the
XDG Shared MIME-info specification and XDG MIME Applications
specification at
<link xlink:href="https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html"/>
and
<link xlink:href="https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html"/>,
respectively.
'';
};
};
config = mkIf config.xdg.mime.enable {
home.packages = [
# Explicitly install package to provide basic mime types.
pkgs.shared-mime-info
];
home.extraProfileCommands = ''
if [[ -w $out/share/mime && -w $out/share/mime/packages && -d $out/share/mime/packages ]]; then
XDG_DATA_DIRS=$out/share \
PKGSYSTEM_ENABLE_FSYNC=0 \
${pkgs.buildPackages.shared-mime-info}/bin/update-mime-database \
-V $out/share/mime > /dev/null
fi
if [[ -w $out/share/applications ]]; then
${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database \
$out/share/applications
fi
'';
};
}

View File

@@ -6,11 +6,17 @@ let
cfg = config.xdg.userDirs;
in
{
in {
meta.maintainers = with maintainers; [ pacien ];
imports = [
(mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [
"xdg"
"userDirs"
"publicShare"
])
];
options.xdg.userDirs = {
enable = mkOption {
type = types.bool;
@@ -56,7 +62,7 @@ in
description = "The Pictures directory.";
};
publishShare = mkOption {
publicShare = mkOption {
type = types.str;
default = "$HOME/Public";
description = "The Public share directory.";
@@ -83,18 +89,22 @@ in
};
config = mkIf cfg.enable {
xdg.configFile."user-dirs.dirs".text = generators.toKeyValue {} (
{
xdg.configFile."user-dirs.dirs".text = let
options = {
XDG_DESKTOP_DIR = cfg.desktop;
XDG_DOCUMENTS_DIR = cfg.documents;
XDG_DOWNLOAD_DIR = cfg.download;
XDG_MUSIC_DIR = cfg.music;
XDG_PICTURES_DIR = cfg.pictures;
XDG_PUBLICSHARE_DIR = cfg.publishShare;
XDG_PUBLICSHARE_DIR = cfg.publicShare;
XDG_TEMPLATES_DIR = cfg.templates;
XDG_VIDEOS_DIR = cfg.videos;
}
// cfg.extraConfig
);
} // cfg.extraConfig;
# For some reason, these need to be wrapped with quotes to be valid.
wrapped = mapAttrs (_: value: ''"${value}"'') options;
in generators.toKeyValue { } wrapped;
xdg.configFile."user-dirs.conf".text = "enabled=False";
};
}

View File

@@ -1,8 +1,13 @@
{ pkgs
# Note, this should be "the standard library" + HM extensions.
, lib
# Whether to enable module type checking.
, check ? true
# If disabled, the pkgs attribute passed to this function is used instead.
, useNixpkgsModule ? true
}:
with lib;
@@ -11,8 +16,6 @@ let
hostPlatform = pkgs.stdenv.hostPlatform;
checkPlatform = any (meta.platformMatch pkgs.stdenv.hostPlatform);
loadModule = file: { condition ? true }: {
inherit file condition;
};
@@ -23,19 +26,22 @@ let
(loadModule ./home-environment.nix { })
(loadModule ./manual.nix { })
(loadModule ./misc/dconf.nix { })
(loadModule ./misc/debug.nix { })
(loadModule ./misc/fontconfig.nix { })
(loadModule ./misc/gtk.nix { })
(loadModule ./misc/lib.nix { })
(loadModule ./misc/news.nix { })
(loadModule ./misc/nixpkgs.nix { })
(loadModule ./misc/nixpkgs.nix { condition = useNixpkgsModule; })
(loadModule ./misc/numlock.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/pam.nix { })
(loadModule ./misc/qt.nix { })
(loadModule ./misc/submodule-support.nix { })
(loadModule ./misc/version.nix { })
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
(loadModule ./misc/xdg.nix { })
(loadModule ./programs/abook.nix { condition = hostPlatform.isLinux; })
(loadModule ./programs/afew.nix { })
(loadModule ./programs/alacritty.nix { })
(loadModule ./programs/alot.nix { })
@@ -48,6 +54,7 @@ let
(loadModule ./programs/browserpass.nix { })
(loadModule ./programs/chromium.nix { condition = hostPlatform.isLinux; })
(loadModule ./programs/command-not-found/command-not-found.nix { })
(loadModule ./programs/dircolors.nix { })
(loadModule ./programs/direnv.nix { })
(loadModule ./programs/eclipse.nix { })
(loadModule ./programs/emacs.nix { })
@@ -64,9 +71,11 @@ let
(loadModule ./programs/htop.nix { })
(loadModule ./programs/info.nix { })
(loadModule ./programs/irssi.nix { })
(loadModule ./programs/lieer.nix { })
(loadModule ./programs/jq.nix { })
(loadModule ./programs/kakoune.nix { })
(loadModule ./programs/keychain.nix { })
(loadModule ./programs/kitty.nix { })
(loadModule ./programs/lesspipe.nix { })
(loadModule ./programs/lsd.nix { })
(loadModule ./programs/man.nix { })
@@ -75,6 +84,7 @@ let
(loadModule ./programs/mercurial.nix { })
(loadModule ./programs/mpv.nix { })
(loadModule ./programs/msmtp.nix { })
(loadModule ./programs/neomutt.nix { })
(loadModule ./programs/neovim.nix { })
(loadModule ./programs/newsboat.nix { })
(loadModule ./programs/noti.nix { })
@@ -82,7 +92,11 @@ let
(loadModule ./programs/obs-studio.nix { })
(loadModule ./programs/offlineimap.nix { })
(loadModule ./programs/opam.nix { })
(loadModule ./programs/password-store.nix { })
(loadModule ./programs/pazi.nix { })
(loadModule ./programs/pidgin.nix { })
(loadModule ./programs/qutebrowser.nix { })
(loadModule ./programs/readline.nix { })
(loadModule ./programs/rofi.nix { })
(loadModule ./programs/rtorrent.nix { })
(loadModule ./programs/skim.nix { })
@@ -100,6 +114,7 @@ let
(loadModule ./programs/zathura.nix { })
(loadModule ./programs/zsh.nix { })
(loadModule ./services/blueman-applet.nix { })
(loadModule ./services/cbatticon.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/compton.nix { })
(loadModule ./services/dunst.nix { })
(loadModule ./services/dwm-status.nix { condition = hostPlatform.isLinux; })
@@ -108,12 +123,17 @@ let
(loadModule ./services/getmail.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/gnome-keyring.nix { })
(loadModule ./services/gpg-agent.nix { })
(loadModule ./services/grobi.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/hound.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/kbfs.nix { })
(loadModule ./services/kdeconnect.nix { })
(loadModule ./services/keepassx.nix { })
(loadModule ./services/keybase.nix { })
(loadModule ./services/keynav.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/lieer.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/lorri.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/mako.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/mbsync.nix { })
(loadModule ./services/mpd.nix { })
(loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; })
@@ -122,7 +142,9 @@ let
(loadModule ./services/nextcloud-client.nix { })
(loadModule ./services/owncloud-client.nix { })
(loadModule ./services/parcellite.nix { })
(loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/pasystray.nix { })
(loadModule ./services/picom.nix { })
(loadModule ./services/polybar.nix { })
(loadModule ./services/random-background.nix { })
(loadModule ./services/redshift.nix { })
@@ -130,6 +152,7 @@ let
(loadModule ./services/screen-locker.nix { })
(loadModule ./services/stalonetray.nix { })
(loadModule ./services/status-notifier-watcher.nix { })
(loadModule ./services/spotifyd.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/sxhkd.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/syncthing.nix { })
(loadModule ./services/taffybar.nix { })
@@ -137,29 +160,36 @@ let
(loadModule ./services/taskwarrior-sync.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/udiskie.nix { })
(loadModule ./services/unclutter.nix { })
(loadModule ./services/unison.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/window-managers/awesome.nix { })
(loadModule ./services/window-managers/i3.nix { })
(loadModule ./services/window-managers/bspwm/default.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/window-managers/i3-sway/i3.nix { })
(loadModule ./services/window-managers/i3-sway/sway.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/window-managers/xmonad.nix { })
(loadModule ./services/xcape.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/xembed-sni-proxy.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/xscreensaver.nix { })
(loadModule ./services/xsuspender.nix { condition = hostPlatform.isLinux; })
(loadModule ./systemd.nix { })
(loadModule ./targets/generic-linux.nix { condition = hostPlatform.isLinux; })
(loadModule ./xcursor.nix { })
(loadModule ./xresources.nix { })
(loadModule ./xsession.nix { })
(loadModule <nixpkgs/nixos/modules/misc/assertions.nix> { })
(loadModule <nixpkgs/nixos/modules/misc/meta.nix> { })
(loadModule (pkgs.path + "/nixos/modules/misc/assertions.nix") { })
(loadModule (pkgs.path + "/nixos/modules/misc/meta.nix") { })
];
modules = map (getAttr "file") (filter (getAttr "condition") allModules);
pkgsModule = {
config._module.args.baseModules = modules;
config._module.args.pkgs = lib.mkDefault pkgs;
config._module.check = check;
config.lib = import ./lib { inherit lib; };
config.nixpkgs.system = mkDefault pkgs.system;
config = {
_module.args.baseModules = modules;
_module.args.pkgs = lib.mkDefault pkgs;
_module.check = check;
lib = lib.hm;
} // optionalAttrs useNixpkgsModule {
nixpkgs.system = mkDefault pkgs.system;
};
};
in

View File

@@ -0,0 +1,40 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.abook;
in {
options.programs.abook = {
enable = mkEnableOption "Abook";
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
field pager = Pager
view CONTACT = name, email
set autosave=true
'';
description = ''
Extra lines added to <filename>$HOME/.config/abook/abookrc</filename>.
Available configuration options are described in the abook repository:
<link xlink:href="https://sourceforge.net/p/abook/git/ci/master/tree/sample.abookrc" />.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.abook ];
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
text = ''
# Generated by Home Manager.
# See http://abook.sourceforge.net/
${cfg.extraConfig}
'';
};
};
}

View File

@@ -6,16 +6,14 @@ let
cfg = config.programs.alacritty;
in
{
in {
options = {
programs.alacritty = {
enable = mkEnableOption "Alacritty";
settings = mkOption {
type = types.attrs;
default = {};
default = { };
example = literalExample ''
{
window.dimensions = {
@@ -45,8 +43,9 @@ in
(mkIf cfg.enable {
home.packages = [ pkgs.alacritty ];
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != {}) {
text = replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings);
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) {
text =
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings);
};
})
];

View File

@@ -18,12 +18,10 @@ with lib;
type = types.attrsOf types.str;
default = {
type = "shellcommand";
command = "'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
regexp =
"'\\[?{"
+ ''"name": "(?P<name>.*)", ''
+ ''"address": "(?P<email>.+)", ''
+ ''"name-addr": ".*"''
command =
"'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
regexp = "'\\[?{" + ''
"name": "(?P<name>.*)", "address": "(?P<email>.+)", "name-addr": ".*"''
+ "}[,\\]]?'";
shellcommand_external_filtering = "False";
};
@@ -36,9 +34,9 @@ with lib;
}
'';
description = ''
Contact completion configuration as expected per alot.
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
explanation about possible values.
Contact completion configuration as expected per alot.
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
explanation about possible values.
'';
};
@@ -52,10 +50,9 @@ with lib;
};
config = mkIf config.notmuch.enable {
alot.sendMailCommand = mkOptionDefault (
if config.msmtp.enable
then "msmtpq --read-envelope-from --read-recipients"
else null
);
alot.sendMailCommand = mkOptionDefault (if config.msmtp.enable then
"msmtpq --read-envelope-from --read-recipients"
else
null);
};
}

View File

@@ -17,7 +17,7 @@ with lib;
extraConfig = mkOption {
type = types.attrs;
default = {};
default = { };
example = { select_query = ""; };
description = ''
Extra settings to add to this astroid account configuration.
@@ -26,8 +26,7 @@ with lib;
};
config = mkIf config.notmuch.enable {
astroid.sendMailCommand = mkIf config.msmtp.enable (
mkOptionDefault "msmtpq --read-envelope-from --read-recipients"
);
astroid.sendMailCommand = mkIf config.msmtp.enable
(mkOptionDefault "msmtpq --read-envelope-from --read-recipients");
};
}

View File

@@ -8,35 +8,32 @@ let
cfg = config.programs.astroid;
astroidAccounts =
filterAttrs
(n: v: v.astroid.enable)
config.accounts.email.accounts;
filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts;
boolOpt = b: if b then "true" else "false";
accountAttr = account: with account; {
email = address;
name = realName;
sendmail = astroid.sendMailCommand;
additional_sent_tags = "";
default = boolOpt primary;
save_drafts_to = folders.drafts;
save_sent = "true";
save_sent_to = folders.sent;
select_query = "";
}
// optionalAttrs (signature.showSignature != "none") {
signature_attach = boolOpt (signature.showSignature == "attach");
signature_default_on = boolOpt (signature.showSignature != "none");
signature_file = pkgs.writeText "signature.txt" signature.text;
signature_file_markdown = "false";
signature_separate = "true"; # prepends '--\n' to the signature
}
// optionalAttrs (gpg != null) {
always_gpg_sign = boolOpt gpg.signByDefault;
gpgkey = gpg.key;
}
// astroid.extraConfig;
accountAttr = account:
with account;
{
email = address;
name = realName;
sendmail = astroid.sendMailCommand;
additional_sent_tags = "";
default = boolOpt primary;
save_drafts_to = "${maildir.absPath}/${folders.drafts}";
save_sent = "true";
save_sent_to = "${maildir.absPath}/${folders.sent}";
select_query = "";
} // optionalAttrs (signature.showSignature != "none") {
signature_attach = boolOpt (signature.showSignature == "attach");
signature_default_on = boolOpt (signature.showSignature != "none");
signature_file = pkgs.writeText "signature.txt" signature.text;
signature_file_markdown = "false";
signature_separate = "true"; # prepends '--\n' to the signature
} // optionalAttrs (gpg != null) {
always_gpg_sign = boolOpt gpg.signByDefault;
gpgkey = gpg.key;
} // astroid.extraConfig;
# See https://github.com/astroidmail/astroid/wiki/Configuration-Reference
configFile = mailAccounts:
@@ -51,12 +48,9 @@ let
cfg.extraConfig
cfg.externalEditor
];
in
builtins.toJSON astroidConfig;
in builtins.toJSON astroidConfig;
in
{
in {
options = {
programs.astroid = {
enable = mkEnableOption "Astroid";
@@ -81,7 +75,8 @@ in
"cmd" = cmd;
};
};
example = "nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
example =
"nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
description = ''
You can use <code>%1</code>, <code>%2</code>, and
<code>%3</code> to refer respectively to:
@@ -96,7 +91,7 @@ in
extraConfig = mkOption {
type = types.attrs;
default = {};
default = { };
example = { poll.interval = 0; };
description = ''
JSON config that will override the default Astroid configuration.
@@ -106,26 +101,15 @@ 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 ];
home.packages = [ pkgs.astroid ];
xdg.configFile."astroid/config".source =
pkgs.runCommand "out.json"
{
json = configFile astroidAccounts;
preferLocalBuild = true;
allowSubstitutes = false;
}
''
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
'';
xdg.configFile."astroid/config".source = pkgs.runCommand "out.json" {
json = configFile astroidAccounts;
preferLocalBuild = true;
allowSubstitutes = false;
} ''
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
'';
xdg.configFile."astroid/poll.sh" = {
executable = true;

View File

@@ -6,20 +6,21 @@ let
cfg = config.programs.autorandr;
matrixOf = n: m: elemType: mkOptionType rec {
name = "matrixOf";
description = "${toString n}×${toString m} matrix of ${elemType.description}s";
check = xss:
let
listOfSize = l: xs: isList xs && length xs == l;
in
listOfSize n xss && all (xs: listOfSize m xs && all elemType.check xs) xss;
merge = mergeOneOption;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*" "*"]);
getSubModules = elemType.getSubModules;
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
functor = (defaultFunctor name) // { wrapped = elemType; };
};
matrixOf = n: m: elemType:
mkOptionType rec {
name = "matrixOf";
description =
"${toString n}×${toString m} matrix of ${elemType.description}s";
check = xss:
let listOfSize = l: xs: isList xs && length xs == l;
in listOfSize n xss
&& all (xs: listOfSize m xs && all elemType.check xs) xss;
merge = mergeOneOption;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "*" "*" ]);
getSubModules = elemType.getSubModules;
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
functor = (defaultFunctor name) // { wrapped = elemType; };
};
profileModule = types.submodule {
options = {
@@ -29,19 +30,19 @@ let
Output name to EDID mapping.
Use <code>autorandr --fingerprint</code> to get current setup values.
'';
default = {};
default = { };
};
config = mkOption {
type = types.attrsOf configModule;
description = "Per output profile configuration.";
default = {};
default = { };
};
hooks = mkOption {
type = profileHooksModule;
description = "Profile hook scripts.";
default = {};
default = { };
};
};
};
@@ -89,7 +90,7 @@ let
};
rotate = mkOption {
type = types.nullOr (types.enum ["normal" "left" "right" "inverted"]);
type = types.nullOr (types.enum [ "normal" "left" "right" "inverted" ]);
description = "Output rotate configuration.";
default = null;
example = "left";
@@ -126,7 +127,7 @@ let
type = types.nullOr (types.submodule {
options = {
method = mkOption {
type = types.enum ["factor" "pixel" ];
type = types.enum [ "factor" "pixel" ];
description = "Output scaling method.";
default = "factor";
example = "pixel";
@@ -178,19 +179,21 @@ let
postswitch = mkOption {
type = types.attrsOf hookType;
description = "Postswitch hook executed after mode switch.";
default = {};
default = { };
};
preswitch = mkOption {
type = types.attrsOf hookType;
description = "Preswitch hook executed before mode switch.";
default = {};
default = { };
};
predetect = mkOption {
type = types.attrsOf hookType;
description = "Predetect hook executed before autorandr attempts to run xrandr.";
default = {};
description = ''
Predetect hook executed before autorandr attempts to run xrandr.
'';
default = { };
};
};
};
@@ -211,50 +214,56 @@ let
predetect = mkOption {
type = hookType;
description = "Predetect hook executed before autorandr attempts to run xrandr.";
description = ''
Predetect hook executed before autorandr attempts to run xrandr.
'';
default = "";
};
};
};
hookToFile = folder: name: hook:
nameValuePair
"autorandr/${folder}/${name}"
{ source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook"; };
profileToFiles = name: profile: with profile; mkMerge ([
{
"autorandr/${name}/setup".text = concatStringsSep "\n" (mapAttrsToList fingerprintToString fingerprint);
"autorandr/${name}/config".text = concatStringsSep "\n" (mapAttrsToList configToString profile.config);
}
(mkIf (hooks.postswitch != "") (listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
(mkIf (hooks.preswitch != "") (listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
(mkIf (hooks.predetect != "") (listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
]);
nameValuePair "autorandr/${folder}/${name}" {
source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook";
};
profileToFiles = name: profile:
with profile;
mkMerge ([
{
"autorandr/${name}/setup".text = concatStringsSep "\n"
(mapAttrsToList fingerprintToString fingerprint);
"autorandr/${name}/config".text =
concatStringsSep "\n" (mapAttrsToList configToString profile.config);
}
(mkIf (hooks.postswitch != "")
(listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
(mkIf (hooks.preswitch != "")
(listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
(mkIf (hooks.predetect != "")
(listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
]);
fingerprintToString = name: edid: "${name} ${edid}";
configToString = name: config: if config.enable then ''
output ${name}
${optionalString (config.position != "") "pos ${config.position}"}
${optionalString config.primary "primary"}
${optionalString (config.dpi != null) "dpi ${toString config.dpi}"}
${optionalString (config.gamma != "") "gamma ${config.gamma}"}
${optionalString (config.mode != "") "mode ${config.mode}"}
${optionalString (config.rate != "") "rate ${config.rate}"}
${optionalString (config.rotate != null) "rotate ${config.rotate}"}
${optionalString (config.scale != null) (
(if config.scale.method == "factor" then "scale" else "scale-from")
+ " ${toString config.scale.x}x${toString config.scale.y}"
)}
${optionalString (config.transform != null) (
"transform " + concatMapStringsSep "," toString (flatten config.transform)
)}
'' else ''
output ${name}
off
'';
configToString = name: config:
if config.enable then ''
output ${name}
${optionalString (config.position != "") "pos ${config.position}"}
${optionalString config.primary "primary"}
${optionalString (config.dpi != null) "dpi ${toString config.dpi}"}
${optionalString (config.gamma != "") "gamma ${config.gamma}"}
${optionalString (config.mode != "") "mode ${config.mode}"}
${optionalString (config.rate != "") "rate ${config.rate}"}
${optionalString (config.rotate != null) "rotate ${config.rotate}"}
${optionalString (config.scale != null)
((if config.scale.method == "factor" then "scale" else "scale-from")
+ " ${toString config.scale.x}x${toString config.scale.y}")}
${optionalString (config.transform != null) ("transform "
+ concatMapStringsSep "," toString (flatten config.transform))}
'' else ''
output ${name}
off
'';
in
{
in {
options = {
programs.autorandr = {
enable = mkEnableOption "Autorandr";
@@ -262,39 +271,39 @@ in
hooks = mkOption {
type = globalHooksModule;
description = "Global hook scripts";
default = {};
default = { };
example = literalExample ''
{
postswitch = {
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
"change-background" = readFile ./change-background.sh;
"change-dpi" = '''
case "$AUTORANDR_CURRENT_PROFILE" in
default)
DPI=120
;;
home)
DPI=192
;;
work)
DPI=144
;;
*)
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
exit 1
esac
{
postswitch = {
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
"change-background" = readFile ./change-background.sh;
"change-dpi" = '''
case "$AUTORANDR_CURRENT_PROFILE" in
default)
DPI=120
;;
home)
DPI=192
;;
work)
DPI=144
;;
*)
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
exit 1
esac
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
'''
};
}
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
'''
};
}
'';
};
profiles = mkOption {
type = types.attrsOf profileModule;
description = "Autorandr profiles specification.";
default = {};
default = { };
example = literalExample ''
{
"work" = {
@@ -323,24 +332,21 @@ in
};
config = mkIf cfg.enable {
assertions = flatten (mapAttrsToList (
profile: { config, ... }: mapAttrsToList (
output: opts: {
assertion = opts.scale == null || opts.transform == null;
message = ''
Cannot use the profile output options 'scale' and 'transform' simultaneously.
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
'';
})
config
)
cfg.profiles);
assertions = flatten (mapAttrsToList (profile:
{ config, ... }:
mapAttrsToList (output: opts: {
assertion = opts.scale == null || opts.transform == null;
message = ''
Cannot use the profile output options 'scale' and 'transform' simultaneously.
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
'';
}) config) cfg.profiles);
home.packages = [ pkgs.autorandr ];
xdg.configFile = mkMerge ([
(mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
(mkMerge (mapAttrsToList profileToFiles cfg.profiles))
]);
};

View File

@@ -82,7 +82,12 @@ in
shellAliases = mkOption {
default = {};
type = types.attrsOf types.str;
example = { ll = "ls -l"; ".." = "cd .."; };
example = literalExample ''
{
ll = "ls -l";
".." = "cd ..";
}
'';
description = ''
An attribute set that maps aliases (the top level attribute names in
this option) to command strings or directly to build outputs.

View File

@@ -6,9 +6,7 @@ let
cfg = config.programs.bat;
in
{
in {
meta.maintainers = [ maintainers.marsam ];
options.programs.bat = {
@@ -16,7 +14,7 @@ in
config = mkOption {
type = types.attrsOf types.str;
default = {};
default = { };
example = {
theme = "TwoDark";
pager = "less -FR";
@@ -26,15 +24,35 @@ in
'';
};
themes = mkOption {
type = types.attrsOf types.lines;
default = { };
example = literalExample ''
{
dracula = builtins.readFile (pkgs.fetchFromGitHub {
owner = "dracula";
repo = "sublime"; # Bat uses sublime syntax for its themes
rev = "26c57ec282abcaa76e57e055f38432bd827ac34e";
sha256 = "019hfl4zbn4vm4154hh3bwk6hm7bdxbr1hdww83nabxwjn99ndhv";
} + "/Dracula.tmTheme");
}
'';
description = ''
Additional themes to provide.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.bat ];
xdg.configFile."bat/config" = mkIf (cfg.config != {}) {
text = concatStringsSep "\n" (
mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config
);
};
xdg.configFile = mkMerge ([{
"bat/config" = mkIf (cfg.config != { }) {
text = concatStringsSep "\n"
(mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config);
};
}] ++ flip mapAttrsToList cfg.themes
(name: body: { "bat/themes/${name}.tmTheme" = { text = body; }; }));
};
}

View File

@@ -6,19 +6,17 @@ let
cfg = config.programs.beets;
in
{
in {
meta.maintainers = [ maintainers.rycee ];
options = {
programs.beets = {
enable = mkOption {
type = types.bool;
default =
if versionAtLeast config.home.stateVersion "19.03"
then false
else cfg.settings != {};
default = if versionAtLeast config.home.stateVersion "19.03" then
false
else
cfg.settings != { };
defaultText = "false";
description = ''
Whether to enable the beets music library manager. This
@@ -28,9 +26,21 @@ in
'';
};
package = mkOption {
type = types.package;
default = pkgs.beets;
defaultText = literalExample "pkgs.beets";
example =
literalExample "(pkgs.beets.override { enableCheck = true; })";
description = ''
The <literal>beets</literal> package to use.
Can be used to specify extensions.
'';
};
settings = mkOption {
type = types.attrs;
default = {};
default = { };
description = ''
Configuration written to
<filename>~/.config/beets/config.yaml</filename>
@@ -40,9 +50,9 @@ in
};
config = mkIf cfg.enable {
home.packages = [ pkgs.beets ];
home.packages = [ cfg.package ];
xdg.configFile."beets/config.yaml".text =
builtins.toJSON config.programs.beets.settings;
builtins.toJSON config.programs.beets.settings;
};
}

View File

@@ -7,29 +7,23 @@ 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
'';
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;
mapAttrsToList (name: value: value // { invocation = name; }) cfg.verbs;
skin = cfg.skin;
};
in
{
in {
meta.maintainers = [ maintainers.aheaume ];
options.programs.broot = {
@@ -63,7 +57,10 @@ in
type = with types; attrsOf (attrsOf (either bool str));
default = {
"p" = { execution = ":parent"; };
"edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; };
"edit" = {
shortcut = "e";
execution = "$EDITOR {file}";
};
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
"view" = { execution = "less {file}"; };
};
@@ -114,7 +111,7 @@ in
skin = mkOption {
type = types.attrsOf types.str;
default = {};
default = { };
example = literalExample ''
{
status_normal_fg = "grayscale(18)";
@@ -177,38 +174,36 @@ in
# 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.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

View File

@@ -2,13 +2,7 @@
with lib;
let
browsers = [
"chrome"
"chromium"
"firefox"
"vivaldi"
];
let browsers = [ "chrome" "chromium" "firefox" "vivaldi" ];
in {
options = {
programs.browserpass = {
@@ -24,57 +18,59 @@ in {
};
config = mkIf config.programs.browserpass.enable {
home.file = builtins.concatLists (with pkgs.stdenv; map (x:
home.file = foldl' (a: b: a // b) { } (concatMap (x:
with pkgs.stdenv;
if x == "chrome" then
let dir = if isDarwin
then "Library/Application Support/Google/Chrome/NativeMessagingHosts"
else ".config/google-chrome/NativeMessagingHosts";
in [
{
target = "${dir}/com.github.browserpass.native.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}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}
]
let
dir = if isDarwin then
"Library/Application Support/Google/Chrome/NativeMessagingHosts"
else
".config/google-chrome/NativeMessagingHosts";
in [{
"${dir}/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}]
else if x == "chromium" then
let dir = if isDarwin
then "Library/Application Support/Chromium/NativeMessagingHosts"
else ".config/chromium/NativeMessagingHosts";
let
dir = if isDarwin then
"Library/Application Support/Chromium/NativeMessagingHosts"
else
".config/chromium/NativeMessagingHosts";
in [
{
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
"${dir}/com.github.browserpass.native.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}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}
]
else if x == "firefox" then
[ {
target = (if isDarwin
then "Library/Application Support/Mozilla/NativeMessagingHosts"
else ".mozilla/native-messaging-hosts")
+ "/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
} ]
let
dir = if isDarwin then
"Library/Application Support/Mozilla/NativeMessagingHosts"
else
".mozilla/native-messaging-hosts";
in [{
"${dir}/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
}]
else if x == "vivaldi" then
let dir = if isDarwin
then "Library/Application Support/Vivaldi/NativeMessagingHosts"
else ".config/vivaldi/NativeMessagingHosts";
in [
{
target = "${dir}/com.github.browserpass.native.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}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}
]
else throw "unknown browser ${x}") config.programs.browserpass.browsers);
let
dir = if isDarwin then
"Library/Application Support/Vivaldi/NativeMessagingHosts"
else
".config/vivaldi/NativeMessagingHosts";
in [{
"${dir}/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
}]
else
throw "unknown browser ${x}") config.programs.browserpass.browsers);
};
}

View File

@@ -5,46 +5,44 @@ with lib;
let
browserModule = defaultPkg: name: visible:
let
browser = (builtins.parseDrvName defaultPkg.name).name;
in
{
enable = mkOption {
inherit visible;
default = false;
example = true;
description = "Whether to enable ${name}.";
type = lib.types.bool;
};
package = mkOption {
inherit visible;
type = types.package;
default = defaultPkg;
defaultText = literalExample "pkgs.${browser}";
description = "The ${name} package to use.";
};
extensions = mkOption {
inherit visible;
type = types.listOf types.str;
default = [];
example = literalExample ''
[
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
]
'';
description = ''
List of ${name} extensions to install.
To find the extension ID, check its URL on the
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
'';
};
let browser = (builtins.parseDrvName defaultPkg.name).name;
in {
enable = mkOption {
inherit visible;
default = false;
example = true;
description = "Whether to enable ${name}.";
type = lib.types.bool;
};
package = mkOption {
inherit visible;
type = types.package;
default = defaultPkg;
defaultText = literalExample "pkgs.${browser}";
description = "The ${name} package to use.";
};
extensions = mkOption {
inherit visible;
type = types.listOf types.str;
default = [ ];
example = literalExample ''
[
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
]
'';
description = ''
List of ${name} extensions to install.
To find the extension ID, check its URL on the
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
'';
};
};
browserConfig = cfg:
let
@@ -57,31 +55,32 @@ let
google-chrome-dev = "Google/Chrome Dev";
};
configDir = if pkgs.stdenv.isDarwin
then "Library/Application Support/${getAttr browser darwinDirs}"
else "${config.xdg.configHome}/${browser}";
configDir = if pkgs.stdenv.isDarwin then
"Library/Application Support/${getAttr browser darwinDirs}"
else
"${config.xdg.configHome}/${browser}";
extensionJson = ext: {
target = "${configDir}/External Extensions/${ext}.json";
text = builtins.toJSON {
external_update_url = "https://clients2.google.com/service/update2/crx";
name = "${configDir}/External Extensions/${ext}.json";
value.text = builtins.toJSON {
external_update_url =
"https://clients2.google.com/service/update2/crx";
};
};
in
mkIf cfg.enable {
home.packages = [ cfg.package ];
home.file = map extensionJson cfg.extensions;
};
in mkIf cfg.enable {
home.packages = [ cfg.package ];
home.file = listToAttrs (map extensionJson cfg.extensions);
};
in
{
in {
options.programs = {
chromium = browserModule pkgs.chromium "Chromium" true;
google-chrome = browserModule pkgs.google-chrome "Google Chrome" false;
google-chrome-beta = browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
google-chrome-dev = browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
google-chrome-beta =
browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
google-chrome-dev =
browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
};
config = mkMerge [

View File

@@ -13,8 +13,11 @@ let
isExecutable = true;
inherit (pkgs) perl;
inherit (cfg) dbPath;
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [
pkgs.perlPackages.DBI
pkgs.perlPackages.DBDSQLite
pkgs.perlPackages.StringShellQuote
]);
};
shInit = commandNotFoundHandlerName: ''
@@ -31,14 +34,13 @@ let
}
'';
in
{
in {
options.programs.command-not-found = {
enable = mkEnableOption "command-not-found hook for interactive shell";
dbPath = mkOption {
default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ;
default =
"/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite";
description = ''
Absolute path to <filename>programs.sqlite</filename>. By
default this file will be provided by your channel

View File

@@ -0,0 +1,223 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.dircolors;
formatLine = n: v: "${n} ${toString v}";
in {
meta.maintainers = [ hm.maintainers.justinlovinger ];
options.programs.dircolors = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to manage <filename>.dir_colors</filename>
and set <code>LS_COLORS</code>.
'';
};
enableBashIntegration = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable Bash integration.
'';
};
enableFishIntegration = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable Fish integration.
'';
};
enableZshIntegration = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable Zsh integration.
'';
};
settings = mkOption {
type = with types; attrsOf str;
default = { };
description = ''
Options to add to <filename>.dir_colors</filename> file.
See <command>dircolors --print-database</command>
for options.
'';
example = literalExample ''
{
OTHER_WRITABLE = "30;46";
".sh" = "01;32";
".csh" = "01;32";
}
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra lines added to <filename>.dir_colors</filename> file.
'';
};
};
config = mkIf cfg.enable {
# Add default settings from `dircolors --print-database`.
programs.dircolors.settings = {
RESET = mkDefault "0";
DIR = mkDefault "01;34";
LINK = mkDefault "01;36";
MULTIHARDLINK = mkDefault "00";
FIFO = mkDefault "40;33";
SOCK = mkDefault "01;35";
DOOR = mkDefault "01;35";
BLK = mkDefault "40;33;01";
CHR = mkDefault "40;33;01";
ORPHAN = mkDefault "40;31;01";
MISSING = mkDefault "00";
SETUID = mkDefault "37;41";
SETGID = mkDefault "30;43";
CAPABILITY = mkDefault "30;41";
STICKY_OTHER_WRITABLE = mkDefault "30;42";
OTHER_WRITABLE = mkDefault "34;42";
STICKY = mkDefault "37;44";
EXEC = mkDefault "01;32";
".tar" = mkDefault "01;31";
".tgz" = mkDefault "01;31";
".arc" = mkDefault "01;31";
".arj" = mkDefault "01;31";
".taz" = mkDefault "01;31";
".lha" = mkDefault "01;31";
".lz4" = mkDefault "01;31";
".lzh" = mkDefault "01;31";
".lzma" = mkDefault "01;31";
".tlz" = mkDefault "01;31";
".txz" = mkDefault "01;31";
".tzo" = mkDefault "01;31";
".t7z" = mkDefault "01;31";
".zip" = mkDefault "01;31";
".z" = mkDefault "01;31";
".dz" = mkDefault "01;31";
".gz" = mkDefault "01;31";
".lrz" = mkDefault "01;31";
".lz" = mkDefault "01;31";
".lzo" = mkDefault "01;31";
".xz" = mkDefault "01;31";
".zst" = mkDefault "01;31";
".tzst" = mkDefault "01;31";
".bz2" = mkDefault "01;31";
".bz" = mkDefault "01;31";
".tbz" = mkDefault "01;31";
".tbz2" = mkDefault "01;31";
".tz" = mkDefault "01;31";
".deb" = mkDefault "01;31";
".rpm" = mkDefault "01;31";
".jar" = mkDefault "01;31";
".war" = mkDefault "01;31";
".ear" = mkDefault "01;31";
".sar" = mkDefault "01;31";
".rar" = mkDefault "01;31";
".alz" = mkDefault "01;31";
".ace" = mkDefault "01;31";
".zoo" = mkDefault "01;31";
".cpio" = mkDefault "01;31";
".7z" = mkDefault "01;31";
".rz" = mkDefault "01;31";
".cab" = mkDefault "01;31";
".wim" = mkDefault "01;31";
".swm" = mkDefault "01;31";
".dwm" = mkDefault "01;31";
".esd" = mkDefault "01;31";
".jpg" = mkDefault "01;35";
".jpeg" = mkDefault "01;35";
".mjpg" = mkDefault "01;35";
".mjpeg" = mkDefault "01;35";
".gif" = mkDefault "01;35";
".bmp" = mkDefault "01;35";
".pbm" = mkDefault "01;35";
".pgm" = mkDefault "01;35";
".ppm" = mkDefault "01;35";
".tga" = mkDefault "01;35";
".xbm" = mkDefault "01;35";
".xpm" = mkDefault "01;35";
".tif" = mkDefault "01;35";
".tiff" = mkDefault "01;35";
".png" = mkDefault "01;35";
".svg" = mkDefault "01;35";
".svgz" = mkDefault "01;35";
".mng" = mkDefault "01;35";
".pcx" = mkDefault "01;35";
".mov" = mkDefault "01;35";
".mpg" = mkDefault "01;35";
".mpeg" = mkDefault "01;35";
".m2v" = mkDefault "01;35";
".mkv" = mkDefault "01;35";
".webm" = mkDefault "01;35";
".ogm" = mkDefault "01;35";
".mp4" = mkDefault "01;35";
".m4v" = mkDefault "01;35";
".mp4v" = mkDefault "01;35";
".vob" = mkDefault "01;35";
".qt" = mkDefault "01;35";
".nuv" = mkDefault "01;35";
".wmv" = mkDefault "01;35";
".asf" = mkDefault "01;35";
".rm" = mkDefault "01;35";
".rmvb" = mkDefault "01;35";
".flc" = mkDefault "01;35";
".avi" = mkDefault "01;35";
".fli" = mkDefault "01;35";
".flv" = mkDefault "01;35";
".gl" = mkDefault "01;35";
".dl" = mkDefault "01;35";
".xcf" = mkDefault "01;35";
".xwd" = mkDefault "01;35";
".yuv" = mkDefault "01;35";
".cgm" = mkDefault "01;35";
".emf" = mkDefault "01;35";
".ogv" = mkDefault "01;35";
".ogx" = mkDefault "01;35";
".aac" = mkDefault "00;36";
".au" = mkDefault "00;36";
".flac" = mkDefault "00;36";
".m4a" = mkDefault "00;36";
".mid" = mkDefault "00;36";
".midi" = mkDefault "00;36";
".mka" = mkDefault "00;36";
".mp3" = mkDefault "00;36";
".mpc" = mkDefault "00;36";
".ogg" = mkDefault "00;36";
".ra" = mkDefault "00;36";
".wav" = mkDefault "00;36";
".oga" = mkDefault "00;36";
".opus" = mkDefault "00;36";
".spx" = mkDefault "00;36";
".xspf" = mkDefault "00;36";
};
home.file.".dir_colors".text = concatStringsSep "\n" ([ ]
++ optional (cfg.extraConfig != "") cfg.extraConfig
++ mapAttrsToList formatLine cfg.settings) + "\n";
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)
'';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
eval (${pkgs.coreutils}/bin/dircolors -c ~/.dir_colors)
'';
# Set `LS_COLORS` before Oh My Zsh and `initExtra`.
programs.zsh.initExtraBeforeCompInit = mkIf cfg.enableZshIntegration ''
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)
'';
};
}

View File

@@ -6,21 +6,17 @@ let
cfg = config.programs.direnv;
configFile = config:
pkgs.runCommand "config.toml"
{
buildInputs = [ pkgs.remarshal ];
preferLocalBuild = true;
allowSubstitutes = false;
}
''
remarshal -if json -of toml \
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
> $out
'';
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
{
in {
meta.maintainers = [ maintainers.rycee ];
options.programs.direnv = {
@@ -28,7 +24,7 @@ in
config = mkOption {
type = types.attrs;
default = {};
default = { };
description = ''
Configuration written to
<filename>~/.config/direnv/config.toml</filename>.
@@ -74,27 +70,31 @@ in
Whether to enable Fish integration.
'';
};
enableNixDirenvIntegration = mkEnableOption ''
<link
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
a fast, persistent use_nix implementation for direnv'';
};
config = mkIf cfg.enable {
home.packages = [ pkgs.direnv ];
xdg.configFile."direnv/config.toml" = mkIf (cfg.config != {}) {
source = configFile cfg.config;
};
xdg.configFile."direnv/config.toml" =
mkIf (cfg.config != { }) { source = configFile cfg.config; };
xdg.configFile."direnv/direnvrc" = mkIf (cfg.stdlib != "") {
text = cfg.stdlib;
};
xdg.configFile."direnv/direnvrc" = let
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
++ optional cfg.enableNixDirenvIntegration
"source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc");
in mkIf (text != "") { inherit text; };
programs.bash.initExtra =
mkIf cfg.enableBashIntegration (
# Using mkAfter to make it more likely to appear after other
# manipulations of the prompt.
mkAfter ''
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
''
);
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
# Using mkAfter to make it more likely to appear after other
# manipulations of the prompt.
mkAfter ''
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
'');
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${pkgs.direnv}/bin/direnv hook zsh)"

View File

@@ -6,9 +6,7 @@ let
cfg = config.programs.eclipse;
in
{
in {
meta.maintainers = [ maintainers.rycee ];
options = {
@@ -27,13 +25,13 @@ in
jvmArgs = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
description = "JVM arguments to use for the Eclipse process.";
};
plugins = mkOption {
type = types.listOf types.package;
default = [];
default = [ ];
description = "Plugins that should be added to Eclipse.";
};
};
@@ -43,10 +41,8 @@ in
home.packages = [
(pkgs.eclipses.eclipseWithPlugins {
eclipse = pkgs.eclipses.eclipse-platform;
jvmArgs =
cfg.jvmArgs
++ optional cfg.enableLombok
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
jvmArgs = cfg.jvmArgs ++ optional cfg.enableLombok
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
plugins = cfg.plugins;
})
];

View File

@@ -4,15 +4,13 @@ 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;
@@ -36,19 +34,19 @@ in
extraPackages = mkOption {
default = self: [];
type = hmTypes.selectorFunction;
type = hm.types.selectorFunction;
defaultText = "epkgs: []";
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
description = ''
Extra packages available to Emacs. To get a list of
available packages run:
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A emacsPackagesNg</command>.
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A emacsPackages</command>.
'';
};
overrides = mkOption {
default = self: super: {};
type = hmTypes.overlayFunction;
type = hm.types.overlayFunction;
defaultText = "self: super: {}";
example = literalExample ''
self: super: rec {

View File

@@ -7,20 +7,37 @@ let
cfg = config.programs.feh;
disableBinding = func: key: func;
enableBinding = func: key: "${func} ${key}";
enableBinding = func: key: "${func} ${toString key}";
in
{
in {
options.programs.feh = {
enable = mkEnableOption "feh - a fast and light image viewer";
keybindings = mkOption {
default = {};
type = types.attrsOf types.str;
example = { zoom_in = "plus"; zoom_out = "minus"; };
buttons = mkOption {
default = { };
type = with types; attrsOf (nullOr (either str int));
example = {
zoom_in = 4;
zoom_out = "C-4";
};
description = ''
Set keybindings.
Override feh's default mouse button mapping. If you want to disable an
action, set its value to null.
See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for
default bindings and available commands.
'';
};
keybindings = mkOption {
default = { };
type = types.attrsOf (types.nullOr types.str);
example = {
zoom_in = "plus";
zoom_out = "minus";
};
description = ''
Override feh's default keybindings. If you want to disable a keybinding
set its value to null.
See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for
default bindings and available commands.
'';
@@ -28,14 +45,26 @@ in
};
config = mkIf cfg.enable {
assertions = [{
assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == { });
message =
"To disable a keybinding, use `null` instead of an empty string.";
}];
home.packages = [ pkgs.feh ];
xdg.configFile."feh/keys".text = ''
# Disable default keybindings
${concatStringsSep "\n" (mapAttrsToList disableBinding cfg.keybindings)}
xdg.configFile."feh/buttons".text = ''
${concatStringsSep "\n" (mapAttrsToList disableBinding
(filterAttrs (n: v: v == null) cfg.buttons))}
${concatStringsSep "\n" (mapAttrsToList enableBinding
(filterAttrs (n: v: v != null) cfg.buttons))}
'';
# Enable new keybindings
${concatStringsSep "\n" (mapAttrsToList enableBinding cfg.keybindings)}
xdg.configFile."feh/keys".text = ''
${concatStringsSep "\n" (mapAttrsToList disableBinding
(filterAttrs (n: v: v == null) cfg.keybindings))}
${concatStringsSep "\n" (mapAttrsToList enableBinding
(filterAttrs (n: v: v != null) cfg.keybindings))}
'';
};
}

View File

@@ -4,15 +4,42 @@ with lib;
let
inherit (pkgs.stdenv.hostPlatform) isDarwin;
cfg = config.programs.firefox;
mozillaConfigPath =
if isDarwin
then "Library/Application Support/Mozilla"
else ".mozilla";
firefoxConfigPath =
if isDarwin
then "Library/Application Support/Firefox"
else "${mozillaConfigPath}/firefox";
profilesPath =
if isDarwin
then "${firefoxConfigPath}/Profiles"
else firefoxConfigPath;
# The extensions path shared by all profiles; will not be supported
# by future Firefox versions.
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
extensionsEnvPkg = pkgs.buildEnv {
name = "hm-firefox-extensions";
paths = cfg.extensions;
};
profiles =
flip mapAttrs' cfg.profiles (_: profile:
nameValuePair "Profile${toString profile.id}" {
Name = profile.name;
Path = profile.path;
Path =
if isDarwin
then "Profiles/${profile.path}"
else profile.path;
IsRelative = 1;
Default = if profile.isDefault then 1 else 0;
}
@@ -39,6 +66,13 @@ in
{
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkRemovedOptionModule ["programs" "firefox" "enableGoogleTalk"]
"Support for this option has been removed.")
(mkRemovedOptionModule ["programs" "firefox" "enableIcedTea"]
"Support for this option has been removed.")
];
options = {
programs.firefox = {
enable = mkEnableOption "Firefox";
@@ -67,9 +101,19 @@ in
]
'';
description = ''
List of Firefox add-on packages to install. Note, it is
necessary to manually enable these extensions inside Firefox
after the first installation.
List of Firefox add-on packages to install. Some
pre-packaged add-ons are accessible from NUR,
<link xlink:href="https://github.com/nix-community/NUR"/>.
Once you have NUR installed run
<screen language="console">
<prompt>$</prompt> <userinput>nix-env -f '&lt;nixpkgs&gt;' -qaP -A nur.repos.rycee.firefox-addons</userinput>
</screen>
to list the available Firefox add-ons.
</para><para>
Note that it is necessary to manually enable these
extensions inside Firefox after the first installation.
'';
};
@@ -117,7 +161,7 @@ in
userChrome = mkOption {
type = types.lines;
default = "";
description = "Custom Firefox CSS.";
description = "Custom Firefox user chrome CSS.";
example = ''
/* Hide tab bar in FF Quantum */
@-moz-document url("chrome://browser/content/browser.xul") {
@@ -133,6 +177,16 @@ in
'';
};
userContent = mkOption {
type = types.lines;
default = "";
description = "Custom Firefox user content CSS.";
example = ''
/* Hide scrollbar in FF Quantum */
*{scrollbar-width:none !important}
'';
};
path = mkOption {
type = types.str;
default = name;
@@ -156,38 +210,6 @@ in
default = false;
description = "Whether to enable the unfree Adobe Flash plugin.";
};
enableGoogleTalk = mkOption {
type = types.bool;
default = false;
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. 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.
'';
};
};
};
@@ -230,8 +252,6 @@ in
# The configuration expected by the Firefox wrapper.
fcfg = {
enableAdobeFlash = cfg.enableAdobeFlash;
enableGoogleTalkPlugin = cfg.enableGoogleTalk;
icedtea = cfg.enableIcedTea;
};
# A bit of hackery to force a config into the wrapper.
@@ -242,40 +262,47 @@ in
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 { };
if isDarwin then
cfg.package
else if versionAtLeast config.home.stateVersion "19.09" then
cfg.package.override { cfg = fcfg; }
else
(pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
in
[ package ];
home.file = mkMerge (
[{
".mozilla/${extensionPath}" = mkIf (cfg.extensions != []) (
let
extensionsEnv = pkgs.buildEnv {
name = "hm-firefox-extensions";
paths = cfg.extensions;
};
in {
source = "${extensionsEnv}/share/mozilla/${extensionPath}";
recursive = true;
}
);
"${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != []) {
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
recursive = true;
};
".mozilla/firefox/profiles.ini" = mkIf (cfg.profiles != {}) {
"${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) {
text = profilesIni;
};
}]
++ flip mapAttrsToList cfg.profiles (_: profile: {
".mozilla/firefox/${profile.path}/chrome/userChrome.css" =
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
mkIf (profile.userChrome != "") {
text = profile.userChrome;
};
".mozilla/firefox/${profile.path}/user.js" =
"${profilesPath}/${profile.path}/chrome/userContent.css" =
mkIf (profile.userContent != "") {
text = profile.userContent;
};
"${profilesPath}/${profile.path}/user.js" =
mkIf (profile.settings != {} || profile.extraConfig != "") {
text = mkUserJs profile.settings profile.extraConfig;
};
"${profilesPath}/${profile.path}/extensions" = mkIf (cfg.extensions != []) {
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
recursive = true;
force = true;
};
})
);
};

View File

@@ -6,119 +6,310 @@ let
cfg = config.programs.fish;
abbrsStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "abbr --add --global ${k} '${v}'") cfg.shellAbbrs
);
pluginModule = types.submodule ({ config, ... }: {
options = {
src = mkOption {
type = types.path;
description = ''
Path to the plugin folder.
</para><para>
Relevant pieces will be added to the fish function path and
the completion path. The <filename>init.fish</filename> and
<filename>key_binding.fish</filename> files are sourced if
they exist.
'';
};
aliasesStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
);
name = mkOption {
type = types.str;
description = ''
The name of the plugin.
'';
};
};
});
in
functionModule = types.submodule {
options = {
body = mkOption {
type = types.lines;
description = ''
The function body.
'';
};
{
argumentNames = mkOption {
type = with types; nullOr (either str (listOf str));
default = null;
description = ''
Assigns the value of successive command line arguments to the names
given.
'';
};
description = mkOption {
type = with types; nullOr str;
default = null;
description = ''
A description of what the function does, suitable as a completion
description.
'';
};
wraps = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Causes the function to inherit completions from the given wrapped
command.
'';
};
onEvent = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Tells fish to run this function when the specified named event is
emitted. Fish internally generates named events e.g. when showing the
prompt.
'';
};
onVariable = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Tells fish to run this function when the specified variable changes
value.
'';
};
onJobExit = mkOption {
type = with types; nullOr (either str int);
default = null;
description = ''
Tells fish to run this function when the job with the specified group
ID exits. Instead of a PID, the stringer <literal>caller</literal> can
be specified. This is only legal when in a command substitution, and
will result in the handler being triggered by the exit of the job
which created this command substitution.
'';
};
onProcessExit = mkOption {
type = with types; nullOr (either str int);
default = null;
example = "$fish_pid";
description = ''
Tells fish to run this function when the fish child process with the
specified process ID exits. Instead of a PID, for backwards
compatibility, <literal>%self</literal> can be specified as an alias
for <literal>$fish_pid</literal>, and the function will be run when
the current fish instance exits.
'';
};
onSignal = mkOption {
type = with types; nullOr (either str int);
default = null;
example = [ "SIGHUP" "HUP" 1 ];
description = ''
Tells fish to run this function when the specified signal is
delievered. The signal can be a signal number or signal name.
'';
};
noScopeShadowing = mkOption {
type = types.bool;
default = false;
description = ''
Allows the function to access the variables of calling functions.
'';
};
inheritVariable = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Snapshots the value of the specified variable and defines a local
variable with that same name and value when the function is defined.
'';
};
};
};
abbrsStr = concatStringsSep "\n"
(mapAttrsToList (k: v: "abbr --add --global -- ${k} ${escapeShellArg v}")
cfg.shellAbbrs);
aliasesStr = concatStringsSep "\n"
(mapAttrsToList (k: v: "alias ${k} ${escapeShellArg v}") cfg.shellAliases);
in {
options = {
programs.fish = {
enable = mkEnableOption "fish friendly interactive shell";
enable = mkEnableOption "fish, the friendly interactive shell";
package = mkOption {
type = types.package;
default = pkgs.fish;
defaultText = literalExample "pkgs.fish";
description = ''
The fish package to install. May be used to change the version.
'';
type = types.package;
};
shellAliases = mkOption {
default = {};
description = ''
Set of aliases for fish shell. See
<option>environment.shellAliases</option> for an option
format description.
type = with types; attrsOf str;
default = { };
example = literalExample ''
{
ll = "ls -l";
".." = "cd ..";
}
'';
description = ''
An attribute set that maps aliases (the top level attribute names
in this option) to command strings or directly to build outputs.
'';
type = types.attrs;
};
shellAbbrs = mkOption {
default = {};
type = with types; attrsOf str;
default = { };
example = {
l = "less";
gco = "git checkout";
};
description = ''
Set of abbreviations for fish shell.
An attribute set that maps aliases (the top level attribute names
in this option) to abbreviations. Abbreviations are expanded with
the longer phrase after they are entered.
'';
type = types.attrs;
};
shellInit = mkOption {
type = types.lines;
default = "";
description = ''
Shell script code called during fish shell initialisation.
Shell script code called during fish shell
initialisation.
'';
type = types.lines;
};
loginShellInit = mkOption {
type = types.lines;
default = "";
description = ''
Shell script code called during fish login shell initialisation.
Shell script code called during fish login shell
initialisation.
'';
type = types.lines;
};
interactiveShellInit = mkOption {
type = types.lines;
default = "";
description = ''
Shell script code called during interactive fish shell initialisation.
Shell script code called during interactive fish shell
initialisation.
'';
type = types.lines;
};
promptInit = mkOption {
type = types.lines;
default = "";
description = ''
Shell script code used to initialise fish prompt.
'';
type = types.lines;
};
};
programs.fish.plugins = mkOption {
type = types.listOf pluginModule;
default = [ ];
example = literalExample ''
[
{
name = "z";
src = pkgs.fetchFromGitHub {
owner = "jethrokuan";
repo = "z";
rev = "ddeb28a7b6a1f0ec6dae40c636e5ca4908ad160a";
sha256 = "0c5i7sdrsp0q3vbziqzdyqn4fmp235ax4mn4zslrswvn8g3fvdyh";
};
}
# oh-my-fish plugins are stored in their own repositories, which
# makes them simple to import into home-manager.
{
name = "fasd";
src = pkgs.fetchFromGitHub {
owner = "oh-my-fish";
repo = "plugin-fasd";
rev = "38a5b6b6011106092009549e52249c6d6f501fba";
sha256 = "06v37hqy5yrv5a6ssd1p3cjd9y3hnp19d3ab7dag56fs1qmgyhbs";
};
}
]
'';
description = ''
The plugins to source in
<filename>conf.d/99plugins.fish</filename>.
'';
};
programs.fish.functions = mkOption {
type = with types; attrsOf (either lines functionModule);
default = { };
example = literalExample ''
{
__fish_command_not_found_handler = {
body = "__fish_default_command_not_found_handler $argv[1]";
onEvent = "fish_command_not_found";
};
gitignore = "curl -sL https://www.gitignore.io/api/$argv";
}
'';
description = ''
Basic functions to add to fish. For more information see
<link xlink:href="https://fishshell.com/docs/current/cmds/function.html"/>.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
config = mkIf cfg.enable (mkMerge [
{
home.packages = [ cfg.package ];
xdg.dataFile."fish/home-manager_generated_completions".source =
let
xdg.dataFile."fish/home-manager_generated_completions".source = let
# paths later in the list will overwrite those already linked
destructiveSymlinkJoin =
args_@{ name
, paths
, preferLocalBuild ? true
, allowSubstitutes ? false
, postBuild ? ""
, ...
}:
destructiveSymlinkJoin = args_@{ name, paths, preferLocalBuild ? true
, allowSubstitutes ? false, postBuild ? "", ... }:
let
args = removeAttrs args_ [ "name" "postBuild" ]
// { inherit preferLocalBuild allowSubstitutes; }; # pass the defaults
in pkgs.runCommand name args
''
mkdir -p $out
for i in $paths; do
if [ -z "$(find $i -prune -empty)" ]; then
cp -srf $i/* $out
fi
done
${postBuild}
'';
generateCompletions = package: pkgs.runCommand
"${package.name}-fish-completions"
{
args = removeAttrs args_ [ "name" "postBuild" ] // {
# pass the defaults
inherit preferLocalBuild allowSubstitutes;
};
in pkgs.runCommand name args ''
mkdir -p $out
for i in $paths; do
if [ -z "$(find $i -prune -empty)" ]; then
cp -srf $i/* $out
fi
done
${postBuild}
'';
generateCompletions = package:
pkgs.runCommand "${package.name}-fish-completions" {
src = package;
nativeBuildInputs = [ pkgs.python2 ];
buildInputs = [ cfg.package ];
preferLocalBuild = true;
allowSubstitutes = false;
}
''
} ''
mkdir -p $out
if [ -d $src/share/man ]; then
find $src/share/man -type f \
@@ -126,66 +317,142 @@ in
> /dev/null
fi
'';
in
destructiveSymlinkJoin {
name = "${config.home.username}-fish-completions";
paths =
let
cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
in
map generateCompletions (sort cmp config.home.packages);
in destructiveSymlinkJoin {
name = "${config.home.username}-fish-completions";
paths =
let cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
in map generateCompletions (sort cmp config.home.packages);
};
programs.fish.interactiveShellInit = ''
# add completions generated by Home Manager to $fish_complete_path
begin
set -l joined (string join " " $fish_complete_path)
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
set -l post_joined (string replace $prev_joined "" $joined)
set -l prev (string split " " (string trim $prev_joined))
set -l post (string split " " (string trim $post_joined))
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
end
'';
xdg.configFile."fish/config.fish".text = ''
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated
# automatically by home-manager.
# if we haven't sourced the general config, do it
if not set -q __fish_general_config_sourced
set -p fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions
fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null
set -e fish_function_path[1]
${cfg.shellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew)
set -g __fish_general_config_sourced 1
end
# if we haven't sourced the login config, do it
status --is-login; and not set -q __fish_login_config_sourced
and begin
# Login shell initialisation
${cfg.loginShellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew)
set -g __fish_login_config_sourced 1
end
# if we haven't sourced the interactive config, do it
status --is-interactive; and not set -q __fish_interactive_config_sourced
and begin
# Abbreviations
${abbrsStr}
# Aliases
${aliasesStr}
# Prompt initialisation
${cfg.promptInit}
# Interactive shell intialisation
${cfg.interactiveShellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew,
# allowing configuration changes in, e.g, aliases, to propagate)
set -g __fish_interactive_config_sourced 1
end
'';
}
{
xdg.configFile = mapAttrs' (name: def: {
name = "fish/functions/${name}.fish";
value = {
text = let
modifierStr = n: v: optional (v != null) ''--${n}="${toString v}"'';
modifierStrs = n: v: optional (v != null) "--${n}=${toString v}";
modifierBool = n: v: optional (v != null && v) "--${n}";
mods = with def;
modifierStr "description" description ++ modifierStr "wraps" wraps
++ modifierStr "on-event" onEvent
++ modifierStr "on-variable" onVariable
++ modifierStr "on-job-exit" onJobExit
++ modifierStr "on-process-exit" onProcessExit
++ modifierStr "on-signal" onSignal
++ modifierBool "no-scope-shadowing" noScopeShadowing
++ modifierStr "inherit-variable" inheritVariable
++ modifierStrs "argument-names" argumentNames;
modifiers = if isAttrs def then " ${toString mods}" else "";
body = if isAttrs def then def.body else def;
in ''
function ${name}${modifiers}
${body}
end
'';
};
}) cfg.functions;
}
programs.fish.interactiveShellInit = ''
# add completions generated by Home Manager to $fish_complete_path
begin
set -l joined (string join " " $fish_complete_path)
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
set -l post_joined (string replace $prev_joined "" $joined)
set -l prev (string split " " (string trim $prev_joined))
set -l post (string split " " (string trim $post_joined))
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
end
'';
# Each plugin gets a corresponding conf.d/plugin-NAME.fish file to load
# in the paths and any initialization scripts.
(mkIf (length cfg.plugins > 0) {
xdg.configFile = mkMerge ((map (plugin: {
"fish/conf.d/plugin-${plugin.name}.fish".text = ''
# Plugin ${plugin.name}
set -l plugin_dir ${plugin.src}
xdg.configFile."fish/config.fish".text = ''
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.
# if we haven't sourced the general config, do it
if not set -q __fish_general_config_sourced
set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null
set -e fish_function_path[1]
# Set paths to import plugin components
if test -d $plugin_dir/functions
set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1]
end
${cfg.shellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew)
set -g __fish_general_config_sourced 1
end
# if we haven't sourced the login config, do it
status --is-login; and not set -q __fish_login_config_sourced
and begin
if test -d $plugin_dir/completions
set fish_complete_path $fish_complete_path[1] $plugin_dir/completions $fish_complete_path[2..-1]
end
${cfg.loginShellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew)
set -g __fish_login_config_sourced 1
end
# if we haven't sourced the interactive config, do it
status --is-interactive; and not set -q __fish_interactive_config_sourced
and begin
# Abbrs
${abbrsStr}
# Source initialization code if it exists.
if test -d $plugin_dir/conf.d
source $plugin_dir/conf.d/*.fish
end
# Aliases
${aliasesStr}
if test -f $plugin_dir/key_bindings.fish
source $plugin_dir/key_bindings.fish
end
${cfg.promptInit}
${cfg.interactiveShellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew,
# allowing configuration changes in, e.g, aliases, to propagate)
set -g __fish_interactive_config_sourced 1
end
'';
};
if test -f $plugin_dir/init.fish
source $plugin_dir/init.fish
end
'';
}) cfg.plugins));
})
]);
}

View File

@@ -6,9 +6,7 @@ let
cfg = config.programs.fzf;
in
{
in {
options.programs.fzf = {
enable = mkEnableOption "fzf - a command-line fuzzy finder";
@@ -24,7 +22,7 @@ in
defaultOptions = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "--height 40%" "--border" ];
description = ''
Extra command line options given to fzf by default.
@@ -43,7 +41,7 @@ in
fileWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "--preview 'head {}'" ];
description = ''
Command line options for the CTRL-T keybinding.
@@ -53,7 +51,7 @@ in
changeDirWidgetCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type d" ;
example = "fd --type d";
description = ''
The command that gets executed as the source for fzf for the
ALT-C keybinding.
@@ -62,7 +60,7 @@ in
changeDirWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "--preview 'tree -C {} | head -200'" ];
description = ''
Command line options for the ALT-C keybinding.
@@ -80,7 +78,7 @@ in
historyWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "--sort" "--exact" ];
description = ''
Command line options for the CTRL-R keybinding.
@@ -102,24 +100,30 @@ in
Whether to enable Zsh integration.
'';
};
enableFishIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Fish integration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.fzf ];
home.sessionVariables =
mapAttrs (n: v: toString v) (
filterAttrs (n: v: v != [] && v != null) {
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
FZF_DEFAULT_OPTS = cfg.defaultOptions;
}
);
home.sessionVariables = mapAttrs (n: v: toString v)
(filterAttrs (n: v: v != [ ] && v != null) {
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
FZF_DEFAULT_OPTS = cfg.defaultOptions;
});
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
@@ -134,5 +138,9 @@ in
. ${pkgs.fzf}/share/fzf/key-bindings.zsh
fi
'';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
source ${pkgs.fzf}/share/fzf/key-bindings.fish && fzf_key_bindings
'';
};
}

View File

@@ -17,8 +17,8 @@ with lib;
mailboxes = mkOption {
type = types.nonEmptyListOf types.str;
default = [];
example = ["INBOX" "INBOX.spam"];
default = [ ];
example = [ "INBOX" "INBOX.spam" ];
description = ''
A non-empty list of mailboxes. To download all mail you can
use the <literal>ALL</literal> mailbox.

View File

@@ -4,33 +4,33 @@ with lib;
let
accounts = filter (a: a.getmail.enable)
(attrValues config.accounts.email.accounts);
accounts =
filter (a: a.getmail.enable) (attrValues config.accounts.email.accounts);
renderAccountConfig = account: with account;
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}/";
};
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} )
@@ -45,15 +45,13 @@ let
'';
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
renderConfigFilepath = a:
".getmail/getmail${if a.primary then "rc" else a.name}";
{
config = mkIf getmailEnabled {
home.file = map (a:
{ target = renderConfigFilepath a;
text = renderAccountConfig a;
}) accounts;
};
}
in {
config = mkIf getmailEnabled {
home.file = foldl' (a: b: a // b) { }
(map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; })
accounts);
};
}

View File

@@ -14,36 +14,41 @@ let
section = head sections;
subsections = tail sections;
subsection = concatStringsSep "." subsections;
in
if containsQuote || subsections == []
then name
else "${section} \"${subsection}\"";
in if containsQuote || subsections == [ ] then
name
else
''${section} "${subsection}"'';
mkValueString = v:
let
escapedV = ''
"${
replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v
}"'';
in generators.mkValueStringDefault { } (if isString v then escapedV else v);
# generation for multiple ini values
mkKeyValue = k: v:
let
mkKeyValue = generators.mkKeyValueDefault {} "=" k;
in
concatStringsSep "\n" (map mkKeyValue (toList v));
mkKeyValue =
generators.mkKeyValueDefault { inherit mkValueString; } " = " k;
in concatStringsSep "\n" (map (kv: " " + mkKeyValue kv) (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));
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);
let toIni = generators.toINI { inherit mkKeyValue mkSectionName; };
in toIni (gitFlattenAttrs attrs);
gitIniType = with types;
let
@@ -51,8 +56,7 @@ let
multipleType = either primitiveType (listOf primitiveType);
sectionType = attrsOf multipleType;
supersectionType = attrsOf (either multipleType sectionType);
in
attrsOf supersectionType;
in attrsOf supersectionType;
signModule = types.submodule {
options = {
@@ -98,21 +102,18 @@ let
contents = mkOption {
type = types.attrs;
default = {};
default = { };
description = ''
Configuration to include. If empty then a path must be given.
'';
};
};
config.path = mkIf (config.contents != {}) (
mkDefault (pkgs.writeText "contents" (gitToIni config.contents))
);
config.path = mkIf (config.contents != { })
(mkDefault (pkgs.writeText "contents" (gitToIni config.contents)));
});
in
{
in {
meta.maintainers = [ maintainers.rycee ];
options = {
@@ -143,7 +144,7 @@ in
aliases = mkOption {
type = types.attrsOf types.str;
default = {};
default = { };
example = { co = "checkout"; };
description = "Git aliases to define.";
};
@@ -156,7 +157,7 @@ in
extraConfig = mkOption {
type = types.either types.lines gitIniType;
default = {};
default = { };
example = {
core = { whitespace = "trailing-space,space-before-tab"; };
url."ssh://git@host".insteadOf = "otherhost";
@@ -174,21 +175,21 @@ in
ignores = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "*~" "*.swp" ];
description = "List of paths that should be globally ignored.";
};
attributes = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "*.pdf diff=pdf" ];
description = "List of defining attributes set globally.";
};
includes = mkOption {
type = types.listOf includeModule;
default = [];
default = [ ];
example = literalExample ''
[
{ path = "~/path/to/config.inc"; }
@@ -217,109 +218,96 @@ in
};
};
config = mkIf cfg.enable (
mkMerge [
{
home.packages = [ cfg.package ];
config = mkIf cfg.enable (mkMerge [
{
home.packages = [ cfg.package ];
programs.git.iniContent.user = {
name = mkIf (cfg.userName != null) cfg.userName;
email = mkIf (cfg.userEmail != null) cfg.userEmail;
programs.git.iniContent.user = {
name = mkIf (cfg.userName != null) cfg.userName;
email = mkIf (cfg.userEmail != null) cfg.userEmail;
};
xdg.configFile = {
"git/config".text = gitToIni cfg.iniContent;
"git/ignore" = mkIf (cfg.ignores != [ ]) {
text = concatStringsSep "\n" cfg.ignores + "\n";
};
xdg.configFile = {
"git/config".text = gitToIni cfg.iniContent;
"git/attributes" = mkIf (cfg.attributes != [ ]) {
text = concatStringsSep "\n" cfg.attributes + "\n";
};
};
}
"git/ignore" = mkIf (cfg.ignores != []) {
text = concatStringsSep "\n" cfg.ignores + "\n";
{
programs.git.iniContent = let
hasSmtp = name: account: account.smtp != null;
genIdentity = name: account:
with account;
nameValuePair "sendemail.${name}" ({
smtpEncryption = if smtp.tls.enable then "tls" else "";
smtpServer = smtp.host;
smtpUser = userName;
from = address;
} // optionalAttrs (smtp.port != null) {
smtpServerPort = smtp.port;
});
in mapAttrs' genIdentity
(filterAttrs hasSmtp config.accounts.email.accounts);
}
(mkIf (cfg.signing != null) {
programs.git.iniContent = {
user.signingKey = cfg.signing.key;
commit.gpgSign = cfg.signing.signByDefault;
gpg.program = cfg.signing.gpgPath;
};
})
(mkIf (cfg.aliases != { }) { programs.git.iniContent.alias = cfg.aliases; })
(mkIf (lib.isAttrs cfg.extraConfig) {
programs.git.iniContent = cfg.extraConfig;
})
(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 = 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)));
})
"git/attributes" = mkIf (cfg.attributes != []) {
text = concatStringsSep "\n" cfg.attributes + "\n";
};
(mkIf cfg.lfs.enable {
home.packages = [ pkgs.git-lfs ];
programs.git.iniContent.filter.lfs =
let skipArg = optional cfg.lfs.skipSmudge "--skip";
in {
clean = "git-lfs clean -- %f";
process =
concatStringsSep " " ([ "git-lfs" "filter-process" ] ++ skipArg);
required = true;
smudge = concatStringsSep " "
([ "git-lfs" "smudge" ] ++ skipArg ++ [ "--" "%f" ]);
};
}
{
programs.git.iniContent =
let
hasSmtp = name: account: account.smtp != null;
genIdentity = name: account: with account;
nameValuePair "sendemail.${name}" ({
smtpEncryption = if smtp.tls.enable then "tls" else "";
smtpServer = smtp.host;
smtpUser = userName;
from = address;
}
// optionalAttrs (smtp.port != null) {
smtpServerPort = smtp.port;
});
in
mapAttrs' genIdentity
(filterAttrs hasSmtp config.accounts.email.accounts);
}
(mkIf (cfg.signing != null) {
programs.git.iniContent = {
user.signingKey = cfg.signing.key;
commit.gpgSign = cfg.signing.signByDefault;
gpg.program = cfg.signing.gpgPath;
};
})
(mkIf (cfg.aliases != {}) {
programs.git.iniContent.alias = cfg.aliases;
})
(mkIf (lib.isAttrs cfg.extraConfig) {
programs.git.iniContent = cfg.extraConfig;
})
(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 =
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 =
let
skipArg = optional cfg.lfs.skipSmudge "--skip";
in
{
clean = "git-lfs clean -- %f";
process = concatStringsSep " " (
[ "git-lfs" "filter-process" ] ++ skipArg
);
required = true;
smudge = concatStringsSep " " (
[ "git-lfs" "smudge" ] ++ skipArg ++ [ "--" "%f" ]
);
};
})
]
);
})
]);
}

View File

@@ -11,125 +11,124 @@ let
. ${pkgs.gnome3.vte}/etc/profile.d/vte.sh
'';
backForeSubModule = types.submodule (
{ ... }: {
options = {
foreground = mkOption {
type = types.str;
description = "The foreground color.";
};
background = mkOption {
type = types.str;
description = "The background color.";
};
backForeSubModule = types.submodule ({ ... }: {
options = {
foreground = mkOption {
type = types.str;
description = "The foreground color.";
};
}
);
profileColorsSubModule = types.submodule (
{ ... }: {
options = {
foregroundColor = mkOption {
type = types.str;
description = "The foreground color.";
};
backgroundColor = mkOption {
type = types.str;
description = "The background color.";
};
boldColor = mkOption {
default = null;
type = types.nullOr types.str;
description = "The bold color, null to use same as foreground.";
};
palette = mkOption {
type = types.listOf types.str;
description = "The terminal palette.";
};
cursor = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The color for the terminal cursor.";
};
highlight = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The colors for the terminals highlighted area.";
};
background = mkOption {
type = types.str;
description = "The background color.";
};
}
);
};
});
profileSubModule = types.submodule (
{ name, config, ... }: {
options = {
default = mkOption {
default = false;
type = types.bool;
description = "Whether this should be the default profile.";
};
visibleName = mkOption {
type = types.str;
description = "The profile name.";
};
colors = mkOption {
default = null;
type = types.nullOr profileColorsSubModule;
description = "The terminal colors, null to use system default.";
};
cursorShape = mkOption {
default = "block";
type = types.enum [ "block" "ibeam" "underline" ];
description = "The cursor shape.";
};
font = mkOption {
default = null;
type = types.nullOr types.str;
description = "The font name, null to use system default.";
};
allowBold = mkOption {
default = null;
type = types.nullOr types.bool;
description = ''
If <literal>true</literal>, allow applications in the
terminal to make text boldface.
'';
};
scrollOnOutput = mkOption {
default = true;
type = types.bool;
description = "Whether to scroll when output is written.";
};
showScrollbar = mkOption {
default = true;
type = types.bool;
description = "Whether the scroll bar should be visible.";
};
scrollbackLines = mkOption {
default = 10000;
type = types.nullOr types.int;
description =
''
The number of scrollback lines to keep, null for infinite.
'';
};
profileColorsSubModule = types.submodule ({ ... }: {
options = {
foregroundColor = mkOption {
type = types.str;
description = "The foreground color.";
};
}
);
backgroundColor = mkOption {
type = types.str;
description = "The background color.";
};
boldColor = mkOption {
default = null;
type = types.nullOr types.str;
description = "The bold color, null to use same as foreground.";
};
palette = mkOption {
type = types.listOf types.str;
description = "The terminal palette.";
};
cursor = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The color for the terminal cursor.";
};
highlight = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The colors for the terminals highlighted area.";
};
};
});
profileSubModule = types.submodule ({ name, config, ... }: {
options = {
default = mkOption {
default = false;
type = types.bool;
description = "Whether this should be the default profile.";
};
visibleName = mkOption {
type = types.str;
description = "The profile name.";
};
colors = mkOption {
default = null;
type = types.nullOr profileColorsSubModule;
description = "The terminal colors, null to use system default.";
};
cursorBlinkMode = mkOption {
default = "system";
type = types.enum [ "system" "on" "off" ];
description = "The cursor blink mode.";
};
cursorShape = mkOption {
default = "block";
type = types.enum [ "block" "ibeam" "underline" ];
description = "The cursor shape.";
};
font = mkOption {
default = null;
type = types.nullOr types.str;
description = "The font name, null to use system default.";
};
allowBold = mkOption {
default = null;
type = types.nullOr types.bool;
description = ''
If <literal>true</literal>, allow applications in the
terminal to make text boldface.
'';
};
scrollOnOutput = mkOption {
default = true;
type = types.bool;
description = "Whether to scroll when output is written.";
};
showScrollbar = mkOption {
default = true;
type = types.bool;
description = "Whether the scroll bar should be visible.";
};
scrollbackLines = mkOption {
default = 10000;
type = types.nullOr types.int;
description = ''
The number of scrollback lines to keep, null for infinite.
'';
};
};
});
buildProfileSet = pcfg:
{
@@ -137,56 +136,42 @@ let
scrollbar-policy = if pcfg.showScrollbar then "always" else "never";
scrollback-lines = pcfg.scrollbackLines;
cursor-shape = pcfg.cursorShape;
}
// (
if (pcfg.font == null)
then { use-system-font = true; }
else { use-system-font = false; font = pcfg.font; }
) // (
if (pcfg.colors == null)
then { use-theme-colors = true; }
else (
{
use-theme-colors = false;
foreground-color = pcfg.colors.foregroundColor;
background-color = pcfg.colors.backgroundColor;
palette = pcfg.colors.palette;
}
// optionalAttrs (pcfg.allowBold != null) {
allow-bold = pcfg.allowBold;
}
// (
if (pcfg.colors.boldColor == null)
then { bold-color-same-as-fg = true; }
else {
bold-color-same-as-fg = false;
bold-color = pcfg.colors.boldColor;
}
)
// (
if (pcfg.colors.cursor != null)
then {
cursor-colors-set = true;
cursor-foreground-color = pcfg.colors.cursor.foreground;
cursor-background-color = pcfg.colors.cursor.background;
}
else { cursor-colors-set = false; }
)
// (
if (pcfg.colors.highlight != null)
then {
highlight-colors-set = true;
highlight-foreground-color = pcfg.colors.highlight.foreground;
highlight-background-color = pcfg.colors.highlight.background;
}
else { highlight-colors-set = false; }
)
)
);
cursor-blink-mode = pcfg.cursorBlinkMode;
} // (if (pcfg.font == null) then {
use-system-font = true;
} else {
use-system-font = false;
font = pcfg.font;
}) // (if (pcfg.colors == null) then {
use-theme-colors = true;
} else
({
use-theme-colors = false;
foreground-color = pcfg.colors.foregroundColor;
background-color = pcfg.colors.backgroundColor;
palette = pcfg.colors.palette;
} // optionalAttrs (pcfg.allowBold != null) {
allow-bold = pcfg.allowBold;
} // (if (pcfg.colors.boldColor == null) then {
bold-color-same-as-fg = true;
} else {
bold-color-same-as-fg = false;
bold-color = pcfg.colors.boldColor;
}) // (if (pcfg.colors.cursor != null) then {
cursor-colors-set = true;
cursor-foreground-color = pcfg.colors.cursor.foreground;
cursor-background-color = pcfg.colors.cursor.background;
} else {
cursor-colors-set = false;
}) // (if (pcfg.colors.highlight != null) then {
highlight-colors-set = true;
highlight-foreground-color = pcfg.colors.highlight.foreground;
highlight-background-color = pcfg.colors.highlight.background;
} else {
highlight-colors-set = false;
})));
in
{
in {
meta.maintainers = [ maintainers.rycee ];
options = {
@@ -201,12 +186,12 @@ in
themeVariant = mkOption {
default = "default";
type = types.enum [ "default" "light" "dark" ];
type = types.enum [ "default" "light" "dark" "system" ];
description = "The theme variation to request";
};
profile = mkOption {
default = {};
default = { };
type = types.attrsOf profileSubModule;
description = "A set of Gnome Terminal profiles.";
};
@@ -216,25 +201,21 @@ in
config = mkIf cfg.enable {
home.packages = [ pkgs.gnome3.gnome_terminal ];
dconf.settings =
let
dconfPath = "org/gnome/terminal/legacy";
in
{
"${dconfPath}" = {
default-show-menubar = cfg.showMenubar;
theme-variant = cfg.themeVariant;
schema-version = 3;
};
dconf.settings = let dconfPath = "org/gnome/terminal/legacy";
in {
"${dconfPath}" = {
default-show-menubar = cfg.showMenubar;
theme-variant = cfg.themeVariant;
schema-version = 3;
};
"${dconfPath}/profiles:" = {
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile;
};
}
// mapAttrs' (n: v:
nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v)
) cfg.profile;
"${dconfPath}/profiles:" = {
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile;
};
} // mapAttrs'
(n: v: nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v))
cfg.profile;
programs.bash.initExtra = mkBefore vteInitStr;
programs.zsh.initExtra = vteInitStr;

View File

@@ -6,9 +6,7 @@ let
cfg = config.programs.go;
in
{
in {
meta.maintainers = [ maintainers.rvolosatovs ];
options = {
@@ -24,7 +22,7 @@ in
packages = mkOption {
type = with types; attrsOf path;
default = {};
default = { };
example = literalExample ''
{
"golang.org/x/text" = builtins.fetchGit "https://go.googlesource.com/text";
@@ -38,7 +36,24 @@ in
type = with types; nullOr str;
default = null;
example = "go";
description = "GOPATH relative to HOME";
description = ''
Primary <envar>GOPATH</envar> relative to
<envar>HOME</envar>. It will be exported first and therefore
used by default by the Go tooling.
'';
};
extraGoPaths = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "extraGoPath1" "extraGoPath2" ];
description = let goPathOpt = "programs.go.goPath";
in ''
Extra <envar>GOPATH</envar>s relative to <envar>HOME</envar> appended
after
<varname><link linkend="opt-${goPathOpt}">${goPathOpt}</link></varname>,
if that option is set.
'';
};
goBin = mkOption {
@@ -47,6 +62,18 @@ in
example = ".local/bin.go";
description = "GOBIN relative to HOME";
};
goPrivate = mkOption {
type = with types; listOf str;
default = [ ];
example = [ "*.corp.example.com" "rsc.io/private" ];
description = ''
The <envar>GOPRIVATE</envar> environment variable controls
which modules the go command considers to be private (not
available publicly) and should therefore not use the proxy
or checksum database.
'';
};
};
};
@@ -54,22 +81,25 @@ in
{
home.packages = [ cfg.package ];
home.file =
let
goPath = if cfg.goPath != null then cfg.goPath else "go";
mkSrc = n: v: {
target = "${goPath}/src/${n}";
source = v;
};
in
mapAttrsToList mkSrc cfg.packages;
home.file = let
goPath = if cfg.goPath != null then cfg.goPath else "go";
mkSrc = n: v: { "${goPath}/src/${n}".source = v; };
in foldl' (a: b: a // b) { } (mapAttrsToList mkSrc cfg.packages);
}
(mkIf (cfg.goPath != null) {
home.sessionVariables.GOPATH = builtins.toPath "${config.home.homeDirectory}/${cfg.goPath}";
home.sessionVariables.GOPATH = concatStringsSep ":" (map builtins.toPath
(map (path: "${config.home.homeDirectory}/${path}")
([ cfg.goPath ] ++ cfg.extraGoPaths)));
})
(mkIf (cfg.goBin != null) {
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
home.sessionVariables.GOBIN =
builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
})
(mkIf (cfg.goPrivate != [ ]) {
home.sessionVariables.GOPRIVATE = concatStringsSep "," cfg.goPrivate;
})
]);
}

View File

@@ -8,9 +8,7 @@ let
dag = config.lib.dag;
in
{
in {
meta.maintainers = [ maintainers.rycee ];
options = {
@@ -33,10 +31,7 @@ in
};
config = mkIf (cfg.enable && !config.submoduleSupport.enable) {
home.packages = [
(pkgs.callPackage ../../home-manager {
inherit (cfg) path;
})
];
home.packages =
[ (pkgs.callPackage ../../home-manager { inherit (cfg) path; }) ];
};
}

View File

@@ -3,6 +3,7 @@
with lib;
let
cfg = config.programs.htop;
list = xs: concatMapStrings (x: "${toString x} ") xs;
@@ -81,16 +82,15 @@ let
RightCPUs2 = 1;
Blank = 2;
CPU = 1;
"CPU(1)"= 1;
"CPU(1)" = 1;
"CPU(2)" = 1;
"CPU(3)" = 1;
"CPU(4)" = 1;
};
singleMeterType = types.coercedTo
(types.enum (attrNames meters))
(m: { kind = m; mode = meters.${m}; })
(types.submodule {
singleMeterType = let
meterEnum = types.enum (attrNames meters);
meterSubmodule = types.submodule {
options = {
kind = mkOption {
type = types.enum (attrNames meters);
@@ -101,10 +101,15 @@ let
mode = mkOption {
type = types.enum [ 1 2 3 4 ];
example = 2;
description = "Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
description =
"Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
};
};
});
};
in types.coercedTo meterEnum (m: {
kind = m;
mode = meters.${m};
}) meterSubmodule;
meterType = types.submodule {
options = {
@@ -115,7 +120,10 @@ let
"Memory"
"LeftCPUs2"
"RightCPUs2"
{ kind = "CPU"; mode = 3; }
{
kind = "CPU";
mode = 3;
}
];
type = types.listOf singleMeterType;
};
@@ -123,7 +131,10 @@ let
description = "Meters shown in the right header.";
default = [ "Tasks" "LoadAverage" "Uptime" ];
example = [
{ kind = "Clock"; mode = 4; }
{
kind = "Clock";
mode = 4;
}
"Uptime"
"Tasks"
];
@@ -131,15 +142,37 @@ let
};
};
};
in
{
in {
options.programs.htop = {
enable = mkEnableOption "htop";
fields = mkOption {
type = types.listOf (types.enum (attrNames fields));
default = [ "PID" "USER" "PRIORITY" "NICE" "M_SIZE" "M_RESIDENT" "M_SHARE" "STATE" "PERCENT_CPU" "PERCENT_MEM" "TIME" "COMM" ];
example = [ "PID" "USER" "PRIORITY" "PERCENT_CPU" "M_RESIDENT" "PERCENT_MEM" "TIME" "COMM" ];
default = [
"PID"
"USER"
"PRIORITY"
"NICE"
"M_SIZE"
"M_RESIDENT"
"M_SHARE"
"STATE"
"PERCENT_CPU"
"PERCENT_MEM"
"TIME"
"COMM"
];
example = [
"PID"
"USER"
"PRIORITY"
"PERCENT_CPU"
"M_RESIDENT"
"PERCENT_MEM"
"TIME"
"COMM"
];
description = "Active fields shown in the table.";
};
@@ -209,7 +242,7 @@ in
default = true;
description = "Display threads in a different color.";
};
treeView = mkOption {
type = types.bool;
default = false;
@@ -225,7 +258,8 @@ in
detailedCpuTime = mkOption {
type = types.bool;
default = false;
description = "Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
description =
"Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
};
cpuCountFromZero = mkOption {
@@ -272,14 +306,23 @@ in
"CPU"
"LeftCPUs2"
"RightCPUs2"
{ kind = "CPU"; mode = 3; }
{
kind = "CPU";
mode = 3;
}
];
right = [
{ kind = "Clock"; mode = 4; }
{
kind = "Clock";
mode = 4;
}
"Uptime"
"Tasks"
"LoadAverage"
{ kind = "Battery"; mode = 1; }
{
kind = "Battery";
mode = 1;
}
];
};
type = meterType;

View File

@@ -26,8 +26,6 @@ let
cfg = config.programs.info;
dag = config.lib.dag;
# Indexes info files found in this location
homeInfoPath = "${config.home.profileDirectory}/share/info";
@@ -36,9 +34,7 @@ let
# from this package in the activation script.
infoPkg = pkgs.texinfoInteractive;
in
{
in {
options = {
programs.info = {
enable = mkEnableOption "GNU Info";
@@ -57,19 +53,20 @@ in
home.sessionVariables.INFOPATH =
"${cfg.homeInfoDirLocation}\${INFOPATH:+:}\${INFOPATH}";
home.activation.createHomeInfoDir = dag.entryAfter ["installPackages"] ''
oPATH=$PATH
export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH"
$DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}"
$DRY_RUN_CMD rm -f "${cfg.homeInfoDirLocation}/dir"
if [[ -d "${homeInfoPath}" ]]; then
find -L "${homeInfoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
-exec $DRY_RUN_CMD ${infoPkg}/bin/install-info '{}' \
"${cfg.homeInfoDirLocation}/dir" \;
fi
export PATH="$oPATH"
unset oPATH
'';
home.activation.createHomeInfoDir =
hm.dag.entryAfter [ "installPackages" ] ''
oPATH=$PATH
export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH"
$DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}"
$DRY_RUN_CMD rm -f "${cfg.homeInfoDirLocation}/dir"
if [[ -d "${homeInfoPath}" ]]; then
find -L "${homeInfoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
-exec $DRY_RUN_CMD ${infoPkg}/bin/install-info '{}' \
"${cfg.homeInfoDirLocation}/dir" \;
fi
export PATH="$oPATH"
unset oPATH
'';
home.packages = [ infoPkg ];

View File

@@ -15,19 +15,17 @@ let
colorsType = types.submodule {
options = {
null = colorType;
false = colorType;
true = colorType;
null = colorType;
false = colorType;
true = colorType;
numbers = colorType;
strings = colorType;
arrays = colorType;
arrays = colorType;
objects = colorType;
};
};
in
{
in {
options = {
programs.jq = {
enable = mkEnableOption "the jq command-line JSON processor";
@@ -52,12 +50,12 @@ in
'';
default = {
null = "1;30";
false = "0;39";
true = "0;39";
null = "1;30";
false = "0;39";
true = "0;39";
numbers = "0;39";
strings = "0;32";
arrays = "1;39";
arrays = "1;39";
objects = "1;39";
};
@@ -69,8 +67,10 @@ in
config = mkIf cfg.enable {
home.packages = [ pkgs.jq ];
home.sessionVariables = let c = cfg.colors; in {
JQ_COLORS = "${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}";
home.sessionVariables = let c = cfg.colors;
in {
JQ_COLORS =
"${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}";
};
};
}

View File

@@ -10,17 +10,46 @@ let
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"
"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"
"ModuleLoaded"
];
example = "SetOption";
description = ''
@@ -159,7 +188,8 @@ let
};
autoInfo = mkOption {
type = types.nullOr (types.listOf (types.enum [ "command" "onkey" "normal" ]));
type = types.nullOr
(types.listOf (types.enum [ "command" "onkey" "normal" ]));
default = null;
example = [ "command" "normal" ];
description = ''
@@ -169,7 +199,7 @@ let
};
autoComplete = mkOption {
type = types.nullOr(types.listOf (types.enum [ "insert" "prompt" ]));
type = types.nullOr (types.listOf (types.enum [ "insert" "prompt" ]));
default = null;
description = ''
Modes in which to display possible completions.
@@ -450,7 +480,7 @@ let
keyMappings = mkOption {
type = types.listOf keyMapping;
default = [];
default = [ ];
description = ''
User-defined key mappings. For documentation, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc"/>.
@@ -459,7 +489,7 @@ let
hooks = mkOption {
type = types.listOf hook;
default = [];
default = [ ];
description = ''
Global hooks. For documentation, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc"/>.
@@ -468,91 +498,114 @@ let
};
};
configFile =
let
wrapOptions = with cfg.config.wrapLines; concatStrings [
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 [
numberLinesOptions = with cfg.config.numberLines;
concatStrings [
"${optionalString relative " -relative "}"
"${optionalString highlightCursor " -hlcursor"}"
"${optionalString (separator != null) " -separator ${separator}"}"
];
uiOptions = with cfg.config.ui; concatStringsSep " " [
showWhitespaceOptions = with cfg.config.showWhitespace;
concatStrings [
(optionalString (tab != null) " -tab ${tab}")
(optionalString (tabStop != null) " -tabpad ${tabStop}")
(optionalString (space != null) " -spc ${space}")
(optionalString (nonBreakingSpace != null) " -nbsp ${nonBreakingSpace}")
(optionalString (lineFeed != null) " -lf ${lineFeed}")
];
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_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}"}"
"ncurses_wheel_down_button=${wheelDownButton}"}"
"${optionalString (wheelUpButton != null)
"ncurses_wheel_up_button=${wheelUpButton}"}"
"ncurses_wheel_up_button=${wheelUpButton}"}"
"${optionalString (shiftFunctionKeys != null)
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
"ncurses_builtin_key_parser=${if useBuiltinKeyParser then "true" else "false"}"
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
"ncurses_builtin_key_parser=${
if useBuiltinKeyParser then "true" else "false"
}"
];
keyMappingString = km: concatStringsSep " " [
keyMappingString = km:
concatStringsSep " " [
"map global"
"${km.mode} ${km.key} '${km.effect}'"
"${optionalString (km.docstring != null) "-docstring '${km.docstring}'"}"
"${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}"
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" ]
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 (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 (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}"
"add-highlighter global/ number-lines${numberLinesOptions}"
++ optional showMatching "add-highlighter global/ show-matching"
++ optional (showWhitespace != null && showWhitespace.enable)
"add-highlighter global/ show-whitespaces${showWhitespaceOptions}"
++ optional (scrollOff != null)
"set-option global scrolloff ${toString scrollOff.lines},${toString scrollOff.columns}"
"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
++ [ "# Key mappings" ] ++ map keyMappingString keyMappings
++ [ "# Hooks" ]
++ map hookString hooks
);
in
pkgs.writeText "kakrc" (
optionalString (cfg.config != null) cfgStr
+ cfg.extraConfig
);
++ [ "# Hooks" ] ++ map hookString hooks);
in pkgs.writeText "kakrc"
(optionalString (cfg.config != null) cfgStr + "\n" + cfg.extraConfig);
in
{
in {
options = {
programs.kakoune = {
enable = mkEnableOption "the kakoune text editor";
config = mkOption {
type = types.nullOr configModule;
default = {};
default = { };
description = "kakoune configuration options.";
};

View File

@@ -6,17 +6,16 @@ let
cfg = config.programs.keychain;
flags = cfg.extraFlags
++ optional (cfg.agents != []) "--agents ${concatStringsSep "," cfg.agents}"
flags = cfg.extraFlags ++ optional (cfg.agents != [ ])
"--agents ${concatStringsSep "," cfg.agents}"
++ optional (cfg.inheritType != null) "--inherit ${cfg.inheritType}";
shellCommand = ''
eval "$(${cfg.package}/bin/keychain --eval ${concatStringsSep " " flags} ${concatStringsSep " " cfg.keys})"
'';
shellCommand =
"${cfg.package}/bin/keychain --eval ${concatStringsSep " " flags} ${
concatStringsSep " " cfg.keys
}";
in
{
in {
meta.maintainers = [ maintainers.marsam ];
options.programs.keychain = {
@@ -41,14 +40,15 @@ in
agents = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
description = ''
Agents to add.
'';
};
inheritType = mkOption {
type = types.nullOr (types.enum ["local" "any" "local-once" "any-once"]);
type =
types.nullOr (types.enum [ "local" "any" "local-once" "any-once" ]);
default = null;
description = ''
Inherit type to attempt from agent variables from the environment.
@@ -71,6 +71,14 @@ in
'';
};
enableFishIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Fish integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
@@ -78,11 +86,30 @@ in
Whether to enable Zsh integration.
'';
};
enableXsessionIntegration = mkOption {
default = true;
type = types.bool;
visible = pkgs.stdenv.hostPlatform.isLinux;
description = ''
Whether to run keychain from your <filename>~/.xsession</filename>.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
programs.bash.initExtra = mkIf cfg.enableBashIntegration shellCommand;
programs.zsh.initExtra = mkIf cfg.enableZshIntegration shellCommand;
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
eval "$(${shellCommand})"
'';
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
eval (${shellCommand})
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${shellCommand})"
'';
xsession.initExtra = mkIf cfg.enableXsessionIntegration ''
eval "$(${shellCommand})"
'';
};
}

View File

@@ -0,0 +1,91 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.kitty;
eitherStrBoolInt = with types; either str (either bool int);
optionalPackage = opt:
optional (opt != null && opt.package != null) opt.package;
toKittyConfig = generators.toKeyValue {
mkKeyValue = key: value:
let
value' = if isBool value then
(if value then "yes" else "no")
else
toString value;
in "${key} ${value'}";
};
toKittyKeybindings = generators.toKeyValue {
mkKeyValue = key: command: "map ${key} ${command}";
};
in {
options.programs.kitty = {
enable = mkEnableOption "Kitty terminal emulator";
settings = mkOption {
type = types.attrsOf eitherStrBoolInt;
default = { };
example = literalExample ''
{
scrollback_lines = 10000;
enable_audio_bell = false;
update_check_interval = 0;
}
'';
description = ''
Configuration written to
<filename>~/.config/kitty/kitty.conf</filename>. See
<link xlink:href="https://sw.kovidgoyal.net/kitty/conf.html" />
for the documentation.
'';
};
font = mkOption {
type = types.nullOr hm.types.fontType;
default = null;
description = "The font to use.";
};
keybindings = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Mapping of keybindings to actions.";
example = literalExample ''
{
"ctrl+c" = "copy_or_interrupt";
"ctrl+f>2" = "set_font_size 20";
}
'';
};
extraConfig = mkOption {
default = "";
type = types.lines;
description = "Additional configuration to add.";
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.kitty ] ++ optionalPackage cfg.font;
xdg.configFile."kitty/kitty.conf".text = ''
# Generated by Home Manager.
# See https://sw.kovidgoyal.net/kitty/conf.html
${optionalString (cfg.font != null) "font_family ${cfg.font.name}"}
${toKittyConfig cfg.settings}
${toKittyKeybindings cfg.keybindings}
${cfg.extraConfig}
'';
};
}

View File

@@ -0,0 +1,69 @@
{ lib, ... }:
with lib;
{
options.lieer = {
enable = mkEnableOption "lieer Gmail synchronization for notmuch";
timeout = mkOption {
type = types.ints.unsigned;
default = 0;
description = ''
HTTP timeout in seconds. 0 means forever or system timeout.
'';
};
replaceSlashWithDot = mkOption {
type = types.bool;
default = false;
description = ''
Replace '/' with '.' in Gmail labels.
'';
};
dropNonExistingLabels = mkOption {
type = types.bool;
default = false;
description = ''
Allow missing labels on the Gmail side to be dropped.
'';
};
ignoreTagsLocal = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Set custom tags to ignore when syncing from local to
remote (after translations).
'';
};
ignoreTagsRemote = mkOption {
type = types.listOf types.str;
default = [
"CATEGORY_FORUMS"
"CATEGORY_PROMOTIONS"
"CATEGORY_UPDATES"
"CATEGORY_SOCIAL"
"CATEGORY_PERSONAL"
];
description = ''
Set custom tags to ignore when syncing from remote to
local (before translations).
'';
};
notmuchSetupWarning = mkOption {
type = types.bool;
default = true;
description = ''
Warn if Notmuch is not also enabled for this account.
</para><para>
This can safely be disabled if <command>notmuch init</command>
has been used to configure this account outside of Home
Manager.
'';
};
};
}

View File

@@ -0,0 +1,89 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.lieer;
lieerAccounts =
filter (a: a.lieer.enable) (attrValues config.accounts.email.accounts);
nonGmailAccounts =
map (a: a.name) (filter (a: a.flavor != "gmail.com") lieerAccounts);
nonGmailConfigHelp =
map (name: ''accounts.email.accounts.${name}.flavor = "gmail.com";'')
nonGmailAccounts;
missingNotmuchAccounts = map (a: a.name)
(filter (a: !a.notmuch.enable && a.lieer.notmuchSetupWarning)
lieerAccounts);
notmuchConfigHelp =
map (name: "accounts.email.accounts.${name}.notmuch.enable = true;")
missingNotmuchAccounts;
configFile = account: {
name = "${account.maildir.absPath}/.gmailieer.json";
value = {
text = builtins.toJSON {
inherit (account.lieer) timeout;
account = account.address;
replace_slash_with_dot = account.lieer.replaceSlashWithDot;
drop_non_existing_label = account.lieer.dropNonExistingLabels;
ignore_tags = account.lieer.ignoreTagsLocal;
ignore_remote_labels = account.lieer.ignoreTagsRemote;
} + "\n";
};
};
in {
meta.maintainers = [ maintainers.tadfisher ];
options = {
programs.lieer.enable =
mkEnableOption "lieer Gmail synchronization for notmuch";
};
config = mkIf cfg.enable (mkMerge [
(mkIf (missingNotmuchAccounts != [ ]) {
warnings = [''
lieer is enabled for the following email accounts, but notmuch is not:
${concatStringsSep "\n " missingNotmuchAccounts}
Notmuch can be enabled with:
${concatStringsSep "\n " notmuchConfigHelp}
If you have configured notmuch outside of Home Manager, you can suppress this
warning with:
programs.lieer.notmuchSetupWarning = false;
''];
})
{
assertions = [{
assertion = nonGmailAccounts == [ ];
message = ''
lieer is enabled for non-Gmail accounts:
${concatStringsSep "\n " nonGmailAccounts}
If these accounts are actually Gmail accounts, you can
fix this error with:
${concatStringsSep "\n " nonGmailConfigHelp}
'';
}];
home.packages = [ pkgs.gmailieer ];
# Notmuch should ignore non-mail files created by lieer.
programs.notmuch.new.ignore = [ "/.*[.](json|lock|bak)$/" ];
home.file = listToAttrs (map configFile lieerAccounts);
}
]);
}

View File

@@ -11,12 +11,10 @@ let
ll = "ls -l";
la = "ls -a";
lt = "ls --tree";
lla ="ls -la";
lla = "ls -la";
};
in
{
in {
meta.maintainers = [ maintainers.marsam ];
options.programs.lsd = {
@@ -37,5 +35,7 @@ in
programs.bash.shellAliases = mkIf cfg.enableAliases aliases;
programs.zsh.shellAliases = mkIf cfg.enableAliases aliases;
programs.fish.shellAliases = mkIf cfg.enableAliases aliases;
};
}

View File

@@ -9,16 +9,13 @@ let
formatLine = o: n: v:
let
formatValue = v:
if isBool v then (if v then "True" else "False")
else toString v;
in
if isAttrs v
then concatStringsSep "\n" (mapAttrsToList (formatLine "${o}${n}.") v)
else (if v == "" then "" else "${o}${n}: ${formatValue v}");
if isBool v then (if v then "True" else "False") else toString v;
in if isAttrs v then
concatStringsSep "\n" (mapAttrsToList (formatLine "${o}${n}.") v)
else
(if v == "" then "" else "${o}${n}: ${formatValue v}");
in
{
in {
meta.maintainers = [ maintainers.rprospero ];
options.programs.matplotlib = {
@@ -31,7 +28,7 @@ in
Add terms to the <filename>matplotlibrc</filename> file to
control the default matplotlib behavior.
'';
example = literalExample ''
example = literalExample ''
{
backend = "Qt5Agg";
axes = {
@@ -55,10 +52,8 @@ in
};
config = mkIf cfg.enable {
xdg.configFile."matplotlib/matplotlibrc".text =
concatStringsSep "\n" ([]
++ mapAttrsToList (formatLine "") cfg.config
++ optional (cfg.extraConfig != "") cfg.extraConfig
) + "\n";
xdg.configFile."matplotlib/matplotlibrc".text = concatStringsSep "\n" ([ ]
++ mapAttrsToList (formatLine "") cfg.config
++ optional (cfg.extraConfig != "") cfg.extraConfig) + "\n";
};
}

View File

@@ -6,9 +6,7 @@ let
extraConfigType = with lib.types; attrsOf (either (either str int) bool);
in
{
in {
options.mbsync = {
enable = mkEnableOption "synchronization using mbsync";
@@ -62,7 +60,7 @@ in
extraConfig.channel = mkOption {
type = extraConfigType;
default = {};
default = { };
example = literalExample ''
{
MaxMessages = 10000;
@@ -76,7 +74,7 @@ in
extraConfig.local = mkOption {
type = extraConfigType;
default = {};
default = { };
description = ''
Local store extra configuration.
'';
@@ -84,7 +82,7 @@ in
extraConfig.remote = mkOption {
type = extraConfigType;
default = {};
default = { };
description = ''
Remote store extra configuration.
'';
@@ -92,7 +90,7 @@ in
extraConfig.account = mkOption {
type = extraConfigType;
default = {};
default = { };
example = literalExample ''
{
PipelineDepth = 10;

View File

@@ -4,22 +4,21 @@ with lib;
let
dag = config.lib.dag;
cfg = config.programs.mbsync;
# Accounts for which mbsync is enabled.
mbsyncAccounts =
filter (a: a.mbsync.enable) (attrValues config.accounts.email.accounts);
genTlsConfig = tls: {
SSLType =
if !tls.enable then "None"
else if tls.useStartTls then "STARTTLS"
else "IMAPS";
}
//
optionalAttrs (tls.enable && tls.certificatesFile != null) {
genTlsConfig = tls:
{
SSLType = if !tls.enable then
"None"
else if tls.useStartTls then
"STARTTLS"
else
"IMAPS";
} // optionalAttrs (tls.enable && tls.certificatesFile != null) {
CertificateFile = toString tls.certificatesFile;
};
@@ -32,79 +31,61 @@ let
genSection = header: entries:
let
escapeValue = escape [ "\"" ];
escapeValue = escape [ ''"'' ];
hasSpace = v: builtins.match ".* .*" v != null;
genValue = n: v:
if isList v
then concatMapStringsSep " " (genValue n) v
else if isBool v then (if v then "yes" else "no")
else if isInt v then toString v
else if isString v && hasSpace v then "\"${escapeValue v}\""
else if isString v then v
if isList v then
concatMapStringsSep " " (genValue n) v
else if isBool v then
(if v then "yes" else "no")
else if isInt v then
toString v
else if isString v && hasSpace v then
''"${escapeValue v}"''
else if isString v then
v
else
let prettyV = lib.generators.toPretty {} v;
in throw "mbsync: unexpected value for option ${n}: '${prettyV}'";
in
''
${header}
${concatStringsSep "\n"
(mapAttrsToList (n: v: "${n} ${genValue n v}") entries)}
'';
let prettyV = lib.generators.toPretty { } v;
in throw "mbsync: unexpected value for option ${n}: '${prettyV}'";
in ''
${header}
${concatStringsSep "\n"
(mapAttrsToList (n: v: "${n} ${genValue n v}") entries)}
'';
genAccountConfig = account: with account;
genSection "IMAPAccount ${name}" (
{
Host = imap.host;
User = userName;
PassCmd = toString passwordCommand;
}
// genTlsConfig imap.tls
// optionalAttrs (imap.port != null) { Port = toString imap.port; }
// mbsync.extraConfig.account
)
+ "\n"
+ genSection "IMAPStore ${name}-remote" (
{
Account = name;
}
// mbsync.extraConfig.remote
)
+ "\n"
+ genSection "MaildirStore ${name}-local" (
{
Path = "${maildir.absPath}/";
Inbox = "${maildir.absPath}/${folders.inbox}";
SubFolders = "Verbatim";
}
// optionalAttrs (mbsync.flatten != null) { Flatten = mbsync.flatten; }
// mbsync.extraConfig.local
)
+ "\n"
+ genSection "Channel ${name}" (
{
Master = ":${name}-remote:";
Slave = ":${name}-local:";
Patterns = mbsync.patterns;
Create = masterSlaveMapping.${mbsync.create};
Remove = masterSlaveMapping.${mbsync.remove};
Expunge = masterSlaveMapping.${mbsync.expunge};
SyncState = "*";
}
// mbsync.extraConfig.channel
)
+ "\n";
genAccountConfig = account:
with account;
genSection "IMAPAccount ${name}" ({
Host = imap.host;
User = userName;
PassCmd = toString passwordCommand;
} // genTlsConfig imap.tls
// optionalAttrs (imap.port != null) { Port = toString imap.port; }
// mbsync.extraConfig.account) + "\n"
+ genSection "IMAPStore ${name}-remote"
({ Account = name; } // mbsync.extraConfig.remote) + "\n"
+ genSection "MaildirStore ${name}-local" ({
Path = "${maildir.absPath}/";
Inbox = "${maildir.absPath}/${folders.inbox}";
SubFolders = "Verbatim";
} // optionalAttrs (mbsync.flatten != null) { Flatten = mbsync.flatten; }
// mbsync.extraConfig.local) + "\n" + genSection "Channel ${name}" ({
Master = ":${name}-remote:";
Slave = ":${name}-local:";
Patterns = mbsync.patterns;
Create = masterSlaveMapping.${mbsync.create};
Remove = masterSlaveMapping.${mbsync.remove};
Expunge = masterSlaveMapping.${mbsync.expunge};
SyncState = "*";
} // mbsync.extraConfig.channel) + "\n";
genGroupConfig = name: channels:
let
genGroupChannel = n: boxes: "Channel ${n}:${concatStringsSep "," boxes}";
in
concatStringsSep "\n" (
[ "Group ${name}" ] ++ mapAttrsToList genGroupChannel channels
);
in concatStringsSep "\n"
([ "Group ${name}" ] ++ mapAttrsToList genGroupChannel channels);
in
{
in {
options = {
programs.mbsync = {
enable = mkEnableOption "mbsync IMAP4 and Maildir mailbox synchronizer";
@@ -119,7 +100,7 @@ in
groups = mkOption {
type = types.attrsOf (types.attrsOf (types.listOf types.str));
default = {};
default = { };
example = literalExample ''
{
inboxes = {
@@ -144,45 +125,40 @@ in
};
config = mkIf cfg.enable {
assertions =
let
checkAccounts = pred: msg:
let
badAccounts = filter pred mbsyncAccounts;
in {
assertion = badAccounts == [];
message = "mbsync: ${msg} for accounts: "
+ concatMapStringsSep ", " (a: a.name) badAccounts;
};
in
[
(checkAccounts (a: a.maildir == null) "Missing maildir configuration")
(checkAccounts (a: a.imap == null) "Missing IMAP configuration")
(checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
(checkAccounts (a: a.userName == null) "Missing username")
];
assertions = let
checkAccounts = pred: msg:
let badAccounts = filter pred mbsyncAccounts;
in {
assertion = badAccounts == [ ];
message = "mbsync: ${msg} for accounts: "
+ concatMapStringsSep ", " (a: a.name) badAccounts;
};
in [
(checkAccounts (a: a.maildir == null) "Missing maildir configuration")
(checkAccounts (a: a.imap == null) "Missing IMAP configuration")
(checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
(checkAccounts (a: a.userName == null) "Missing username")
];
home.packages = [ cfg.package ];
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
home.file.".mbsyncrc".text =
let
accountsConfig = map genAccountConfig mbsyncAccounts;
groupsConfig = mapAttrsToList genGroupConfig cfg.groups;
in
concatStringsSep "\n" (
[ "# Generated by Home Manager.\n" ]
++ optional (cfg.extraConfig != "") cfg.extraConfig
++ accountsConfig
++ groupsConfig
) + "\n";
home.file.".mbsyncrc".text = let
accountsConfig = map genAccountConfig mbsyncAccounts;
groupsConfig = mapAttrsToList genGroupConfig cfg.groups;
in concatStringsSep "\n" ([''
# Generated by Home Manager.
''] ++ optional (cfg.extraConfig != "") cfg.extraConfig ++ accountsConfig
++ groupsConfig) + "\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 =
hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
}
'';
};
};
}

View File

@@ -6,9 +6,7 @@ let
cfg = config.programs.mercurial;
in
{
in {
options = {
programs.mercurial = {
@@ -33,13 +31,13 @@ in
aliases = mkOption {
type = types.attrs;
default = {};
default = { };
description = "Mercurial aliases to define.";
};
extraConfig = mkOption {
type = types.either types.attrs types.lines;
default = {};
default = { };
description = "Additional configuration to add.";
};
@@ -50,53 +48,53 @@ in
ignores = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "*~" "*.swp" ];
description = "List of globs for files to be globally ignored.";
};
ignoresRegexp = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "^.*~$" "^.*\\.swp$" ];
description =
"List of regular expressions for files to be globally ignored.";
"List of regular expressions for files to be globally ignored.";
};
};
};
config = mkIf cfg.enable (
mkMerge [
{
home.packages = [ cfg.package ];
config = mkIf cfg.enable (mkMerge [
{
home.packages = [ cfg.package ];
programs.mercurial.iniContent.ui = {
username = cfg.userName + " <" + cfg.userEmail + ">";
};
programs.mercurial.iniContent.ui = {
username = cfg.userName + " <" + cfg.userEmail + ">";
};
xdg.configFile."hg/hgrc".text = generators.toINI {} cfg.iniContent;
}
xdg.configFile."hg/hgrc".text = generators.toINI { } cfg.iniContent;
}
(mkIf (cfg.ignores != [] || cfg.ignoresRegexp != []) {
programs.mercurial.iniContent.ui.ignore =
"${config.xdg.configHome}/hg/hgignore_global";
(mkIf (cfg.ignores != [ ] || cfg.ignoresRegexp != [ ]) {
programs.mercurial.iniContent.ui.ignore =
"${config.xdg.configHome}/hg/hgignore_global";
xdg.configFile."hg/hgignore_global".text =
"syntax: glob\n" + concatStringsSep "\n" cfg.ignores + "\n" +
"syntax: regexp\n" + concatStringsSep "\n" cfg.ignoresRegexp + "\n";
})
xdg.configFile."hg/hgignore_global".text = ''
syntax: glob
'' + concatStringsSep "\n" cfg.ignores + "\n" + ''
syntax: regexp
'' + concatStringsSep "\n" cfg.ignoresRegexp + "\n";
})
(mkIf (cfg.aliases != {}) {
programs.mercurial.iniContent.alias = cfg.aliases;
})
(mkIf (cfg.aliases != { }) {
programs.mercurial.iniContent.alias = cfg.aliases;
})
(mkIf (lib.isAttrs cfg.extraConfig) {
programs.mercurial.iniContent = cfg.extraConfig;
})
(mkIf (lib.isAttrs cfg.extraConfig) {
programs.mercurial.iniContent = cfg.extraConfig;
})
(mkIf (lib.isString cfg.extraConfig) {
xdg.configFile."hg/hgrc".text = cfg.extraConfig;
})
]
);
(mkIf (lib.isString cfg.extraConfig) {
xdg.configFile."hg/hgrc".text = cfg.extraConfig;
})
]);
}

View File

@@ -23,31 +23,21 @@ let
}.${typeOf option};
renderOptions = options:
concatStringsSep "\n"
(mapAttrsToList
(name: value:
let
rendered = renderOption value;
length = toString (stringLength rendered);
in
"${name}=%${length}%${rendered}")
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);
concatStringsSep "\n" (mapAttrsToList (name: value: ''
[${name}]
${renderOptions value}
'') profiles);
renderBindings = bindings:
concatStringsSep "\n"
(mapAttrsToList
(name: value:
"${name} ${value}")
bindings);
(mapAttrsToList (name: value: "${name} ${value}") bindings);
in {
options = {
@@ -55,8 +45,8 @@ in {
enable = mkEnableOption "mpv";
scripts = mkOption {
type = types.listOf types.package;
default = [];
type = with types; listOf (either package str);
default = [ ];
example = literalExample "[ pkgs.mpvScripts.mpris ]";
description = ''
List of scripts to use with mpv.
@@ -74,7 +64,7 @@ in {
for the full list of options.
'';
type = mpvOptions;
default = {};
default = { };
example = literalExample ''
{
profile = "gpu-hq";
@@ -92,7 +82,7 @@ in {
<option>programs.mpv.config</option> for more information.
'';
type = mpvProfiles;
default = {};
default = { };
example = literalExample ''
{
fast = {
@@ -117,7 +107,7 @@ in {
for the full list of options.
'';
type = mpvBindings;
default = {};
default = { };
example = literalExample ''
{
WHEEL_UP = "seek 10";
@@ -131,19 +121,20 @@ in {
config = mkIf cfg.enable (mkMerge [
{
home.packages = [(
if cfg.scripts == []
then pkgs.mpv
else pkgs.mpv-with-scripts.override { scripts = cfg.scripts; }
)];
home.packages = [
(if cfg.scripts == [ ] then
pkgs.mpv
else
pkgs.mpv-with-scripts.override { scripts = cfg.scripts; })
];
}
(mkIf (cfg.config != {} || cfg.profiles != {}) {
(mkIf (cfg.config != { } || cfg.profiles != { }) {
xdg.configFile."mpv/mpv.conf".text = ''
${optionalString (cfg.config != {}) (renderOptions cfg.config)}
${optionalString (cfg.profiles != {}) (renderProfiles cfg.profiles)}
${optionalString (cfg.config != { }) (renderOptions cfg.config)}
${optionalString (cfg.profiles != { }) (renderProfiles cfg.profiles)}
'';
})
(mkIf (cfg.bindings != {}) {
(mkIf (cfg.bindings != { }) {
xdg.configFile."mpv/input.conf".text = renderBindings cfg.bindings;
})
]);

View File

@@ -23,7 +23,8 @@ with lib;
};
tls.fingerprint = mkOption {
type = types.nullOr (types.strMatching "([[:alnum:]]{2}\:)+[[:alnum:]]{2}");
type =
types.nullOr (types.strMatching "([[:alnum:]]{2}:)+[[:alnum:]]{2}");
default = null;
example = "my:SH:a2:56:ha:sh";
description = ''

View File

@@ -6,38 +6,32 @@ let
cfg = config.programs.msmtp;
msmtpAccounts = filter (a: a.msmtp.enable)
(attrValues config.accounts.email.accounts);
msmtpAccounts =
filter (a: a.msmtp.enable) (attrValues config.accounts.email.accounts);
onOff = p: if p then "on" else "off";
accountStr = account: with account;
concatStringsSep "\n" (
[ "account ${name}" ]
++ mapAttrsToList (n: v: n + " " + v) (
{
host = smtp.host;
from = address;
auth = "on";
user = userName;
tls = onOff smtp.tls.enable;
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;
}
accountStr = account:
with account;
concatStringsSep "\n" ([ "account ${name}" ]
++ mapAttrsToList (n: v: n + " " + v) ({
host = smtp.host;
from = address;
auth = "on";
user = userName;
tls = onOff smtp.tls.enable;
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; }
// optionalAttrs (passwordCommand != null) {
# msmtp requires the password to finish with a newline.
passwordeval = ''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"'';
}
// msmtp.extraConfig
)
++ optional primary "\naccount default : ${name}"
);
passwordeval =
''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"'';
} // msmtp.extraConfig) ++ optional primary ''
account default : ${name}'');
configFile = mailAccounts: ''
# Generated by Home Manager.
@@ -47,9 +41,7 @@ let
${concatStringsSep "\n\n" (map accountStr mailAccounts)}
'';
in
{
in {
options = {
programs.msmtp = {
@@ -71,7 +63,7 @@ in
xdg.configFile."msmtp/config".text = configFile msmtpAccounts;
home.sessionVariables = {
home.sessionVariables = {
MSMTP_QUEUE = "${config.xdg.dataHome}/msmtp/queue";
MSMTP_LOG = "${config.xdg.dataHome}/msmtp/queue.log";
};

View File

@@ -0,0 +1,36 @@
{ config, lib, ... }:
with lib;
{
options.neomutt = {
enable = mkEnableOption "NeoMutt";
sendMailCommand = mkOption {
type = types.nullOr types.str;
default = if config.msmtp.enable then
"msmtpq --read-envelope-from --read-recipients"
else
null;
defaultText = literalExample ''
if config.msmtp.enable then
"msmtpq --read-envelope-from --read-recipients"
else
null
'';
example = "msmtpq --read-envelope-from --read-recipients";
description = ''
Command to send a mail. If not set, neomutt will be in charge of sending mails.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
example = "color status cyan default";
description = ''
Extra lines to add to the folder hook for this account.
'';
};
};
}

View File

@@ -0,0 +1,306 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.neomutt;
neomuttAccounts =
filter (a: a.neomutt.enable) (attrValues config.accounts.email.accounts);
sidebarModule = types.submodule {
options = {
enable = mkEnableOption "sidebar support";
width = mkOption {
type = types.int;
default = 22;
description = "Width of the sidebar";
};
shortPath = mkOption {
type = types.bool;
default = true;
description = ''
By default sidebar shows the full path of the mailbox, but
with this enabled only the relative name is shown.
'';
};
format = mkOption {
type = types.str;
default = "%B%?F? [%F]?%* %?N?%N/?%S";
description = ''
Sidebar format. Check neomutt documentation for details.
'';
};
};
};
sortOptions = [
"date"
"date-received"
"from"
"mailbox-order"
"score"
"size"
"spam"
"subject"
"threads"
"to"
];
bindModule = types.submodule {
options = {
map = mkOption {
type = types.enum [
"alias"
"attach"
"browser"
"compose"
"editor"
"generic"
"index"
"mix"
"pager"
"pgp"
"postpone"
"query"
"smime"
];
default = "index";
description = "Select the menu to bind the command to.";
};
key = mkOption {
type = types.str;
example = "<left>";
description = "The key to bind.";
};
action = mkOption {
type = types.str;
example = "<enter-command>toggle sidebar_visible<enter><refresh>";
description = "Specify the action to take.";
};
};
};
yesno = x: if x then "yes" else "no";
setOption = n: v: if v == null then "unset ${n}" else "set ${n}=${v}";
escape = replaceStrings [ "%" ] [ "%25" ];
accountFilename = account: config.xdg.configHome + "/neomutt/" + account.name;
genCommonFolderHooks = account:
with account; {
from = "'${address}'";
realname = "'${realName}'";
spoolfile = "'+${folders.inbox}'";
record = if folders.sent == null then null else "'+${folders.sent}'";
postponed = "'+${folders.drafts}'";
trash = "'+${folders.trash}'";
};
mtaSection = account:
with account;
let passCmd = concatStringsSep " " passwordCommand;
in if neomutt.sendMailCommand != null then {
sendmail = "'${neomutt.sendMailCommand}'";
} else
let
smtpProto = if smtp.tls.enable then "smtps" else "smtp";
smtpBaseUrl = "${smtpProto}://${escape userName}@${smtp.host}";
in {
smtp_url = "'${smtpBaseUrl}'";
smtp_pass = "'`${passCmd}`'";
};
genMaildirAccountConfig = account:
with account;
let
folderHook = mapAttrsToList setOption (genCommonFolderHooks account // {
folder = "'${account.maildir.absPath}'";
}) ++ optional (neomutt.extraConfig != "") neomutt.extraConfig;
in ''
${concatStringsSep "\n" folderHook}
'';
registerAccount = account:
with account; ''
# register account ${name}
mailboxes "${account.maildir.absPath}/${folders.inbox}"
folder-hook ${account.maildir.absPath}/ " \
source ${accountFilename account} "
'';
mraSection = account:
with account;
if account.maildir != null then
genMaildirAccountConfig account
else
throw "Only maildir is supported at the moment";
optionsStr = attrs: concatStringsSep "\n" (mapAttrsToList setOption attrs);
sidebarSection = ''
# Sidebar
set sidebar_visible = yes
set sidebar_short_path = ${yesno cfg.sidebar.shortPath}
set sidebar_width = ${toString cfg.sidebar.width}
set sidebar_format = '${cfg.sidebar.format}'
'';
bindSection = concatMapStringsSep "\n"
(bind: ''bind ${bind.map} ${bind.key} "${bind.action}"'') cfg.binds;
macroSection = concatMapStringsSep "\n"
(bind: ''macro ${bind.map} ${bind.key} "${bind.action}"'') cfg.macros;
mailCheckSection = ''
set mail_check_stats
set mail_check_stats_interval = ${toString cfg.checkStatsInterval}
'';
notmuchSection = account:
with account; ''
# notmuch section
set nm_default_uri = "notmuch://${config.accounts.email.maildirBasePath}"
virtual-mailboxes "My INBOX" "notmuch://?query=tag:inbox"
'';
accountStr = account:
with account;
''
# Generated by Home Manager.
set ssl_force_tls = yes
set certificate_file=${config.accounts.email.certificatesFile}
# GPG section
set crypt_use_gpgme = yes
set crypt_autosign = ${yesno (gpg.signByDefault or false)}
set pgp_use_gpg_agent = yes
set mbox_type = ${if maildir != null then "Maildir" else "mbox"}
set sort = "${cfg.sort}"
# MTA section
${optionsStr (mtaSection account)}
${optionalString (cfg.checkStatsInterval != null) mailCheckSection}
${optionalString cfg.sidebar.enable sidebarSection}
# MRA section
${mraSection account}
# Extra configuration
${account.neomutt.extraConfig}
'' + optionalString (account.signature.showSignature != "none") ''
set signature = ${pkgs.writeText "signature.txt" account.signature.text}
'' + optionalString account.notmuch.enable (notmuchSection account);
in {
options = {
programs.neomutt = {
enable = mkEnableOption "the NeoMutt mail client";
sidebar = mkOption {
type = sidebarModule;
default = { };
description = "Options related to the sidebar.";
};
binds = mkOption {
type = types.listOf bindModule;
default = [ ];
description = "List of keybindings.";
};
macros = mkOption {
type = types.listOf bindModule;
default = [ ];
description = "List of macros.";
};
sort = mkOption {
# allow users to choose any option from sortOptions, or any option prefixed with "reverse-"
type = types.enum
(sortOptions ++ (map (option: "reverse-" + option) sortOptions));
default = "threads";
description = "Sorting method on messages.";
};
vimKeys = mkOption {
type = types.bool;
default = false;
description = "Enable vim-like bindings.";
};
checkStatsInterval = mkOption {
type = types.nullOr types.int;
default = null;
example = 60;
description = "Enable and set the interval of automatic mail check.";
};
editor = mkOption {
type = types.str;
default = "$EDITOR";
description = "Select the editor used for writing mail.";
};
settings = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Extra configuration appended to the end.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra configuration appended to the end.";
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.neomutt ];
home.file = let
rcFile = account: {
"${accountFilename account}".text = accountStr account;
};
in foldl' (a: b: a // b) { } (map rcFile neomuttAccounts);
xdg.configFile."neomutt/neomuttrc" = mkIf (neomuttAccounts != [ ]) {
text = let primary = filter (a: a.primary) neomuttAccounts;
in ''
# Generated by Home Manager.
set header_cache = "${config.xdg.cacheHome}/neomutt/headers/"
set message_cachedir = "${config.xdg.cacheHome}/neomutt/messages/"
set editor = "${cfg.editor}"
set implicit_autoview = yes
alternative_order text/enriched text/plain text
set delete = yes
# Binds
${bindSection}
# Macros
${macroSection}
${optionalString cfg.vimKeys
"source ${pkgs.neomutt}/share/doc/neomutt/vim-keys/vim-keys.rc"}
# Extra configuration
${optionsStr cfg.settings}
${cfg.extraConfig}
'' + concatMapStringsSep "\n" registerAccount neomuttAccounts +
# source primary account
"source ${accountFilename (builtins.head primary)}";
};
};
}

View File

@@ -43,7 +43,7 @@ in
type = types.bool;
default = false;
description = ''
Symlink `vi` to `nvim` binary.
Symlink <command>vi</command> to <command>nvim</command> binary.
'';
};
@@ -51,7 +51,15 @@ in
type = types.bool;
default = false;
description = ''
Symlink `vim` to `nvim` binary.
Symlink <command>vim</command> to <command>nvim</command> binary.
'';
};
vimdiffAlias = mkOption {
type = types.bool;
default = false;
description = ''
Alias <command>vimdiff</command> to <command>nvim -d</command>.
'';
};
@@ -148,8 +156,8 @@ in
</para><para>
This option is deprecated. Please use the options <varname>extraConfig</varname>
and <varname>plugins</varname> which are mutually exclusive with this option.
This option is mutually exclusive with <varname>extraConfig</varname>
and <varname>plugins</varname>.
'';
};
@@ -193,11 +201,6 @@ in
}
];
warnings = optional (cfg.configure != {}) ''
The programs.neovim.configure option is deprecated. Please use
extraConfig and package option.
'';
home.packages = [ cfg.finalPackage ];
programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package {
@@ -208,5 +211,9 @@ in
configure = cfg.configure // moduleConfigure;
};
programs.bash.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
programs.fish.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
programs.zsh.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; };
};
}

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