Compare commits

...

379 Commits

Author SHA1 Message Date
Robert Helgesson
ef64bc598f redshift: add assertion on latitude and longitude
These two options must be set if the provider is set to "manual".

Closes #841

(cherry picked from commit 8bddc1adab)
2019-10-02 23:18:51 +02:00
Robert Helgesson
8def383511 mpd: allow path literal values in options
This allows specifying, for example, the music directory using path
literals without causing the directory to be copied to the Nix store.

Suggested-by: Silvan Mosberger <infinisil@icloud.com>
(cherry picked from commit b0544c8cde)
2019-09-17 22:55:16 +02:00
Robert Helgesson
c13c1b33d9 xsession: remove bashisms in start scripts
Fixes #836

(cherry picked from commit 0dfa1eef25)
2019-09-17 22:54:56 +02:00
Robert Helgesson
d74320012e polybar: restart service on failure
(cherry picked from commit 698d0f0a44)
2019-09-17 22:53:09 +02:00
Alex Rice
aa2f70def7 rofi: string -> str
(cherry picked from commit ec0459e139)
2019-09-03 15:39:48 +02:00
Robert Helgesson
76ba4bedff systemd: fix unit examples
Closes #823

(cherry picked from commit 875eea1330)
2019-08-29 19:22:06 +02:00
Robert Helgesson
46eaee3262 Replace use of stdenv.shell by runtimeShell
(cherry picked from commit eb1b86a5ec)
2019-08-29 19:20:21 +02:00
Robert Helgesson
f8187816a4 nixpkgs: improve description formatting slightly
(cherry picked from commit 57925c50bf)
2019-08-29 19:19:31 +02:00
Robert Helgesson
f9ac2671bb Use types.port where applicable
This changes the type of all options that specify ports to
`types.port`. This type restricts values to between 0 and 65535.

(cherry picked from commit ed4f66185f)
2019-08-29 19:19:16 +02:00
Robert Helgesson
2307cb280a nix-darwin: pass on warnings to the system configuration
(cherry picked from commit c2429ca0cf)
2019-08-29 19:17:59 +02:00
Robert Helgesson
14c5a22cfb nixos: pass on warnings to the system configuration
Fixes #804

(cherry picked from commit 7834ffbbf1)
2019-08-29 19:17:52 +02:00
Robert Helgesson
0f85326dee emacs: document how to list available extra packages
(cherry picked from commit 5eed33ef08)
2019-08-29 19:17:10 +02:00
pacien
35d31c390d alot: fix account extraConfig section
(cherry picked from commit 31ae1bc2ff)
2019-08-29 19:17:00 +02:00
Robert Helgesson
176e82ee1c install: restrict to nix-shell
This commit adds a "build" command to the install derivation that
tells the user that `nix-shell` should be used.

A derivation attribute `shellHookOnly = true` is also added with the
intent to indicate that the shell hook is the entire point of the
derivation.

(cherry picked from commit fcdab6a62d)
2019-08-29 19:16:25 +02:00
Tobias Happ
634a909ddc xsession: set RemainAfterExit for setxkbmap.service
(cherry picked from commit 2eae9daae7)
2019-08-29 19:16:14 +02:00
Robert Helgesson
33c6230dac gitlab-ci: only run a single test
Unfortunately the full test suite seems to run out of memory on the
GitLab CI runner.

(cherry picked from commit 8830b8d082)
2019-08-19 16:37:53 +02:00
Robert Helgesson
1d8b6e7d9e gitlab-ci: trigger NUR update
This will trigger a CI job at

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

that will update Home Manager in NUR.

(cherry picked from commit 55c962fda2)
2019-08-19 16:37:52 +02:00
Robert Helgesson
cf5e08cfb8 gitlab-ci: add test stage
(cherry picked from commit eb7f39f0aa)
2019-08-19 16:37:50 +02:00
Nikita Uvarov
45a73067ac zsh: fix completion when oh-my-zsh is enabled
enableCompletion option not only calls compinit but also adds
nix-zsh-completions package to home.packages which should still happen
even if oh-my-zsh is enabled.

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

Fixes #771.

(cherry picked from commit 7310cfc557)
2019-08-14 17:09:39 +02:00
Nikita Uvarov
ef906c5a92 zsh: create oh-my-zsh cache directory
Fixes #761.

(cherry picked from commit 42ad0effdd)
2019-08-14 17:09:39 +02:00
paumr
bb18d4c746 mbsync: fix use of certificatesFile
The `tls.certificatesFile` option may be set to a path but the
`CertificateFile` attribute should be a string.

(cherry picked from commit 3743e8995a)
2019-08-14 17:09:20 +02:00
Tobias Happ
6d5246f49f systemd-activate.rb: add start/stop/restart sockets
(cherry picked from commit 4c9b40ca0e)
2019-08-14 17:09:20 +02:00
Olli Helenius
5d054abe6a dconf: assume empty list value is a list of strings
Fixes #769.

(cherry picked from commit caf3349f01)
2019-08-14 17:09:14 +02:00
Brian Hicks
a85f22164d nix-darwin: add docs
(cherry picked from commit 6239ce20af)
2019-07-28 15:03:42 +02:00
Robert Helgesson
dd6d8e278b vscode: fix configuration path for Darwin
Fixes #737

(cherry picked from commit 056443ccbd)
2019-07-28 15:03:22 +02:00
Shanon McQuay
9291923e84 skim: correctly name default options
skim uses SKIM_DEFAULT_OPTIONS rather than SKIM_DEFAULT_OPTS.

(cherry picked from commit 734128930f)
2019-07-28 15:03:13 +02:00
Robert Helgesson
b8bbd242f8 mbsync: use full path to mu in example
(cherry picked from commit ca4f22be85)
2019-07-28 15:02:55 +02:00
Robert Helgesson
413ac52bed mbsync: put extra config at the beginning
If it is at the end it will just end up applying to the last defined
section.

Fixes #748

(cherry picked from commit c3520bfa52)
2019-07-05 22:19:57 +02:00
Robert Helgesson
4f13f06b01 network-manager-applet: fix indentation
(cherry picked from commit 5b50eb18fc)
2019-06-09 22:49:19 +02:00
Florian Klink
d714740961 screen-locker: fix systemd unit
In particular, don't add trailing backslashes introduced by
`xautolockExtraOptions`. Systemd's unit file parser seems to have
gotten a bit stricter and with systemd 242, the trailing backslash
caused the next non-empty line to be ignored.

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

Simplify and fix this by using `concatStringsSep` to build a single
`ExecStart` line.

(cherry picked from commit 8991fe2e90)
2019-06-09 22:48:06 +02:00
Robert Helgesson
81d600d948 vscode: add example for extensions option
(cherry picked from commit e1535d2bd8)
2019-06-09 22:47:27 +02:00
Jaka Hudoklin
3daa1da497 nixos: use usercfg.home.username for username
Use `usercfg.home.username` for username instead of attribute name,
as this way we can change username regardless of the name of the attribute.

(cherry picked from commit 2e13c3cdfd)
2019-06-09 22:46:11 +02:00
Roman Volosatovs
41d2a16f99 nix-darwin: actually install packages
Also apply assertions when using the nix-darwin module.

Closes #702

(cherry picked from commit 1480a6ca14)
2019-06-09 22:46:01 +02:00
Tadeo Kondrak
24b734500f alacritty: don't create file if settings is empty
Also add a few test cases for the alacritty module.

(cherry picked from commit d2ed39f103)
2019-05-15 00:01:21 +02:00
Robert Helgesson
de9fc235d0 tests: bump nmt version
(cherry picked from commit 939274281a)
2019-05-15 00:00:35 +02:00
Robert Helgesson
14a0dce9e8 flameshot: fix service description
(cherry picked from commit f99d4ba7c4)
2019-05-01 18:24:38 +02:00
Will Dietz
ef78cae6a4 files: fix find invocation broken in c94eaa0e
Add parens to expression so the `-exec` includes files matching both.

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

    file or (link -> doexec)
      =>
    (file or link) -> doexec

(cherry picked from commit f56256f488)
2019-05-01 18:24:30 +02:00
Robert Helgesson
e3c4ec12cc home-manager: add uninstall command
(cherry picked from commit 3bb7c75db3)
2019-05-01 18:24:02 +02:00
Robert Helgesson
f73c6ed74f files: replace unnecessary use of xargs
(cherry picked from commit c94eaa0e6c)
2019-05-01 18:24:02 +02:00
Robert Helgesson
de0dae5666 firefox: deprecate Google Talk and IcedTea options
(cherry picked from commit a16439e38e)
2019-05-01 18:24:02 +02:00
Robert Helgesson
162a65f029 Fix type of various sessionVariables options
Unfortunately, using `attrsOf` is not possible since it results in too
eager evaluation. In particular, the

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

example will cause an infinite recursion.

This commit restores the option type of

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

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

Fixes #659

(cherry picked from commit b6e613c771)
2019-05-01 18:24:02 +02:00
Robert Helgesson
ba0375bf06 docs: add systemd type change to 19.03 release notes 2019-04-23 22:02:29 +02:00
Robert Helgesson
13ad532412 xscreensaver: add option settings 2019-04-22 23:44:46 +02:00
Robert Helgesson
8ecc311bcc Update stable version to 19.03
Also prepares for 19.09.
2019-04-22 20:04:31 +02:00
hyperfekt
e3831d8ecc alacritty: add module 2019-04-22 14:43:43 +02:00
Robert Helgesson
9c0536deda emacs: prevent service restart on change
Fixes #668
2019-04-18 01:38:25 +02:00
Robert Helgesson
6b42bd7abf systemd: support X-RestartIfChanged = false
Having this in the unit file will prevent the file from being
restarted if a change is detected. This is useful if data loss may
occur if the unit is suddenly restarted. For example, restarting the
Emacs service may result in the loss of unsaved open buffers.
2019-04-18 01:38:20 +02:00
Robert Helgesson
0d246aa435 systemd: escape unit names in systemctl commands 2019-04-18 01:37:59 +02:00
Benjamin Staffin
c5f35b7ff9 dconf: allow values to be floats
Technically dconf calls these "double" but nix floats ought to work.
2019-04-17 23:04:48 +02:00
Alex Ameen
ff602cb906 manual: add option manual.json.enable
Make it possible to install a JSON file containing the available Home
Manager options.
2019-04-15 22:43:46 +02:00
Olli Helenius
1806e5511e skim: add module 2019-04-14 17:36:27 +02:00
ash lea
cb93316fed browserpass: update app id 2019-04-14 11:40:37 +02:00
Nick Hu
a6f0fa90f7 email: add facility for email aliases
Also update the notmuch and alot modules to include support for email
aliases.
2019-04-12 21:26:46 +02:00
Robert Helgesson
30a16e3a87 polybar: change restart trigger to contain a string
The systemd unit type is a bit more strict now and needs an explicit
string in this position.
2019-04-12 17:56:14 +02:00
Robert Helgesson
3db46fa9bf news: limit mpdris2 and xcape news to Linux
These modules are limited to Linux since they define systemd services.
2019-04-12 01:02:12 +02:00
Robert Helgesson
12cb82af91 systemd: make the unit option type more robust
This should allow more sensible merging behavior. In particular, with
this change it is possible to use, for example, `mkForce` for greater
control of merging.

Fixes #543
2019-04-12 01:02:12 +02:00
Nick Hu
d49b514aa6 make notmuch search.exclude_tags configurable 2019-04-11 23:28:36 +09:00
Robert Helgesson
b6e1d82685 home-environment: make home.keyboard optional
When set to `null` then the `xsession` module will not attempt to
manage the keyboard settings.
2019-04-11 01:09:27 +02:00
Nick Hu
6cd5c8fca5 alot: fix address book completion regex 2019-04-10 23:55:07 +02:00
Robert Helgesson
67aee78fdf home-manager: remove unnecessary error message
An error message about the erroneous option is already printed by
`getopts` so there is no need to print it again.
2019-04-10 01:31:22 +02:00
Nick Hu
c48db4fbba xcape: add service 2019-04-09 22:15:48 +02:00
Robert Helgesson
f8b03f5750 modules: register the base modules path
This is needed, for example, to support relative paths when disabling
modules.
2019-04-07 13:26:38 +02:00
arcnmx
2c07829be2 home-manager: use callPackage where appropriate 2019-04-06 18:48:29 +02:00
Wael M. Nasreddine
652c694244 programs.tmux: implement secureSocket 2019-04-04 17:14:29 -07:00
Olli Helenius
995fa3af36 qt: add option platformTheme
This deprecates `useGtkTheme=true` with the intention of replacing it
with the `platformTheme` selection.
2019-04-03 23:55:36 +02:00
Robert Helgesson
4323b35198 pam: use attrsOf instead of attrs 2019-04-03 00:09:56 +02:00
Robert Helgesson
fd50f5465f zsh: use attrsOf instead of attrs 2019-04-03 00:09:55 +02:00
Robert Helgesson
13d2c470be home-environment: use attrsOf instead of attrs 2019-04-03 00:09:55 +02:00
Robert Helgesson
b690a8be2f bash: use attrsOf instead of attrs 2019-04-03 00:09:55 +02:00
Robert Helgesson
e85804efa2 feh: use attrsOf instead of attrs 2019-04-03 00:09:55 +02:00
Robert Helgesson
e26ad2026c gtk: use attrsOf instead of attrs 2019-04-03 00:09:46 +02:00
Olli Helenius
03162970cd gnome-terminal: add cursor and highlight color settings 2019-03-31 14:24:31 +02:00
Tadeo Kondrak
bc2b7d4f09 qt: use xdg.configHome instead of hard-coding 2019-03-27 22:40:12 +01:00
Robert Helgesson
f77d6b7a2d taffybar: restart the service on failure 2019-03-26 18:05:44 +01:00
Olli Helenius
1fdb16866b systemd: add support for session variables
Via environment.d(5).
2019-03-24 17:23:50 +01:00
Robert Helgesson
6ebf14143a systemd: add some basic tests 2019-03-24 15:52:30 +01:00
Robert Helgesson
cf5dac9563 random-background: minor documentation improvements 2019-03-24 15:29:08 +01:00
Robert Helgesson
2e1c825b90 readme: expand contact section slightly
In particular, mention that the channel is hosted by freenode and the
channel logs are hosted by samueldr.
2019-03-23 23:20:22 +01:00
Robert Helgesson
a974ce6257 readme: add contact section with the IRC channel 2019-03-22 19:10:43 +01:00
Robert Helgesson
5d81cb6ac7 manual: use writeShellScriptBin 2019-03-21 00:39:54 +01:00
Robert Helgesson
41356ac267 polybar: use writeShellScriptBin 2019-03-21 00:39:36 +01:00
Robert Helgesson
86af599a18 firefox: make the extensions option visible
Also change the example to use the firefox-addons available on NUR.
2019-03-20 23:41:02 +01:00
Mario Rodas
95e36dfe74 lsd: add module 2019-03-20 00:07:49 +01:00
Mario Rodas
24b5f62090 bat: add module 2019-03-19 23:58:12 +01:00
Robert Helgesson
989e636d98 ssh: add some basic tests 2019-03-19 23:00:17 +01:00
Robert Helgesson
eec78fbd1e ssh: support multiple identity files in a match block
Fixes #625
2019-03-19 22:35:13 +01:00
Robert Helgesson
70d4cf2cd9 Remove some use of mkDerivation
Instead use `runCommand`, which by default uses `stdenvNoCC` resulting
in a reduced dependency footprint.

Fixes #612
2019-03-18 23:09:54 +01:00
arcnmx
52692e299d git: make userName and userEmail options optional 2019-03-17 20:46:00 +01:00
Robert Helgesson
fd2bc150d8 faq: add entry about missing ca.desrt.dconf 2019-03-17 15:30:59 +01:00
Robert Helgesson
267afa5a3b firefox: add support for add-on packages
Since no official source of packages exist the option is hidden for
now. For adventurous people there is an overlay of a few selected
add-ons available at

    https://rycee.gitlab.io/nixpkgs-firefox-addons/overlay.tar.gz

This overlay is automatically built daily using the REST API available
on https://addons.mozilla.org/.
2019-03-11 00:55:32 +01:00
Wael M. Nasreddine
7ec153889c nix-darwin: login as the user when activating 2019-03-10 02:10:15 +01:00
Wael M. Nasreddine
efc795920b nix-darwin: support package install through user packages 2019-03-10 02:09:00 +01:00
Wael M. Nasreddine
d3fd287efb nix-darwin: activate home-manager through postActivation 2019-03-10 02:03:26 +01:00
Robert Prije
0fa19ed555 gnome-terminal: add support for light/dark theme variants 2019-03-10 01:59:00 +01:00
Robert Helgesson
52fdf5b7ec docs: add NixOS module installation instructions 2019-03-06 19:20:42 +01:00
Robert Helgesson
a09196c4ae docs: add language attribute to program listings 2019-03-06 18:52:54 +01:00
Robert Helgesson
1d8997633c docs: use <screen> for terminal interaction 2019-03-06 18:52:54 +01:00
Maximilian Bosch
0898b6b482 nixos module: evaluate assertions from Home Manager modules 2019-03-06 18:37:37 +01:00
Olli Helenius
848b8b983e pam: enclose session variable values in quotes 2019-03-06 18:00:51 +01:00
Maximilian Bosch
465d08d99f programs/zsh: properly escape shell aliases
Otherwise all aliases break that use single quotes inside.

Already fixed in the nixpkgs module in 1e211a70cbdaf230a18ea4cb67a959039d5c2ddb.
2019-02-28 14:10:14 +01:00
Peter Jones
f07510e2b6 mpdris2: add module 2019-02-24 01:32:34 +01:00
Robert Helgesson
b8b391ad18 tests: remove tests attribute from root default.nix
Having it there prevented, e.g., `nix-env -qaP` from working in some
cases.

Fixes #509
2019-02-23 22:32:44 +01:00
Matthieu Coudron
81dae2f88e alot: support contact completion
Make choice of contact completion easier.
2019-02-20 00:55:39 +01:00
Douglas Wilson
74811679b7 systemd: sanitize unit derivation names
To allow a few special characters such as "@".

This is taken from

    c414e5bd08/nixos/modules/system/boot/systemd-lib.nix (L14)
2019-02-19 23:43:47 +01:00
Robert Helgesson
93f5fcae1e msmtp: use <parameter> for CLI options in description 2019-02-17 23:25:42 +01:00
Robert Helgesson
92d4e3e75a autorandr: remove unnecessary method attribute
I mistakenly added this before noticing that it was already defaulted
to "factory". Sorry!
2019-02-17 23:06:39 +01:00
Terje Larsen
03f1aea069 autorandr: add support for xrandr scale and dpi 2019-02-17 22:56:01 +01:00
Mario Rodas
6da88339f5 git: allow contents in git.includes 2019-02-17 22:28:15 +01:00
Robert Helgesson
e0e8d5061d keychain: add news entry 2019-02-17 22:12:25 +01:00
Mario Rodas
62e73b17d2 keychain: add module 2019-02-17 22:07:24 +01:00
Robert Helgesson
799a90ecfa fontconfig: make fonts accessible when in NixOS module 2019-02-16 21:42:47 +01:00
Robert Helgesson
ef168979bf nixos module: support NixOS user packages install
When using the NixOS module we cannot guarantee that the Nix store
will be writable during startup. Installing the user packages through
`nix-env -i` will fail in these cases.

This commit adds a NixOS option `home-manager.useUserPackages` that,
when enabled, installs user packages through the NixOS

    users.users.<name?>.packages

option.

Note, when submodule support and external package install is enabled
then the installed packages are not available in `~/.nix-profile`. We
therefore set `home.profileDirectory` directly to the HM profile
packages.
2019-02-16 21:42:47 +01:00
Wael M. Nasreddine
2093cf425f tmux: general improvements and added options
See #575 for discussion.
2019-02-13 22:14:30 +01:00
Olli Helenius
a3462daeb1 msmtp: use XDG config directory 2019-02-11 01:06:28 +01:00
Robert Helgesson
a334a941c4 tests: bump to latest nmt version 2019-02-10 12:09:47 +01:00
Robert Helgesson
1cdb8abf30 git: add basic support for LFS
Fixes #542
2019-02-10 00:51:16 +01:00
Ingolf Wanger
fbdb5beb59 nixos: use correct username for systemd service 2019-02-10 00:46:44 +01:00
Robert Helgesson
2f372ab4d6 Clean up support code for Home Manager as a submodule
This removes the `nixosSubmodule` option in favor of a new option
`submoduleSupport.enable`. This name better indicates that the
submodule mode applies to both NixOS and nix-darwin.
2019-02-10 00:44:55 +01:00
Lorenzo Manacorda
524ce43e23 doc: add "See also" section to manpages
Pointing to each other.
2019-02-10 00:38:35 +01:00
Lorenzo Manacorda
7f8e139413 doc: remove extraneous contrib element
`contrib` is "A summary of the contributions made to a document by a
credited source", which we don't need in this case.
2019-02-10 00:38:35 +01:00
Robert Helgesson
99d79d0a80 doc: move home-manager man page to section 1
This is not really a system administration tool so 8 is unsuitable.
2019-02-10 00:38:28 +01:00
Jonas Holst Damtoft
0ca1bf3cfd emacs: add service module 2019-02-09 15:28:11 +01:00
Matthieu Coudron
c18984c452 neovim: allow to override package
If you want to run a development version for instance, it is easier to
set neovim.package rather than work around the wrapping mechanism etc.
2019-02-04 21:52:01 +01:00
Robert Helgesson
445c0b1482 git: use attrsOf instead of attrs
This makes sure that values added to

    programs.git.aliases

or

    programs.git.extraConfig

are merged as expected.

Also add a few option examples.
2019-02-01 01:12:58 +01:00
Robert Helgesson
0590c2a4f6 mbsync: add basic test of result configuration 2019-01-31 02:08:40 +01:00
Nadrieril
81ec856a0f mbsync: add some required assertions 2019-01-31 01:41:12 +01:00
Yurii Rashkovskii
2410bc603b nixpkgs: fix installation on non-x86
On non-x86 architectures (for example, aarch64) the installation of
home-manager fails indicating that it is attempting to select i686
packages for Linux and those aren't available.

Solution: make the condition for choosing these packages stricter
2019-01-29 20:15:18 +01:00
Robert Helgesson
45cadbd4f3 git: quote sendemail section header
This will allow, e.g., the character `@` in the email identity.

Also adds a test case.

Fixes #557
2019-01-29 18:28:55 +01:00
Amarandus
02a5a678f6 irssi: add module
irssi is a cli IRC client.
2019-01-29 00:53:39 +01:00
Robert Helgesson
98f534e172 flameshot: add bars to systemd After
Fixes #544
2019-01-29 00:20:16 +01:00
Matthieu Coudron
a68c8cf5f1 git: generate identities from mail accounts 2019-01-29 00:13:21 +01:00
wedens
604fc92943 polybar: add /run/wrappers/bin to PATH
Without this the network module in polybar is unable to check
connection as it invokes 'ping' command directly.
2019-01-26 14:44:57 +01:00
Robert Helgesson
008d93928f xembed-sni-proxy: add module 2019-01-26 14:20:46 +01:00
Jonas Holst Damtoft
601619660d fish: use global for abbr
Makes fish use global scope for abbreviations.
This makes it so that they don't stick across config changes.
Before, an abbreviation would still exist even if removed from the config.
2019-01-23 21:19:23 +01:00
Robert Helgesson
4aa07c3547 doc: bump copyright year to 2019 in man pages 2019-01-20 18:03:04 +01:00
Robert Helgesson
f3f7c5cc57 doc: reformat XML files 2019-01-20 18:01:22 +01:00
Robert Helgesson
c035046999 doc: add basic release notes 2019-01-20 17:56:44 +01:00
Robert Helgesson
e15cd64ac9 Update LICENSE file for 2019 2019-01-19 22:12:55 +01:00
Robert Helgesson
59a4ac71f9 i3: replace use of types.string by types.str 2019-01-19 19:02:59 +01:00
Robert Helgesson
7c04351a57 files: allow a wider range of source file names
In particular support source files whose name start with `.` or
contain characters not allowed in the nix store, such as spaces.

Also add some test cases for `home.file`.
2019-01-19 12:44:58 +01:00
Robert Helgesson
46f787950a tests: bump nmt version 2019-01-19 12:41:45 +01:00
Adam Washington
6a244b3a8d matplotlib: add module 2019-01-18 01:23:36 +01:00
John Wiegley
3cf8b9ea86 ssh: add proxyJump option 2019-01-15 22:31:08 +01:00
Nadrieril
df8a14e12a i3: add bar.extraConfig option 2019-01-15 12:31:10 +09:00
Robert Helgesson
f6ec26075d tests: simplify test names 2019-01-14 23:02:33 +01:00
Robert Helgesson
c42206db02 i3: add test of keybinding merge logic 2019-01-14 22:50:11 +01:00
Robert Helgesson
bb64012914 tests: bump nmt to latest 2019-01-14 22:48:59 +01:00
Nadrieril
d5cc53a4e1 i3: reallow using null to disable a keybinding 2019-01-14 22:21:42 +01:00
Robert Helgesson
55100918cc dunst: avoid error on missing dunst process 2019-01-14 00:04:50 +01:00
Robert Helgesson
faee571850 dunst: kill daemon on configuration change
Since Dunst is DBus activated it is OK to simply kill it since DBus
will restart it when necessary.
2019-01-13 23:48:20 +01:00
hyperfekt
6f422785c3 fish: autogenerate completions from man pages 2019-01-13 01:06:46 +01:00
David Guibert
a7affc93ba msmtp: add extraConfig account option
This patch allow to define custom msmtp options per email account. For
example: to change the "auth" method from "on" to "login", add
`msmtp.extraConfig.auth="login"`.
2019-01-13 00:25:05 +01:00
Marcial Gaißert
9052131aef programs.zsh: option localVariables
Add option "extraLocalVars" for additional local variable definitions
in .zshrc, at the top of the file.

Some zsh plugins/themes expect configuration in local variables before they
are loaded (example: https://github.com/bhilburn/powerlevel9k). Exporting
those clutters the environment and is unnecessary.
2019-01-11 10:26:13 +01:00
Marcial Gaißert
6b5e0efd1e programs.zsh: generate export statements in zsh syntax
Use the new module lib.zsh to generate export statements in zsh syntax, using
zsh arrays for lists.

Being a zsh script, this seems more intuitive for .zshrc
2019-01-11 10:26:12 +01:00
Marcial Gaißert
62eb7ebeba lib.zsh: add module
Added utilities to generate export statements and definitions for zsh scripts.

Currently, there is only lib.shell which generates export statements in bash
syntax. However, this does not allow to generate export statements for zsh
arrays (syntax: NAME=(elem1 elem2 ...) ), which would be the natural
representation of lists in the nix language.
2019-01-11 10:26:12 +01:00
Wael M. Nasreddine
c48fd9d842 autorandr: add support for xrandr transformation 2019-01-10 01:39:01 +01:00
Robert Helgesson
e150dd4a66 texlive: always require at least one extra package
Fixes #526
2019-01-09 02:09:23 +01:00
Olli Helenius
b3d73e0aff gnome-terminal: enable VTE OSC7 support for bash and zsh 2019-01-08 23:14:55 +01:00
Olli Helenius
16946a6f00 Address review comments 2019-01-03 10:51:37 +01:00
Olli Helenius
a4383075af zsh: add default keymap configuration 2019-01-03 10:51:37 +01:00
Robert Helgesson
20a60be550 emacs: make finalPackage option more accessible
Instead of "internal" mark it as "invisible".
2019-01-03 02:15:17 +01:00
Mario Rodas
7afefcf75d opam: add module 2018-12-28 13:33:13 +01:00
Robert Helgesson
40b3443c8f dconf: add some information of use under NixOS 2018-12-24 18:36:55 +01:00
Robert Helgesson
e3167068d9 Merge PR #436 2018-12-24 17:35:48 +01:00
Robert Helgesson
cc964b4609 gtk: remove option gtk.gtk3.waylandSupport 2018-12-24 17:26:34 +01:00
Robert Helgesson
370a84192e gtk: make gtk.gtk2 and gtk.gtk3 not submodules 2018-12-24 17:26:34 +01:00
Robert Helgesson
4104ff2b6a gtk: use dconf module for settings 2018-12-24 17:26:34 +01:00
Robert Helgesson
a0162dacf6 gnome-terminal: use dconf module for settings 2018-12-24 17:26:34 +01:00
Robert Helgesson
b2cc186d22 dconf: add module
This module allows unified configuration of dconf settings.
2018-12-24 17:26:34 +01:00
Robert Helgesson
235a6617c4 readme: add notice that relog may be needed
Also add instructions for non-NixOS users to add the user channel
directory to `NIX_PATH`.
2018-12-23 10:55:30 +01:00
Robert Helgesson
218a8c4d90 modules: support conditional module inclusion
Also make use of this functionality for the `programs.chromium`
module.

See #501
2018-12-22 23:57:00 +01:00
Robert Helgesson
e68d6e7924 emacs: add overrides option
This option enables overriding packages within the generated Emacs
package set.

Fixes #486
2018-12-17 23:01:43 +01:00
Olli Helenius
dc72aa2305 jq: add module 2018-12-12 22:02:51 +01:00
Lorenzo
93b10bcf3c readme: fix .gitconfig example
The example was referencing `~/.gitconfig`, which isn't being checked
anymore since 356c0bf751.
2018-12-12 00:17:09 +01:00
Lorenzo Manacorda
4971e3735e readme: clarify bash/zsh compatibility
Makes it clearer that the compatibility mentioned only relates to the
manual loading approach.
2018-12-12 00:15:54 +01:00
Robert Helgesson
6d56abcec1 tests: add initial test framework 2018-12-11 00:57:58 +01:00
Nikita Uvarov
5d63abb473 i3: fix default keybindings override
All default keybindings should have a default priority attached to them.
This will allow users to redefine some of the default keybindings
without using mkForce. Fixes #485.
2018-12-08 15:32:30 +01:00
Robert Helgesson
6e67bb7ae6 doc: add installation instructions to manual
Also minor cleanups in README.
2018-12-06 00:57:49 +01:00
Nikita Uvarov
d67835260d polybar: switch from attrs to attrsOf 2018-12-05 12:14:43 +01:00
Nikita Uvarov
b085344b91 dunst: switch from attrs to attrsOf 2018-12-05 12:14:40 +01:00
Nikita Uvarov
c108eaba42 i3: switch from attrs to attrsOf 2018-12-05 12:00:20 +01:00
dsx
6ce3ce69b9 ssh: add addressFamily option 2018-12-05 00:24:34 +01:00
Robert Helgesson
6826521ec5 ssh: add certificateFile option 2018-12-05 00:19:40 +01:00
Robert Helgesson
5fe62660aa ssh: realign options 2018-12-05 00:14:15 +01:00
dsx
7a28f68ad0 dunst: use 'icon_path' instead of 'icon_folders'
The 'icon_folders' option is deprecated.
2018-12-05 00:05:06 +01:00
Robert Helgesson
ea9d44bede rofi: switch from types.string to types.str 2018-12-04 23:43:12 +01:00
Robert Helgesson
fd3692b36f newsboat: switch from types.string to types.str 2018-12-04 23:42:30 +01:00
Robert Helgesson
cd7b6fdbc1 autorandr: switch from types.string to types.str 2018-12-04 23:41:42 +01:00
zimbatm
571e17410a home-manager: add edit command
With this change, running

    home-manager edit

opens `$HOME_MANAGER_CONFIG` in `$EDITOR`.

This is mainly for convenience. Users should not have to remember the
exact location of the Home Manager configuration.
2018-12-04 23:17:19 +01:00
Robert Helgesson
797fbbf826 beets: add enable option 2018-12-04 23:03:23 +01:00
Robert Helgesson
a37b5c9c61 Change installation instructions to use nix-channel
This avoids the uncontrollable nature of fetching the tarball as part
of the evaluation. Instead the user can decide when to update and also
perform rollbacks, if necessary.
2018-12-04 00:59:52 +01:00
Wael M. Nasreddine
30f3baabaf home-manager: import modules using relative path 2018-12-04 00:39:34 +01:00
Robert Helgesson
ef29f321e0 readme: switch stable channel to 18.09 2018-12-03 01:06:12 +01:00
dsx
15bca92b2c i3: support for workspace_layout option 2018-12-01 01:01:35 +01:00
dsx
71f6bc41eb i3: support for bar tray_output option 2018-12-01 00:53:16 +01:00
Robert Helgesson
6d2f16a7ae pasystray: add paprefs and pavucontrol
This enables the "volume control" and "control local sound server"
menu options.

Fixes #461
2018-11-30 23:43:26 +01:00
zimbatm
40b279e3a3 ssh: tweak default controlPath
Instead of using the hostname `%h`, which can be changed by the
~/.ssh/config file, use the commandline-given hostname `%n`.

This allows to alias a host with different hostnames, which then point
to different configurations. A common use-case for this is if you have
multiple accounts on github with each access to different private repos:

    Host github.com
      IdentitiesOnly yes
      User git
      IdentityFile ~/.ssh/id_rsa

    Host customer.github.com
      IdentitiesOnly yes
      User git
      IdentityFile ~/.ssh/customer
      HostName github.com

Without this change, if a connection was established with the first
github.com alias, then the user would try to pull a repo from the second
account, ssh would re-use the SSH connection which doesn't have access
to that repository.
2018-11-30 00:13:50 +01:00
Lee Henson
5d8b089188 neovim: support withNodeJs option 2018-11-29 00:54:27 +01:00
Wael M. Nasreddine
9686d93ff6 keybase: install the keybase package 2018-11-29 00:51:58 +01:00
zimbatm
67ebe16b40 termite: setup the shell hook
This fixes Ctrl+Shift+T not working.
2018-11-26 21:28:06 +01:00
hyperfekt
6ab6488e5a vscode: add module 2018-11-26 00:01:01 +01:00
Manuel Bärenz
ffdbefe22c nextcloud-client: add module
Adds the nextcloud-client as a service, simply copying the syntax from owncloud.client.
2018-11-25 23:13:13 +01:00
zimbatm
456e2d7ed5 ssh: add more options 2018-11-25 22:46:06 +01:00
Robert Helgesson
fa3d1f98e0 astroid: require notmuch synchronize flags 2018-11-25 13:53:45 +01:00
Robert Helgesson
c21b69e73e notmuch: add maildir.synchronizeFlags option 2018-11-25 13:33:30 +01:00
Robert Helgesson
9318bd3b0d notmuch: replace incorrect use of toJSON 2018-11-25 13:33:30 +01:00
Robert Helgesson
59448d635c version: add module 2018-11-24 17:27:59 +01:00
Will Fancher
a9a4fb641f nix-darwin: add system module for nix-darwin 2018-11-20 00:22:53 +01:00
Wael M. Nasreddine
f247b3b99b offlineimap: add an extraConfig for the account section 2018-11-19 23:57:58 +01:00
Robert Helgesson
fa62c5afb6 modules: fix list sort order 2018-11-19 00:07:29 +01:00
Ben Sima
061c7b633f afew: add module 2018-11-18 23:47:45 +01:00
Matthieu Coudron
dacc07136c astroid: add module
Astroid is a notmuch/gtk based MUA: https://github.com/astroidmail/astroid
2018-11-18 19:55:28 +01:00
Robert Helgesson
abfc37076a compton: minor reformatting 2018-11-15 00:28:52 +01:00
Robert Helgesson
9a0f388f66 compton: fix corrupt colors under Mesa 18
Fixes #441
2018-11-15 00:28:50 +01:00
Ben Sima
b08e6221e0 faq: add instructions on targeting multiple logins
Content adapted from

    https://github.com/rycee/home-manager/issues/394#issuecomment-422958338
2018-11-14 23:25:17 +01:00
Robert Helgesson
0efda9cd6b Use preferLocalBuild with runCommand 2018-11-14 20:59:45 +01:00
Sam Stites
f4ebbcbf70 tmux: add module
This commit adds the tmux program to Home Manager.

In addition to configuring tmux, a user may specify tmux plugins from
Nixpkgs. These can be included in the list of `plugins` and can either
be a package (all tmux plugins live under `nixpkgs.tmuxPlugins.*`), or
an object which includes the plugin and an `extraConfig`, which will
be run immediately after sourcing the tmux plugin.

Finally, this commit introduces two nested programs which may be
enabled which depend on tmux: tmuxp and tmuxinator. These do not have
the ability to be configured, although this may be a future
contribution.
2018-11-14 00:08:39 +01:00
Robert Helgesson
36ecad6cbe Add basic gitignore file 2018-11-14 00:08:39 +01:00
Robert Helgesson
22568a3d26 Revert PR #408
This reverts the commits

- "alot: change msmtp default command"
  8e798e4c28

- "astroid: init"
  736e340bde

because they include changes that break some configurations and some
options that are misplaced.
2018-11-12 21:59:11 +01:00
Matthieu Coudron
8e798e4c28 alot: change msmtp default command 2018-11-12 23:16:03 +09:00
Matthieu Coudron
736e340bde astroid: init
Astroid is a notmuch/gtk based MUA: https://github.com/astroidmail/astroid
2018-11-12 23:16:03 +09:00
Robert Helgesson
05c93ff3ae home-manager: remove uninstall activation phase
The manual install has been long deprecated so it should be safe to no
longer attempt to do an uninstall on each activation.
2018-11-04 09:58:00 +01:00
Robert Helgesson
8d4c65f259 fzf: only enable when line editing is available
Fixes #401

Suggested-by: Alex Vorobiev
Suggested-by: Mario Rodas
2018-10-30 00:17:09 +01:00
Robert Helgesson
0435d9c338 news: remove news item about removed vim options 2018-10-29 19:42:09 +01:00
Jonas Carpay
15a5f3278a Remove tabSize and lineNumbers check from news item 2018-10-20 16:57:27 +02:00
Nikita Uvarov
34bbd0ded1 vim: remove deprecated options 2018-10-20 13:13:19 +02:00
Nikita Uvarov
c17f37857c urxvt: add module 2018-10-20 11:35:39 +02:00
Nikita Uvarov
a2e09b4c9d vim: add options 2018-10-20 11:00:13 +02:00
Robert Helgesson
5013155e58 readme: documentation is now hosted on GitLab 2018-10-18 23:42:15 +02:00
Alex Brandt
7575e119d6 systemd: add more detail to user unit documentation
The current documentation does not provide guidance to users on how
systemd units are defined in Home Manager. A user may expect the
configuration to be similar to NixOS, when it actually differs.

Fixes #418
2018-10-18 23:39:28 +02:00
Alex Brandt
3b9b897af3 home-manager: add generation expiration command
This adds a new command to the home-manager shell script that allows
generations to be removed that are older than an given absolute or
relative date.

This allows users to manage the expiration of their home-manager
generations separately from their system or user profiles via
nix-collect-garbage. It is most important if the user desires to have
a convenient way to have different expiration times for Home Manager
generations than other system or user profiles.
2018-10-18 23:12:29 +02:00
Will Dietz
0cfd21cc15 compton: drop no-dock-blur option, add dock and dnd shadow
no-dock-blur doesn't exist in compton and was added by mistake.
2018-10-14 12:13:57 +02:00
Daniël de Kok
05a98b6be0 mbsync: change service unit type to 'oneshot'
The ExecStartPost command is currently started when the mbsync is
invoked succesfully. However, we typically want to run something like
'mu index' or 'notmuch new' after mbsync completes.  This changes the
unit type to oneshot, so that the ExecStartPost command is run after
mbsync finishes succesfully.
2018-10-13 19:28:40 +02:00
Nikita Uvarov
52b9363745 rofi: set configPath defaultText to avoid rebuilds 2018-10-12 10:52:41 +02:00
Mario Rodas
f947fafec9 direnv: add config option 2018-10-10 23:05:30 +02:00
Mario Rodas
68d3cdd722 direnv: add stdlib option 2018-10-10 23:02:31 +02:00
Will Dietz
5770dc58b9 mbsync: add option to add extra account configuration 2018-10-03 13:35:04 -05:00
Edward Betts
36da7a918f Correct spelling mistakes 2018-10-02 22:41:08 +02:00
Matthieu Coudron
782d2fab83 rofi: fix default path 2018-10-01 09:27:33 +02:00
Matthieu Coudron
d9c5d3c868 alot: add module
Alot is a python mail user agent (MUA) built around the Notmuch mail
system.
2018-09-28 23:43:40 +02:00
Robert Helgesson
9b3122e92c lib: copy module from NixOS
Importing the module directly from NixOS causes the documentation to
break, in particular the "Declared by" section.

Fixes #405
2018-09-27 21:01:13 +02:00
adisbladis
f44d4a1d86 obs-studio: add module 2018-09-27 19:58:31 +02:00
gnidorah
33a2943e8c gtk: add support for wayland 2018-09-26 21:32:43 +02:00
Mario Rodas
a1a7e7cd24 bash: fix bashrcExtra interactive shell test
To determine if bash is running interactively test whether "$-"
contains "i".

See: https://www.gnu.org/software/bash/manual/html_node/Is-this-Shell-Interactive_003f.html
2018-09-26 18:18:57 +02:00
Robert Helgesson
6957911657 xresources: remove unnecessary parentheses 2018-09-24 23:24:04 +02:00
Robert Helgesson
7cc36b7703 xresources: run xrdb -merge on change
Fixes #400
2018-09-24 23:19:54 +02:00
Matthieu Coudron
9407b42f97 accounts.emails: adding gpg/signature modules 2018-09-23 23:22:39 +02:00
Matthieu Coudron
151f29a17a mbsync: add options extraConfig.{channel|local|remote}
To allow supporting more advanced configurations. The local refers to
the "maildir store" configuration, remote to the "IMAP store", and
"channel" to the channel.
2018-09-23 23:22:39 +02:00
Roman Volosatovs
f7dc354f42 go: Fix package example 2018-09-21 09:46:11 +02:00
Robert Helgesson
4d870f665b taffybar: fix indentation 2018-09-21 00:51:23 +02:00
Roman Volosatovs
0635423e73 go: add module 2018-09-21 00:11:25 +02:00
Mario Rodas
3f34bf4465 noti: add module 2018-09-20 21:26:55 +02:00
Robert Helgesson
9f0fdc68a9 xsession: add option xsession.scriptPath
This option allows overriding the default script path `~/.xsession`.
On NixOS, this is needed to allow multiple possible graphical login
sessions.

Fixes #391.
2018-09-19 23:33:13 +02:00
Robert Helgesson
701b4130bd Remove unnecessary dag variables
Also remove a few trailing whitespaces.
2018-09-19 00:13:31 +02:00
Adam Washington
d27bccdff1 zathura: add module
Add the zathura document viewer as a program option with support for
managing the zathurarc configuration file.
2018-09-18 23:57:36 +02:00
Minijackson
5ff03ce5ac taskwarrior: add module 2018-09-18 23:31:37 +02:00
Nikita Uvarov
6eea2a409e vim: improve instructions for listing available plugins 2018-09-15 12:01:36 +02:00
Robert Helgesson
ea74820176 home-environment: add option home.extraProfileCommands
This _internal_ option indicates extra commands that should be run in
the `postBuild` step of the profile environment build.

Fixes #386
2018-09-14 21:08:51 +02:00
Robert Helgesson
50de1a6885 emacs: add internal finalPackage option 2018-09-11 21:23:11 +02:00
gnidorah
055d100548 i3 module: add missing pieces to default config 2018-09-10 11:33:51 +09:00
Roman Volosatovs
63efd26767 neovim: support new extraPython*Packages options
Also fix `configure` argument.
2018-09-09 22:09:00 +02:00
Robert Helgesson
8d2cb0ef9b fish: minor formatting fixes 2018-09-09 21:18:39 +02:00
gnidorah
2bff6e5188 fish module: envoke hm-session-vars.sh 2018-09-09 21:17:13 +02:00
Matthieu Coudron
453d0494fb notmuch: synchronize_flag should be "true"
...and not "True"

According to doc https://notmuchmail.org/manpages/notmuch-config-1/

It also causes a crash in astroid :
https://github.com/astroidmail/astroid/issues/546
2018-09-07 19:38:39 +02:00
gnidorah
97c6073d39 i3 module: fonts option for bar section 2018-09-06 17:09:47 +02:00
Roman Volosatovs
9fe6fa7f44 neovim: add vi{,m}Alias options 2018-09-04 07:32:01 +02:00
Mario Rodas
7699ed3fc8 email: fix port setting for flavor gmail.com
See https://support.google.com/mail/answer/7126229.
2018-09-02 12:07:30 +02:00
Matthieu Coudron
5eca556fe7 offlineimap: add module
OfflineIMAP is a Mail Retrieval Agent (MRA) like mbsync but written in
Python.
2018-08-30 18:57:35 +02:00
Robert Helgesson
4602c00dcf polybar: minor reformatting 2018-08-29 21:46:11 +02:00
Jonathan Reeve
629d66e0b9 polybar: only quote strings if needed
Polybar expects quoted values only when whitespace is important to the
value.

Fixes #356
2018-08-29 21:42:42 +02:00
Robert Helgesson
859c132ee2 home-manager: enable build output during switch
Fixes #352
2018-08-28 00:17:57 +02:00
adisbladis
99a0e2469b direnv: add fish support 2018-08-27 22:52:53 +02:00
Mogria
2548c43175 fzf: add options for setting commands for all keys
This allows you to specify your own custom commands
to be run when calling fzf. You might use tools like
fd to search faster and take `.gitignore` files into
consideration.
2018-08-23 23:22:53 +02:00
Anton Plotnikov
90bcaaf582 pasystray: add module 2018-08-22 23:17:47 +02:00
Tad Fisher
da8307cd26 chromium: parseDrvName quick fix 2018-08-22 23:13:54 +02:00
Matthieu Coudron
cfa06c3f38 msmtp: add module
msmtp is a simple mail transfer agent (MTA).
2018-08-21 00:22:51 +02:00
Robert Helgesson
906965b48b Revert "email: note that passwordCommand should output '\n'"
This reverts commit d5bbbbd41d.

This was premature, the example will not emit a terminal newline and
it is not clear whether it is a good idea to force this limitation.
2018-08-21 00:19:33 +02:00
Robert Helgesson
d5bbbbd41d email: note that passwordCommand should output '\n'
This is because some programs, for example msmtp, expect the output to
end with a newline character.
2018-08-20 22:47:49 +02:00
Robert Helgesson
8e05229e62 Add initial GitLab CI configuration
This will automatically build and publish the Home Manager manual on
GitLab Pages.
2018-08-20 22:03:26 +02:00
Matthieu Coudron
7a8d50a803 xdg: create $XDG_CACHE_HOME
Some programs fail silently (bash with HISTFILE for instance) when the
folder doesn't exist.
2018-08-20 20:37:26 +02:00
Robert Helgesson
6630cfbe16 chromium: only enable for the linux platform 2018-08-20 07:11:00 +02:00
Tad Fisher
dd25fbcb4b chromium: add module 2018-08-19 22:46:30 +02:00
LightDiscord
f9ac73732b awesome: fix missing concatenation 2018-08-19 22:42:14 +02:00
Tad Fisher
26342588ab gpg-agent: add extraConfig option 2018-08-19 21:46:25 +02:00
Vincent Demeester
29191eb2c7 fish: add module
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-08-17 22:32:08 +02:00
Matthieu Coudron
168d546304 accounts.mail: add "gmail.com" as a flavor
To help with some autoconfiguration.
2018-08-16 23:46:27 +02:00
Robert Helgesson
34133ca7f3 accounts.email: add global certificatesFile option
This defaults to `/etc/ssl/certs/ca-certificates.crt` and will be
picked up as default by the account specific option.
2018-08-16 23:29:10 +02:00
Robert Helgesson
4b32f16747 Use submodules for program email accounts
This reworks the way program specific email account options are
specified. In particular, we no longer use the deprecated `options`
field of `mkOption`. Instead submodules are used.
2018-08-16 21:37:42 +02:00
Robert Helgesson
99c900946d Avoid substitution for some derivations
In particular, don't bother attempting to do substitution of the home
files and home generation derivations since these rarely, if ever,
could be substituted.

Fixes #330
2018-07-31 21:16:36 +02:00
Robert Helgesson
39213a1847 home-manager: fix work directory when building generation 2018-07-31 21:05:05 +02:00
Malte Brandy
c18b1328a5 Parametrize path to profile directory 2018-07-31 16:04:19 +02:00
Robert Helgesson
93ef6aefce direnv: add module 2018-07-31 15:48:08 +02:00
Anton Plotnikov
2e9e1909da status-notifier-watcher: add service 2018-07-31 15:33:57 +02:00
Robert Helgesson
4f67e8d0c3 home-manager: fix GC issue
It was previously possible to create the news information and lose it
in a Nix GC before being able to view it. This also causes a switch to
error out. This change makes the news information a root in the
garbage collector.

Note, this change also removes the need for `nix eval` so the
`doBuildAttr` function is simplified accordingly.

Fixes #327
2018-07-31 13:42:56 +02:00
Andrew Scott
30cba446f2 files: add onChange option
This option allows execution of arbitrary shell code when a file that
is linked into the home directory has been changed between
generations.
2018-07-27 22:07:12 +02:00
Robert Helgesson
dda65c0877 polybar: let systemd reload trigger restart 2018-07-26 18:01:35 +02:00
Roman Volosatovs
cf80199bfc xresources: join lists with a "," 2018-07-25 20:53:02 +02:00
Robert Helgesson
6694330bb2 udiskie: use xsession.preferStatusNotifierItems 2018-07-24 12:59:56 +02:00
Robert Helgesson
a5a49c350d network-manager-applet: use xsession.preferStatusNotifierItems 2018-07-24 12:59:50 +02:00
Robert Helgesson
6ae2d74fca xsession: add option preferStatusNotifierItems
The intent is for tray applets to honor this option if they support
the SNI protocol.
2018-07-24 12:53:20 +02:00
Anton Plotnikov
29ad012763 udiskie: add sni support 2018-07-24 11:52:38 +02:00
Robert Helgesson
9570cedff6 nixos module: we need a running nix-daemon
Make sure the nix-daemon is prepared before we attempt to do the user
activation otherwise the script may fail due to not being able to
communicate.
2018-07-21 13:15:34 +02:00
rembo10
d3871ed774 mpd: add module 2018-07-18 22:17:26 +02:00
rembo10
34db8df6d9 redshift: enable geoclue2 2018-07-13 22:07:07 +02:00
Mario Rodas
092706eff8 nixpkgs: only pass pkgs_i686 argument on Linux
Nixpkgs added an assertion on pkgsi686Linux [1] to avoid evaluating it
pkgsi686Linux on non-Linux systems.

[1] ad20a4a1c3
2018-07-13 19:26:08 +02:00
Robert Helgesson
f4a1a5e94c home-manager: resolve default configuration file path
Home Manager needs an absolute and resolved path to its configuration
file. The default configuration path is absolute but not necessarily
resolved. For example, some users may have `~/.config` be a symbolic
link to somewhere else. We therefore run the default configuration
path through the `realpath` tool to resolve it.

Fixes #304
2018-07-12 00:30:54 +02:00
Robert Helgesson
dadfaed829 home-manager: add support for the nix tool
This adds an experimantal, undocumented, and unsupported flag `-2` for
the `home-manager` command that enables the use of the new `nix`
command instead of `nix-build`.
2018-07-08 23:24:35 +02:00
LightDiscord
e365943a70 awesome: add module 2018-07-07 17:49:11 +02:00
Robert Helgesson
86fcfc74da nixpkgs: replace use of traceValIfNot
The `traceValIfNot` function is deprecated in Nixpkgs master. Instead
use `traceSeqN`.

Fixes #301
2018-07-04 19:56:13 +02:00
Robert Helgesson
eecebbf186 notmuch: add module
Co-authored-by: Matthieu Coudron <mattator@gmail.com>
2018-07-01 18:44:53 +02:00
Robert Helgesson
8dc1737e39 mbsync: add module
Co-authored-by: Matthieu Coudron <mattator@gmail.com>
2018-07-01 18:44:53 +02:00
Robert Helgesson
34bb9b5766 email: add module
This adds a general module infrastructure for configuring email
accounts. The intent is to specify high level information such as IMAP
and SMTP hostnames and login information so that more specific program
and service modules do not have to duplicate options for specifying
accounts.

It is allowed for modules to inject further options within this
namespace where relevant. For example, an MUA may wish add an option
to add per-account filter rules.

Co-authored-by: Matthieu Coudron <mattator@gmail.com>
2018-07-01 18:06:09 +02:00
Olli Helenius
299e01722f Add support for systemd path units 2018-07-01 18:04:06 +02:00
jD91mZM2
97ee4578c9 gpg-agent: Add maxCacheTtl(Ssh) options 2018-06-29 00:39:14 +02:00
Robin Stumm
0d3f9ba913 compton: fix syntax error 2018-06-27 15:18:30 +02:00
Denny Schaefer
6aa44d62ad autorandr: add rotate option 2018-06-26 21:17:54 +02:00
Nadrieril
5641ee3f94 i3: use null to disable a keybinding 2018-06-14 09:26:30 +02:00
Robert Helgesson
2e9fbbc978 termite: use docbook man page reference 2018-06-13 23:56:47 +02:00
Robert Helgesson
ad634c0a94 compton: use docbook man page references 2018-06-13 23:51:53 +02:00
gmarmstrong
7190f46938 bash: fix shellAliases description
The aliases aren't added to all users' shells.
2018-06-11 22:32:53 +02:00
Robert Helgesson
e27cd96494 newsboat: remove unnecessary period 2018-06-09 11:40:49 +02:00
Mats Rauhala
4caa45b8bb newsboat: add module 2018-06-09 11:36:45 +02:00
Robert Helgesson
f3473b9eba zsh: add missing periods in descriptions 2018-06-09 10:29:02 +02:00
Mats Rauhala
06a984e4ff zsh: add extended, expireDuplicatesFirst history options 2018-06-09 10:26:41 +02:00
adisbladis
53f10f4d46 kdeconnect: add module 2018-06-05 14:58:54 +02:00
Robert Helgesson
ed0cd78e05 i3: use fancy docbook markup in description 2018-06-03 20:53:07 +02:00
Robert Helgesson
faf04b009b qt: support GTK+ theming for Qt services 2018-06-03 17:26:47 +02:00
Lenz Weber
965bad626a flameshot: set PATH to let Qt find plugins 2018-05-31 20:26:25 +02:00
Julien Langlois
69445cb4a0 udiskie: change package
The old package is deprecated.
2018-05-31 20:10:47 +02:00
Nikita Uvarov
30c97391d7 i3: add modifier option
This allows to easily change modifier key for default keybindings and
gives a possibility to reference specified value in other modules.

Fixes #147.
2018-05-27 20:20:00 +02:00
Nikita Uvarov
cacb8d410e i3: deprecate i3.config.startup.*.workspace option
Fixes #265.
2018-05-27 00:00:10 +02:00
Nikita Uvarov
4b388ee902 i3: fix reloading for nixos module
By default, i3-msg gets socket from X11 property
which is not available when home manager is running
as nixos module.

This patch changes i3-msg command call by specifying
all i3 sockets found in $XDG_RUNTIME_DIR/i3 folder.

Fixes #252.
2018-05-26 19:14:05 +02:00
Robert Helgesson
10865f9952 bash: escape alias values
This should allow use of the apostrophe character within aliases
without having to escape them manually.

Fixes #273
2018-05-26 10:52:40 +02:00
Robert Helgesson
dfaccdd03b readme: make branch suggestion more clear
Fixes #270.
2018-05-22 18:14:37 +02:00
Robert Helgesson
f812260c23 manual: add HTML manual
Also add a `home-manager-help` script that attempts to open the HTML
manual in a browser.
2018-05-18 23:22:03 +02:00
Robert Helgesson
b6da6569c4 qt: add module 2018-05-18 20:57:36 +02:00
Robert Helgesson
bbcef2fd33 readme: add link to online options documentation 2018-05-11 22:38:47 +02:00
Robert Helgesson
ec3cbf81c4 manual: some cleanups 2018-05-11 22:26:21 +02:00
Adrian Kummerlaender
1a471b0a45 xcursor: add default cursor file option 2018-05-10 20:26:01 +02:00
Cornelius Mika
73b8aa8bcc systemd: merge unit definitions recursively
This removes the need for monolithic unit definitions and allows
users to modify existing units.

Example:
```
{
  systemd.user.services.owncloud-client.Unit.OnFailure = "my-notify-service";
}
```
2018-05-10 20:13:58 +02:00
Cornelius Mika
394045f68a systemd: improve comments 2018-05-09 16:22:02 +02:00
Robert Helgesson
f9af8e0390 manual: fix import path
Need to refer to the `default.nix` in the same home-manager source
otherwise you might get an old version.
2018-05-07 00:10:58 +02:00
Robert Helgesson
1260349384 doc: make documentation independent from NixOS
Unfortunately this duplicates some code from NixOS but it does allow
much more flexibility and, hopefully, stability in the Home Manager
documentation.

Fixes #254.
2018-05-06 22:16:48 +02:00
Nikita Uvarov
74f4ed5fd2 syncthing: fix tray startup
Workaround for #249.
2018-05-04 13:08:08 +02:00
Nikita Uvarov
91725ddced owncloud-client: fix startup
Workaround for #249.
2018-05-04 13:01:34 +02:00
Hamish Hutchings
e055e4a092 flameshot: add module 2018-05-03 17:21:03 +02:00
Peter Jones
f26cc3b957 mbsync: add module 2018-05-01 22:50:37 +02:00
Minijackson
9a3b1ec222 screen-locker: Add extraOptions for xss-lock and xautolock 2018-05-01 22:40:32 +02:00
Robert Helgesson
9141d11a7d readme: update stable NixOS version to 18.03 2018-04-19 18:29:04 +02:00
Tad Fisher
6dc4f31ba1 git: add 'includes' option 2018-04-19 17:45:09 +02:00
Silvan Mosberger
d294aa4356 zsh: only source plugin file if it exists
This allows adding plugins to fpath without sourcing anything
2018-04-19 16:43:03 +02:00
Nikita Uvarov
f314ee3d6a autorandr: add module 2018-04-19 10:41:52 +02:00
Tad Fisher
581ad6fc29 kbfs: fix systemd service PATH 2018-04-18 19:01:57 +02:00
Anton Plotnikov
8ff7d934b2 Add blur options to compton 2018-04-16 08:50:28 +02:00
Anton Plotnikov
5bdebf5ab0 Add opacity-rules to compton 2018-04-16 08:50:28 +02:00
Guthrie McAfee Armstrong
96250b7ad3 Fix typo: compton.shadowOffsets description 2018-04-16 08:45:48 +02:00
Lenz Weber
7c9278bd92 xresources: add option extraConfig 2018-03-26 21:10:32 +02:00
Robert Helgesson
4205c91609 ssh: move options to end of configuration file
This is needed to support overriding these options inside match
blocks. A new option `programs.ssh.extraOptionOverrides` has been
added to allow global overrides.
2018-03-25 08:51:20 +02:00
Robert Helgesson
75c4075345 nixpkgs: expand description of nixpkgs.config and nixpkgs.overlays 2018-03-20 20:23:42 +01:00
Gleb Peregud
f8398339a3 fzf: add enableZshIntegration option
When enabled this will extend user's `$HOME/.zshrc` with sourcing of fzf's
completion and key-bindings integration libraries.
2018-03-14 17:37:39 +01:00
Gleb Peregud
9bf9e7ac5c gpg-agent: add enableExtraSocket and verbose options.
This option enables a GPG Agent restricted socket (aka "extra-socket"), which
can be used to forward GPG Agent over SSH.

Additionally `verbose` option enables verbose output of an `gpg-agent.service`
unit for easier debugging.

See: https://wiki.gnupg.org/AgentForwarding
2018-03-13 22:36:30 +01:00
Robert Helgesson
567b21b1d6 activation-init: sanity check oldGenNum and oldGenPath
Something is terribly wrong if one is set but not the other so error
out with a message if that happens.
2018-03-13 20:49:45 +01:00
Robert Helgesson
fa7d63d9d1 fzf: add module 2018-03-07 22:44:29 +01:00
Robert Helgesson
46a94cce56 texlive: add option programs.texlive.package
This read-only option will hold a reference to the customized texlive
package.
2018-03-05 19:05:30 +01:00
Robert Helgesson
bc50202d0d gpg-agent: do updatestartuptty only when SSH is enabled
Inspired by #163.
2018-03-04 22:20:35 +01:00
Tad Fisher
8fc8e158e2 unclutter: add module 2018-03-03 22:54:46 -08:00
Robert Helgesson
06e7d087f2 home-manager: colorize only when connected to terminal
Before, the output of `home-manager generations` would be colorized
even when used in a pipeline.
2018-03-03 22:00:02 +01:00
Robert Helgesson
fbff38de33 xscreensaver: install the xscreensaver package
This is needed to make the xscreensaver tools available.
2018-03-01 23:21:45 +01:00
Robert Helgesson
19b4002f25 home-environment: use nix-env from PATH
It is safest to use the system install of Nix since that will be
compatible with the running nix-daemon and/or databases.

Also add a printout of the used Nix version in the activation script
when running in verbose mode.

Fixes #218.
2018-02-27 20:31:03 +01:00
Robert Helgesson
b47cc4bc66 qsyncthingtray: remove deprecated option 2018-02-26 22:30:28 +01:00
Robert Helgesson
e307ceeee7 systemd: replace use of who command
Curiously the `who` command sometimes does not list logged-in users,
resulting in systemd not being reloaded. Instead we use

    systemctl --user is-system-running

to more directly detect whether systemd is running.
2018-02-20 22:04:29 +01:00
Robert Helgesson
4745c7a00d pidgin: add module 2018-02-19 22:57:50 +01:00
Robert Helgesson
5c783e1a63 Add initial Travis-CI configuration 2018-02-19 22:52:56 +01:00
Nikita Uvarov
05ad0c9e06 i3: escape ${} in bars.command example 2018-02-19 20:17:33 +01:00
Matthieu Coudron
6d7b5c9513 i3: don't evaluate "command" example
else it attempts to build i3-gaps and fails on darwin see
https://github.com/rycee/home-manager/pull/214#issuecomment-366594833
2018-02-19 16:28:30 +09:00
Nikita Uvarov
de001e05da i3: add missing bar options
New options are: id, commmand, workspaceNumbers, colors.
Fixes #210.
2018-02-18 20:58:52 +01:00
Matthieu Coudron
08ce0579aa Merge pull request #212 from teto/neovim_configurable
neovim: add 'configure' flag
2018-02-18 22:42:24 +09:00
Matthieu Coudron
be60600a47 neovim: add 'configure' flag
so that we have the same options as in nixpkgs.
2018-02-19 07:41:24 +09:00
Andrew Scott
f2265b10e4 rofi: add theme option
The preferred method of theming rofi is now to use "rasi" theme files.
This commit therefore downplays the colors option and introduces the
theme option.
2018-02-10 20:11:33 +01:00
195 changed files with 11313 additions and 887 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/result*

37
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,37 @@
image: nixos/nix:latest
stages:
- test
- deploy
Run tests:
stage: test
script:
- nix-shell tests -A run.files-text
only:
- release-19.03
Deploy manual:
stage: deploy
script:
- mkdir -p ~/.config/nixpkgs
- echo '{ manual.html.enable = true; }' > ~/.config/nixpkgs/home.nix
- nix-shell . -A install
- mkdir public
- cp -r ~/.nix-profile/share/doc/home-manager/* public/
artifacts:
paths:
- public
only:
- master
Deploy NUR:
stage: deploy
variables:
HM_BRANCH: $CI_COMMIT_REF_NAME
HM_COMMIT_SHA: $CI_COMMIT_SHA
trigger:
project: rycee/nur-expressions
branch: master
only:
- release-19.03

12
.travis.yml Normal file
View File

@@ -0,0 +1,12 @@
language: nix
os:
- linux
- osx
before_script:
- mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
script:
- nix-shell . -A install
- nix-shell tests -A run.all

55
FAQ.md
View File

@@ -64,3 +64,58 @@ adding
to your `.profile` and `.zshrc` files, respectively. The
`hm-session-vars.sh` file should work in most Bourne-like shells.
How do set up a configuration for multiple users/machines?
----------------------------------------------------------
A typical way to prepare a repository of configurations for multiple
logins and machines is to prepare one "top-level" file for each unique
combination.
For example, if you have two machines, called "kronos" and "rhea" on
which you want to configure your user "jane" then you could create the
files
- `kronos-jane.nix`,
- `rhea-jane.nix`, and
- `common.nix`
in your repository. On the kronos and rhea machines you can then make
`~jane/.config/nixpkgs/home.nix` be a symbolic link to the
corresponding file in your configuration repository.
The `kronos-jane.nix` and `rhea-jane.nix` files follow the format
```nix
{ ... }:
{
imports = [ ./common.nix ];
# Various options that are specific for this machine/user.
}
```
while the `common.nix` file contains configuration shared across the
two logins. Of course, instead of just a single `common.nix` file you
can have multiple ones, even one per program or service.
You can get some inspiration from the [Post your home-manager home.nix
file!][1] Reddit thread.
[1]: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/
Why do I get an error message about `ca.desrt.dconf`?
-----------------------------------------------------
You are most likely trying to configure the GTK or Gnome Terminal but
the DBus session is not aware of the dconf service. The full error you
might get is
error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt.dconf was not provided by any .service files
The solution on NixOS is to add
services.dbus.packages = with pkgs; [ gnome3.dconf ];
to your system configuration.

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-2018 Robert Helgesson
Copyright (c) 2017-2019 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

@@ -19,7 +19,7 @@ will write to your dconf store and cannot tell whether a configuration
that it is about to be overwrite was from a previous Home Manager
generation or from manual configuration.
Home Manager targets [NixOS][] unstable and NixOS version 17.09 (the
Home Manager targets [NixOS][] unstable and NixOS version 19.03 (the
current stable version), it may or may not work on other Linux
distributions and NixOS versions.
@@ -31,6 +31,13 @@ on how to manually perform a rollback.
Now when your expectations have been built up and you are eager to try
all this out you can go ahead and read the rest of this text.
Contact
-------
You can chat with us on IRC in the channel [#home-manager][] on
[freenode][]. The [channel logs][] are hosted courtesy of
[samueldr][].
Installation
------------
@@ -48,56 +55,57 @@ Currently the easiest way to install Home Manager is as follows:
Also make sure that your user is able to build and install Nix
packages. For example, you should be able to successfully run a
command like `nix-instantiate '<nixpkgs>' -A hello`. For a
multi-user install of Nix this means that your user must be
covered by the [`allowed-users`][nixAllowedUsers] Nix option. On
NixOS you can control this option using the
command like `nix-instantiate '<nixpkgs>' -A hello` without having
to switch to the root user. For a multi-user install of Nix this
means that your user must be covered by the
[`allowed-users`][nixAllowedUsers] Nix option. On NixOS you can
control this option using the
[`nix.allowedUsers`][nixosAllowedUsers] system option.
2. Assign a temporary variable holding the URL to the appropriate
archive. Typically this is
2. Add the appropriate Home Manager channel. Typically this is
```console
$ HM_PATH=https://github.com/rycee/home-manager/archive/master.tar.gz
$ nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager
$ nix-channel --update
```
or
if you are following Nixpkgs master or an unstable channel and
```console
$ HM_PATH=https://github.com/rycee/home-manager/archive/release-17.09.tar.gz
$ nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager
$ nix-channel --update
```
depending on whether you follow Nixpkgs unstable or version 17.09.
if you follow a Nixpkgs version 19.03 channel.
3. Create an initial Home Manager configuration file:
On NixOS you may need to log out and back in for the channel to
become available. On non-NixOS you may have to add
```shell
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
```
to your shell (see [nix#2033](https://github.com/NixOS/nix/issues/2033)).
3. Install Home Manager and create the first Home Manager generation:
```console
$ cat > ~/.config/nixpkgs/home.nix <<EOF
{
programs.home-manager.enable = true;
programs.home-manager.path = $HM_PATH;
}
EOF
$ nix-shell '<home-manager>' -A install
```
4. Install Home Manager and create the first Home Manager generation:
Once finished, Home Manager should be active and available in your
user environment.
```console
$ nix-shell $HM_PATH -A install
```
Home Manager should now be active and available in your user
environment.
5. If you do not plan on having Home Manager manage your shell
3. If you do not plan on having Home Manager manage your shell
configuration then you must source the
```
"$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
```
file in your shell configuration. Unfortunately, we currently only
support POSIX.2-like shells such as [Bash][] or [Z shell][].
file in your shell configuration. Unfortunately, in this specific
case we currently only support POSIX.2-like shells such as
[Bash][] or [Z shell][].
For example, if you use Bash then add
@@ -107,11 +115,10 @@ Currently the easiest way to install Home Manager is as follows:
to your `~/.profile` file.
Note, because the `HM_PATH` variable above points to the live Home
Manager repository you will automatically get updates whenever you
build a new generation. If you dislike automatic updates then perform
a Git clone of the desired branch and instead do the above steps with
`HM_PATH` set to the _absolute path_ of your clone.
If instead of using channels you want to run Home Manager from a Git
checkout of the repository then you can use the
`programs.home-manager.path` option to specify the absolute path to
the repository.
Usage
-----
@@ -179,8 +186,9 @@ $ home-manager build
which will create a `result` link to a directory containing an
activation script and the generated home directory files.
To see available configuration options with descriptions and usage
examples run
Documentation of available configuration options, including
descriptions and usage examples, is available in the [Home Manager
manual][configuration options] or offline by running
```console
$ man home-configuration.nix
@@ -231,7 +239,7 @@ such collision is detected the activation will terminate before
changing anything on your computer.
For example, suppose you have a wonderful, painstakingly created
`~/.gitconfig` and add
`~/.config/git/config` and add
```nix
{
@@ -299,3 +307,8 @@ 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/
[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/
[channel logs]: https://logs.nix.samueldr.com/home-manager/
[samueldr]: https://github.com/samueldr/

View File

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

328
doc/default.nix Normal file
View File

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

310
doc/installation.xml Normal file
View File

@@ -0,0 +1,310 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="ch-installation">
<title>Installing Home Manager</title>
<para>
Home Manager can be used in three primary ways:
<orderedlist>
<listitem>
<para>
Using the standalone <command>home-manager</command> tool. For platforms
other than NixOS and Darwin, this is the only available choice. It is also
recommended for people on NixOS or Darwin that want to manage their home
directory independent of the system as a whole. See
<xref linkend="sec-install-standalone"/> for instructions on how to
perform this installation.
</para>
</listitem>
<listitem>
<para>
As a module within a NixOS system configuration. This allows the user
profiles to be built together with the system when running
<command>nixos-rebuild</command>. See
<xref linkend="sec-install-nixos-module"/> for a description of this
setup.
</para>
</listitem>
<listitem>
<para>
As a module within a
<link xlink:href="https://github.com/LnL7/nix-darwin/">nix-darwin</link>
system configuration. This allows the user profiles to be built together
with the system when running <command>darwin-rebuild</command>. See
<xref linkend="sec-install-nix-darwin-module"/> for a description of this
setup.
</para>
</listitem>
</orderedlist>
</para>
<section xml:id="sec-install-standalone">
<title>Standalone installation</title>
<orderedlist>
<listitem>
<para>
Make sure you have a working Nix installation. 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
<link xlink:href="https://nixos.org/nix/manual/#conf-allowed-users"><literal>allowed-users</literal></link>
Nix option. On NixOS you can control this option using the
<link xlink:href="https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers"><literal>nix.allowedUsers</literal></link>
system option.
</para>
</listitem>
<listitem>
<para>
Add the Home Manager channel that you wish to follow. This is done by
running
</para>
<screen>
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager</userinput>
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you are following Nixpkgs master or an unstable channel and
</para>
<screen>
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager</userinput>
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 19.03 channel.
</para>
<para>
On NixOS you may need to log out and back in for the channel to become
available. On non-NixOS you may have to add
<programlisting language="bash">
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
</programlisting>
to your shell (see
<link xlink:href="https://github.com/NixOS/nix/issues/2033">nix#2033</link>).
</para>
</listitem>
<listitem>
<para>
Run the Home Manager installation command and create the first Home
Manager generation:
</para>
<screen>
<prompt>$</prompt> <userinput>nix-shell '&lt;home-manager&gt;' -A install</userinput>
</screen>
<para>
Once finished, Home Manager should be active and available in your user
environment.
</para>
</listitem>
<listitem>
<para>
If you do not plan on having Home Manager manage your shell configuration
then you must source the
</para>
<programlisting language="bash">
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
</programlisting>
<para>
file in your shell configuration. Unfortunately, we currently only support
POSIX.2-like shells such as
<link xlink:href="https://www.gnu.org/software/bash/">Bash</link> or
<link xlink:href="http://zsh.sourceforge.net/">Z shell</link>.
</para>
<para>
For example, if you use Bash then add
</para>
<programlisting language="bash">
. &quot;$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh&quot;
</programlisting>
<para>
to your <literal>~/.profile</literal> file.
</para>
</listitem>
</orderedlist>
<para>
If instead of using channels you want to run Home Manager from a Git
checkout of the repository then you can use the
<literal>programs.home-manager.path</literal> option to specify the absolute
path to the repository.
</para>
</section>
<section xml:id="sec-install-nixos-module">
<title>NixOS module</title>
<para>
Home Manager provides a NixOS module that allows you to prepare user
environments directly from the system configuration file, which often is
more convenient than using the <command>home-manager</command> tool. It also
opens up additional possibilities, for example, to automatically configure
user environments in NixOS declarative containers or on systems deployed
through NixOps.
</para>
<para>
To make the NixOS module available for use you must <option>import</option>
it into your system configuration. This is most conveniently done by adding
a Home Manager channel, for example
</para>
<screen>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you are following Nixpkgs master or an unstable channel and
</para>
<screen>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 19.03 channel.
</para>
<para>
It is then possible to add
</para>
<programlisting language="nix">
imports = [ &lt;home-manager/nixos&gt; ];
</programlisting>
<para>
to your system <filename>configuration.nix</filename> file, which will
introduce a new NixOS option called <option>home-manager.users</option>
whose type is an attribute set that maps user names to Home Manager
configurations.
</para>
<para>
For example, a NixOS configuration may include the lines
</para>
<programlisting language="nix">
users.users.eve.isNormalUser = true;
home-manager.users.eve = { pkgs, ... }: {
home.packages = [ pkgs.atool pkgs.httpie ];
programs.bash.enable = true;
};
</programlisting>
<para>
and after a <command>nixos-rebuild switch</command> the user eve's
environment should include a basic Bash configuration and the packages atool
and httpie.
</para>
<note>
<para>
By default packages will be installed to
<filename>$HOME/.nix-profile</filename> but they can be installed to
<filename>/etc/profiles</filename> if
</para>
<programlisting language="nix">
home-manager.useUserPackages = true;
</programlisting>
<para>
is added to the system configuration. This is necessary if, for example,
you wish to use <command>nixos-rebuild build-vm</command>. This option may
become the default value in the future.
</para>
</note>
</section>
<section xml:id="sec-install-nix-darwin-module">
<title>nix-darwin module</title>
<para>
Home Manager provides a module that allows you to prepare user
environments directly from the nix-darwin configuration file, which often is
more convenient than using the <command>home-manager</command> tool.
</para>
<para>
To make the NixOS module available for use you must <option>import</option>
it into your system configuration. This is most conveniently done by adding
a Home Manager channel, for example
</para>
<screen>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you are following Nixpkgs master or an unstable channel and
</para>
<screen>
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 19.03 channel.
</para>
<para>
It is then possible to add
</para>
<programlisting language="nix">
imports = [ &lt;home-manager/nix-darwin&gt; ];
</programlisting>
<para>
to your nix-darwin <filename>configuration.nix</filename> file, which will
introduce a new NixOS option called <option>home-manager</option> whose type
is an attribute set that maps user names to Home Manager configurations.
</para>
<para>
For example, a nix-darwin configuration may include the lines
</para>
<programlisting language="nix">
home-manager.users.eve = { pkgs, ... }: {
home.packages = [ pkgs.atool pkgs.httpie ];
programs.bash.enable = true;
};
</programlisting>
<para>
and after a <command>darwin-rebuild --switch</command> the user eve's
environment should include a basic Bash configuration and the packages atool
and httpie.
</para>
<note>
<para>
By default user packages will not be ignored in favor of
<option>environment.systemPackages</option>, but they will be intalled to
<option>/etc/profiles/per-user/$USERNAME</option> if
</para>
<programlisting language="nix">
home-manager.useUserPackages = true;
</programlisting>
<para>
is added to the nix-darwin configuration. This option may become the default
value in the future.
</para>
</note>
</section>
</chapter>

40
doc/man-configuration.xml Normal file
View File

@@ -0,0 +1,40 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><filename>home-configuration.nix</filename></refentrytitle>
<manvolnum>5</manvolnum>
<refmiscinfo class="source">Home Manager</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta>
<refnamediv>
<refname><filename>home-configuration.nix</filename></refname>
<refpurpose>Home Manager configuration specification</refpurpose>
</refnamediv>
<refsection>
<title>Description</title>
<para>
The file <filename>~/.config/nixpkgs/home.nix</filename> contains the
declarative specification of your Home Manager configuration. The command
<command>home-manager</command> takes this file and realises the user
environment configuration specified therein.
</para>
</refsection>
<refsection>
<title>Options</title>
<para>
You can use the following options in
<filename>home-configuration.nix</filename>:
</para>
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
</refsection>
<refsection>
<title>See also</title>
<para>
<citerefentry>
<refentrytitle>home-manager</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
</para>
</refsection>
</refentry>

88
doc/man-home-manager.xml Normal file
View File

@@ -0,0 +1,88 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>home-manager</command></refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Home Manager</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta>
<refnamediv>
<refname><command>home-manager</command></refname>
<refpurpose>reconfigure a user environment</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>home-manager</command> <group choice="req">
<arg choice="plain">
<option>help</option>
</arg>
<arg choice="plain">
<option>build</option>
</arg>
<arg choice="plain">
<option>switch</option>
</arg>
<arg choice="plain">
<option>generations</option>
</arg>
<arg choice="plain">
<option>remove-generations</option>
</arg>
<arg choice="plain">
<option>packages</option>
</arg>
<arg choice="plain">
<option>news</option>
</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsection>
<title>Description</title>
<para>
This command updates the user environment so that it corresponds to the
configuration specified in <filename>~/.config/nixpkgs/home.nix</filename>.
</para>
</refsection>
<refsection>
<title>Files</title>
<variablelist>
<varlistentry>
<term>
<filename>~/.local/share/home-manager/news-read-ids</filename>
</term>
<listitem>
<para>
Identifiers of news items that have been shown. Can be deleted to reset
the read news indicator.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection>
<title>Bugs</title>
<para>
Please report any bugs on the
<link
xlink:href="https://github.com/rycee/home-manager/issues">project
issue tracker</link>.
</para>
</refsection>
<refsection>
<title>See also</title>
<para>
<citerefentry>
<refentrytitle>home-configuration.nix</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
</para>
</refsection>
</refentry>

12
doc/man-pages.xml Normal file
View File

@@ -0,0 +1,12 @@
<reference xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Home Manager Reference Pages</title>
<info>
<author><personname>Home Manager contributors</personname></author>
<copyright><year>20172019</year><holder>Home Manager contributors</holder>
</copyright>
</info>
<xi:include href="man-configuration.xml" />
<xi:include href="man-home-manager.xml" />
</reference>

34
doc/manual.xml Normal file
View File

@@ -0,0 +1,34 @@
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="book-home-manager-manual">
<info>
<title>Home Manager Manual</title>
</info>
<preface>
<title>Preface</title>
<para>
This manual will eventually describes how to install, use, and extend Home
Manager.
</para>
<para>
If you encounter problems or bugs then please report them on the
<link xlink:href="https://github.com/rycee/home-manager/issues">Home Manager
issue tracker</link>.
</para>
<note>
<para>
Commands prefixed with <literal>#</literal> have to be run as root, either
requiring to login as root user or temporarily switching to it using
<literal>sudo</literal> for example.
</para>
</note>
</preface>
<xi:include href="installation.xml" />
<appendix xml:id="ch-options">
<title>Configuration Options</title>
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
</appendix>
<xi:include href="./release-notes/release-notes.xml" />
</book>

239
doc/options-to-docbook.xsl Normal file
View File

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

9
doc/overrides.css Normal file
View File

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

View File

@@ -0,0 +1,14 @@
<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

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

View File

@@ -0,0 +1,88 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.03">
<title>Release 19.03</title>
<para>
The 19.03 release branch became the stable branch in April, 2019.
</para>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.03-highlights">
<title>Highlights</title>
<para>
This release has the following notable changes:
</para>
<itemizedlist>
<listitem>
<para>
The <option>home.file.&lt;name?&gt;.source</option> now allows source
files to be hidden, that is, having a name starting with the
<literal>.</literal> character. It also allows the source file name to
contain characters not typically allowed for Nix store paths. For example,
your configuration can now contain things such as
<programlisting>
home.file."my file".source = ./. + "/file with spaces!";
</programlisting>
</para>
</listitem>
<listitem>
<para>
The type used for the systemd unit options under
<option>systemd.user.services</option>,
<option>systemd.user.sockets</option>, etc. has been changed to offer more
robust merging of configurations. If you don't override values within
systemd units then you are not affected by this change. Unfortunately, if
you do override unit values you may encounter errors.
</para>
<para>
In particular, if you get an error saying that a <quote>unique
option</quote> is <quote>defined multiple times</quote> then you need to
use the
<code xlink:href="https://nixos.org/nixos/manual/#sec-option-definitions-setting-priorities">mkForce</code>
function. For example,
<programlisting language="nix">
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
</programlisting>
becomes
<programlisting language="nix">
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
</programlisting>
We had to make this change because the old merging was causing too many
confusing situations for people.
</para>
</listitem>
</itemizedlist>
</section>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-release-19.03-state-version-changes">
<title>State Version Changes</title>
<para>
The state version in this release includes the changes below. These changes
are only active if the <option>home.stateVersion</option> option is set to
"19.03" or later.
</para>
<itemizedlist>
<listitem>
<para>
There is now an option <option>programs.beets.enable</option> that
defaults to <literal>false</literal>. Before the module would be active if
the <option>programs.beets.settings</option> option was non-empty.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View File

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

271
doc/style.css Normal file
View File

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

View File

@@ -1,4 +1,4 @@
{ pkgs
{ runCommand, lib, bash, coreutils, findutils, gnused, less
# Extra path to Home Manager. If set then this path will be tried
# before `$HOME/.config/nixpkgs/home-manager` and
@@ -12,23 +12,26 @@ let
in
pkgs.stdenv.mkDerivation {
name = "home-manager";
buildCommand = ''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
runCommand
"home-manager"
{
preferLocalBuild = true;
allowSubstitutes = false;
meta = with lib; {
description = "A user environment configurator";
maintainers = [ maintainers.rycee ];
platforms = platforms.unix;
license = licenses.mit;
};
}
''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${pkgs.bash}" \
--subst-var-by coreutils "${pkgs.coreutils}" \
--subst-var-by less "${pkgs.less}" \
--subst-var-by bash "${bash}" \
--subst-var-by coreutils "${coreutils}" \
--subst-var-by findutils "${findutils}" \
--subst-var-by gnused "${gnused}" \
--subst-var-by less "${less}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
'';
meta = with pkgs.stdenv.lib; {
description = "A user environment configurator";
maintainers = [ maintainers.rycee ];
platforms = platforms.unix;
license = licenses.mit;
};
}
''

View File

@@ -1,9 +1,7 @@
#!@bash@/bin/bash
# This code explicitly requires GNU Core Utilities and we therefore
# need to ensure they are prioritized over any other similarly named
# tools on the system.
PATH=@coreutils@/bin:@less@/bin${PATH:+:}$PATH
# Prepare to use tools from Nixpkgs.
PATH=@coreutils@/bin:@findutils@/bin:@gnused@/bin:@less@/bin${PATH:+:}$PATH
set -euo pipefail
@@ -12,6 +10,28 @@ function errorEcho() {
echo $* >&2
}
function setVerboseAndDryRun() {
if [[ -v VERBOSE ]]; then
export VERBOSE_ARG="--verbose"
else
export VERBOSE_ARG=""
fi
if [[ -v DRY_RUN ]] ; then
export DRY_RUN_CMD=echo
else
export DRY_RUN_CMD=""
fi
}
function setWorkDir() {
if [[ ! -v WORK_DIR ]]; then
WORK_DIR="$(mktemp --tmpdir -d home-manager-build.XXXXXXXXXX)"
# shellcheck disable=2064
trap "rm -r '$WORK_DIR'" EXIT
fi
}
# Attempts to set the HOME_MANAGER_CONFIG global variable.
#
# If no configuration file can be found then this function will print
@@ -32,7 +52,7 @@ function setConfigFile() {
for confFile in "$defaultConfFile" \
"$HOME/.nixpkgs/home.nix" ; do
if [[ -e "$confFile" ]] ; then
HOME_MANAGER_CONFIG="$confFile"
HOME_MANAGER_CONFIG="$(realpath "$confFile")"
return
fi
done
@@ -69,11 +89,19 @@ function doBuildAttr() {
fi
# shellcheck disable=2086
nix-build \
"<home-manager/home-manager/home-manager.nix>" \
$extraArgs \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
if [[ -v USE_NIX2_COMMAND ]]; then
nix build \
-f "<home-manager/home-manager/home-manager.nix>" \
$extraArgs \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
else
nix-build \
"<home-manager/home-manager/home-manager.nix>" \
$extraArgs \
--argstr confPath "$HOME_MANAGER_CONFIG" \
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
fi
}
# Presents news to the user. Takes as argument the path to a "news
@@ -115,18 +143,37 @@ function presentNews() {
fi
}
function doEdit() {
if [[ ! -v EDITOR || -z $EDITOR ]]; then
errorEcho "Please set the \$EDITOR environment variable"
return 1
fi
setConfigFile
exec "$EDITOR" "$HOME_MANAGER_CONFIG"
}
function doBuild() {
if [[ ! -w . ]]; then
errorEcho "Cannot run build in read-only directory";
return 1
fi
setWorkDir
local newsInfo
newsInfo=$(buildNews)
local exitCode
doBuildAttr -A activationPackage \
&& exitCode=0 || exitCode=1
if [[ -v USE_NIX2_COMMAND ]]; then
doBuildAttr activationPackage \
&& exitCode=0 || exitCode=1
else
doBuildAttr --attr activationPackage \
&& exitCode=0 || exitCode=1
fi
presentNews "$newsInfo"
@@ -134,24 +181,31 @@ function doBuild() {
}
function doSwitch() {
setWorkDir
local newsInfo
newsInfo=$(buildNews)
local generation
local exitCode=0
local wrkdir
# Build the generation and run the activate script. Note, we
# specify an output link so that it is treated as a GC root. This
# prevents an unfortunately timed GC from removing the generation
# before activation completes.
wrkdir="$(mktemp -d)"
generation=$(doBuildAttr -o "$wrkdir/result" -A activationPackage) \
&& $generation/activate || exitCode=1
generation="$WORK_DIR/generation"
# Because the previous command never fails, the script keeps
# running and $wrkdir is always removed.
rm -r "$wrkdir"
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
presentNews "$newsInfo"
@@ -159,9 +213,15 @@ function doSwitch() {
}
function doListGens() {
# Whether to colorize the generations output.
local color="never"
if [[ -t 1 ]]; then
color="always"
fi
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
# shellcheck disable=2012
ls --color=yes -gG --time-style=long-iso --sort time home-manager-*-link \
ls --color=$color -gG --time-style=long-iso --sort time home-manager-*-link \
| cut -d' ' -f 4- \
| sed -E 's/home-manager-([[:digit:]]*)-link/: id \1/'
popd > /dev/null
@@ -170,17 +230,7 @@ function doListGens() {
# Removes linked generations. Takes as arguments identifiers of
# generations to remove.
function doRmGenerations() {
if [[ -v VERBOSE ]]; then
export VERBOSE_ARG="--verbose"
else
export VERBOSE_ARG=""
fi
if [[ -v DRY_RUN ]] ; then
export DRY_RUN_CMD=echo
else
export DRY_RUN_CMD=""
fi
setVerboseAndDryRun
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
@@ -200,6 +250,28 @@ function doRmGenerations() {
popd > /dev/null
}
function doRmAllGenerations() {
$DRY_RUN_CMD rm $VERBOSE_ARG \
"/nix/var/nix/profiles/per-user/$USER/home-manager"*
}
function doExpireGenerations() {
local profileDir="/nix/var/nix/profiles/per-user/$USER"
local generations
generations="$( \
find "$profileDir" -name 'home-manager-*-link' -not -newermt "$1" \
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
)"
if [[ -n $generations ]]; then
# shellcheck disable=2086
doRmGenerations $generations
elif [[ -v VERBOSE ]]; then
echo "No generations to expire"
fi
}
function doListPackages() {
local outPath
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
@@ -227,18 +299,36 @@ function newsReadIdsFile() {
# Builds news meta information to be sourced into this script.
#
# Note, we suppress build output to remove unnecessary verbosity. We
# also use "no out link" to avoid the need for a build directory
# (although this exposes the risk of GC removing the result before we
# manage to source it).
# put the output in the work directory to avoid the risk of an
# unfortunately timed GC removing it.
function buildNews() {
doBuildAttr --quiet \
--attr newsInfo \
--no-out-link \
--arg check false \
--argstr newsReadIdsFile "$(newsReadIdsFile)"
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
echo "$output"
}
function doShowNews() {
setWorkDir
local infoFile
infoFile=$(buildNews) || return 1
@@ -266,6 +356,56 @@ function doShowNews() {
fi
}
function doUninstall() {
setVerboseAndDryRun
echo "This will remove Home Manager from your system."
if [[ -v DRY_RUN ]]; then
echo "This is a dry run, nothing will actually be uninstalled."
fi
local confirmation
read -r -n 1 -p "Really uninstall Home Manager? [y/n] " confirmation
echo
case $confirmation in
y|Y)
echo "Switching to empty Home Manager configuration..."
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
echo "{}" > "$HOME_MANAGER_CONFIG"
doSwitch
rm "$HOME_MANAGER_CONFIG"
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
$DRY_RUN_CMD rm $VERBOSE_ARG \
"/nix/var/nix/gcroots/per-user/$USER/current-home"
;;
*)
echo "Yay!"
exit 0
;;
esac
local deleteProfiles
read -r -n 1 \
-p 'Remove all Home Manager generations? [y/n] ' \
deleteProfiles
echo
case $deleteProfiles in
y|Y)
doRmAllGenerations
echo "All generations are now eligible for garbage collection."
;;
*)
echo "Leaving generations but they may still be garbage collected."
;;
esac
echo "Home Manager is uninstalled but your home.nix is left untouched."
}
function doHelp() {
echo "Usage: $0 [OPTION] COMMAND"
echo
@@ -284,6 +424,8 @@ function doHelp() {
echo
echo " help Print this help"
echo
echo " edit Open the home configuration in \$EDITOR"
echo
echo " build Build configuration into result directory"
echo
echo " switch Build and activate configuration"
@@ -294,9 +436,16 @@ function doHelp() {
echo " Remove indicated generations. Use 'generations' command to"
echo " find suitable generation numbers."
echo
echo " expire-generations TIMESTAMP"
echo " Remove generations older than TIMESTAMP where TIMESTAMP is"
echo " interpreted as in the -d argument of the date tool. For"
echo " example \"-30 days\" or \"2018-01-01\"."
echo
echo " packages List all packages installed in home-manager-path"
echo
echo " news Show news entries in a pager"
echo
echo " uninstall Remove Home Manager"
}
EXTRA_NIX_PATH=()
@@ -311,8 +460,11 @@ for arg in "$@"; do
fi
done
while getopts f:I:A:vnh opt; do
while getopts 2f:I:A:vnh opt; do
case $opt in
2)
USE_NIX2_COMMAND=1
;;
f)
HOME_MANAGER_CONFIG="$OPTARG"
;;
@@ -333,7 +485,6 @@ while getopts f:I:A:vnh opt; do
exit 0
;;
*)
errorEcho "Unknown option -$OPTARG"
doHelp >&2
exit 1
;;
@@ -352,6 +503,9 @@ cmd="$1"
shift 1
case "$cmd" in
edit)
doEdit
;;
build)
doBuild
;;
@@ -364,12 +518,18 @@ case "$cmd" in
remove-generations)
doRmGenerations "$@"
;;
expire-generations)
doExpireGenerations "$@"
;;
packages)
doListPackages
;;
news)
doShowNews --all
;;
uninstall)
doUninstall
;;
help|--help)
doHelp
;;

View File

@@ -9,7 +9,7 @@ with pkgs.lib;
let
env = import <home-manager/modules> {
env = import ../modules {
configuration =
if confAttr == ""
then confPath

View File

@@ -1,10 +1,30 @@
{ home-manager, pkgs }:
{ home-manager, runCommand }:
pkgs.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
echo
echo "Creating initial Home Manager generation..."
echo
@@ -15,7 +35,7 @@ pkgs.runCommand
All done! The home-manager tool should now be installed and you
can edit
''${XDG_CONFIG_HOME:-~/.config}/nixpkgs/home.nix
$confFile
to configure Home Manager. Run 'man home-configuration.nix' to
see all available options.
@@ -34,4 +54,7 @@ pkgs.runCommand
fi
'';
}
""
''
echo This derivation is not buildable, instead run it using nix-shell.
exit 1
''

421
modules/accounts/email.nix Normal file
View File

@@ -0,0 +1,421 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.accounts.email;
gpgModule = types.submodule {
options = {
key = mkOption {
type = types.str;
description = ''
The key to use as listed in <command>gpg --list-keys</command>.
'';
};
signByDefault = mkOption {
type = types.bool;
default = false;
description = "Sign messages by default.";
};
encryptByDefault = mkOption {
type = types.bool;
default = false;
description = "Encrypt outgoing messages by default.";
};
};
};
signatureModule = types.submodule {
options = {
text = mkOption {
type = types.str;
default = "";
example = ''
--
Luke Skywalker
May the force be with you.
'';
description = ''
Signature content.
'';
};
showSignature = mkOption {
type = types.enum [ "append" "attach" "none" ];
default = "none";
description = "Method to communicate the signature.";
};
};
};
tlsModule = types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable TLS/SSL.
'';
};
useStartTls = mkOption {
type = types.bool;
default = false;
description = ''
Whether to use STARTTLS.
'';
};
certificatesFile = mkOption {
type = types.path;
default = config.accounts.email.certificatesFile;
defaultText = "config.accounts.email.certificatesFile";
description = ''
Path to file containing certificate authorities that should
be used to validate the connection authenticity. If
<literal>null</literal> then the system default is used.
Note, if set then the system default may still be accepted.
'';
};
};
};
imapModule = types.submodule {
options = {
host = mkOption {
type = types.str;
example = "imap.example.org";
description = ''
Hostname of IMAP server.
'';
};
port = mkOption {
type = types.nullOr types.port;
default = null;
example = 993;
description = ''
The port on which the IMAP server listens. If
<literal>null</literal> then the default port is used.
'';
};
tls = mkOption {
type = tlsModule;
default = {};
description = ''
Configuration for secure connections.
'';
};
};
};
smtpModule = types.submodule {
options = {
host = mkOption {
type = types.str;
example = "smtp.example.org";
description = ''
Hostname of SMTP server.
'';
};
port = mkOption {
type = types.nullOr types.port;
default = null;
example = 465;
description = ''
The port on which the SMTP server listens. If
<literal>null</literal> then the default port is used.
'';
};
tls = mkOption {
type = tlsModule;
default = {};
description = ''
Configuration for secure connections.
'';
};
};
};
maildirModule = types.submodule ({ config, ... }: {
options = {
path = mkOption {
type = types.str;
description = ''
Path to maildir directory where mail for this account is
stored. This is relative to the base maildir path.
'';
};
absPath = mkOption {
type = types.path;
readOnly = true;
internal = true;
default = "${cfg.maildirBasePath}/${config.path}";
description = ''
A convenience option whose value is the absolute path of
this maildir.
'';
};
};
});
mailAccountOpts = { name, config, ... }: {
options = {
name = mkOption {
type = types.str;
readOnly = true;
description = ''
Unique identifier of the account. This is set to the
attribute name of the account configuration.
'';
};
primary = mkOption {
type = types.bool;
default = false;
description = ''
Whether this is the primary account. Only one account may be
set as primary.
'';
};
flavor = mkOption {
type = types.enum [ "plain" "gmail.com" "runbox.com" ];
default = "plain";
description = ''
Some email providers have peculiar behavior that require
special treatment. This option is therefore intended to
indicate the nature of the provider.
</para><para>
When this indicates a specific provider then, for example,
the IMAP and SMTP server configuration may be set
automatically.
'';
};
address = mkOption {
type = types.strMatching ".*@.*";
example = "jane.doe@example.org";
description = "The email address of this account.";
};
aliases = mkOption {
type = types.listOf (types.strMatching ".*@.*");
default = [];
example = [ "webmaster@example.org" "admin@example.org" ];
description = "Alternative email addresses of this account.";
};
realName = mkOption {
type = types.str;
example = "Jane Doe";
description = "Name displayed when sending mails.";
};
userName = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The server username of this account. This will be used as
the SMTP and IMAP user name.
'';
};
passwordCommand = mkOption {
type = types.nullOr (types.either types.str (types.listOf types.str));
default = null;
apply = p: if isString p then splitString " " p else p;
example = "secret-tool lookup email me@example.org";
description = ''
A command, which when run writes the account password on
standard output.
'';
};
folders = mkOption {
type = types.submodule {
options = {
inbox = mkOption {
type = types.str;
default = "Inbox";
description = ''
Relative path of the inbox mail.
'';
};
sent = mkOption {
type = types.nullOr types.str;
default = "Sent";
description = ''
Relative path of the sent mail folder.
'';
};
drafts = mkOption {
type = types.str;
default = "Drafts";
description = ''
Relative path of the drafts mail folder.
'';
};
trash = mkOption {
type = types.str;
default = "Trash";
description = ''
Relative path of the deleted mail folder.
'';
};
};
};
default = {};
description = ''
Standard email folders.
'';
};
imap = mkOption {
type = types.nullOr imapModule;
default = null;
description = ''
The IMAP configuration to use for this account.
'';
};
signature = mkOption {
type = signatureModule;
default = {};
description = ''
Signature configuration.
'';
};
gpg = mkOption {
type = types.nullOr gpgModule;
default = null;
description = ''
GPG configuration.
'';
};
smtp = mkOption {
type = types.nullOr smtpModule;
default = null;
description = ''
The SMTP configuration to use for this account.
'';
};
maildir = mkOption {
type = types.nullOr maildirModule;
defaultText = { path = "\${name}"; };
description = ''
Maildir configuration for this account.
'';
};
};
config = mkMerge [
{
name = name;
maildir = mkOptionDefault { path = "${name}"; };
}
(mkIf (config.flavor == "gmail.com") {
userName = mkDefault config.address;
imap = {
host = "imap.gmail.com";
};
smtp = {
host = "smtp.gmail.com";
port = if config.smtp.tls.useStartTls then 587 else 465;
};
})
(mkIf (config.flavor == "runbox.com") {
imap = {
host = "mail.runbox.com";
};
smtp = {
host = "mail.runbox.com";
};
})
];
};
in
{
options.accounts.email = {
certificatesFile = mkOption {
type = types.path;
default = "/etc/ssl/certs/ca-certificates.crt";
description = ''
Path to default file containing certificate authorities that
should be used to validate the connection authenticity. This
path may be overridden on a per-account basis.
'';
};
maildirBasePath = mkOption {
type = types.str;
default = "${config.home.homeDirectory}/Maildir";
defaultText = "$HOME/Maildir";
apply = p:
if hasPrefix "/" p
then p
else "${config.home.homeDirectory}/${p}";
description = ''
The base directory for account maildir directories. May be a
relative path, in which case it is relative the home
directory.
'';
};
accounts = mkOption {
type = types.attrsOf (types.submodule [
mailAccountOpts
(import ../programs/alot-accounts.nix pkgs)
(import ../programs/astroid-accounts.nix)
(import ../programs/mbsync-accounts.nix)
(import ../programs/msmtp-accounts.nix)
(import ../programs/notmuch-accounts.nix)
(import ../programs/offlineimap-accounts.nix)
]);
default = {};
description = "List of email accounts.";
};
};
config = mkIf (cfg.accounts != {}) {
assertions = [
(
let
primaries =
catAttrs "name"
(filter (a: a.primary)
(attrValues cfg.accounts));
in
{
assertion = length primaries == 1;
message =
"Must have exactly one primary mail account but found "
+ toString (length primaries)
+ optionalString (length primaries > 1)
(", namely " + concatStringsSep ", " primaries);
}
)
];
};
}

View File

@@ -23,6 +23,9 @@ let
modules =
[ configuration ]
++ (import ./modules.nix { inherit check lib pkgs; });
specialArgs = {
modulesPath = builtins.toString ./.;
};
};
module = showWarnings (

View File

@@ -14,6 +14,15 @@ let
inherit homeDirectory lib pkgs;
}).fileType;
sourceStorePath = file:
let
sourcePath = toString file.source;
sourceName = config.lib.strings.storeFileName (baseNameOf sourcePath);
in
if builtins.hasContext sourcePath
then file.source
else builtins.path { path = file.source; name = sourceName; };
# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*";
@@ -36,20 +45,6 @@ in
};
config = {
assertions = [
(let
badFiles =
filter (f: hasPrefix "." (baseNameOf f))
(map (v: toString v.source)
(attrValues cfg));
badFilesStr = toString badFiles;
in
{
assertion = badFiles == [];
message = "Source file names must not start with '.': ${badFilesStr}";
})
];
# This verifies that the links we are about to create will not
# overwrite an existing file.
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
@@ -79,8 +74,8 @@ in
function checkNewGenCollision() {
local newGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
find "$newGenFiles" -type f -print0 -or -type l -print0 \
| xargs -0 bash ${check} "$newGenFiles"
find "$newGenFiles" \( -type f -or -type l \) \
-exec bash ${check} "$newGenFiles" {} +
}
checkNewGenCollision || exit 1
@@ -160,8 +155,8 @@ in
local newGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
find "$newGenFiles" -type f -print0 -or -type l -print0 \
| xargs -0 bash ${link} "$newGenFiles"
find "$newGenFiles" \( -type f -or -type l \) \
-exec bash ${link} "$newGenFiles" {} +
}
function cleanOldGen() {
@@ -197,14 +192,34 @@ in
''
);
home-files = pkgs.stdenv.mkDerivation {
name = "home-manager-files";
home.activation.checkFilesChanged = dag.entryBefore ["linkGeneration"] (
''
declare -A changedFiles
'' + concatMapStrings (v: ''
cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \
&& changedFiles["${v.target}"]=0 \
|| changedFiles["${v.target}"]=1
'') (filter (v: v.onChange != "") (attrValues cfg))
);
nativeBuildInputs = [ pkgs.xlibs.lndir ];
home.activation.onFilesChange = dag.entryAfter ["linkGeneration"] (
concatMapStrings (v: ''
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then
${v.onChange}
fi
'') (filter (v: v.onChange != "") (attrValues cfg))
);
# Symlink directories and files that have the right execute bit.
# Copy files that need their execute bit changed.
buildCommand = ''
# Symlink directories and files that have the right execute bit.
# Copy files that need their execute bit changed.
home-files = pkgs.runCommand
"home-manager-files"
{
nativeBuildInputs = [ pkgs.xlibs.lndir ];
preferLocalBuild = true;
allowSubstitutes = false;
}
(''
mkdir -p $out
function insertFile() {
@@ -256,14 +271,13 @@ in
}
'' + concatStrings (
mapAttrsToList (n: v: ''
insertFile "${v.source}" \
insertFile "${sourceStorePath v}" \
"${v.target}" \
"${if v.executable == null
then "inherit"
else builtins.toString v.executable}" \
"${builtins.toString v.recursive}"
'') cfg
);
};
));
};
}

View File

@@ -121,6 +121,17 @@ in
description = "The user's home directory.";
};
home.profileDirectory = mkOption {
type = types.path;
defaultText = "~/.nix-profile";
internal = true;
readOnly = true;
description = ''
The profile directory where Home Manager generations are
installed.
'';
};
home.language = mkOption {
type = languageSubModule;
default = {};
@@ -128,9 +139,12 @@ in
};
home.keyboard = mkOption {
type = keyboardSubModule;
type = types.nullOr keyboardSubModule;
default = {};
description = "Keyboard configuration.";
description = ''
Keyboard configuration. Set to <literal>null</literal> to
disable Home Manager keyboard management.
'';
};
home.sessionVariables = mkOption {
@@ -152,20 +166,20 @@ in
Note, these variables may be set in any order so no session
variable may have a runtime dependency on another session
variable. In particular code like
<programlisting>
home.sessionVariables = {
FOO = "Hello";
BAR = "$FOO World!";
};
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "$FOO World!";
};
</programlisting>
may not work as expected. If you need to reference another
session variable, then do so inside Nix instead. The above
example then becomes
<programlisting>
home.sessionVariables = {
FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!";
};
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!";
};
</programlisting>
'';
};
@@ -232,6 +246,15 @@ in
Extra commands to run in the Home Manager generation builder.
'';
};
home.extraProfileCommands = mkOption {
type = types.lines;
default = "";
internal = true;
description = ''
Extra commands to run in the Home Manager profile builder.
'';
};
};
config = {
@@ -249,6 +272,12 @@ in
home.username = mkDefault (builtins.getEnv "USER");
home.homeDirectory = mkDefault (builtins.getEnv "HOME");
home.profileDirectory =
if config.submoduleSupport.enable
&& config.submoduleSupport.externalPackageInstall
then config.home.path
else cfg.homeDirectory + "/.nix-profile";
home.sessionVariables =
let
maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
@@ -285,9 +314,33 @@ in
home.activation.writeBoundary = dag.entryAnywhere "";
# Install packages to the user environment.
home.activation.installPackages = dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD nix-env -i ${cfg.path}
'';
#
# Note, sometimes our target may not allow modification of the Nix
# store and then we cannot rely on `nix-env -i`. This is the case,
# for example, if we are running as a NixOS module and building a
# virtual machine. Then we must instead rely on an external
# mechanism for installing packages, which in NixOS is provided by
# the `users.users.<name?>.packages` option. The activation
# command is still needed since some modules need to run their
# activation commands after the packages are guaranteed to be
# installed.
#
# In case the user has moved from a user-install of Home Manager
# to a submodule managed one we attempt to uninstall the
# `home-manager-path` package if it is installed.
home.activation.installPackages = dag.entryAfter ["writeBoundary"] (
if config.submoduleSupport.externalPackageInstall
then
''
if nix-env -q | grep '^home-manager-path$'; then
$DRY_RUN_CMD nix-env -e home-manager-path
fi
''
else
''
$DRY_RUN_CMD nix-env -i ${cfg.path}
''
);
home.activationPackage =
let
@@ -313,12 +366,11 @@ in
pkgs.gnugrep
pkgs.gnused
pkgs.ncurses # For `tput`.
pkgs.nix
]
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
activationScript = pkgs.writeScript "activation-script" ''
#!${pkgs.stdenv.shell}
#!${pkgs.runtimeShell}
set -eu
set -o pipefail
@@ -334,10 +386,13 @@ in
${activationCmds}
'';
in
pkgs.stdenv.mkDerivation {
name = "home-manager-generation";
buildCommand = ''
pkgs.runCommand
"home-manager-generation"
{
preferLocalBuild = true;
allowSubstitutes = false;
}
''
mkdir -p $out
cp ${activationScript} $out/activate
@@ -350,7 +405,6 @@ in
${cfg.extraBuilderCommands}
'';
};
home.path = pkgs.buildEnv {
name = "home-manager-path";
@@ -358,6 +412,8 @@ in
paths = cfg.packages;
inherit (cfg) extraOutputsToInstall;
postBuild = cfg.extraProfileCommands;
meta = {
description = "Environment of packages installed through home-manager";
};

View File

@@ -1,3 +1,5 @@
#!/usr/bin/env bash
function setupVars() {
local profilesPath="/nix/var/nix/profiles/per-user/$USER"
local gcPath="/nix/var/nix/gcroots/per-user/$USER"
@@ -9,27 +11,38 @@ function setupVars() {
| sort -rn \
| head -1)
if [[ -n "$greatestGenNum" ]] ; then
if [[ -n $greatestGenNum ]] ; then
oldGenNum=$greatestGenNum
newGenNum=$((oldGenNum + 1))
else
newGenNum=1
fi
if [[ -e "$gcPath/current-home" ]] ; then
if [[ -e $gcPath/current-home ]] ; then
oldGenPath="$(readlink -e "$gcPath/current-home")"
fi
$VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath"
if [[ -v oldGenNum && ! -v oldGenPath
|| ! -v oldGenNum && -v oldGenPath ]]; then
errorEcho "Invalid profile number and GC root values! These must be"
errorEcho "either both empty or both set but are now set to"
errorEcho " '${oldGenNum:-}' and '${oldGenPath:-}'"
errorEcho "If you don't mind losing previous profile generations then"
errorEcho "the easiest solution is probably to run"
errorEcho " rm $profilesPath/home-manager*"
errorEcho " rm $gcPath/current-home"
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"
}
setupVars
echo "Starting home manager activation"
if [[ -v VERBOSE ]]; then
export VERBOSE_ECHO=echo
export VERBOSE_ARG="--verbose"
@@ -38,6 +51,10 @@ else
export VERBOSE_ARG=""
fi
echo "Starting home manager activation"
setupVars
if [[ -v DRY_RUN ]] ; then
echo "This is a dry run"
export DRY_RUN_CMD=echo
@@ -46,6 +63,11 @@ else
export DRY_RUN_CMD=""
fi
if [[ -v VERBOSE ]]; then
echo -n "Using Nix version: "
nix-env --version
fi
$VERBOSE_ECHO "Activation variables:"
if [[ -v oldGenNum ]] ; then
$VERBOSE_ECHO " oldGenNum=$oldGenNum"

View File

@@ -16,5 +16,8 @@
entryBefore = d.dagEntryBefore;
};
strings = import ./strings.nix { inherit lib; };
shell = import ./shell.nix { inherit lib; };
zsh = import ./zsh.nix { inherit lib; };
}

View File

@@ -4,27 +4,7 @@ with lib;
let
# Figures out a valid Nix store name for the given path.
storeFileName = path:
let
# All characters that are considered safe. Note "-" is not
# included to avoid "-" followed by digit being interpreted as a
# version.
safeChars =
[ "+" "." "_" "?" "=" ]
++ lowerChars
++ upperChars
++ stringToCharacters "0123456789";
empties = l: genList (x: "") (length l);
unsafeInName = stringToCharacters (
replaceStrings safeChars (empties safeChars) path
);
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
in
"home_file_" + safeName;
stringsExtra = import ./strings.nix { inherit lib; };
in
@@ -95,6 +75,17 @@ in
are symbolic links to the files of the source directory.
'';
};
onChange = mkOption {
type = types.lines;
default = "";
description = ''
Shell commands to run when file has changed between
generations. The script will be run
<emphasis>after</emphasis> the new files have been linked
into place.
'';
};
};
config = {
@@ -102,7 +93,7 @@ in
source = mkIf (config.text != null) (
mkDefault (pkgs.writeTextFile {
inherit (config) executable text;
name = storeFileName name;
name = stringsExtra.storeFileName name;
})
);
};

27
modules/lib/strings.nix Normal file
View File

@@ -0,0 +1,27 @@
{ lib }:
with lib;
{
# Figures out a valid Nix store name for the given path.
storeFileName = path:
let
# All characters that are considered safe. Note "-" is not
# included to avoid "-" followed by digit being interpreted as a
# version.
safeChars =
[ "+" "." "_" "?" "=" ]
++ lowerChars
++ upperChars
++ stringToCharacters "0123456789";
empties = l: genList (x: "") (length l);
unsafeInName = stringToCharacters (
replaceStrings safeChars (empties safeChars) path
);
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
in
"hm_" + safeName;
}

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

@@ -0,0 +1,28 @@
{ lib }:
rec {
# Produces a Zsh shell like value
toZshValue = v: if builtins.isBool v then
if v then "true" else "false"
else if builtins.isString v then
"\"${v}\""
else if builtins.isList v then
"(${lib.concatStringsSep " " (map toZshValue v)})"
else "\"${toString v}\"";
# Produces a Zsh shell like definition statement
define = n: v: "${n}=${toZshValue v}";
# Given an attribute set containing shell variable names and their
# assignments, this function produces a string containing a definition
# statement for each set entry.
defineAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList define vars);
# Produces a Zsh shell like export statement
export = n: v: "export ${define n v}";
# Given an attribute set containing shell variable names and their
# assignments, this function produces a string containing an export
# statement for each set entry.
exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars);
}

View File

@@ -4,19 +4,21 @@ with lib;
let
cfg = config.manual;
/* For the purpose of generating docs, evaluate options with each derivation
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
It isn't perfect, but it seems to cover a vast majority of use cases.
Caveat: even if the package is reached by a different means,
the path above will be shown and not e.g. `${config.services.foo.package}`. */
nixosManual = import <nixpkgs/nixos/doc/manual> {
homeManagerManual = import ../doc {
inherit pkgs config;
version = "0.1";
revision = "release-0.1";
revision = "master";
options =
let
scrubbedEval = evalModules {
modules = [ { nixpkgs.system = pkgs.stdenv.system; } ] ++ baseModules;
modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules;
args = (config._module.args) // { modules = [ ]; };
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
};
@@ -32,18 +34,42 @@ let
in scrubbedEval.options;
};
homeEnvironmentManPages = pkgs.runCommand "home-environment-manpages" {
allowedReferences = [ "out" ];
} ''
install -v -D -m444 \
${nixosManual.manpages}/share/man/man5/configuration.nix.5 \
$out/share/man/man5/home-configuration.nix.5
'';
manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";
helpScript = pkgs.writeShellScriptBin "home-manager-help" ''
#!${pkgs.bash}/bin/bash -e
if [ -z "$BROWSER" ]; then
for candidate in xdg-open open w3m; do
BROWSER="$(type -P $candidate || true)"
if [ -x "$BROWSER" ]; then
break;
fi
done
fi
if [ -z "$BROWSER" ]; then
echo "$0: unable to start a web browser; please set \$BROWSER"
exit 1
fi
exec "$BROWSER" ${manualHtmlRoot}
'';
in
{
options = {
manual.html.enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to install the HTML manual. This also installs the
<command>home-manager-help</command> tool, which opens a local
copy of the Home Manager manual in the system web browser.
'';
};
manual.manpages.enable = mkOption {
type = types.bool;
default = true;
@@ -57,25 +83,32 @@ in
Thanks!
'';
};
manual.json.enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to install a JSON formatted list of all Home Manager
options. This can be located at
<filename>&lt;profile directory&gt;/share/doc/home-manager/options.json</filename>,
and may be used for navigating definitions, auto-completing,
and other miscellaneous tasks.
'';
};
};
config = mkIf config.manual.manpages.enable {
home.packages = [ homeEnvironmentManPages ];
config = {
home.packages = mkMerge [
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
(mkIf cfg.json.enable [ homeManagerManual.optionsJSON ])
];
};
# To fix error during manpage build.
meta = {
maintainers = [ maintainers.rycee ];
doc = builtins.toFile "nothingness" ''
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-nothing">
<title>this is just to make the docs compile</title>
<para xml:id="sec-grsecurity"></para>
<para xml:id="sec-emacs-docbook-xml"></para>
</chapter>
'';
doc = builtins.toFile "nothingness" "";
};
}

89
modules/misc/dconf.nix Normal file
View File

@@ -0,0 +1,89 @@
{ config, lib, pkgs, ... }:
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));
in
{
meta.maintainers = [ maintainers.gnidorah maintainers.rycee ];
options = {
dconf = {
enable = mkOption {
type = types.bool;
default = true;
visible = false;
description = ''
Whether to enable dconf settings.
'';
};
settings = mkOption {
type = with types;
attrsOf (attrsOf (either primitive (listOf primitive)));
default = {};
example = literalExample ''
{
"org/gnome/calculator" = {
button-mode = "programming";
show-thousands = true;
base = 10;
word-size = 64;
};
}
'';
description = ''
Settings to write to the dconf configuration system.
'';
};
};
};
config = mkIf (cfg.enable && cfg.settings != {}) {
home.activation.dconfSettings = dag.entryAfter ["installPackages"] (
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
in
''
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
DCONF_DBUS_RUN_SESSION=""
else
DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session"
fi
if [[ -v DRY_RUN ]]; then
echo $DCONF_DBUS_RUN_SESSION ${pkgs.gnome3.dconf}/bin/dconf load / "<" ${iniFile}
else
$DCONF_DBUS_RUN_SESSION ${pkgs.gnome3.dconf}/bin/dconf load / < ${iniFile}
fi
unset DCONF_DBUS_RUN_SESSION
''
);
};
}

View File

@@ -33,8 +33,8 @@ in
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<dir>~/.nix-profile/lib/X11/fonts</dir>
<dir>~/.nix-profile/share/fonts</dir>
<dir>${config.home.profileDirectory}/lib/X11/fonts</dir>
<dir>${config.home.profileDirectory}/share/fonts</dir>
</fontconfig>
'';
};

View File

@@ -76,6 +76,12 @@ in
{
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkRemovedOptionModule ["gtk" "gtk3" "waylandSupport"] ''
This options is not longer needed and can be removed.
'')
];
options = {
gtk = {
enable = mkEnableOption "GTK 2/3 configuration";
@@ -100,48 +106,36 @@ in
description = "The GTK+2/3 theme to use.";
};
gtk2 = mkOption {
description = "Options specific to GTK+ 2";
default = {};
type = types.submodule {
options = {
extraConfig = mkOption {
type = types.lines;
default = "";
example = "gtk-can-change-accels = 1";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.gtkrc-2.0</filename>.
'';
};
};
gtk2 = {
extraConfig = mkOption {
type = types.lines;
default = "";
example = "gtk-can-change-accels = 1";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.gtkrc-2.0</filename>.
'';
};
};
gtk3 = mkOption {
description = "Options specific to GTK+ 3";
default = {};
type = types.submodule {
options = {
extraConfig = mkOption {
type = types.attrs;
default = {};
example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
description = ''
Extra configuration options to add to
<filename>~/.config/gtk-3.0/settings.ini</filename>.
'';
};
gtk3 = {
extraConfig = mkOption {
type = with types; attrsOf (either bool (either int str));
default = {};
example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
description = ''
Extra configuration options to add to
<filename>~/.config/gtk-3.0/settings.ini</filename>.
'';
};
extraCss = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.config/gtk-3.0/gtk.css</filename>.
'';
};
};
extraCss = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.config/gtk-3.0/gtk.css</filename>.
'';
};
};
};
@@ -159,11 +153,20 @@ in
optionalAttrs (cfg.iconTheme != null)
{ gtk-icon-theme-name = cfg.iconTheme.name; };
dconfIni =
optionalAttrs (cfg.font != null)
{ font-name = cfg.font.name; }
//
optionalAttrs (cfg.theme != null)
{ gtk-theme = cfg.theme.name; }
//
optionalAttrs (cfg.iconTheme != null)
{ icon-theme = cfg.iconTheme.name; };
optionalPackage = opt:
optional (opt != null && opt.package != null) opt.package;
in
{
home.packages =
optionalPackage cfg.font
++ optionalPackage cfg.theme
@@ -178,6 +181,8 @@ in
toGtk3Ini { Settings = ini // cfg3.extraConfig; };
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
dconf.settings."org/gnome/desktop/interface" = dconfIni;
}
);
}

14
modules/misc/lib.nix Normal file
View File

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

View File

@@ -6,6 +6,8 @@ let
cfg = config.news;
hostPlatform = pkgs.stdenv.hostPlatform;
entryModule = types.submodule ({ config, ... }: {
options = {
id = mkOption {
@@ -240,25 +242,6 @@ in
'';
}
{
time = "2017-09-30T09:44:18+00:00";
condition = with config.programs.vim;
enable && (tabSize != null || lineNumbers != null);
message = ''
The options 'programs.vim.tabSize' and 'programs.vim.lineNumbers' have
been deprecated and will be removed in the near future.
The new and preferred way to configure tab size and line numbers is to
use the more general 'programs.vim.settings' option. Specifically,
instead of
- 'programs.vim.lineNumbers' use 'programs.vim.settings.number', and
- 'programs.vim.tabSize' use 'programs.vim.settings.tabstop' and
'programs.vim.settings.shiftwidth'.
'';
}
{
time = "2017-10-02T11:15:03+00:00";
condition = config.services.udiskie.enable;
@@ -479,17 +462,6 @@ in
'';
}
{
time = "2018-01-25T11:35:08+00:00";
condition = options.services.qsyncthingtray.enable.isDefined;
message = ''
'services.qsyncthingtray' has been merged into 'services.syncthing'.
Please, use 'services.syncthing.tray' option to activate the tray service.
The old module will be removed on February 25, 2018.
'';
}
{
time = "2018-02-02T11:15:00+00:00";
message = ''
@@ -560,6 +532,539 @@ in
feature is slowly forthcoming.
'';
}
{
time = "2018-02-09T21:14:42+00:00";
condition = with config.programs.rofi; enable && colors != null;
message = ''
The new and preferred way to configure the rofi theme is
using rasi themes through the 'programs.rofi.theme' option.
This option can take as value either the name of a
pre-installed theme or the path to a theme file.
A rasi theme can be generated from an Xresources config
using 'rofi -dump-theme'.
The option 'programs.rofi.colors' is still supported but may
become deprecated and removed in the future.
'';
}
{
time = "2018-02-19T21:45:26+00:00";
message = ''
A new module is available: 'programs.pidgin'
'';
}
{
time = "2018-03-04T06:54:26+00:00";
message = ''
A new module is available: 'services.unclutter'
'';
}
{
time = "2018-03-07T21:38:27+00:00";
message = ''
A new module is available: 'programs.fzf'.
'';
}
{
time = "2018-03-25T06:49:57+00:00";
condition = with config.programs.ssh; enable && matchBlocks != {};
message = ''
Options set through the 'programs.ssh' module are now placed
at the end of the SSH configuration file. This was done to
make it possible to override global options such as
'ForwardAgent' or 'Compression' inside a host match block.
If you truly need to override an SSH option across all match
blocks then the new option
programs.ssh.extraOptionOverrides
can be used.
'';
}
{
time = "2018-04-19T07:42:01+00:00";
message = ''
A new module is available: 'programs.autorandr'.
'';
}
{
time = "2018-04-19T15:44:55+00:00";
condition = config.programs.git.enable;
message = ''
A new option 'programs.git.includes' is available. Additional
Git configuration files may be included via
programs.git.includes = [
{ path = "~/path/to/config.inc"; }
];
or conditionally via
programs.git.includes = [
{ path = "~/path/to/config.inc"; condition = "gitdir:~/src/"; }
];
and the corresponding '[include]' or '[includeIf]' sections will be
appended to the main Git configuration file.
'';
}
{
time = "2018-05-01T20:49:31+00:00";
message = ''
A new module is available: 'services.mbsync'.
'';
}
{
time = "2018-05-03T12:34:47+00:00";
message = ''
A new module is available: 'services.flameshot'.
'';
}
{
time = "2018-05-18T18:34:15+00:00";
message = ''
A new module is available: 'qt'
At the moment this module allows you to set up Qt to use the
GTK+ theme, and not much else.
'';
}
{
time = "2018-06-05T01:36:45+00:00";
message = ''
A new module is available: 'services.kdeconnect'.
'';
}
{
time = "2018-06-09T09:11:59+00:00";
message = ''
A new module is available: `programs.newsboat`.
'';
}
{
time = "2018-07-01T14:33:15+00:00";
message = ''
A new module is available: 'accounts.email'.
As the name suggests, this new module offers a number of
options for configuring email accounts. This, for example,
includes the email address and owner's real name but also
server settings for IMAP and SMTP.
The intent is to have a central location for account
specific configuration that other modules can use.
Note, this module is still somewhat experimental and its
structure should not be seen as final. Feedback is greatly
appreciated, both positive and negative.
'';
}
{
time = "2018-07-01T16:07:04+00:00";
message = ''
A new module is available: 'programs.mbsync'.
'';
}
{
time = "2018-07-01T16:12:20+00:00";
message = ''
A new module is available: 'programs.notmuch'.
'';
}
{
time = "2018-07-07T15:48:56+00:00";
message = ''
A new module is available: 'xsession.windowManager.awesome'.
'';
}
{
time = "2018-07-18T20:14:11+00:00";
message = ''
A new module is available: 'services.mpd'.
'';
}
{
time = "2018-07-31T13:33:39+00:00";
message = ''
A new module is available: 'services.status-notifier-watcher'.
'';
}
{
time = "2018-07-31T13:47:06+00:00";
message = ''
A new module is available: 'programs.direnv'.
'';
}
{
time = "2018-08-17T20:30:14+00:00";
message = ''
A new module is available: 'programs.fish'.
'';
}
{
time = "2018-08-18T19:03:42+00:00";
condition = config.services.gpg-agent.enable;
message = ''
A new option is available: 'services.gpg-agent.extraConfig'.
Extra lines may be appended to $HOME/.gnupg/gpg-agent.conf
using this option.
'';
}
{
time = "2018-08-19T20:46:09+00:00";
condition = hostPlatform.isLinux;
message = ''
A new modules is available: 'programs.chromium'.
'';
}
{
time = "2018-08-20T20:27:26+00:00";
message = ''
A new module is available: 'programs.msmtp'.
'';
}
{
time = "2018-08-21T20:13:50+00:00";
message = ''
A new module is available: 'services.pasystray'.
'';
}
{
time = "2018-08-29T20:27:04+00:00";
message = ''
A new module is available: 'programs.offlineimap'.
'';
}
{
time = "2018-09-18T21:25:14+00:00";
message = ''
A new module is available: 'programs.taskwarrior'.
'';
}
{
time = "2018-09-18T21:43:54+00:00";
message = ''
A new module is available: 'programs.zathura'.
'';
}
{
time = "2018-09-20T19:26:40+00:00";
message = ''
A new module is available: 'programs.noti'.
'';
}
{
time = "2018-09-20T22:10:45+00:00";
message = ''
A new module is available: 'programs.go'.
'';
}
{
time = "2018-09-27T17:48:08+00:00";
message = ''
A new module is available: 'programs.obs-studio'.
'';
}
{
time = "2018-09-28T21:38:48+00:00";
message = ''
A new module is available: 'programs.alot'.
'';
}
{
time = "2018-10-20T09:30:57+00:00";
message = ''
A new module is available: 'programs.urxvt'.
'';
}
{
time = "2018-11-13T23:08:03+00:00";
message = ''
A new module is available: 'programs.tmux'.
'';
}
{
time = "2018-11-18T18:55:15+00:00";
message = ''
A new module is available: 'programs.astroid'.
'';
}
{
time = "2018-11-18T21:41:51+00:00";
message = ''
A new module is available: 'programs.afew'.
'';
}
{
time = "2018-11-19T00:40:34+00:00";
message = ''
A new nix-darwin module is available. Use it the same way the NixOS
module is used. A major limitation is that Home Manager services don't
work, as they depend explicitly on Linux and systemd user services.
However, 'home.file' and 'home.packages' do work. Everything else is
untested at this time.
'';
}
{
time = "2018-11-24T16:22:19+00:00";
message = ''
A new option 'home.stateVersion' is available. Its function
is much like the 'system.stateVersion' option in NixOS.
Briefly, the state version indicates a stable set of option
defaults. In the future, whenever Home Manager changes an
option default in a way that may cause program breakage it
will do so only for the unstable state version, currently
19.03. Once 19.03 becomes the stable version only backwards
compatible changes will be made and 19.09 becomes the
unstable state version.
The default value for this option is 18.09 but it may still
be a good idea to explicitly add
home.stateVersion = "18.09";
to your Home Manager configuration.
'';
}
{
time = "2018-11-25T22:10:15+00:00";
message = ''
A new module is available: 'services.nextcloud-client'.
'';
}
{
time = "2018-11-25T22:55:12+00:00";
message = ''
A new module is available: 'programs.vscode'.
'';
}
{
time = "2018-12-04T21:54:38+00:00";
condition = config.programs.beets.settings != {};
message = ''
A new option 'programs.beets.enable' has been added.
Starting with state version 19.03 this option defaults to
false. For earlier versions it defaults to true if
'programs.beets.settings' is non-empty.
It is recommended to explicitly add
programs.beets.enable = true;
to your configuration.
'';
}
{
time = "2018-12-12T21:02:05+00:00";
message = ''
A new module is available: 'programs.jq'.
'';
}
{
time = "2018-12-24T16:26:16+00:00";
message = ''
A new module is available: 'dconf'.
Note, on NixOS you may need to add
services.dbus.packages = with pkgs; [ gnome3.dconf ];
to the system configuration for this module to work as
expected. In particular if you get the error message
The name ca.desrt.dconf was not provided by any .service files
when activating your Home Manager configuration.
'';
}
{
time = "2018-12-28T12:32:30+00:00";
message = ''
A new module is available: 'programs.opam'.
'';
}
{
time = "2019-01-18T00:21:56+00:00";
message = ''
A new module is available: 'programs.matplotlib'.
'';
}
{
time = "2019-01-26T13:20:37+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.xembed-sni-proxy'.
'';
}
{
time = "2019-01-28T23:36:10+00:00";
message = ''
A new module is available: 'programs.irssi'.
'';
}
{
time = "2019-02-09T14:09:58+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.emacs'.
This module provides a user service that runs the Emacs
configured in
programs.emacs
as an Emacs daemon.
'';
}
{
time = "2019-02-16T20:33:56+00:00";
condition = hostPlatform.isLinux;
message = ''
When using Home Manager as a NixOS submodule it is now
possible to install packages using the NixOS
users.users.<name?>.packages
option. This is enabled by adding
home-manager.useUserPackages = true;
to your NixOS system configuration. This mode of operation
is necessary if you want to use 'nixos-rebuild build-vm'.
'';
}
{
time = "2019-02-17T21:11:24+00:00";
message = ''
A new module is available: 'programs.keychain'.
'';
}
{
time = "2019-02-24T00:32:23+00:00";
condition = hostPlatform.isLinux;
message = ''
A new service is available: 'services.mpdris2'.
'';
}
{
time = "2019-03-19T22:56:20+00:00";
message = ''
A new module is available: 'programs.bat'.
'';
}
{
time = "2019-03-19T23:07:34+00:00";
message = ''
A new module is available: 'programs.lsd'.
'';
}
{
time = "2019-04-09T20:10:22+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.xcape'.
'';
}
{
time = "2019-04-11T22:50:10+00:00";
condition = hostPlatform.isLinux;
message = ''
The type used for the systemd unit options under
systemd.user.services, systemd.user.sockets, etc.
has been changed to offer more robust merging of configurations.
If you don't override values within systemd units then you are not
affected by this change. Unfortunately, if you do override unit values
you may encounter errors due to this change.
In particular, if you get an error saying that a "unique option" is
"defined multiple times" then you need to use 'lib.mkForce'. For
example,
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
becomes
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
We had to make this change because the old merging was causing too
many confusing situations for people. Apologies for potentially
breaking your configuration!
'';
}
{
time = "2019-04-14T15:35:16+00:00";
message = ''
A new module is available: 'programs.skim'.
'';
}
{
time = "2019-04-22T12:43:20+00:00";
message = ''
A new module is available: 'programs.alacritty'.
'';
}
];
};
}

View File

@@ -34,7 +34,11 @@ let
configType = mkOptionType {
name = "nixpkgs-config";
description = "nixpkgs config";
check = traceValIfNot isConfig;
check = x:
let traceXIfNot = c:
if c x then true
else lib.traceSeqN 1 x false;
in traceXIfNot isConfig;
merge = args: fold (def: mergeConfig def.value) {};
};
@@ -61,10 +65,27 @@ in
The configuration of the Nix Packages collection. (For
details, see the Nixpkgs documentation.) It allows you to set
package configuration options.
</para><para>
If <literal>null</literal>, then configuration is taken from
the fallback location, for example,
<filename>~/.config/nixpkgs/config.nix</filename>.
</para><para>
Note, this option will not apply outside your Home Manager
configuration like when installing manually through
<command>nix-env</command>. If you want to apply it both
inside and outside Home Manager you can put it in a separate
file and include something like
<programlisting language="nix">
nixpkgs.config = import ./nixpkgs-config.nix;
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
</programlisting>
in your Home Manager configuration.
'';
};
@@ -89,10 +110,19 @@ in
an argument the <emphasis>original</emphasis> Nixpkgs. The
first argument should be used for finding dependencies, and
the second should be used for overriding recipes.
</para><para>
If <literal>null</literal>, then the overlays are taken from
the fallback location, for example,
<filename>~/.config/nixpkgs/overlays</filename>.
</para><para>
Like <varname>nixpkgs.config</varname> this option only
applies within the Home Manager configuration. See
<varname>nixpkgs.config</varname> for a suggested setup that
works both internally and externally.
'';
};
@@ -113,7 +143,10 @@ in
config = {
_module.args = {
pkgs = _pkgs;
pkgs_i686 = _pkgs.pkgsi686Linux;
pkgs_i686 =
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
then _pkgs.pkgsi686Linux
else { };
};
};
}

View File

@@ -30,7 +30,7 @@ in
config = mkIf (vars != {}) {
home.file.".pam_environment".text =
concatStringsSep "\n" (
mapAttrsToList (n: v: "${n} OVERRIDE=${toString v}") vars
mapAttrsToList (n: v: "${n} OVERRIDE=\"${toString v}\"") vars
) + "\n";
};
}

78
modules/misc/qt.nix Normal file
View File

@@ -0,0 +1,78 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qt;
dag = config.lib.dag;
in
{
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkChangedOptionModule
[ "qt" "useGtkTheme" ]
[ "qt" "platformTheme" ]
(config:
if getAttrFromPath [ "qt" "useGtkTheme" ] config
then "gtk"
else null))
];
options = {
qt = {
enable = mkEnableOption "Qt 4 and 5 configuration";
platformTheme = mkOption {
type = types.nullOr (types.enum [ "gtk" "gnome" ]);
default = null;
example = "gnome";
relatedPackages = [
"qgnomeplatform"
["libsForQt5" "qtstyleplugins"]
];
description = ''
Selects the platform theme to use for Qt applications.</para>
<para>The options are
<variablelist>
<varlistentry>
<term><literal>gtk</literal></term>
<listitem><para>Use GTK theme with
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>gnome</literal></term>
<listitem><para>Use GNOME theme with
<link xlink:href="https://github.com/FedoraQt/QGnomePlatform">qgnomeplatform</link>
</para></listitem>
</varlistentry>
</variablelist>
'';
};
};
};
config = mkIf (cfg.enable && cfg.platformTheme != null) {
home.sessionVariables.QT_QPA_PLATFORMTHEME =
if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
home.packages =
if cfg.platformTheme == "gnome"
then [ pkgs.qgnomeplatform ]
else [ pkgs.libsForQt5.qtstyleplugins ];
xsession.profileExtra =
"systemctl --user import-environment QT_QPA_PLATFORMTHEME";
# Enable GTK+ style for Qt4 in either case.
# It doesnt support the platform theme packages.
home.activation.useGtkThemeInQt4 = dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
--set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+
'';
};
}

View File

@@ -0,0 +1,32 @@
{ lib, ... }:
with lib;
{
meta.maintainers = [ maintainers.rycee ];
options.submoduleSupport = {
enable = mkOption {
type = types.bool;
default = false;
internal = true;
description = ''
Whether the Home Manager module system is used as a submodule
in, for example, NixOS or nix-darwin.
'';
};
externalPackageInstall = mkOption {
type = types.bool;
default = false;
internal = true;
description = ''
Whether the packages of <option>home.packages</option> are
installed separately from the Home Manager activation script.
In NixOS, for example, this may be accomplished by installing
the packages through
<option>users.users.&lt;name?&gt;.packages</option>.
'';
};
};
}

24
modules/misc/version.nix Normal file
View File

@@ -0,0 +1,24 @@
{ config, lib, ... }:
with lib;
{
options = {
home.stateVersion = mkOption {
type = types.enum [ "18.09" "19.03" "19.09" ];
default = "18.09";
description = ''
It is occasionally necessary for Home Manager to change
configuration defaults in a way that is incompatible with
stateful data. This could, for example, include switching the
default data format or location of a file.
</para><para>
The <emphasis>state version</emphasis> indicates which default
settings are in effect and will therefore help avoid breaking
program configurations. Switching to a higher state version
typically requires performing some manual steps, such as data
conversion or moving files.
'';
};
};
}

View File

@@ -6,6 +6,8 @@ let
cfg = config.xdg;
dag = config.lib.dag;
fileType = (import ../lib/file-type.nix {
inherit (config.home) homeDirectory;
inherit lib pkgs;
@@ -91,6 +93,9 @@ in
{
home.file = mkMerge [ cfg.configFile cfg.dataFile ];
home.activation.xdgCreateCache = dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir $VERBOSE_ARG -m0700 -p "${config.xdg.cacheHome}"
'';
}
];
}

View File

@@ -3,92 +3,141 @@
# Whether to enable module type checking.
, check ? true
# Whether these modules are inside a NixOS submodule.
, nixosSubmodule ? false
}:
with lib;
let
modules = [
./files.nix
./home-environment.nix
./manual.nix
./misc/fontconfig.nix
./misc/gtk.nix
./misc/news.nix
./misc/nixpkgs.nix
./misc/pam.nix
./misc/xdg.nix
./programs/bash.nix
./programs/beets.nix
./programs/browserpass.nix
./programs/command-not-found/command-not-found.nix
./programs/eclipse.nix
./programs/emacs.nix
./programs/feh.nix
./programs/firefox.nix
./programs/git.nix
./programs/gnome-terminal.nix
./programs/home-manager.nix
./programs/htop.nix
./programs/info.nix
./programs/lesspipe.nix
./programs/man.nix
./programs/mercurial.nix
./programs/neovim.nix
./programs/rofi.nix
./programs/ssh.nix
./programs/termite.nix
./programs/texlive.nix
./programs/vim.nix
./programs/zsh.nix
./services/blueman-applet.nix
./services/compton.nix
./services/dunst.nix
./services/gnome-keyring.nix
./services/gpg-agent.nix
./services/kbfs.nix
./services/keepassx.nix
./services/keybase.nix
./services/network-manager-applet.nix
./services/owncloud-client.nix
./services/parcellite.nix
./services/polybar.nix
./services/random-background.nix
./services/redshift.nix
./services/screen-locker.nix
./services/stalonetray.nix
./services/syncthing.nix
./services/taffybar.nix
./services/tahoe-lafs.nix
./services/udiskie.nix
./services/window-managers/i3.nix
./services/window-managers/xmonad.nix
./services/xscreensaver.nix
./systemd.nix
./xcursor.nix
./xresources.nix
./xsession.nix
<nixpkgs/nixos/modules/misc/assertions.nix>
<nixpkgs/nixos/modules/misc/lib.nix>
<nixpkgs/nixos/modules/misc/meta.nix>
hostPlatform = pkgs.stdenv.hostPlatform;
checkPlatform = any (meta.platformMatch pkgs.stdenv.hostPlatform);
loadModule = file: { condition ? true }: {
inherit file condition;
};
allModules = [
(loadModule ./accounts/email.nix { })
(loadModule ./files.nix { })
(loadModule ./home-environment.nix { })
(loadModule ./manual.nix { })
(loadModule ./misc/dconf.nix { })
(loadModule ./misc/fontconfig.nix { })
(loadModule ./misc/gtk.nix { })
(loadModule ./misc/lib.nix { })
(loadModule ./misc/news.nix { })
(loadModule ./misc/nixpkgs.nix { })
(loadModule ./misc/pam.nix { })
(loadModule ./misc/qt.nix { })
(loadModule ./misc/submodule-support.nix { })
(loadModule ./misc/version.nix { })
(loadModule ./misc/xdg.nix { })
(loadModule ./programs/afew.nix { })
(loadModule ./programs/alacritty.nix { })
(loadModule ./programs/alot.nix { })
(loadModule ./programs/astroid.nix { })
(loadModule ./programs/autorandr.nix { })
(loadModule ./programs/bash.nix { })
(loadModule ./programs/bat.nix { })
(loadModule ./programs/beets.nix { })
(loadModule ./programs/browserpass.nix { })
(loadModule ./programs/chromium.nix { condition = hostPlatform.isLinux; })
(loadModule ./programs/command-not-found/command-not-found.nix { })
(loadModule ./programs/direnv.nix { })
(loadModule ./programs/eclipse.nix { })
(loadModule ./programs/emacs.nix { })
(loadModule ./programs/feh.nix { })
(loadModule ./programs/firefox.nix { })
(loadModule ./programs/fish.nix { })
(loadModule ./programs/fzf.nix { })
(loadModule ./programs/git.nix { })
(loadModule ./programs/gnome-terminal.nix { })
(loadModule ./programs/go.nix { })
(loadModule ./programs/home-manager.nix { })
(loadModule ./programs/htop.nix { })
(loadModule ./programs/info.nix { })
(loadModule ./programs/irssi.nix { })
(loadModule ./programs/jq.nix { })
(loadModule ./programs/keychain.nix { })
(loadModule ./programs/lesspipe.nix { })
(loadModule ./programs/lsd.nix { })
(loadModule ./programs/man.nix { })
(loadModule ./programs/matplotlib.nix { })
(loadModule ./programs/mbsync.nix { })
(loadModule ./programs/mercurial.nix { })
(loadModule ./programs/msmtp.nix { })
(loadModule ./programs/neovim.nix { })
(loadModule ./programs/newsboat.nix { })
(loadModule ./programs/noti.nix { })
(loadModule ./programs/notmuch.nix { })
(loadModule ./programs/obs-studio.nix { })
(loadModule ./programs/offlineimap.nix { })
(loadModule ./programs/opam.nix { })
(loadModule ./programs/pidgin.nix { })
(loadModule ./programs/rofi.nix { })
(loadModule ./programs/skim.nix { })
(loadModule ./programs/ssh.nix { })
(loadModule ./programs/taskwarrior.nix { })
(loadModule ./programs/termite.nix { })
(loadModule ./programs/texlive.nix { })
(loadModule ./programs/tmux.nix { })
(loadModule ./programs/urxvt.nix { })
(loadModule ./programs/vim.nix { })
(loadModule ./programs/vscode.nix { })
(loadModule ./programs/zathura.nix { })
(loadModule ./programs/zsh.nix { })
(loadModule ./services/blueman-applet.nix { })
(loadModule ./services/compton.nix { })
(loadModule ./services/dunst.nix { })
(loadModule ./services/emacs.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/flameshot.nix { })
(loadModule ./services/gnome-keyring.nix { })
(loadModule ./services/gpg-agent.nix { })
(loadModule ./services/kbfs.nix { })
(loadModule ./services/kdeconnect.nix { })
(loadModule ./services/keepassx.nix { })
(loadModule ./services/keybase.nix { })
(loadModule ./services/mbsync.nix { })
(loadModule ./services/mpd.nix { })
(loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/network-manager-applet.nix { })
(loadModule ./services/nextcloud-client.nix { })
(loadModule ./services/owncloud-client.nix { })
(loadModule ./services/parcellite.nix { })
(loadModule ./services/pasystray.nix { })
(loadModule ./services/polybar.nix { })
(loadModule ./services/random-background.nix { })
(loadModule ./services/redshift.nix { })
(loadModule ./services/screen-locker.nix { })
(loadModule ./services/stalonetray.nix { })
(loadModule ./services/status-notifier-watcher.nix { })
(loadModule ./services/syncthing.nix { })
(loadModule ./services/taffybar.nix { })
(loadModule ./services/tahoe-lafs.nix { })
(loadModule ./services/udiskie.nix { })
(loadModule ./services/unclutter.nix { })
(loadModule ./services/window-managers/awesome.nix { })
(loadModule ./services/window-managers/i3.nix { })
(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 ./systemd.nix { })
(loadModule ./xcursor.nix { })
(loadModule ./xresources.nix { })
(loadModule ./xsession.nix { })
(loadModule <nixpkgs/nixos/modules/misc/assertions.nix> { })
(loadModule <nixpkgs/nixos/modules/misc/meta.nix> { })
];
pkgsModule = {
options.nixosSubmodule = mkOption {
type = types.bool;
internal = true;
readOnly = true;
};
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.nixosSubmodule = nixosSubmodule;
config.nixpkgs.system = mkDefault pkgs.system;
};

52
modules/programs/afew.nix Normal file
View File

@@ -0,0 +1,52 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.afew;
in
{
options.programs.afew = {
enable = mkEnableOption "the afew initial tagging script for Notmuch";
extraConfig = mkOption {
type = types.lines;
default = ''
[SpamFilter]
[KillThreadsFilter]
[ListMailsFilter]
[ArchiveSentMailsFilter]
[InboxFilter]
'';
example = ''
[SpamFilter]
[Filter.0]
query = from:pointyheaded@boss.com
tags = -new;+boss
message = Message from above
[InboxFilter]
'';
description = ''
Extra lines added to afew configuration file. Available
configuration options are described in the afew manual:
<link xlink:href="https://afew.readthedocs.io/en/latest/configuration.html" />.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.afew ];
xdg.configFile."afew/config".text = ''
# Generated by Home Manager.
# See https://afew.readthedocs.io/
${cfg.extraConfig}
'';
};
}

View File

@@ -0,0 +1,53 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.alacritty;
in
{
options = {
programs.alacritty = {
enable = mkEnableOption "Alacritty";
settings = mkOption {
type = types.attrs;
default = {};
example = literalExample ''
{
window.dimensions = {
lines = 3;
columns = 200;
};
key_bindings = [
{
key = "K";
mods = "Control";
chars = "\\x0c";
}
];
}
'';
description = ''
Configuration written to
<filename>~/.config/alacritty/alacritty.yml</filename>. See
<link xlink:href="https://github.com/jwilm/alacritty/blob/master/alacritty.yml"/>
for the default configuration.
'';
};
};
};
config = mkMerge [
(mkIf cfg.enable {
home.packages = [ pkgs.alacritty ];
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != {}) {
text = replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings);
};
})
];
}

View File

@@ -0,0 +1,61 @@
pkgs:
{ config, lib, ... }:
with lib;
{
options.alot = {
sendMailCommand = mkOption {
type = types.nullOr types.str;
description = ''
Command to send a mail. If msmtp is enabled for the account,
then this is set to
<command>msmtpq --read-envelope-from --read-recipients</command>.
'';
};
contactCompletion = mkOption {
type = types.attrsOf types.str;
default = {
type = "shellcommand";
command = "'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
regexp =
"'\\[?{"
+ ''"name": "(?P<name>.*)", ''
+ ''"address": "(?P<email>.+)", ''
+ ''"name-addr": ".*"''
+ "}[,\\]]?'";
shellcommand_external_filtering = "False";
};
example = literalExample ''
{
type = "shellcommand";
command = "abook --mutt-query";
regexp = "'^(?P<email>[^@]+@[^\t]+)\t+(?P<name>[^\t]+)'";
ignorecase = "True";
}
'';
description = ''
Contact completion configuration as expected per alot.
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
explanation about possible values.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra settings to add to this Alot account configuration.
'';
};
};
config = mkIf config.notmuch.enable {
alot.sendMailCommand = mkOptionDefault (
if config.msmtp.enable
then "msmtpq --read-envelope-from --read-recipients"
else null
);
};
}

171
modules/programs/alot.nix Normal file
View File

@@ -0,0 +1,171 @@
# alot config loader is sensitive to leading space !
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.alot;
alotAccounts = filter (a: a.notmuch.enable)
(attrValues config.accounts.email.accounts);
boolStr = v: if v then "True" else "False";
accountStr = account: with account;
concatStringsSep "\n" (
[ "[[${name}]]" ]
++ mapAttrsToList (n: v: n + "=" + v) (
{
address = address;
realname = realName;
sendmail_command =
optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
}
// optionalAttrs (aliases != []) {
aliases = concatStringsSep "," aliases;
}
// optionalAttrs (gpg != null) {
gpg_key = gpg.key;
encrypt_by_default = if gpg.encryptByDefault then "all" else "none";
sign_by_default = boolStr gpg.signByDefault;
}
// optionalAttrs (signature.showSignature != "none") {
signature = pkgs.writeText "signature.txt" signature.text;
signature_as_attachment =
boolStr (signature.showSignature == "attach");
}
)
++ [ alot.extraConfig ]
++ [ "[[[abook]]]" ]
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion
);
configFile =
let
bindingsToStr = attrSet:
concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${v}") attrSet);
in
''
# Generated by Home Manager.
# See http://alot.readthedocs.io/en/latest/configuration/config_options.html
${cfg.extraConfig}
[bindings]
${bindingsToStr cfg.bindings.global}
[[bufferlist]]
${bindingsToStr cfg.bindings.bufferlist}
[[search]]
${bindingsToStr cfg.bindings.search}
[[envelope]]
${bindingsToStr cfg.bindings.envelope}
[[taglist]]
${bindingsToStr cfg.bindings.taglist}
[[thread]]
${bindingsToStr cfg.bindings.thread}
[accounts]
${concatStringsSep "\n\n" (map accountStr alotAccounts)}
'';
in
{
options.programs.alot = {
enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to enable the Alot mail user agent. Alot uses the
Notmuch email system and will therefore be automatically
enabled for each email account that is managed by Notmuch.
'';
};
hooks = mkOption {
type = types.lines;
default = "";
description = ''
Content of the hooks file.
'';
};
bindings = mkOption {
type = types.submodule {
options = {
global = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Global keybindings.";
};
bufferlist = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Bufferlist mode keybindings.";
};
search = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Search mode keybindings.";
};
envelope = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Envelope mode keybindings.";
};
taglist = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Taglist mode keybindings.";
};
thread = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Thread mode keybindings.";
};
};
};
default = {};
description = ''
Keybindings.
'';
};
extraConfig = mkOption {
type = types.lines;
default = ''
auto_remove_unread = True
ask_subject = False
handle_mouse = True
initial_command = "search tag:inbox AND NOT tag:killed"
input_timeout = 0.3
prefer_plaintext = True
thread_indent_replies = 4
'';
description = ''
Extra lines added to alot configuration file.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.alot ];
xdg.configFile."alot/config".text = configFile;
xdg.configFile."alot/hooks.py".text =
''
# Generated by Home Manager.
''
+ cfg.hooks;
};
}

View File

@@ -0,0 +1,33 @@
{ config, lib, ... }:
with lib;
{
options.astroid = {
enable = mkEnableOption "Astroid";
sendMailCommand = mkOption {
type = types.str;
description = ''
Command to send a mail. If msmtp is enabled for the account,
then this is set to
<command>msmtpq --read-envelope-from --read-recipients</command>.
'';
};
extraConfig = mkOption {
type = types.attrs;
default = {};
example = { select_query = ""; };
description = ''
Extra settings to add to this astroid account configuration.
'';
};
};
config = mkIf config.notmuch.enable {
astroid.sendMailCommand = mkIf config.msmtp.enable (
mkOptionDefault "msmtpq --read-envelope-from --read-recipients"
);
};
}

View File

@@ -0,0 +1,113 @@
{
"astroid": {
"config": {
"version": "11"
},
"debug": {
"dryrun_sending": "false"
},
"hints": {
"level": "0"
},
"log": {
"syslog": "false",
"stdout": "true",
"level": "info"
}
},
"startup": {
"queries": {
"inbox": "tag:inbox"
}
},
"terminal": {
"height": "10",
"font_description": "default"
},
"thread_index": {
"page_jump_rows": "6",
"sort_order": "newest",
"cell": {
"font_description": "default",
"line_spacing": "2",
"date_length": "10",
"message_count_length": "4",
"authors_length": "20",
"subject_color": "#807d74",
"subject_color_selected": "#000000",
"background_color_selected": "",
"background_color_marked": "#fff584",
"background_color_marked_selected": "#bcb559",
"tags_length": "80",
"tags_upper_color": "#e5e5e5",
"tags_lower_color": "#333333",
"tags_alpha": "0.5",
"hidden_tags": "attachment,flagged,unread"
}
},
"general": {
"time": {
"clock_format": "local",
"same_year": "%b %-e",
"diff_year": "%x"
}
},
"editor": {
"charset": "utf-8",
"save_draft_on_force_quit": "true",
"attachment_words": "attach",
"attachment_directory": "~",
"markdown_processor": "marked"
},
"mail": {
"reply": {
"quote_line": "Excerpts from %1's message of %2:",
"mailinglist_reply_to_sender": "true"
},
"forward": {
"quote_line": "Forwarding %1's message of %2:",
"disposition": "inline"
},
"sent_tags": "sent",
"message_id_fqdn": "",
"message_id_user": "",
"user_agent": "default",
"send_delay": "2",
"close_on_success": "false",
"format_flowed": "false"
},
"poll": {
"interval": "60",
"always_full_refresh": "false"
},
"attachment": {
"external_open_cmd": "xdg-open"
},
"thread_view": {
"open_html_part_external": "false",
"preferred_type": "plain",
"preferred_html_only": "false",
"allow_remote_when_encrypted": "false",
"open_external_link": "xdg-open",
"default_save_directory": "~",
"indent_messages": "false",
"gravatar": {
"enable": "true"
},
"mark_unread_delay": "0.5",
"expand_flagged": "true"
},
"crypto": {
"gpg": {
"path": "gpg2",
"always_trust": "true",
"enabled": "true"
}
},
"saved_searches": {
"show_on_startup": "false",
"save_history": "true",
"history_lines_to_show": "15",
"history_lines": "1000"
}
}

View File

@@ -0,0 +1,139 @@
{ config, lib, pkgs, ... }:
with lib;
with builtins;
let
cfg = config.programs.astroid;
astroidAccounts =
filterAttrs
(n: v: v.astroid.enable)
config.accounts.email.accounts;
boolOpt = b: if b then "true" else "false";
accountAttr = account: with account; {
email = address;
name = realName;
sendmail = astroid.sendMailCommand;
additional_sent_tags = "";
default = boolOpt primary;
save_drafts_to = 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;
# See https://github.com/astroidmail/astroid/wiki/Configuration-Reference
configFile = mailAccounts:
let
template = fromJSON (readFile ./astroid-config-template.json);
astroidConfig = foldl' recursiveUpdate template [
{
astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc";
accounts = mapAttrs (n: accountAttr) astroidAccounts;
crypto.gpg.path = "${pkgs.gnupg}/bin/gpg";
}
cfg.extraConfig
cfg.externalEditor
];
in
builtins.toJSON astroidConfig;
in
{
options = {
programs.astroid = {
enable = mkEnableOption "Astroid";
pollScript = mkOption {
type = types.str;
default = "";
example = "mbsync gmail";
description = ''
Script to run to fetch/update mails.
'';
};
externalEditor = mkOption {
type = types.nullOr types.str;
default = null;
# Converts it into JSON that can be merged into the configuration.
apply = cmd:
optionalAttrs (cmd != null) {
editor = {
"external_editor" = "true";
"cmd" = cmd;
};
};
example = "nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
description = ''
You can use <code>%1</code>, <code>%2</code>, and
<code>%3</code> to refer respectively to:
<orderedlist numeration="arabic">
<listitem><para>file name</para></listitem>
<listitem><para>server name</para></listitem>
<listitem><para>socket ID</para></listitem>
</orderedlist>
See <link xlink:href='https://github.com/astroidmail/astroid/wiki/Customizing-editor' />.
'';
};
extraConfig = mkOption {
type = types.attrs;
default = {};
example = { poll.interval = 0; };
description = ''
JSON config that will override the default Astroid configuration.
'';
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = config.programs.notmuch.maildir.synchronizeFlags;
message = "The astroid module requires"
+ " 'programs.notmuch.maildir.synchronizeFlags = true'.";
}
];
home.packages = [ pkgs.astroid ];
xdg.configFile."astroid/config".source =
pkgs.runCommand "out.json"
{
json = configFile astroidAccounts;
preferLocalBuild = true;
allowSubstitutes = false;
}
''
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
'';
xdg.configFile."astroid/poll.sh" = {
executable = true;
text = ''
# Generated by Home Manager
${cfg.pollScript}
'';
};
};
}

View File

@@ -0,0 +1,349 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.autorandr;
matrixOf = n: m: elemType: mkOptionType rec {
name = "matrixOf";
description = "${toString n}×${toString m} matrix of ${elemType.description}s";
check = xss:
let
listOfSize = l: xs: isList xs && length xs == l;
in
listOfSize n xss && all (xs: listOfSize m xs && all elemType.check xs) xss;
merge = mergeOneOption;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*" "*"]);
getSubModules = elemType.getSubModules;
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
functor = (defaultFunctor name) // { wrapped = elemType; };
};
profileModule = types.submodule {
options = {
fingerprint = mkOption {
type = types.attrsOf types.str;
description = ''
Output name to EDID mapping.
Use <code>autorandr --fingerprint</code> to get current setup values.
'';
default = {};
};
config = mkOption {
type = types.attrsOf configModule;
description = "Per output profile configuration.";
default = {};
};
hooks = mkOption {
type = profileHooksModule;
description = "Profile hook scripts.";
default = {};
};
};
};
configModule = types.submodule {
options = {
enable = mkOption {
type = types.bool;
description = "Whether to enable the output.";
default = true;
};
primary = mkOption {
type = types.bool;
description = "Whether output should be marked as primary";
default = false;
};
position = mkOption {
type = types.str;
description = "Output position";
default = "";
example = "5760x0";
};
mode = mkOption {
type = types.str;
description = "Output resolution.";
default = "";
example = "3840x2160";
};
rate = mkOption {
type = types.str;
description = "Output framerate.";
default = "";
example = "60.00";
};
gamma = mkOption {
type = types.str;
description = "Output gamma configuration.";
default = "";
example = "1.0:0.909:0.833";
};
rotate = mkOption {
type = types.nullOr (types.enum ["normal" "left" "right" "inverted"]);
description = "Output rotate configuration.";
default = null;
example = "left";
};
transform = mkOption {
type = types.nullOr (matrixOf 3 3 types.float);
default = null;
example = literalExample ''
[
[ 0.6 0.0 0.0 ]
[ 0.0 0.6 0.0 ]
[ 0.0 0.0 1.0 ]
]
'';
description = ''
Refer to
<citerefentry>
<refentrytitle>xrandr</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
for the documentation of the transform matrix.
'';
};
dpi = mkOption {
type = types.nullOr types.ints.positive;
description = "Output DPI configuration.";
default = null;
example = 96;
};
scale = mkOption {
type = types.nullOr (types.submodule {
options = {
method = mkOption {
type = types.enum ["factor" "pixel" ];
description = "Output scaling method.";
default = "factor";
example = "pixel";
};
x = mkOption {
type = types.either types.float types.ints.positive;
description = "Horizontal scaling factor/pixels.";
};
y = mkOption {
type = types.either types.float types.ints.positive;
description = "Vertical scaling factor/pixels.";
};
};
});
description = ''
Output scale configuration.
</para><para>
Either configure by pixels or a scaling factor. When using pixel method the
<citerefentry>
<refentrytitle>xrandr</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
option
<parameter class="command">--scale-from</parameter>
will be used; when using factor method the option
<parameter class="command">--scale</parameter>
will be used.
</para><para>
This option is a shortcut version of the transform option and they are mutually
exclusive.
'';
default = null;
example = literalExample ''
{
x = 1.25;
y = 1.25;
}
'';
};
};
};
hookType = types.lines;
globalHooksModule = types.submodule {
options = {
postswitch = mkOption {
type = types.attrsOf hookType;
description = "Postswitch hook executed after mode switch.";
default = {};
};
preswitch = mkOption {
type = types.attrsOf hookType;
description = "Preswitch hook executed before mode switch.";
default = {};
};
predetect = mkOption {
type = types.attrsOf hookType;
description = "Predetect hook executed before autorandr attempts to run xrandr.";
default = {};
};
};
};
profileHooksModule = types.submodule {
options = {
postswitch = mkOption {
type = hookType;
description = "Postswitch hook executed after mode switch.";
default = "";
};
preswitch = mkOption {
type = hookType;
description = "Preswitch hook executed before mode switch.";
default = "";
};
predetect = mkOption {
type = hookType;
description = "Predetect hook executed before autorandr attempts to run xrandr.";
default = "";
};
};
};
hookToFile = folder: name: hook:
nameValuePair
"autorandr/${folder}/${name}"
{ source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook"; };
profileToFiles = name: profile: with profile; mkMerge ([
{
"autorandr/${name}/setup".text = concatStringsSep "\n" (mapAttrsToList fingerprintToString fingerprint);
"autorandr/${name}/config".text = concatStringsSep "\n" (mapAttrsToList configToString profile.config);
}
(mkIf (hooks.postswitch != "") (listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
(mkIf (hooks.preswitch != "") (listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
(mkIf (hooks.predetect != "") (listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
]);
fingerprintToString = name: edid: "${name} ${edid}";
configToString = name: config: if config.enable then ''
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
{
options = {
programs.autorandr = {
enable = mkEnableOption "Autorandr";
hooks = mkOption {
type = globalHooksModule;
description = "Global hook scripts";
default = {};
example = literalExample ''
{
postswitch = {
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
"change-background" = readFile ./change-background.sh;
"change-dpi" = '''
case "$AUTORANDR_CURRENT_PROFILE" in
default)
DPI=120
;;
home)
DPI=192
;;
work)
DPI=144
;;
*)
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
exit 1
esac
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
'''
};
}
'';
};
profiles = mkOption {
type = types.attrsOf profileModule;
description = "Autorandr profiles specification.";
default = {};
example = literalExample ''
{
"work" = {
fingerprint = {
eDP1 = "<EDID>";
DP1 = "<EDID>";
};
config = {
eDP1.enable = false;
DP1 = {
enable = true;
primary = true;
position = "0x0";
mode = "3840x2160";
gamma = "1.0:0.909:0.833";
rate = "60.00";
rotate = "left";
};
};
hooks.postswitch = readFile ./work-postswitch.sh;
};
}
'';
};
};
};
config = mkIf cfg.enable {
assertions = flatten (mapAttrsToList (
profile: { config, ... }: mapAttrsToList (
output: opts: {
assertion = opts.scale == null || opts.transform == null;
message = ''
Cannot use the profile output options 'scale' and 'transform' simultaneously.
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
'';
})
config
)
cfg.profiles);
home.packages = [ pkgs.autorandr ];
xdg.configFile = mkMerge ([
(mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
(mkMerge (mapAttrsToList profileToFiles cfg.profiles))
]);
};
meta.maintainers = [ maintainers.uvnikita ];
}

View File

@@ -81,13 +81,12 @@ in
shellAliases = mkOption {
default = {};
type = types.attrsOf types.str;
example = { ll = "ls -l"; ".." = "cd .."; };
description = ''
An attribute set that maps aliases (the top level attribute names in
this option) to command strings or directly to build outputs. The
aliases are added to all users' shells.
this option) to command strings or directly to build outputs.
'';
type = types.attrs;
};
enableAutojump = mkOption {
@@ -130,7 +129,7 @@ in
config = (
let
aliasesStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}") cfg.shellAliases
);
shoptsStr = concatStringsSep "\n" (
@@ -156,7 +155,7 @@ in
in mkIf cfg.enable {
programs.bash.bashrcExtra = ''
# Commands that should be applied only for interactive shells.
if [[ -n $PS1 ]]; then
if [[ $- == *i* ]]; then
${historyControlStr}
${shoptsStr}
@@ -183,7 +182,7 @@ in
home.file.".profile".text = ''
# -*- mode: sh -*-
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
${sessionVarsStr}

40
modules/programs/bat.nix Normal file
View File

@@ -0,0 +1,40 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.bat;
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.bat = {
enable = mkEnableOption "bat, a cat clone with wings";
config = mkOption {
type = types.attrsOf types.str;
default = {};
example = {
theme = "TwoDark";
pager = "less -FR";
};
description = ''
Bat configuration.
'';
};
};
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
);
};
};
}

View File

@@ -13,6 +13,21 @@ in
options = {
programs.beets = {
enable = mkOption {
type = types.bool;
default =
if versionAtLeast config.home.stateVersion "19.03"
then false
else cfg.settings != {};
defaultText = "false";
description = ''
Whether to enable the beets music library manager. This
defaults to <literal>false</literal> for state
version  19.03. For earlier versions beets is enabled if
<option>programs.beets.settings</option> is non-empty.
'';
};
settings = mkOption {
type = types.attrs;
default = {};
@@ -24,7 +39,7 @@ in
};
};
config = mkIf (cfg.settings != {}) {
config = mkIf cfg.enable {
home.packages = [ pkgs.beets ];
xdg.configFile."beets/config.yaml".text =

View File

@@ -31,11 +31,11 @@ in {
else ".config/google-chrome/NativeMessagingHosts";
in [
{
target = "${dir}/com.dannyvankooten.browserpass.json";
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-host.json";
}
{
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-policy.json";
}
]
@@ -45,11 +45,11 @@ in {
else ".config/chromium/NativeMessagingHosts";
in [
{
target = "${dir}/com.dannyvankooten.browserpass.json";
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-host.json";
}
{
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-policy.json";
}
]
@@ -58,8 +58,8 @@ in {
target = (if isDarwin
then "Library/Application Support/Mozilla/NativeMessagingHosts"
else ".mozilla/native-messaging-hosts")
+ "/com.dannyvankooten.browserpass.json";
source = "${pkgs.browserpass}/lib/mozilla/native-messaging-hosts/com.dannyvankooten.browserpass.json";
+ "/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/lib/mozilla/native-messaging-hosts/com.github.browserpass.native.json";
} ]
else if x == "vivaldi" then
let dir = if isDarwin
@@ -67,11 +67,11 @@ in {
else ".config/vivaldi/NativeMessagingHosts";
in [
{
target = "${dir}/com.dannyvankooten.browserpass.json";
target = "${dir}/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-host.json";
}
{
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
source = "${pkgs.browserpass}/etc/chrome-policy.json";
}
]

View File

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

107
modules/programs/direnv.nix Normal file
View File

@@ -0,0 +1,107 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.direnv;
configFile = config:
pkgs.runCommand "config.toml"
{
buildInputs = [ pkgs.remarshal ];
preferLocalBuild = true;
allowSubstitutes = false;
}
''
remarshal -if json -of toml \
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
> $out
'';
in
{
meta.maintainers = [ maintainers.rycee ];
options.programs.direnv = {
enable = mkEnableOption "direnv, the environment switcher";
config = mkOption {
type = types.attrs;
default = {};
description = ''
Configuration written to
<filename>~/.config/direnv/config.toml</filename>.
</para><para>
See
<citerefentry>
<refentrytitle>direnv.toml</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>.
for the full list of options.
'';
};
stdlib = mkOption {
type = types.lines;
default = "";
description = ''
Custom stdlib written to
<filename>~/.config/direnv/direnvrc</filename>.
'';
};
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
enableFishIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Fish integration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.direnv ];
xdg.configFile."direnv/config.toml" = mkIf (cfg.config != {}) {
source = configFile cfg.config;
};
xdg.configFile."direnv/direnvrc" = mkIf (cfg.stdlib != "") {
text = cfg.stdlib;
};
programs.bash.initExtra =
mkIf cfg.enableBashIntegration (
# Using mkAfter to make it more likely to appear after other
# manipulations of the prompt.
mkAfter ''
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
''
);
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${pkgs.direnv}/bin/direnv hook zsh)"
'';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
eval (${pkgs.direnv}/bin/direnv hook fish)
'';
};
}

View File

@@ -6,8 +6,13 @@ let
cfg = config.programs.emacs;
# Copied from all-packages.nix.
emacsPackages = pkgs.emacsPackagesNgGen cfg.package;
# Copied from all-packages.nix, with modifications to support
# overrides.
emacsPackages =
let
epkgs = pkgs.emacsPackagesNgGen cfg.package;
in
epkgs.overrideScope' cfg.overrides;
emacsWithPackages = emacsPackages.emacsWithPackages;
in
@@ -31,12 +36,40 @@ in
default = self: [];
defaultText = "epkgs: []";
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
description = "Extra packages available to Emacs.";
description = ''
Extra packages available to Emacs. To get a list of
available packages run:
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A emacsPackagesNg</command>.
'';
};
overrides = mkOption {
default = self: super: {};
defaultText = "self: super: {}";
example = literalExample ''
self: super: rec {
haskell-mode = self.melpaPackages.haskell-mode;
# ...
};
'';
description = ''
Allows overriding packages within the Emacs package set.
'';
};
finalPackage = mkOption {
type = types.package;
visible = false;
readOnly = true;
description = ''
The Emacs package including any overrides and extra packages.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [ (emacsWithPackages cfg.extraPackages) ];
home.packages = [ cfg.finalPackage ];
programs.emacs.finalPackage = emacsWithPackages cfg.extraPackages;
};
}

View File

@@ -17,7 +17,7 @@ in
keybindings = mkOption {
default = {};
type = types.attrs;
type = types.attrsOf types.str;
example = { zoom_in = "plus"; zoom_out = "minus"; };
description = ''
Set keybindings.

View File

@@ -6,6 +6,8 @@ let
cfg = config.programs.firefox;
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
in
{
@@ -22,6 +24,22 @@ in
description = "The unwrapped Firefox package to use.";
};
extensions = mkOption {
type = types.listOf types.package;
default = [];
example = literalExample ''
with pkgs.nur.repos.rycee.firefox-addons; [
https-everywhere
privacy-badger
]
'';
description = ''
List of Firefox add-on packages to install. Note, it is
necessary to manually enable these extensions inside Firefox
after the first installation.
'';
};
enableAdobeFlash = mkOption {
type = types.bool;
default = false;
@@ -31,13 +49,33 @@ in
enableGoogleTalk = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the unfree Google Talk plugin.";
description = ''
Whether to enable the unfree Google Talk plugin. This option
is <emphasis>deprecated</emphasis> and will only work if
<programlisting language="nix">
programs.firefox.package = pkgs.firefox-esr-52-unwrapped;
</programlisting>
and the <option>plugin.load_flash_only</option> Firefox
option has been disabled.
'';
};
enableIcedTea = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the Java applet plugin.";
description = ''
Whether to enable the Java applet plugin. This option is
<emphasis>deprecated</emphasis> and will only work if
<programlisting language="nix">
programs.firefox.package = pkgs.firefox-esr-52-unwrapped;
</programlisting>
and the <option>plugin.load_flash_only</option> Firefox
option has been disabled.
'';
};
};
};
@@ -60,5 +98,18 @@ in
};
in
[ (wrapper cfg.package { }) ];
home.file.".mozilla/${extensionPath}" = mkIf (cfg.extensions != []) (
let
extensionsEnv = pkgs.buildEnv {
name = "hm-firefox-extensions";
paths = cfg.extensions;
};
in
{
source = "${extensionsEnv}/share/mozilla/${extensionPath}";
recursive = true;
}
);
};
}

191
modules/programs/fish.nix Normal file
View File

@@ -0,0 +1,191 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.fish;
abbrsStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "abbr --add --global ${k} '${v}'") cfg.shellAbbrs
);
aliasesStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
);
in
{
options = {
programs.fish = {
enable = mkEnableOption "fish friendly interactive shell";
package = mkOption {
default = pkgs.fish;
defaultText = "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 = types.attrs;
};
shellAbbrs = mkOption {
default = {};
description = ''
Set of abbreviations for fish shell.
'';
type = types.attrs;
};
shellInit = mkOption {
default = "";
description = ''
Shell script code called during fish shell initialisation.
'';
type = types.lines;
};
loginShellInit = mkOption {
default = "";
description = ''
Shell script code called during fish login shell initialisation.
'';
type = types.lines;
};
interactiveShellInit = mkOption {
default = "";
description = ''
Shell script code called during interactive fish shell initialisation.
'';
type = types.lines;
};
promptInit = mkOption {
default = "";
description = ''
Shell script code used to initialise fish prompt.
'';
type = types.lines;
};
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
xdg.dataFile."fish/home-manager_generated_completions".source =
let
# paths later in the list will overwrite those already linked
destructiveSymlinkJoin =
args_@{ name
, paths
, preferLocalBuild ? true
, allowSubstitutes ? false
, postBuild ? ""
, ...
}:
let
args = removeAttrs args_ [ "name" "postBuild" ]
// { 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"
{
src = package;
nativeBuildInputs = [ pkgs.python2 ];
buildInputs = [ cfg.package ];
preferLocalBuild = true;
allowSubstitutes = false;
}
''
mkdir -p $out
if [ -d $src/share/man ]; then
find $src/share/man -type f \
| xargs python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out \
> /dev/null
fi
'';
in
destructiveSymlinkJoin {
name = "${config.home.username}-fish-completions";
paths =
let
cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
in
map generateCompletions (sort cmp config.home.packages);
};
programs.fish.interactiveShellInit = ''
# add completions generated by Home Manager to $fish_complete_path
begin
set -l joined (string join " " $fish_complete_path)
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
set -l post_joined (string replace $prev_joined "" $joined)
set -l prev (string split " " (string trim $prev_joined))
set -l post (string split " " (string trim $post_joined))
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
end
'';
xdg.configFile."fish/config.fish".text = ''
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.
# 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]
${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
${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}
# Aliases
${aliasesStr}
${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
'';
};
}

138
modules/programs/fzf.nix Normal file
View File

@@ -0,0 +1,138 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.fzf;
in
{
options.programs.fzf = {
enable = mkEnableOption "fzf - a command-line fuzzy finder";
defaultCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type f";
description = ''
The command that gets executed as the default source for fzf
when running.
'';
};
defaultOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--height 40%" "--border" ];
description = ''
Extra command line options given to fzf by default.
'';
};
fileWidgetCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type f";
description = ''
The command that gets executed as the source for fzf for the
CTRL-T keybinding.
'';
};
fileWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--preview 'head {}'" ];
description = ''
Command line options for the CTRL-T keybinding.
'';
};
changeDirWidgetCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type d" ;
description = ''
The command that gets executed as the source for fzf for the
ALT-C keybinding.
'';
};
changeDirWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--preview 'tree -C {} | head -200'" ];
description = ''
Command line options for the ALT-C keybinding.
'';
};
historyWidgetCommand = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The command that gets executed as the source for fzf for the
CTRL-R keybinding.
'';
};
historyWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--sort" "--exact" ];
description = ''
Command line options for the CTRL-R keybinding.
'';
};
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.fzf ];
home.sessionVariables =
mapAttrs (n: v: toString v) (
filterAttrs (n: v: v != [] && v != null) {
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
FZF_DEFAULT_OPTS = cfg.defaultOptions;
}
);
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
. ${pkgs.fzf}/share/fzf/completion.bash
. ${pkgs.fzf}/share/fzf/key-bindings.bash
fi
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
if [[ $options[zle] = on ]]; then
. ${pkgs.fzf}/share/fzf/completion.zsh
. ${pkgs.fzf}/share/fzf/key-bindings.zsh
fi
'';
};
}

View File

@@ -6,6 +6,12 @@ let
cfg = config.programs.git;
gitIniType = with types;
let
primitiveType = either bool (either int str);
in
attrsOf (attrsOf primitiveType);
signModule = types.submodule {
options = {
key = mkOption {
@@ -28,6 +34,40 @@ let
};
};
includeModule = types.submodule ({ config, ... }: {
options = {
condition = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Include this configuration only when <varname>condition</varname>
matches. Allowed conditions are described in
<citerefentry>
<refentrytitle>git-config</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>.
'';
};
path = mkOption {
type = with types; either str path;
description = "Path of the configuration file to include.";
};
contents = mkOption {
type = types.attrs;
default = {};
description = ''
Configuration to include. If empty then a path must be given.
'';
};
};
config.path = mkIf (config.contents != {}) (
mkDefault (pkgs.writeText "contents" (generators.toINI {} config.contents))
);
});
in
{
@@ -41,22 +81,28 @@ in
type = types.package;
default = pkgs.git;
defaultText = "pkgs.git";
description = "Git package to install.";
description = ''
Git package to install. Use <varname>pkgs.gitAndTools.gitFull</varname>
to gain access to <command>git send-email</command> for instance.
'';
};
userName = mkOption {
type = types.str;
type = types.nullOr types.str;
default = null;
description = "Default user name to use.";
};
userEmail = mkOption {
type = types.str;
type = types.nullOr types.str;
default = null;
description = "Default user email to use.";
};
aliases = mkOption {
type = types.attrs;
type = types.attrsOf types.str;
default = {};
example = { co = "checkout"; };
description = "Git aliases to define.";
};
@@ -67,13 +113,16 @@ in
};
extraConfig = mkOption {
type = types.either types.attrs types.lines;
type = types.either types.lines gitIniType;
default = {};
example = {
core = { whitespace = "trailing-space,space-before-tab"; };
};
description = "Additional configuration to add.";
};
iniContent = mkOption {
type = types.attrsOf types.attrs;
type = gitIniType;
internal = true;
};
@@ -83,6 +132,35 @@ in
example = [ "*~" "*.swp" ];
description = "List of paths that should be globally ignored.";
};
includes = mkOption {
type = types.listOf includeModule;
default = [];
example = literalExample ''
[
{ path = "~/path/to/config.inc"; }
{
path = "~/path/to/conditional.inc";
condition = "gitdir:~/src/dir";
}
]
'';
description = "List of configuration files to include.";
};
lfs = {
enable = mkEnableOption "Git Large File Storage";
skipSmudge = mkOption {
type = types.bool;
default = false;
description = ''
Skip automatic downloading of objects on clone or pull.
This requires a manual <command>git lfs pull</command>
every time a new commit is checked out on your repository.
'';
};
};
};
};
@@ -92,8 +170,8 @@ in
home.packages = [ cfg.package ];
programs.git.iniContent.user = {
name = cfg.userName;
email = cfg.userEmail;
name = mkIf (cfg.userName != null) cfg.userName;
email = mkIf (cfg.userEmail != null) cfg.userEmail;
};
xdg.configFile = {
@@ -105,6 +183,26 @@ in
};
}
{
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;
@@ -124,6 +222,35 @@ in
(mkIf (lib.isString cfg.extraConfig) {
xdg.configFile."git/config".text = cfg.extraConfig;
})
(mkIf (cfg.includes != []) {
xdg.configFile."git/config".text = mkAfter
(concatMapStringsSep "\n"
(i: with i; ''
[${if (condition == null) then "include" else "includeIf \"${condition}\""}]
path = ${path}
'')
cfg.includes);
})
(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

@@ -6,7 +6,26 @@ let
cfg = config.programs.gnome-terminal;
dag = config.lib.dag;
vteInitStr = ''
# gnome-terminal: Show current directory in the terminal window title.
. ${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.";
};
};
}
);
profileColorsSubModule = types.submodule (
{ ... }: {
@@ -31,6 +50,18 @@ let
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.";
};
};
}
);
@@ -67,6 +98,15 @@ let
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;
@@ -91,19 +131,6 @@ let
}
);
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
mkIniKeyValue = key: value:
let
tweakVal = v:
if isString v then "'${v}'"
else if isList v then "[" + concatStringsSep "," (map tweakVal v) + "]"
else if isBool v && v then "true"
else if isBool v && !v then "false"
else toString v;
in
"${key}=${tweakVal value}";
buildProfileSet = pcfg:
{
visible-name = pcfg.visibleName;
@@ -125,6 +152,9 @@ let
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; }
@@ -133,28 +163,27 @@ let
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; }
)
)
);
buildIniSet = cfg:
{
"/" = {
default-show-menubar = cfg.showMenubar;
schema-version = 3;
};
}
//
{
"profiles:" = {
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile;
};
}
//
mapAttrs' (name: value:
nameValuePair ("profiles:/:${name}") (buildProfileSet value)
) cfg.profile;
in
{
@@ -170,6 +199,12 @@ in
description = "Whether to show the menubar by default";
};
themeVariant = mkOption {
default = "default";
type = types.enum [ "default" "light" "dark" ];
description = "The theme variation to request";
};
profile = mkOption {
default = {};
type = types.attrsOf profileSubModule;
@@ -181,20 +216,27 @@ in
config = mkIf cfg.enable {
home.packages = [ pkgs.gnome3.gnome_terminal ];
# The dconf service needs to be installed and prepared.
home.activation.gnomeTerminal = dag.entryAfter ["installPackages"] (
dconf.settings =
let
iniText = toDconfIni (buildIniSet cfg);
iniFile = pkgs.writeText "gnome-terminal.ini" iniText;
dconfPath = "/org/gnome/terminal/legacy/";
dconfPath = "org/gnome/terminal/legacy";
in
''
if [[ -v DRY_RUN ]]; then
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile}
else
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile}
fi
''
);
{
"${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;
programs.bash.initExtra = mkBefore vteInitStr;
programs.zsh.initExtra = vteInitStr;
};
}

75
modules/programs/go.nix Normal file
View File

@@ -0,0 +1,75 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.go;
in
{
meta.maintainers = [ maintainers.rvolosatovs ];
options = {
programs.go = {
enable = mkEnableOption "Go";
package = mkOption {
type = types.package;
default = pkgs.go;
defaultText = "pkgs.go";
description = "The Go package to use.";
};
packages = mkOption {
type = with types; attrsOf path;
default = {};
example = literalExample ''
{
"golang.org/x/text" = builtins.fetchGit "https://go.googlesource.com/text";
"golang.org/x/time" = builtins.fetchGit "https://go.googlesource.com/time";
}
'';
description = "Packages to add to GOPATH.";
};
goPath = mkOption {
type = with types; nullOr str;
default = null;
example = "go";
description = "GOPATH relative to HOME";
};
goBin = mkOption {
type = with types; nullOr str;
default = null;
example = ".local/bin.go";
description = "GOBIN relative to HOME";
};
};
};
config = mkIf cfg.enable (mkMerge [
{
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;
}
(mkIf (cfg.goPath != null) {
home.sessionVariables.GOPATH = builtins.toPath "${config.home.homeDirectory}/${cfg.goPath}";
})
(mkIf (cfg.goBin != null) {
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
})
]);
}

View File

@@ -32,24 +32,11 @@ in
};
};
config = mkIf (cfg.enable && !config.nixosSubmodule) {
config = mkIf (cfg.enable && !config.submoduleSupport.enable) {
home.packages = [
(import ../../home-manager {
inherit pkgs;
(pkgs.callPackage ../../home-manager {
inherit (cfg) path;
})
];
# Uninstall manually installed home-manager, if such exists.
# Without this a file collision error will be printed.
home.activation.uninstallHomeManager =
dag.entryBetween [ "installPackages" ] [ "writeBoundary" ] ''
if nix-env -q | grep -q "^home-manager$" ; then
$DRY_RUN_CMD nix-env -e home-manager
echo "You can now remove the 'home-manager' packageOverride"
echo "or overlay in '~/.config/nixpkgs/', if you want."
fi
'';
};
}

View File

@@ -29,7 +29,7 @@ let
dag = config.lib.dag;
# Indexes info files found in this location
homeInfoPath = "$HOME/.nix-profile/share/info";
homeInfoPath = "${config.home.profileDirectory}/share/info";
# Installs this package -- the interactive just means that it
# includes the curses `info` program. We also use `install-info`

211
modules/programs/irssi.nix Normal file
View File

@@ -0,0 +1,211 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.irssi;
boolStr = b: if b then "yes" else "no";
quoteStr = s: escape ["\""] s;
assignFormat = set:
concatStringsSep "\n"
(mapAttrsToList (k: v: " ${k} = \"${quoteStr v}\";") set);
chatnetString =
concatStringsSep "\n"
(flip mapAttrsToList cfg.networks
(k: v: ''
${k} = {
type = "${v.type}";
nick = "${quoteStr v.nick}";
autosendcmd = "${concatMapStringsSep ";" quoteStr v.autoCommands}";
};
''));
serversString =
concatStringsSep ",\n"
(flip mapAttrsToList cfg.networks
(k: v: ''
{
chatnet = "${k}";
address = "${v.server.address}";
port = "${toString v.server.port}";
use_ssl = "${boolStr v.server.ssl.enable}";
ssl_verify = "${boolStr v.server.ssl.verify}";
autoconnect = "${boolStr v.server.autoConnect}";
}
''));
channelString =
concatStringsSep ",\n"
(flip mapAttrsToList cfg.networks
(k: v:
concatStringsSep ",\n"
(flip mapAttrsToList v.channels
(c: cv: ''
{
chatnet = "${k}";
name = "${c}";
autojoin = "${boolStr cv.autoJoin}";
}
''))));
channelType = types.submodule {
options = {
name = mkOption {
type = types.nullOr types.str;
visible = false;
default = null;
description = "Name of the channel.";
};
autoJoin = mkOption {
type = types.bool;
default = false;
description = "Whether to join this channel on connect.";
};
};
};
networkType = types.submodule ({ name, ...}: {
options = {
name = mkOption {
visible = false;
default = name;
type = types.str;
};
nick = mkOption {
type = types.str;
description = "Nickname in that network.";
};
type = mkOption {
type = types.str;
description = "Type of the network.";
default = "IRC";
};
autoCommands = mkOption {
type = types.listOf types.str;
default = [];
description = "List of commands to execute on connect.";
};
server = {
address = mkOption {
type = types.str;
description = "Address of the chat server.";
};
port = mkOption {
type = types.port;
default = 6667;
description = "Port of the chat server.";
};
ssl = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether SSL should be used.";
};
verify = mkOption {
type = types.bool;
default = true;
description = "Whether the SSL certificate should be verified.";
};
};
autoConnect = mkOption {
type = types.bool;
default = false;
description = "Whether Irssi connects to the server on launch.";
};
};
channels = mkOption {
description = "Channels for the given network.";
type = types.attrsOf channelType;
default = {};
};
};
});
in
{
options = {
programs.irssi = {
enable = mkEnableOption "the Irssi chat client";
extraConfig = mkOption {
default = "";
description = "These lines are appended to the Irssi configuration.";
type = types.str;
};
aliases = mkOption {
default = {};
example = { J = "join"; BYE = "quit";};
description = "An attribute set that maps aliases to commands.";
type = types.attrsOf types.str;
};
networks = mkOption {
default = {};
example = literalExample ''
{
freenode = {
nick = "hmuser";
server = {
address = "chat.freenode.net";
port = 6697;
autoConnect = true;
};
channels = {
nixos.autoJoin = true;
};
};
}
'';
description = "An attribute set of chat networks.";
type = types.attrsOf networkType;
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.irssi ];
home.file.".irssi/config".text = ''
settings = {
core = {
settings_autosave = "no";
};
};
aliases = {
${assignFormat cfg.aliases}
};
chatnets = {
${chatnetString}
};
servers = (
${serversString}
);
channels = (
${channelString}
);
${cfg.extraConfig}
'';
};
}

76
modules/programs/jq.nix Normal file
View File

@@ -0,0 +1,76 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.jq;
colorType = mkOption {
type = types.str;
description = "ANSI color definition";
example = "1;31";
visible = false;
};
colorsType = types.submodule {
options = {
null = colorType;
false = colorType;
true = colorType;
numbers = colorType;
strings = colorType;
arrays = colorType;
objects = colorType;
};
};
in
{
options = {
programs.jq = {
enable = mkEnableOption "the jq command-line JSON processor";
colors = mkOption {
description = ''
The colors used in colored JSON output.</para>
<para>See <link xlink:href="https://stedolan.github.io/jq/manual/#Colors"/>.
'';
example = literalExample ''
{
null = "1;30";
false = "0;31";
true = "0;32";
numbers = "0;36";
strings = "0;33";
arrays = "1;35";
objects = "1;37";
}
'';
default = {
null = "1;30";
false = "0;39";
true = "0;39";
numbers = "0;39";
strings = "0;32";
arrays = "1;39";
objects = "1;39";
};
type = colorsType;
};
};
};
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}";
};
};
}

View File

@@ -0,0 +1,88 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.keychain;
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})"
'';
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.keychain = {
enable = mkEnableOption "keychain";
package = mkOption {
type = types.package;
default = pkgs.keychain;
defaultText = "pkgs.keychain";
description = ''
Keychain package to install.
'';
};
keys = mkOption {
type = types.listOf types.str;
default = [ "id_rsa" ];
description = ''
Keys to add to keychain.
'';
};
agents = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Agents to add.
'';
};
inheritType = mkOption {
type = types.nullOr (types.enum ["local" "any" "local-once" "any-once"]);
default = null;
description = ''
Inherit type to attempt from agent variables from the environment.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [ "--quiet" ];
description = ''
Extra flags to pass to keychain.
'';
};
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
programs.bash.initExtra = mkIf cfg.enableBashIntegration shellCommand;
programs.zsh.initExtra = mkIf cfg.enableZshIntegration shellCommand;
};
}

41
modules/programs/lsd.nix Normal file
View File

@@ -0,0 +1,41 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.lsd;
aliases = {
ls = "${pkgs.lsd}/bin/lsd";
ll = "ls -l";
la = "ls -a";
lt = "ls --tree";
lla ="ls -la";
};
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.lsd = {
enable = mkEnableOption "lsd";
enableAliases = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable recommended lsd aliases.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.lsd ];
programs.bash.shellAliases = mkIf cfg.enableAliases aliases;
programs.zsh.shellAliases = mkIf cfg.enableAliases aliases;
};
}

View File

@@ -0,0 +1,64 @@
{ config, lib, ... }:
with lib;
let
cfg = config.programs.matplotlib;
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}");
in
{
meta.maintainers = [ maintainers.rprospero ];
options.programs.matplotlib = {
enable = mkEnableOption "matplotlib, a plotting library for python";
config = mkOption {
default = { };
type = types.attrs;
description = ''
Add terms to the <filename>matplotlibrc</filename> file to
control the default matplotlib behavior.
'';
example = literalExample ''
{
backend = "Qt5Agg";
axes = {
grid = true;
facecolor = "black";
edgecolor = "FF9900";
};
grid.color = "FF9900";
}
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional commands for matplotlib that will be added to the
<filename>matplotlibrc</filename> file.
'';
};
};
config = mkIf cfg.enable {
xdg.configFile."matplotlib/matplotlibrc".text =
concatStringsSep "\n" ([]
++ mapAttrsToList (formatLine "") cfg.config
++ optional (cfg.extraConfig != "") cfg.extraConfig
) + "\n";
};
}

View File

@@ -0,0 +1,107 @@
{ lib, ... }:
with lib;
let
extraConfigType = with lib.types; attrsOf (either (either str int) bool);
in
{
options.mbsync = {
enable = mkEnableOption "synchronization using mbsync";
flatten = mkOption {
type = types.nullOr types.str;
default = null;
example = ".";
description = ''
If set, flattens the hierarchy within the maildir by
substituting the canonical hierarchy delimiter
<literal>/</literal> with this value.
'';
};
create = mkOption {
type = types.enum [ "none" "maildir" "imap" "both" ];
default = "none";
example = "maildir";
description = ''
Automatically create missing mailboxes within the
given mail store.
'';
};
remove = mkOption {
type = types.enum [ "none" "maildir" "imap" "both" ];
default = "none";
example = "imap";
description = ''
Propagate mailbox deletions to the given mail store.
'';
};
expunge = mkOption {
type = types.enum [ "none" "maildir" "imap" "both" ];
default = "none";
example = "both";
description = ''
Permanently remove messages marked for deletion from
the given mail store.
'';
};
patterns = mkOption {
type = types.listOf types.str;
default = [ "*" ];
description = ''
Pattern of mailboxes to synchronize.
'';
};
extraConfig.channel = mkOption {
type = extraConfigType;
default = {};
example = literalExample ''
{
MaxMessages = 10000;
MaxSize = "1m";
};
'';
description = ''
Per channel extra configuration.
'';
};
extraConfig.local = mkOption {
type = extraConfigType;
default = {};
description = ''
Local store extra configuration.
'';
};
extraConfig.remote = mkOption {
type = extraConfigType;
default = {};
description = ''
Remote store extra configuration.
'';
};
extraConfig.account = mkOption {
type = extraConfigType;
default = {};
example = literalExample ''
{
PipelineDepth = 10;
Timeout = 60;
};
'';
description = ''
Account section extra configuration.
'';
};
};
}

188
modules/programs/mbsync.nix Normal file
View File

@@ -0,0 +1,188 @@
{ config, lib, pkgs, ... }:
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) {
CertificateFile = toString tls.certificatesFile;
};
masterSlaveMapping = {
none = "None";
imap = "Master";
maildir = "Slave";
both = "Both";
};
genSection = header: entries:
let
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
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)}
'';
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
{
options = {
programs.mbsync = {
enable = mkEnableOption "mbsync IMAP4 and Maildir mailbox synchronizer";
package = mkOption {
type = types.package;
default = pkgs.isync;
defaultText = "pkgs.isync";
example = literalExample "pkgs.isync";
description = "The package to use for the mbsync binary.";
};
groups = mkOption {
type = types.attrsOf (types.attrsOf (types.listOf types.str));
default = {};
example = literalExample ''
{
inboxes = {
account1 = [ "Inbox" ];
account2 = [ "Inbox" ];
};
}
'';
description = ''
Definition of groups.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add to the mbsync configuration.
'';
};
};
};
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")
];
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.activation.createMaildir =
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
}
'';
};
}

View File

@@ -0,0 +1,36 @@
{ config, lib, ... }:
with lib;
{
options.msmtp = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable msmtp.
</para><para>
If enabled then it is possible to use the
<parameter class="command">--account</parameter> command line
option to send a message for a given account using the
<command>msmtp</command> or <command>msmtpq</command> tool.
For example, <command>msmtp --account=private</command> would
send using the account defined in
<option>accounts.email.accounts.private</option>. If the
<parameter class="command">--account</parameter> option is not
given then the primary account will be used.
'';
};
extraConfig = mkOption {
type = types.attrsOf types.str;
default = { };
example = { auth = "login"; };
description = ''
Extra configuration options to add to <filename>~/.msmtprc</filename>.
See <link xlink:href="https://marlam.de/msmtp/msmtprc.txt"/> for
examples.
'';
};
};
}

View File

@@ -0,0 +1,76 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.msmtp;
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 (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}"
);
configFile = mailAccounts: ''
# Generated by Home Manager.
${cfg.extraConfig}
${concatStringsSep "\n\n" (map accountStr mailAccounts)}
'';
in
{
options = {
programs.msmtp = {
enable = mkEnableOption "msmtp";
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add to <filename>~/.msmtprc</filename>.
See <link xlink:href="https://marlam.de/msmtp/msmtprc.txt"/> for examples.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.msmtp ];
xdg.configFile."msmtp/config".text = configFile msmtpAccounts;
home.sessionVariables = {
MSMTP_QUEUE = "${config.xdg.dataHome}/msmtp/queue";
MSMTP_LOG = "${config.xdg.dataHome}/msmtp/queue.log";
};
};
}

View File

@@ -6,6 +6,24 @@ let
cfg = config.programs.neovim;
extraPythonPackageType = mkOptionType {
name = "extra-python-packages";
description = "python packages in python.withPackages format";
check = with types; (x: if isFunction x
then isList (x pkgs.pythonPackages)
else false);
merge = mergeOneOption;
};
extraPython3PackageType = mkOptionType {
name = "extra-python3-packages";
description = "python3 packages in python.withPackages format";
check = with types; (x: if isFunction x
then isList (x pkgs.python3Packages)
else false);
merge = mergeOneOption;
};
in
{
@@ -13,6 +31,31 @@ in
programs.neovim = {
enable = mkEnableOption "Neovim";
viAlias = mkOption {
type = types.bool;
default = false;
description = ''
Symlink `vi` to `nvim` binary.
'';
};
vimAlias = mkOption {
type = types.bool;
default = false;
description = ''
Symlink `vim` to `nvim` binary.
'';
};
withNodeJs = mkOption {
type = types.bool;
default = false;
description = ''
Enable node provider. Set to <literal>true</literal> to
use Node plugins.
'';
};
withPython = mkOption {
type = types.bool;
default = true;
@@ -23,12 +66,13 @@ in
};
extraPythonPackages = mkOption {
type = types.listOf types.package;
default = [ ];
example = literalExample "with pkgs.python2Packages; [ pandas jedi ]";
type = with types; either extraPythonPackageType (listOf package);
default = (_: []);
defaultText = "ps: []";
example = literalExample "(ps: with ps; [ pandas jedi ])";
description = ''
List here Python 2 packages required for your plugins to
work.
A function in python.withPackages format, which returns a
list of Python 2 packages required for your plugins to work.
'';
};
@@ -50,12 +94,42 @@ in
};
extraPython3Packages = mkOption {
type = types.listOf types.package;
default = [ ];
example = literalExample
"with pkgs.python3Packages; [ python-language-server ]";
type = with types; either extraPython3PackageType (listOf package);
default = (_: []);
defaultText = "ps: []";
example = literalExample "(ps: with ps; [ python-language-server ])";
description = ''
List here Python 3 packages required for your plugins to work.
A function in python.withPackages format, which returns a
list of Python 3 packages required for your plugins to work.
'';
};
package = mkOption {
type = types.package;
default = pkgs.neovim-unwrapped;
defaultText = "pkgs.neovim-unwrapped";
description = "The package to use for the neovim binary.";
};
configure = mkOption {
type = types.attrs;
default = {};
example = literalExample ''
configure = {
customRC = $''''
" here your custom configuration goes!
$'''';
packages.myVimPackage = with pkgs.vimPlugins; {
# loaded on launch
start = [ fugitive ];
# manually loadable by calling `:packadd $plugin-name`
opt = [ ];
};
};
'';
description = ''
Generate your init file from your list of plugins and custom commands,
and loads it from the store via <command>nvim -u /nix/store/hash-vimrc</command>
'';
};
};
@@ -63,11 +137,11 @@ in
config = mkIf cfg.enable {
home.packages = [
(pkgs.neovim.override {
(pkgs.wrapNeovim cfg.package {
inherit (cfg)
extraPython3Packages withPython3
extraPythonPackages withPython
withRuby;
withNodeJs withRuby viAlias vimAlias configure;
})
];
};

View File

@@ -0,0 +1,98 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.newsboat;
wrapQuote = x: "\"${x}\"";
in
{
options = {
programs.newsboat = {
enable = mkEnableOption "the Newsboat feed reader";
urls = mkOption {
type = types.listOf types.attrs;
default = [];
example = [{url = "http://example.com"; tags = ["foo" "bar"];}];
description = "List of urls and tokens.";
};
maxItems = mkOption {
type = types.int;
default = 0;
description = "Maximum number of items per feed, 0 for infinite.";
};
reloadThreads = mkOption {
type = types.int;
default = 5;
description = "How many threads to use for updating the feeds.";
};
autoReload = mkOption {
type = types.bool;
default = false;
description = "Whether to enable automatic reloading while newsboat is running.";
};
reloadTime = mkOption {
type = types.nullOr types.int;
default = 60;
description = "Time in minutes between reloads.";
};
browser = mkOption {
type = types.str;
default = "${pkgs.xdg_utils}/bin/xdg-open";
description = "External browser to use.";
};
queries = mkOption {
type = types.attrsOf types.str;
default = {};
example = {
"foo" = "rssurl =~ \"example.com\"";
};
description = "A list of queries to use.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra configuration values that will be appended to the end.";
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.newsboat ];
home.file.".newsboat/urls".text =
let
urls = builtins.concatStringsSep "\n" (
map (u: builtins.concatStringsSep " " ([u.url] ++ (map wrapQuote u.tags)))
cfg.urls);
queries = builtins.concatStringsSep "\n" (
mapAttrsToList (n: v: "\"query:${n}:${escape ["\""] v}\"") cfg.queries);
in
''
${urls}
${queries}
'';
home.file.".newsboat/config".text = ''
max-items ${toString cfg.maxItems}
browser ${cfg.browser}
reload-threads ${toString cfg.reloadThreads}
auto-reload ${if cfg.autoReload then "yes" else "no"}
${optionalString (cfg.reloadTime != null) (toString "reload-time ${toString cfg.reloadTime}")}
prepopulate-query-feeds yes
${cfg.extraConfig}
'';
};
}

53
modules/programs/noti.nix Normal file
View File

@@ -0,0 +1,53 @@
{ config, lib, pkgs, ...}:
with lib;
let
cfg = config.programs.noti;
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.noti = {
enable = mkEnableOption "Noti";
settings = mkOption {
type = types.attrsOf (types.attrsOf types.str);
default = {};
description = ''
Configuration written to
<filename>~/.config/noti/noti.yaml</filename>.
</para><para>
See
<citerefentry>
<refentrytitle>noti.yaml</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>.
for the full list of options.
'';
example = literalExample ''
{
say = {
voice = "Alex";
};
slack = {
token = "1234567890abcdefg";
channel = "@jaime";
};
}
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.noti ];
xdg.configFile."noti/noti.yaml" = mkIf (cfg.settings != {}) {
text = generators.toYAML {} cfg.settings;
};
};
}

View File

@@ -0,0 +1,7 @@
{ lib, ... }:
{
options.notmuch = {
enable = lib.mkEnableOption "notmuch indexing";
};
}

View File

@@ -0,0 +1,211 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.notmuch;
mkIniKeyValue = key: value:
let
tweakVal = v:
if isString v then v
else if isList v then concatMapStringsSep ";" tweakVal v
else if isBool v then (if v then "true" else "false")
else toString v;
in
"${key}=${tweakVal value}";
notmuchIni =
recursiveUpdate
{
database = {
path = config.accounts.email.maildirBasePath;
};
maildir = {
synchronize_flags = cfg.maildir.synchronizeFlags;
};
new = {
ignore = cfg.new.ignore;
tags = cfg.new.tags;
};
user =
let
accounts =
filter (a: a.notmuch.enable)
(attrValues config.accounts.email.accounts);
primary = filter (a: a.primary) accounts;
secondaries = filter (a: !a.primary) accounts;
in {
name = catAttrs "realName" primary;
primary_email = catAttrs "address" primary;
other_email = catAttrs "aliases" primary
++ catAttrs "address" secondaries
++ catAttrs "aliases" secondaries;
};
search = {
exclude_tags = cfg.search.excludeTags;
};
}
cfg.extraConfig;
in
{
options = {
programs.notmuch = {
enable = mkEnableOption "Notmuch mail indexer";
new = mkOption {
type = types.submodule {
options = {
ignore = mkOption {
type = types.listOf types.str;
default = [];
description = ''
A list to specify files and directories that will not be
searched for messages by <command>notmuch new</command>.
'';
};
tags = mkOption {
type = types.listOf types.str;
default = [ "unread" "inbox" ];
example = [ "new" ];
description = ''
A list of tags that will be added to all messages
incorporated by <command>notmuch new</command>.
'';
};
};
};
default = {};
description = ''
Options related to email processing performed by
<command>notmuch new</command>.
'';
};
extraConfig = mkOption {
type = types.attrsOf (types.attrsOf types.str);
default = {};
description = ''
Options that should be appended to the notmuch configuration file.
'';
};
hooks = {
preNew = mkOption {
type = types.lines;
default = "";
example = "mbsync --all";
description = ''
Bash statements run before scanning or importing new
messages into the database.
'';
};
postNew = mkOption {
type = types.lines;
default = "";
example = ''
notmuch tag +nixos -- tag:new and from:nixos1@discoursemail.com
'';
description = ''
Bash statements run after new messages have been imported
into the database and initial tags have been applied.
'';
};
postInsert = mkOption {
type = types.lines;
default = "";
description = ''
Bash statements run after a message has been inserted
into the database and initial tags have been applied.
'';
};
};
maildir = {
synchronizeFlags = mkOption {
type = types.bool;
default = true;
description = ''
Whether to synchronize Maildir flags.
'';
};
};
search = {
excludeTags = mkOption {
type = types.listOf types.str;
default = [ "deleted" "spam" ];
example = [ "trash" "spam" ];
description = ''
A list of tags that will be excluded from search results by
default. Using an excluded tag in a query will override that
exclusion.
'';
};
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = notmuchIni.user.name != [];
message = "notmuch: Must have a user name set.";
}
{
assertion = notmuchIni.user.primary_email != [];
message = "notmuch: Must have a user primary email address set.";
}
];
home.packages = [ pkgs.notmuch ];
home.sessionVariables = {
NOTMUCH_CONFIG = "${config.xdg.configHome}/notmuch/notmuchrc";
NMBGIT = "${config.xdg.dataHome}/notmuch/nmbug";
};
xdg.configFile."notmuch/notmuchrc".text =
let
toIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
in
"# Generated by Home Manager.\n\n"
+ toIni notmuchIni;
home.file =
let
hook = name: cmds:
{
target = "${notmuchIni.database.path}/.notmuch/hooks/${name}";
source = pkgs.writeScript name ''
#!${pkgs.runtimeShell}
export PATH="${pkgs.notmuch}/bin''${PATH:+:}$PATH"
export NOTMUCH_CONFIG="${config.xdg.configHome}/notmuch/notmuchrc"
export NMBGIT="${config.xdg.dataHome}/notmuch/nmbug"
${cmds}
'';
executable = true;
};
in
optional (cfg.hooks.preNew != "")
(hook "pre-new" cfg.hooks.preNew)
++
optional (cfg.hooks.postNew != "")
(hook "post-new" cfg.hooks.postNew)
++
optional (cfg.hooks.postInsert != "")
(hook "post-insert" cfg.hooks.postInsert);
};
}

View File

@@ -0,0 +1,53 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.obs-studio;
package = pkgs.obs-studio;
mkPluginEnv = packages:
let
pluginDirs = map (pkg: "${pkg}/share/obs/obs-plugins") packages;
plugins = concatMapStringsSep " " (p: "${p}/*") pluginDirs;
in
pkgs.runCommand "obs-studio-plugins"
{
preferLocalBuild = true;
allowSubstitutes = false;
}
''
mkdir $out
[[ '${plugins}' ]] || exit 0
for plugin in ${plugins}; do
ln -s "$plugin" $out/
done
'';
in
{
meta.maintainers = [ maintainers.adisbladis ];
options = {
programs.obs-studio = {
enable = mkEnableOption "obs-studio";
plugins = mkOption {
default = [];
example = literalExample "[ pkgs.obs-linuxbrowser ]";
description = "Optional OBS plugins.";
type = types.listOf types.package;
};
};
};
config = mkIf cfg.enable {
home.packages = [ package ];
xdg.configFile."obs-studio/plugins" = mkIf (cfg.plugins != []) {
source = mkPluginEnv cfg.plugins;
};
};
}

View File

@@ -0,0 +1,57 @@
{ config, lib, ... }:
with lib;
let
extraConfigType = with types; attrsOf (either (either str int) bool);
in
{
options.offlineimap = {
enable = mkEnableOption "OfflineIMAP";
extraConfig.account = mkOption {
type = extraConfigType;
default = {};
example = {
autorefresh = 20;
};
description = ''
Extra configuration options to add to the account section.
'';
};
extraConfig.local = mkOption {
type = extraConfigType;
default = {};
example = {
sync_deletes = true;
};
description = ''
Extra configuration options to add to the local account
section.
'';
};
extraConfig.remote = mkOption {
type = extraConfigType;
default = {};
example = {
maxconnections = 2;
expunge = false;
};
description = ''
Extra configuration options to add to the remote account
section.
'';
};
postSyncHookCommand = mkOption {
type = types.lines;
default = "";
description = "Command to run after fetching new mails.";
};
};
}

View File

@@ -0,0 +1,207 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.offlineimap;
accounts = filter (a: a.offlineimap.enable)
(attrValues config.accounts.email.accounts);
toIni = generators.toINI {
mkKeyValue = key: value:
let
value' =
if isBool value then (if value then "yes" else "no")
else toString value;
in
"${key} = ${value'}";
};
# Generates a script to fetch only a specific account.
#
# Note, these scripts are not actually created and installed at the
# moment. It will need some thinking on whether this is a good idea
# and whether other modules should have some similar functionality.
#
# Perhaps have a single tool `email` that wraps the command?
# Something like
#
# $ email <account name> <program name> <program args>
genOfflineImapScript = account: with account;
pkgs.writeShellScriptBin "offlineimap-${name}" ''
exec ${pkgs.offlineimap}/bin/offlineimap -a${account.name} "$@"
'';
accountStr = account: with account;
let
postSyncHook = optionalAttrs (offlineimap.postSyncHookCommand != "") {
postsynchook =
pkgs.writeShellScriptBin
"postsynchook"
offlineimap.postSyncHookCommand
+ "/bin/postsynchook";
};
localType =
if account.flavor == "gmail.com"
then "GmailMaildir"
else "Maildir";
remoteType =
if account.flavor == "gmail.com"
then "Gmail"
else "IMAP";
remoteHost = optionalAttrs (imap.host != null) {
remotehost = imap.host;
};
remotePort = optionalAttrs ((imap.port or null) != null) {
remoteport = imap.port;
};
ssl =
if imap.tls.enable
then
{
ssl = true;
sslcacertfile = imap.tls.certificatesFile;
starttls = imap.tls.useStartTls;
}
else
{
ssl = false;
};
remotePassEval =
let
arglist = concatMapStringsSep "," (x: "'${x}'") passwordCommand;
in
optionalAttrs (passwordCommand != null) {
remotepasseval = ''get_pass("${name}", [${arglist}])'';
};
in
toIni {
"Account ${name}" = {
localrepository = "${name}-local";
remoterepository = "${name}-remote";
}
// postSyncHook
// offlineimap.extraConfig.account;
"Repository ${name}-local" = {
type = localType;
localfolders = maildir.absPath;
}
// offlineimap.extraConfig.local;
"Repository ${name}-remote" = {
type = remoteType;
remoteuser = userName;
}
// remoteHost
// remotePort
// remotePassEval
// ssl
// offlineimap.extraConfig.remote;
};
extraConfigType = with types; attrsOf (either (either str int) bool);
in
{
options = {
programs.offlineimap = {
enable = mkEnableOption "OfflineIMAP";
pythonFile = mkOption {
type = types.lines;
default = ''
import subprocess
def get_pass(service, cmd):
return subprocess.check_output(cmd, )
'';
description = ''
Python code that can then be used in other parts of the
configuration.
'';
};
extraConfig.general = mkOption {
type = extraConfigType;
default = {};
example = {
maxage = 30;
ui = "blinkenlights";
};
description = ''
Extra configuration options added to the
<option>general</option> section.
'';
};
extraConfig.default = mkOption {
type = extraConfigType;
default = {};
example = {
gmailtrashfolder = "[Gmail]/Papierkorb";
};
description = ''
Extra configuration options added to the
<option>DEFAULT</option> section.
'';
};
extraConfig.mbnames = mkOption {
type = extraConfigType;
default = {};
example = literalExample ''
{
filename = "~/.config/mutt/mailboxes";
header = "'mailboxes '";
peritem = "'+%(accountname)s/%(foldername)s'";
sep = "' '";
footer = "'\\n'";
}
'';
description = ''
Extra configuration options added to the
<code>mbnames</code> section.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.offlineimap ];
xdg.configFile."offlineimap/get_settings.py".text = cfg.pythonFile;
xdg.configFile."offlineimap/config".text =
''
# Generated by Home Manager.
# See https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf
# for an exhaustive list of options.
''
+ toIni ({
general = {
accounts = concatMapStringsSep "," (a: a.name) accounts;
pythonfile = "${config.xdg.configHome}/offlineimap/get_settings.py";
metadata = "${config.xdg.dataHome}/offlineimap";
}
// cfg.extraConfig.general;
}
// optionalAttrs (cfg.extraConfig.mbnames != {}) {
mbnames = { enabled = true; } // cfg.extraConfig.mbnames;
}
// optionalAttrs (cfg.extraConfig.default != {}) {
DEFAULT = cfg.extraConfig.default;
})
+ "\n"
+ concatStringsSep "\n" (map accountStr accounts);
};
}

52
modules/programs/opam.nix Normal file
View File

@@ -0,0 +1,52 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.opam;
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.opam = {
enable = mkEnableOption "Opam";
package = mkOption {
type = types.package;
default = pkgs.opam;
defaultText = "pkgs.opam";
description = "Opam package to install.";
};
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
eval "$(${cfg.package}/bin/opam env --shell=bash)"
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${cfg.package}/bin/opam env --shell=zsh)"
'';
};
}

View File

@@ -0,0 +1,36 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.pidgin;
in
{
meta.maintainers = [ maintainers.rycee ];
options = {
programs.pidgin = {
enable = mkEnableOption "Pidgin messaging client";
package = mkOption {
type = types.package;
default = pkgs.pidgin;
defaultText = "pkgs.pidgin";
description = "The Pidgin package to use.";
};
plugins = mkOption {
default = [];
example = literalExample "[ pkgs.pidgin-otr pkgs.pidgin-osd ]";
description = "Plugins that should be available to Pidgin.";
};
};
};
config = mkIf cfg.enable {
home.packages = [ (cfg.package.override { inherit (cfg) plugins; }) ];
};
}

View File

@@ -8,7 +8,7 @@ let
cfg = config.programs.rofi;
colorOption = description: mkOption {
type = types.string;
type = types.str;
description = description;
};
@@ -124,6 +124,14 @@ let
bottom-left = 7;
left = 8;
};
themeName =
if (cfg.theme == null) then null
else if (lib.isString cfg.theme) then cfg.theme
else lib.removeSuffix ".rasi" (baseNameOf cfg.theme);
themePath = if (lib.isString cfg.theme) then null else cfg.theme;
in
{
@@ -167,7 +175,7 @@ in
font = mkOption {
default = null;
type = types.nullOr types.string;
type = types.nullOr types.str;
example = "Droid Sans Mono 14";
description = "Font to use.";
};
@@ -180,7 +188,7 @@ in
terminal = mkOption {
default = null;
type = types.nullOr types.string;
type = types.nullOr types.str;
description = ''
Path to the terminal which will be used to run console applications
'';
@@ -232,8 +240,10 @@ in
default = null;
type = types.nullOr colorsSubmodule;
description = ''
Color scheme settings.
Colors can be specified in CSS color formats.
Color scheme settings. Colors can be specified in CSS color
formats. This option may become deprecated in the future and
therefore the <varname>programs.rofi.theme</varname> option
should be used whenever possible.
'';
example = literalExample ''
colors = {
@@ -258,9 +268,21 @@ in
'';
};
theme = mkOption {
default = null;
type = with types; nullOr (either str path);
example = "Arc";
description = ''
Name of theme or path to theme file in rasi format. Available
named themes can be viewed using the
<command>rofi-theme-selector</command> tool.
'';
};
configPath = mkOption {
default = ".config/rofi/config";
type = types.string;
default = "${config.xdg.configHome}/rofi/config";
defaultText = "$XDG_CONFIG_HOME/rofi/config";
type = types.str;
description = "Path where to put generated configuration file.";
};
@@ -273,6 +295,15 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.theme == null || cfg.colors == null;
message = ''
Cannot use the rofi options 'theme' and 'colors' simultaneously.
'';
}
];
home.packages = [ pkgs.rofi ];
home.file."${cfg.configPath}".text = ''
@@ -296,8 +327,13 @@ in
${setOption "yoffset" cfg.yoffset}
${setColorScheme cfg.colors}
${setOption "theme" themeName}
${cfg.extraConfig}
'';
xdg.dataFile = mkIf (themePath != null) {
"rofi/themes/${themeName}.rasi".source = themePath;
};
};
}

128
modules/programs/skim.nix Normal file
View File

@@ -0,0 +1,128 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.skim;
in
{
options.programs.skim = {
enable = mkEnableOption "skim - a command-line fuzzy finder";
defaultCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type f";
description = ''
The command that gets executed as the default source for skim
when running.
'';
};
defaultOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--height 40%" "--prompt " ];
description = ''
Extra command line options given to skim by default.
'';
};
fileWidgetCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type f";
description = ''
The command that gets executed as the source for skim for the
CTRL-T keybinding.
'';
};
fileWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--preview 'head {}'" ];
description = ''
Command line options for the CTRL-T keybinding.
'';
};
changeDirWidgetCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "fd --type d" ;
description = ''
The command that gets executed as the source for skim for the
ALT-C keybinding.
'';
};
changeDirWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--preview 'tree -C {} | head -200'" ];
description = ''
Command line options for the ALT-C keybinding.
'';
};
historyWidgetOptions = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--tac" "--exact" ];
description = ''
Command line options for the CTRL-R keybinding.
'';
};
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.skim ];
home.sessionVariables =
mapAttrs (n: v: toString v) (
filterAttrs (n: v: v != [] && v != null) {
SKIM_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
SKIM_ALT_C_OPTS = cfg.changeDirWidgetOptions;
SKIM_CTRL_R_OPTS = cfg.historyWidgetOptions;
SKIM_CTRL_T_COMMAND = cfg.fileWidgetCommand;
SKIM_CTRL_T_OPTS = cfg.fileWidgetOptions;
SKIM_DEFAULT_COMMAND = cfg.defaultCommand;
SKIM_DEFAULT_OPTIONS = cfg.defaultOptions;
}
);
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
. ${pkgs.skim}/share/skim/completion.bash
. ${pkgs.skim}/share/skim/key-bindings.bash
fi
'';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
if [[ $options[zle] = on ]]; then
. ${pkgs.skim}/share/skim/completion.zsh
. ${pkgs.skim}/share/skim/key-bindings.zsh
fi
'';
};
}

View File

@@ -8,6 +8,8 @@ let
yn = flag: if flag then "yes" else "no";
unwords = builtins.concatStringsSep " ";
matchBlockModule = types.submodule ({ name, ... }: {
options = {
host = mkOption {
@@ -19,11 +21,20 @@ let
};
port = mkOption {
type = types.nullOr types.int;
type = types.nullOr types.port;
default = null;
description = "Specifies port number to connect on remote host.";
};
forwardAgent = mkOption {
default = null;
type = types.nullOr types.bool;
description = ''
Whether the connection to the authentication agent (if any)
will be forwarded to the remote machine.
'';
};
forwardX11 = mkOption {
type = types.bool;
default = false;
@@ -55,10 +66,15 @@ let
};
identityFile = mkOption {
type = types.nullOr types.str;
default = null;
type = with types; either (listOf str) (nullOr str);
default = [];
apply = p:
if p == null then []
else if isString p then [p]
else p;
description = ''
Specifies a file from which the user identity is read.
Specifies files from which the user identity is read.
Identities will be tried in the given order.
'';
};
@@ -81,6 +97,15 @@ let
"Set timeout in seconds after which response will be requested.";
};
sendEnv = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Environment variables to send from the local host to the
server.
'';
};
compression = mkOption {
type = types.nullOr types.bool;
default = null;
@@ -105,6 +130,28 @@ let
description = "The command to use to connect to the server.";
};
proxyJump = mkOption {
type = types.nullOr types.str;
default = null;
description = "The proxy host to use to connect to the server.";
};
certificateFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Specifies a file from which the user certificate is read.
'';
};
addressFamily = mkOption {
default = null;
type = types.nullOr (types.enum ["any" "inet" "inet6"]);
description = ''
Specifies which address family to use when connecting.
'';
};
extraOptions = mkOption {
type = types.attrsOf types.str;
default = {};
@@ -117,18 +164,23 @@ let
matchBlockStr = cf: concatStringsSep "\n" (
["Host ${cf.host}"]
++ optional (cf.port != null) " Port ${toString cf.port}"
++ optional cf.forwardX11 " ForwardX11 yes"
++ optional cf.forwardX11Trusted " ForwardX11Trusted yes"
++ optional cf.identitiesOnly " IdentitiesOnly yes"
++ optional (cf.user != null) " User ${cf.user}"
++ optional (cf.identityFile != null) " IdentityFile ${cf.identityFile}"
++ optional (cf.hostname != null) " HostName ${cf.hostname}"
++ optional (cf.port != null) " Port ${toString cf.port}"
++ optional (cf.forwardAgent != null) " ForwardAgent ${yn cf.forwardAgent}"
++ optional cf.forwardX11 " ForwardX11 yes"
++ optional cf.forwardX11Trusted " ForwardX11Trusted yes"
++ optional cf.identitiesOnly " IdentitiesOnly yes"
++ optional (cf.user != null) " User ${cf.user}"
++ optional (cf.certificateFile != null) " CertificateFile ${cf.certificateFile}"
++ optional (cf.hostname != null) " HostName ${cf.hostname}"
++ optional (cf.addressFamily != null) " AddressFamily ${cf.addressFamily}"
++ optional (cf.sendEnv != []) " SendEnv ${unwords cf.sendEnv}"
++ optional (cf.serverAliveInterval != 0)
" ServerAliveInterval ${toString cf.serverAliveInterval}"
++ optional (cf.compression != null) " Compression ${yn cf.compression}"
++ optional (!cf.checkHostIP) " CheckHostIP no"
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}"
++ optional (cf.compression != null) " Compression ${yn cf.compression}"
++ optional (!cf.checkHostIP) " CheckHostIP no"
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}"
++ optional (cf.proxyJump != null) " ProxyJump ${cf.proxyJump}"
++ map (file: " IdentityFile ${file}") cf.identityFile
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
);
@@ -144,8 +196,8 @@ in
default = false;
type = types.bool;
description = ''
Whether connection to authentication agent (if any) will be forwarded
to remote machine.
Whether the connection to the authentication agent (if any)
will be forwarded to the remote machine.
'';
};
@@ -197,7 +249,7 @@ in
controlPath = mkOption {
type = types.str;
default = "~/.ssh/master-%r@%h:%p";
default = "~/.ssh/master-%r@%n:%p";
description = ''
Specify path to the control socket used for connection sharing.
'';
@@ -220,9 +272,18 @@ in
'';
};
extraOptionOverrides = mkOption {
type = types.attrsOf types.str;
default = {};
description = ''
Extra SSH configuration options that take precedence over any
host specific configuration.
'';
};
matchBlocks = mkOption {
type = types.loaOf matchBlockModule;
default = [];
default = {};
example = literalExample ''
{
"john.example.com" = {
@@ -248,20 +309,24 @@ in
config = mkIf cfg.enable {
home.file.".ssh/config".text = ''
ForwardAgent ${yn cfg.forwardAgent}
Compression ${yn cfg.compression}
ServerAliveInterval ${toString cfg.serverAliveInterval}
HashKnownHosts ${yn cfg.hashKnownHosts}
UserKnownHostsFile ${cfg.userKnownHostsFile}
ControlMaster ${cfg.controlMaster}
ControlPath ${cfg.controlPath}
ControlPersist ${cfg.controlPersist}
${cfg.extraConfig}
${concatStringsSep "\n" (
mapAttrsToList (n: v: "${n} ${v}") cfg.extraOptionOverrides)}
${concatStringsSep "\n\n" (
map matchBlockStr (
builtins.attrValues cfg.matchBlocks))}
Host *
ForwardAgent ${yn cfg.forwardAgent}
Compression ${yn cfg.compression}
ServerAliveInterval ${toString cfg.serverAliveInterval}
HashKnownHosts ${yn cfg.hashKnownHosts}
UserKnownHostsFile ${cfg.userKnownHostsFile}
ControlMaster ${cfg.controlMaster}
ControlPath ${cfg.controlPath}
ControlPersist ${cfg.controlPersist}
${replaceStrings ["\n"] ["\n "] cfg.extraConfig}
'';
};
}

View File

@@ -0,0 +1,112 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.taskwarrior;
themePath = theme: "${pkgs.taskwarrior}/share/doc/task/rc/${theme}.theme";
includeTheme = location:
if location == null then ""
else if isString location then "include ${themePath location}"
else "include ${location}";
formatValue = value:
if isBool value then if value then "true" else "false"
else if isList value then concatMapStringsSep "," formatValue value
else toString value;
formatLine = key: value:
"${key}=${formatValue value}";
formatSet = key: values:
(concatStringsSep "\n"
(mapAttrsToList
(subKey: subValue: formatPair "${key}.${subKey}" subValue)
values));
formatPair = key: value:
if isAttrs value then formatSet key value
else formatLine key value;
in
{
options = {
programs.taskwarrior = {
enable = mkEnableOption "Task Warrior";
config = mkOption {
type = types.attrs;
default = {};
example = literalExample ''
{
confirmation = false;
report.minimal.filter = "status:pending";
report.active.columns = [ "id" "start" "entry.age" "priority" "project" "due" "description" ];
report.active.labels = [ "ID" "Started" "Age" "Priority" "Project" "Due" "Description" ];
taskd = {
certificate = "/path/to/cert";
key = "/path/to/key";
ca = "/path/to/ca";
server = "host.domain:53589";
credentials = "Org/First Last/cf31f287-ee9e-43a8-843e-e8bbd5de4294";
};
}
'';
description = ''
Key-value configuration written to
<filename>~/.taskrc</filename>.
'';
};
dataLocation = mkOption {
type = types.str;
default = "${config.xdg.dataHome}/task";
defaultText = "$XDG_DATA_HOME/task";
description = ''
Location where Task Warrior will store its data.
</para><para>
Home Manager will attempt to create this directory.
'';
};
colorTheme = mkOption {
type = with types; nullOr (either str path);
default = null;
example = "dark-blue-256";
description = ''
Either one of the default provided theme as string, or a
path to a theme configuration file.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional content written at the end of
<filename>~/.taskrc</filename>.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.taskwarrior ];
home.file."${cfg.dataLocation}/.keep".text = "";
home.file.".taskrc".text = ''
data.location=${cfg.dataLocation}
${includeTheme cfg.colorTheme}
${concatStringsSep "\n" (
mapAttrsToList formatPair cfg.config)}
${cfg.extraConfig}
'';
};
}

View File

@@ -6,6 +6,13 @@ let
cfg = config.programs.termite;
vteInitStr = ''
# See https://github.com/thestinger/termite#id1
if [[ $TERM == xterm-termite ]]; then
. ${pkgs.gnome3.vte-ng}/etc/profile.d/vte.sh
fi
'';
in
{
@@ -150,7 +157,11 @@ in
type = types.nullOr types.bool;
description = ''
Emit escape sequences for extra keys,
like the modifyOtherKeys resource for xterm(1).
like the modifyOtherKeys resource for
<citerefentry>
<refentrytitle>xterm</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>.
'';
};
@@ -359,6 +370,9 @@ in
${cfg.hintsExtra}
'';
programs.bash.initExtra = vteInitStr;
programs.zsh.initExtra = vteInitStr;
}
);
}

View File

@@ -6,6 +6,8 @@ let
cfg = config.programs.texlive;
texlivePkgs = cfg.extraPackages pkgs.texlive;
in
{
@@ -16,19 +18,33 @@ in
enable = mkEnableOption "Texlive";
extraPackages = mkOption {
default = self: {};
default = tpkgs: { inherit (tpkgs) collection-basic; };
defaultText = "tpkgs: { inherit (tpkgs) collection-basic; }";
example = literalExample ''
tpkgs: { inherit (tpkgs) collection-fontsrecommended algorithms; }
'';
description = "Extra packages available to Texlive.";
};
package = mkOption {
type = types.package;
description = "Resulting customized Texlive package.";
readOnly = true;
};
};
};
config = mkIf cfg.enable {
home.packages = [
(pkgs.texlive.combine (cfg.extraPackages pkgs.texlive))
assertions = [
{
assertion = texlivePkgs != {};
message = "Must provide at least one extra package in"
+ " 'programs.texlive.extraPackages'.";
}
];
home.packages = [ cfg.package ];
programs.texlive.package = pkgs.texlive.combine texlivePkgs;
};
}

307
modules/programs/tmux.nix Normal file
View File

@@ -0,0 +1,307 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.tmux;
pluginName = p: if types.package.check p then p.name else p.plugin.name;
pluginModule = types.submodule {
options = {
plugin = mkOption {
type = types.package;
description = "Path of the configuration file to include.";
};
extraConfig = mkOption {
type = types.lines;
description = "Additional configuration for the associated plugin.";
default = "";
};
};
};
defaultKeyMode = "emacs";
defaultResize = 5;
defaultShortcut = "b";
defaultTerminal = "screen";
boolToStr = value: if value then "on" else "off";
tmuxConf = ''
set -g default-terminal "${cfg.terminal}"
set -g base-index ${toString cfg.baseIndex}
setw -g pane-base-index ${toString cfg.baseIndex}
${optionalString cfg.newSession "new-session"}
${optionalString cfg.reverseSplit ''
bind v split-window -h
bind s split-window -v
''}
set -g status-keys ${cfg.keyMode}
set -g mode-keys ${cfg.keyMode}
${optionalString (cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize) ''
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r H resize-pane -L ${toString cfg.resizeAmount}
bind -r J resize-pane -D ${toString cfg.resizeAmount}
bind -r K resize-pane -U ${toString cfg.resizeAmount}
bind -r L resize-pane -R ${toString cfg.resizeAmount}
''}
${optionalString (cfg.shortcut != defaultShortcut) ''
# rebind main key: C-${cfg.shortcut}
unbind C-${defaultShortcut}
set -g prefix C-${cfg.shortcut}
bind ${cfg.shortcut} send-prefix
bind C-${cfg.shortcut} last-window
''}
setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
set -s escape-time ${toString cfg.escapeTime}
set -g history-limit ${toString cfg.historyLimit}
${cfg.extraConfig}
'';
in
{
options = {
programs.tmux = {
aggressiveResize = mkOption {
default = false;
type = types.bool;
description = ''
Resize the window to the size of the smallest session for
which it is the current window.
'';
};
baseIndex = mkOption {
default = 0;
example = 1;
type = types.ints.unsigned;
description = "Base index for windows and panes.";
};
clock24 = mkOption {
default = false;
type = types.bool;
description = "Use 24 hour clock.";
};
customPaneNavigationAndResize = mkOption {
default = false;
type = types.bool;
description = ''
Override the hjkl and HJKL bindings for pane navigation and
resizing in VI mode.
'';
};
enable = mkEnableOption "tmux";
escapeTime = mkOption {
default = 500;
example = 0;
type = types.ints.unsigned;
description = ''
Time in milliseconds for which tmux waits after an escape is
input.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional configuration to add to
<filename>tmux.conf</filename>.
'';
};
historyLimit = mkOption {
default = 2000;
example = 5000;
type = types.ints.positive;
description = "Maximum number of lines held in window history.";
};
keyMode = mkOption {
default = defaultKeyMode;
example = "vi";
type = types.enum [ "emacs" "vi" ];
description = "VI or Emacs style shortcuts.";
};
newSession = mkOption {
default = false;
type = types.bool;
description = ''
Automatically spawn a session if trying to attach and none
are running.
'';
};
package = mkOption {
type = types.package;
default = pkgs.tmux;
defaultText = "pkgs.tmux";
example = literalExample "pkgs.tmux";
description = "The tmux package to install";
};
reverseSplit = mkOption {
default = false;
type = types.bool;
description = "Reverse the window split shortcuts.";
};
resizeAmount = mkOption {
default = defaultResize;
example = 10;
type = types.ints.positive;
description = "Number of lines/columns when resizing.";
};
sensibleOnTop = mkOption {
type = types.bool;
default = true;
description = ''
Run the sensible plugin at the top of the configuration. It
is possible to override the sensible settings using the
<option>programs.tmux.extraConfig</option> option.
'';
};
shortcut = mkOption {
default = defaultShortcut;
example = "a";
type = types.str;
description = ''
CTRL following by this key is used as the main shortcut.
'';
};
terminal = mkOption {
default = defaultTerminal;
example = "screen-256color";
type = types.str;
description = "Set the $TERM variable.";
};
secureSocket = mkOption {
default = true;
type = types.bool;
description = ''
Store tmux socket under <filename>/run</filename>, which is more
secure than <filename>/tmp</filename>, but as a downside it doesn't
survive user logout.
'';
};
tmuxp.enable = mkEnableOption "tmuxp";
tmuxinator.enable = mkEnableOption "tmuxinator";
plugins = mkOption {
type = with types;
listOf (either package pluginModule)
// { description = "list of plugin packages or submodules"; };
description = ''
List of tmux plugins to be included at the end of your tmux
configuration. The sensible plugin, however, is defaulted to
run at the top of your configuration.
'';
default = [ ];
example = literalExample ''
with pkgs; [
tmuxPlugins.cpu
{
plugin = tmuxPlugins.resurrect;
extraConfig = "set -g @resurrect-strategy-nvim 'session'";
}
{
plugin = tmuxPlugins.continuum;
extraConfig = '''
set -g @continuum-restore 'on'
set -g @continuum-save-interval '60' # minutes
''';
}
]
'';
};
};
};
config = mkIf cfg.enable (
mkMerge [
{
home.packages = [ cfg.package ]
++ optional cfg.tmuxinator.enable pkgs.tmuxinator
++ optional cfg.tmuxp.enable pkgs.tmuxp;
home.file.".tmux.conf".text = tmuxConf;
}
(mkIf cfg.sensibleOnTop {
home.file.".tmux.conf".text = mkBefore ''
# ============================================= #
# Start with defaults from the Sensible plugin #
# --------------------------------------------- #
run-shell ${pkgs.tmuxPlugins.sensible.rtp}
# ============================================= #
'';
})
(mkIf cfg.secureSocket {
home.sessionVariables = {
TMUX_TMPDIR = ''''${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}'';
};
})
(mkIf (cfg.plugins != []) {
assertions = [(
let
hasBadPluginName = p: !(hasPrefix "tmuxplugin" (pluginName p));
badPlugins = filter hasBadPluginName cfg.plugins;
in
{
assertion = badPlugins == [];
message =
"Invalid tmux plugin (not prefixed with \"tmuxplugins\"): "
+ concatMapStringsSep ", " pluginName badPlugins;
}
)];
home.file.".tmux.conf".text = mkAfter ''
# ============================================= #
# Load plugins with Home Manager #
# --------------------------------------------- #
${(concatMapStringsSep "\n\n" (p: ''
# ${pluginName p}
# ---------------------
${p.extraConfig or ""}
run-shell ${
if types.package.check p
then p.rtp
else p.plugin.rtp
}
'') cfg.plugins)}
# ============================================= #
'';
})
]
);
}

156
modules/programs/urxvt.nix Normal file
View File

@@ -0,0 +1,156 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.urxvt;
in
{
options.programs.urxvt = {
enable = mkEnableOption "rxvt-unicode terminal emulator";
package = mkOption {
type = types.package;
default = pkgs.rxvt_unicode;
defaultText = "pkgs.rxvt_unicode";
description = "rxvt-unicode package to install.";
};
fonts = mkOption {
type = types.listOf types.str;
default = [];
description = "List of fonts to be used.";
example = [ "xft:Droid Sans Mono Nerd Font:size=9" ];
};
keybindings = mkOption {
type = types.attrsOf types.str;
default = {};
description = "Mapping of keybindings to actions";
example = literalExample ''
{
"Shift-Control-C" = "eval:selection_to_clipboard";
"Shift-Control-V" = "eval:paste_clipboard";
}
'';
};
iso14755 = mkOption {
type = types.bool;
default = true;
description = "ISO14755 support for viewing and entering unicode characters.";
};
scroll = {
bar = mkOption {
type = types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable the scrollbar";
};
style = mkOption {
type = types.enum [ "rxvt" "plain" "next" "xterm" ];
default = "plain";
description = "Scrollbar style.";
};
align = mkOption {
type = types.enum [ "top" "bottom" "center" ];
default = "center";
description = "Scrollbar alignment.";
};
position = mkOption {
type = types.enum [ "left" "right" ];
default = "right";
description = "Scrollbar position.";
};
floating = mkOption {
type = types.bool;
default = true;
description = "Whether to display an rxvt scrollbar without a trough.";
};
};
};
default = {};
description = "Scrollbar settings.";
};
lines = mkOption {
type = types.ints.unsigned;
default = 10000;
description = "Number of lines to save in the scrollback buffer.";
};
keepPosition = mkOption {
type = types.bool;
default = true;
description = "Whether to keep a scroll position when TTY receives new lines.";
};
scrollOnKeystroke = mkOption {
type = types.bool;
default = true;
description = "Whether to scroll to bottom on keyboard input.";
};
scrollOnOutput = mkOption {
type = types.bool;
default = false;
description = "Whether to scroll to bottom on TTY output.";
};
};
transparent = mkOption {
type = types.bool;
default = false;
description = "Whether to enable pseudo-transparency.";
};
shading = mkOption {
type = types.ints.between 0 200;
default = 100;
description = "Darken (0 .. 99) or lighten (101 .. 200) the transparent background.";
};
extraConfig = mkOption {
default = {};
type = types.attrs;
description = "Additional configuration to add.";
example = { "shading" = 15; };
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
xresources.properties = {
"URxvt.scrollBar" = cfg.scroll.bar.enable;
"URxvt.scrollstyle" = cfg.scroll.bar.style;
"URxvt.scrollBar_align" = cfg.scroll.bar.align;
"URxvt.scrollBar_right" = cfg.scroll.bar.position == "right";
"URxvt.scrollBar_floating" = cfg.scroll.bar.floating;
"URxvt.saveLines" = cfg.scroll.lines;
"URxvt.scrollWithBuffer" = cfg.scroll.keepPosition;
"URxvt.scrollTtyKeypress" = cfg.scroll.scrollOnKeystroke;
"URxvt.scrollTtyOutput" = cfg.scroll.scrollOnOutput;
"URxvt.transparent" = cfg.transparent;
"URxvt.shading" = cfg.shading;
"URxvt.iso14755" = cfg.iso14755;
} // flip mapAttrs' cfg.keybindings (kb: action:
nameValuePair "URxvt.keysym.${kb}" action
) // optionalAttrs (cfg.fonts != []) {
"URxvt.font" = concatStringsSep "," cfg.fonts;
} // flip mapAttrs' cfg.extraConfig (k: v:
nameValuePair "URxvt.${k}" v
);
};
}

View File

@@ -9,17 +9,25 @@ let
knownSettings = {
background = types.enum [ "dark" "light" ];
backupdir = types.listOf types.str;
copyindent = types.bool;
directory = types.listOf types.str;
expandtab = types.bool;
hidden = types.bool;
history = types.int;
ignorecase = types.bool;
modeline = types.bool;
mouse = types.enum [ "n" "v" "i" "c" "h" "a" "r" ];
mousefocus = types.bool;
mousehide = types.bool;
mousemodel = types.enum [ "extend" "popup" "popup_setpos" ];
number = types.bool;
relativenumber = types.bool;
shiftwidth = types.int;
smartcase = types.bool;
tabstop = types.int;
undodir = types.listOf types.str;
undofile = types.bool;
};
vimSettingsType = types.submodule {
@@ -38,7 +46,12 @@ let
let
v =
if isBool value then (if value then "" else "no") + name
else name + "=" + toString value;
else
"${name}=${
if isList value
then concatStringsSep "," value
else toString value
}";
in
optionalString (value != null) ("set " + v);
@@ -49,34 +62,13 @@ in
programs.vim = {
enable = mkEnableOption "Vim";
lineNumbers = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Whether to show line numbers. DEPRECATED: Use
<varname>programs.vim.settings.number</varname>.
'';
};
tabSize = mkOption {
type = types.nullOr types.int;
default = null;
example = 4;
description = ''
Set tab size and shift width to a specified number of
spaces. DEPRECATED: Use
<varname>programs.vim.settings.tabstop</varname> and
<varname>programs.vim.settings.shiftwidth</varname>.
'';
};
plugins = mkOption {
type = types.listOf types.str;
default = defaultPlugins;
example = [ "YankRing" ];
description = ''
List of vim plugins to install. For supported plugins see:
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/vim-plugin-names"/>.
List of vim plugins to install. To get a list of supported plugins run:
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A vimPlugins</command>.
'';
};
@@ -150,31 +142,9 @@ in
];
};
in mkIf cfg.enable (mkMerge [
{
programs.vim.package = vim;
home.packages = [ cfg.package ];
}
(mkIf (cfg.lineNumbers != null) {
warnings = [
("'programs.vim.lineNumbers' is deprecated, "
+ "use 'programs.vim.settings.number'")
];
programs.vim.settings.number = cfg.lineNumbers;
})
(mkIf (cfg.tabSize != null) {
warnings = [
("'programs.vim.tabSize' is deprecated, use "
+ "'programs.vim.settings.tabstop' and "
+ "'programs.vim.settings.shiftwidth'")
];
programs.vim.settings.tabstop = cfg.tabSize;
programs.vim.settings.shiftwidth = cfg.tabSize;
})
])
in mkIf cfg.enable {
programs.vim.package = vim;
home.packages = [ cfg.package ];
}
);
}

View File

@@ -0,0 +1,58 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.vscode;
configFilePath =
if pkgs.stdenv.hostPlatform.isDarwin then
"Library/Application Support/Code/User/settings.json"
else
"${config.xdg.configHome}/Code/User/settings.json";
in
{
options = {
programs.vscode = {
enable = mkEnableOption "Visual Studio Code";
userSettings = mkOption {
type = types.attrs;
default = {};
example = literalExample ''
{
"update.channel" = "none";
"[nix]"."editor.tabSize" = 2;
}
'';
description = ''
Configuration written to Visual Studio Code's
<filename>settings.json</filename>.
'';
};
extensions = mkOption {
type = types.listOf types.package;
default = [];
example = literalExample "[ pkgs.vscode-extensions.bbenoist.Nix ]";
description = ''
The extensions Visual Studio Code should be started with.
These will override but not delete manually installed ones.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [
(pkgs.vscode-with-extensions.override {
vscodeExtensions = cfg.extensions;
})
];
home.file."${configFilePath}".text = builtins.toJSON cfg.userSettings;
};
}

View File

@@ -0,0 +1,61 @@
{ config, lib, pkgs, ...}:
with lib;
let
cfg = config.programs.zathura;
formatLine = n: v:
let
formatValue = v:
if isBool v then (if v then "true" else "false")
else toString v;
in
"set ${n}\t\"${formatValue v}\"";
in
{
meta.maintainers = [ maintainers.rprospero ];
options.programs.zathura = {
enable = mkEnableOption ''
Zathura, a highly customizable and functional document viewer
focused on keyboard interaction'';
options = mkOption {
default = {};
type = with types; attrsOf (either str (either bool int));
description = ''
Add <option>:set</option> command options to zathura and make
them permanent. See
<citerefentry>
<refentrytitle>zathurarc</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
for the full list of options.
'';
example = { default-bg = "#000000"; default-fg = "#FFFFFF"; };
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional commands for zathura that will be added to the
<filename>zathurarc</filename> file.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.zathura ];
xdg.configFile."zathura/zathurarc".text =
concatStringsSep "\n" ([]
++ optional (cfg.extraConfig != "") cfg.extraConfig
++ mapAttrsToList formatLine cfg.options
) + "\n";
};
}

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