Compare commits

...

299 Commits

Author SHA1 Message Date
Robert Helgesson
9a61b83445 news: add entry about support stopping as of May 1 2019-04-23 21:28:17 +02:00
ash lea
2ccbf43e46 browserpass: update app id
(cherry picked from commit cb93316fed)
2019-04-14 17:25:37 +02:00
Robert Helgesson
5c1d10497d modules: register the base modules path
This is needed, for example, to support relative paths when disabling
modules.

(cherry picked from commit f8b03f5750)
2019-04-14 17:23:40 +02:00
Robert Helgesson
69851e4c35 home-environment: make home.keyboard optional
When set to `null` then the `xsession` module will not attempt to
manage the keyboard settings.

(cherry picked from commit b6e1d82685)
2019-04-11 01:18:13 +02:00
Tadeo Kondrak
9d23f09790 qt: use xdg.configHome instead of hard-coding
(cherry picked from commit bc2b7d4f09)
2019-04-04 23:43:08 +02:00
Robert Helgesson
2fa6dd4cf5 taffybar: restart the service on failure
(cherry picked from commit f77d6b7a2d)
2019-04-04 23:43:08 +02:00
Robert Helgesson
d5f6e84862 systemd: add some basic tests
(cherry picked from commit 6ebf14143a)
2019-04-04 23:42:28 +02:00
Robert Helgesson
0312d450e2 random-background: minor documentation improvements
(cherry picked from commit cf5dac9563)
2019-04-04 23:39:56 +02:00
Robert Helgesson
15ef36a7f4 readme: expand contact section slightly
In particular, mention that the channel is hosted by freenode and the
channel logs are hosted by samueldr.

(cherry picked from commit 2e1c825b90)
2019-04-04 23:39:56 +02:00
Robert Helgesson
78ce79e57d readme: add contact section with the IRC channel
(cherry picked from commit a974ce6257)
2019-04-04 23:39:56 +02:00
Robert Helgesson
b8eb7a03c5 manual: use writeShellScriptBin
(cherry picked from commit 5d81cb6ac7)
2019-04-04 23:39:56 +02:00
Robert Helgesson
deb2868d57 polybar: use writeShellScriptBin
(cherry picked from commit 41356ac267)
2019-04-04 23:39:56 +02:00
Robert Helgesson
6fcaef5235 firefox: make the extensions option visible
Also change the example to use the firefox-addons available on NUR.

(cherry picked from commit 86af599a18)
2019-04-04 23:39:56 +02:00
Robert Helgesson
6bc07d4f53 ssh: add some basic tests
(cherry picked from commit 989e636d98)
2019-04-04 23:37:05 +02:00
Robert Helgesson
c40fa72cde ssh: support multiple identity files in a match block
Fixes #625

(cherry picked from commit eec78fbd1e)
2019-04-04 23:36:18 +02:00
Robert Helgesson
594294e2ca Remove some use of mkDerivation
Instead use `runCommand`, which by default uses `stdenvNoCC` resulting
in a reduced dependency footprint.

Fixes #612

(cherry picked from commit 70d4cf2cd9)
2019-04-04 23:36:02 +02:00
arcnmx
2b19f15be3 git: make userName and userEmail options optional
(cherry picked from commit 52692e299d)
2019-04-04 23:35:34 +02:00
Robert Helgesson
9901509ef8 faq: add entry about missing ca.desrt.dconf
(cherry picked from commit fd2bc150d8)
2019-04-04 23:35:34 +02:00
Robert Helgesson
5d5bc3dc5a 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/.

(cherry picked from commit 267afa5a3b)
2019-04-04 23:35:34 +02:00
Wael M. Nasreddine
ec05213a41 nix-darwin: login as the user when activating
(cherry picked from commit 7ec153889c)
2019-04-04 23:35:34 +02:00
Wael M. Nasreddine
9b82a37d28 nix-darwin: support package install through user packages
(cherry picked from commit efc795920b)
2019-04-04 23:35:33 +02:00
Wael M. Nasreddine
0ac92c6a42 nix-darwin: activate home-manager through postActivation
(cherry picked from commit d3fd287efb)
2019-04-04 23:35:33 +02:00
Robert Helgesson
5342c9479b docs: add NixOS module installation instructions
(cherry picked from commit 52fdf5b7ec)
2019-04-04 23:35:09 +02:00
Robert Helgesson
d99f0cbe62 docs: add language attribute to program listings
(cherry picked from commit a09196c4ae)
2019-04-04 23:35:09 +02:00
Robert Helgesson
87a897e0c9 docs: use <screen> for terminal interaction
(cherry picked from commit 1d8997633c)
2019-04-04 23:35:09 +02:00
Mario Rodas
fdda547e9e git: allow contents in git.includes
(cherry picked from commit 6da88339f5)
2019-04-04 23:34:35 +02:00
Maximilian Bosch
da31e466a1 nixos module: evaluate assertions from Home Manager modules
(cherry picked from commit 0898b6b482)
2019-04-04 23:32:34 +02:00
Olli Helenius
fa19c18343 pam: enclose session variable values in quotes
(cherry picked from commit 848b8b983e)
2019-04-04 23:32:34 +02:00
Maximilian Bosch
3c2823e3cd programs/zsh: properly escape shell aliases
Otherwise all aliases break that use single quotes inside.

Already fixed in the nixpkgs module in 1e211a70cbdaf230a18ea4cb67a959039d5c2ddb.

(cherry picked from commit 465d08d99f)
2019-04-04 23:32:34 +02:00
Robert Helgesson
dd94a849df tests: remove tests attribute from root default.nix
Having it there prevented, e.g., `nix-env -qaP` from working in some
cases.

Fixes #509

(cherry picked from commit b8b391ad18)
2019-02-23 22:59:15 +01:00
Douglas Wilson
ee1bfa0d92 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)

(cherry picked from commit 74811679b7)
2019-02-23 22:59:08 +01:00
Robert Helgesson
8980e08240 msmtp: use <parameter> for CLI options in description
(cherry picked from commit 93f5fcae1e)
2019-02-23 22:59:01 +01:00
Robert Helgesson
afd2d0fb84 fontconfig: make fonts accessible when in NixOS module
(cherry picked from commit 799a90ecfa)
2019-02-23 22:58:47 +01:00
Robert Helgesson
2bdaf4ae98 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.

(cherry picked from commit ef168979bf)
2019-02-23 22:58:47 +01:00
Robert Helgesson
1ade5cad80 Revert "fish: use global for abbr"
This reverts commit 7d6a6cbbe3.

The version of fish in Nixpkgs 18.09 is not compatible with this
option. See #581.
2019-02-13 17:25:03 +01:00
Olli Helenius
cf5b16b45f msmtp: use XDG config directory
(cherry picked from commit a3462daeb1)
2019-02-11 01:23:50 +01:00
Robert Helgesson
45057f353c tests: bump to latest nmt version
(cherry picked from commit a334a941c4)
2019-02-11 01:22:02 +01:00
Robert Helgesson
ee7631fbe3 git: add basic support for LFS
Fixes #542

(cherry picked from commit 1cdb8abf30)
2019-02-11 01:22:02 +01:00
Ingolf Wanger
fdb81a7ea0 nixos: use correct username for systemd service
(cherry picked from commit fbdb5beb59)
2019-02-11 01:22:02 +01:00
Robert Helgesson
1c3614cbc8 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.

(cherry picked from commit 2f372ab4d6)
2019-02-11 01:22:02 +01:00
Lorenzo Manacorda
75538973db doc: add "See also" section to manpages
Pointing to each other.

(cherry picked from commit 524ce43e23)
2019-02-11 01:22:02 +01:00
Lorenzo Manacorda
37760ed934 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.

(cherry picked from commit 7f8e139413)
2019-02-11 01:22:01 +01:00
Robert Helgesson
6924761aaf doc: move home-manager man page to section 1
This is not really a system administration tool so 8 is unsuitable.

(cherry picked from commit 99d79d0a80)
2019-02-11 01:22:01 +01:00
Jonas Holst Damtoft
5ccc2298de emacs: add service module
(cherry picked from commit 0ca1bf3cfd)
2019-02-11 01:22:01 +01:00
Matthieu Coudron
0f4c798c81 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.

(cherry picked from commit c18984c452)
2019-02-11 01:22:01 +01:00
Robert Helgesson
f89522362f 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.

(cherry picked from commit 445c0b1482)
2019-02-11 01:22:01 +01:00
Robert Helgesson
7772158ac4 mbsync: add basic test of result configuration
(cherry picked from commit 0590c2a4f6)
2019-02-11 01:22:01 +01:00
Nadrieril
fb96af9b9d mbsync: add some required assertions
(cherry picked from commit 81ec856a0f)
2019-02-11 01:22:01 +01:00
Yurii Rashkovskii
c73685ec74 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
(cherry picked from commit 2410bc603b)
2019-02-11 01:22:00 +01:00
Robert Helgesson
de2d6a5d95 git: quote sendemail section header
This will allow, e.g., the character `@` in the email identity.

Also adds a test case.

Fixes #557

(cherry picked from commit 45cadbd4f3)
2019-02-11 01:22:00 +01:00
Amarandus
3bef871dac irssi: add module
irssi is a cli IRC client.

(cherry picked from commit 02a5a678f6)
2019-02-11 01:22:00 +01:00
Robert Helgesson
27042d1050 flameshot: add bars to systemd After
Fixes #544

(cherry picked from commit 98f534e172)
2019-02-11 01:22:00 +01:00
Matthieu Coudron
a6475e3e60 git: generate identities from mail accounts
(cherry picked from commit a68c8cf5f1)
2019-02-11 01:22:00 +01:00
wedens
17aaf04f72 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.

(cherry picked from commit 604fc92943)
2019-02-11 01:21:05 +01:00
Robert Helgesson
708de1ac8d xembed-sni-proxy: add module
(cherry picked from commit 008d93928f)
2019-02-11 01:21:04 +01:00
Jonas Holst Damtoft
7d6a6cbbe3 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.

(cherry picked from commit 601619660d)
2019-02-11 01:21:04 +01:00
Robert Helgesson
016005a3a3 doc: bump copyright year to 2019 in man pages
(cherry picked from commit 4aa07c3547)
2019-02-11 01:21:04 +01:00
Robert Helgesson
966b790859 doc: reformat XML files
(cherry picked from commit f3f7c5cc57)
2019-02-11 01:21:04 +01:00
Robert Helgesson
bceb74a78c doc: add basic release notes
(cherry picked from commit c035046999)
2019-02-11 01:21:04 +01:00
Robert Helgesson
bde13d0482 Update LICENSE file for 2019
(cherry picked from commit e15cd64ac9)
2019-02-11 01:21:04 +01:00
Robert Helgesson
6c30decf8d i3: replace use of types.string by types.str
(cherry picked from commit 59a4ac71f9)
2019-02-11 01:21:04 +01:00
Robert Helgesson
4bed99c71c 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`.

(cherry picked from commit 7c04351a57)
2019-02-11 01:21:04 +01:00
Robert Helgesson
f174f90fdf tests: bump nmt version
(cherry picked from commit 46f787950a)
2019-02-11 01:21:03 +01:00
Adam Washington
a9e218dddd matplotlib: add module
(cherry picked from commit 6a244b3a8d)
2019-02-11 01:21:03 +01:00
John Wiegley
3656bf1ad7 ssh: add proxyJump option
(cherry picked from commit 3cf8b9ea86)
2019-02-11 01:20:30 +01:00
Nadrieril
47450371d9 i3: add bar.extraConfig option
(cherry picked from commit df8a14e12a)
2019-02-11 01:20:30 +01:00
Robert Helgesson
4bb40ac42d tests: simplify test names
(cherry picked from commit f6ec26075d)
2019-02-11 01:20:29 +01:00
Robert Helgesson
4c311835a7 i3: add test of keybinding merge logic
(cherry picked from commit c42206db02)
2019-02-11 01:20:29 +01:00
Robert Helgesson
e9942375ce tests: bump nmt to latest
(cherry picked from commit bb64012914)
2019-02-11 01:20:29 +01:00
Nadrieril
e6bc17e7fb i3: reallow using null to disable a keybinding
(cherry picked from commit d5cc53a4e1)
2019-02-11 01:20:29 +01:00
Robert Helgesson
9f013a8fb8 dunst: avoid error on missing dunst process
(cherry picked from commit 55100918cc)
2019-01-14 18:40:51 +01:00
Robert Helgesson
3c429c2462 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.

(cherry picked from commit faee571850)
2019-01-14 18:40:51 +01:00
hyperfekt
f60f0c647f fish: autogenerate completions from man pages
(cherry picked from commit 6f422785c3)
2019-01-14 18:40:51 +01:00
David Guibert
6d8a296625 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"`.

(cherry picked from commit a7affc93ba)
2019-01-14 18:40:51 +01:00
Marcial Gaißert
2d77421d7c 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.

(cherry picked from commit 9052131aef)
2019-01-14 18:40:51 +01:00
Marcial Gaißert
257dcbcd8a 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

(cherry picked from commit 6b5e0efd1e)
2019-01-14 18:40:50 +01:00
Marcial Gaißert
f221e4935d 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.

(cherry picked from commit 62eb7ebeba)
2019-01-14 18:40:50 +01:00
Wael M. Nasreddine
29161b6e21 autorandr: add support for xrandr transformation
(cherry picked from commit c48fd9d842)
2019-01-14 18:40:50 +01:00
Robert Helgesson
9e913a9a30 texlive: always require at least one extra package
Fixes #526

(cherry picked from commit e150dd4a66)
2019-01-14 18:40:50 +01:00
Olli Helenius
e57e34f799 gnome-terminal: enable VTE OSC7 support for bash and zsh
(cherry picked from commit b3d73e0aff)
2019-01-14 18:40:50 +01:00
Olli Helenius
af94896ba1 Address review comments
(cherry picked from commit 16946a6f00)
2019-01-14 18:40:50 +01:00
Olli Helenius
8026e4ff6f zsh: add default keymap configuration
(cherry picked from commit a4383075af)
2019-01-14 18:40:50 +01:00
Robert Helgesson
ad0b33387d emacs: make finalPackage option more accessible
Instead of "internal" mark it as "invisible".

(cherry picked from commit 20a60be550)
2019-01-14 18:40:49 +01:00
Mario Rodas
c67d2a916f opam: add module
(cherry picked from commit 7afefcf75d)
2019-01-14 18:40:49 +01:00
Robert Helgesson
82ed4dae2a dconf: add some information of use under NixOS
(cherry picked from commit 40b3443c8f)
2019-01-14 18:37:51 +01:00
Robert Helgesson
7e65605d8f gtk: remove option gtk.gtk3.waylandSupport
(cherry picked from commit cc964b4609)
2019-01-14 18:37:51 +01:00
Robert Helgesson
be7017b9c8 gtk: make gtk.gtk2 and gtk.gtk3 not submodules
(cherry picked from commit 370a84192e)
2019-01-14 18:37:51 +01:00
Robert Helgesson
5b66b89d6e gtk: use dconf module for settings
(cherry picked from commit 4104ff2b6a)
2019-01-14 18:37:50 +01:00
Robert Helgesson
1e7fbde1be gnome-terminal: use dconf module for settings
(cherry picked from commit a0162dacf6)
2019-01-14 18:37:50 +01:00
Robert Helgesson
54fc5f778b dconf: add module
This module allows unified configuration of dconf settings.

(cherry picked from commit b2cc186d22)
2019-01-14 18:37:46 +01:00
Robert Helgesson
f60f9c4bb6 readme: add notice that relog may be needed
Also add instructions for non-NixOS users to add the user channel
directory to `NIX_PATH`.

(cherry picked from commit 235a6617c4)
2019-01-14 18:36:50 +01:00
Robert Helgesson
944c12dbbb modules: support conditional module inclusion
Also make use of this functionality for the `programs.chromium`
module.

See #501

(cherry picked from commit 218a8c4d90)
2019-01-14 18:36:50 +01:00
hyperfekt
17fd9cbbd0 vscode: add module
(cherry picked from commit 6ab6488e5a)
2019-01-07 18:35:39 +01:00
Robert Helgesson
dc9be1eee6 emacs: add overrides option
This option enables overriding packages within the generated Emacs
package set.

Fixes #486

(cherry picked from commit e68d6e7924)
2018-12-24 11:20:25 +01:00
Olli Helenius
c2cff13f15 jq: add module
(cherry picked from commit dc72aa2305)
2018-12-24 11:20:08 +01:00
Lorenzo
e267dfea2d readme: fix .gitconfig example
The example was referencing `~/.gitconfig`, which isn't being checked
anymore since 356c0bf751.

(cherry picked from commit 93b10bcf3c)
2018-12-12 00:56:40 +01:00
Lorenzo Manacorda
461869b438 readme: clarify bash/zsh compatibility
Makes it clearer that the compatibility mentioned only relates to the
manual loading approach.

(cherry picked from commit 4971e3735e)
2018-12-12 00:56:40 +01:00
Robert Helgesson
1484b1d48b tests: add initial test framework
(cherry picked from commit 6d56abcec1)
2018-12-12 00:56:40 +01:00
Nikita Uvarov
d5e21feebb 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.

(cherry picked from commit 5d63abb473)
2018-12-12 00:56:40 +01:00
Robert Helgesson
cb29a29055 doc: add installation instructions to manual
Also minor cleanups in README.

(cherry picked from commit 6e67bb7ae6)
2018-12-12 00:56:40 +01:00
Nikita Uvarov
c2646f9f2b polybar: switch from attrs to attrsOf
(cherry picked from commit d67835260d)
2018-12-06 00:32:53 +01:00
Nikita Uvarov
48ba1010ab dunst: switch from attrs to attrsOf
(cherry picked from commit b085344b91)
2018-12-06 00:32:53 +01:00
Nikita Uvarov
b837f8ae41 i3: switch from attrs to attrsOf
(cherry picked from commit c108eaba42)
2018-12-06 00:32:52 +01:00
dsx
0312cb611e ssh: add addressFamily option
(cherry picked from commit 6ce3ce69b9)
2018-12-06 00:32:52 +01:00
Robert Helgesson
3b7f74ab87 ssh: add certificateFile option
(cherry picked from commit 6826521ec5)
2018-12-06 00:32:52 +01:00
Robert Helgesson
c9945550de ssh: realign options
(cherry picked from commit 5fe62660aa)
2018-12-06 00:32:52 +01:00
dsx
a471c62bf2 dunst: use 'icon_path' instead of 'icon_folders'
The 'icon_folders' option is deprecated.

(cherry picked from commit 7a28f68ad0)
2018-12-06 00:32:52 +01:00
Robert Helgesson
1e2d80a583 rofi: switch from types.string to types.str
(cherry picked from commit ea9d44bede)
2018-12-06 00:32:52 +01:00
Robert Helgesson
159ee7a269 newsboat: switch from types.string to types.str
(cherry picked from commit fd3692b36f)
2018-12-06 00:32:52 +01:00
Robert Helgesson
ab562d4c2a autorandr: switch from types.string to types.str
(cherry picked from commit cd7b6fdbc1)
2018-12-06 00:32:52 +01:00
zimbatm
3646088248 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.

(cherry picked from commit 571e17410a)
2018-12-06 00:32:51 +01:00
Robert Helgesson
371715a51c beets: add enable option
(cherry picked from commit 797fbbf826)
2018-12-06 00:32:47 +01:00
Robert Helgesson
c4a9546831 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.

(cherry picked from commit a37b5c9c61)
2018-12-06 00:31:54 +01:00
Wael M. Nasreddine
88c681606b home-manager: import modules using relative path
(cherry picked from commit 30f3baabaf)
2018-12-06 00:31:54 +01:00
Robert Helgesson
63668b2172 readme: switch stable channel to 18.09
(cherry picked from commit ef29f321e0)
2018-12-06 00:31:54 +01:00
dsx
0686063f62 i3: support for workspace_layout option
(cherry picked from commit 15bca92b2c)
2018-12-06 00:31:53 +01:00
dsx
4a574ca544 i3: support for bar tray_output option
(cherry picked from commit 71f6bc41eb)
2018-12-06 00:31:53 +01:00
Robert Helgesson
f4af8151de pasystray: add paprefs and pavucontrol
This enables the "volume control" and "control local sound server"
menu options.

Fixes #461

(cherry picked from commit 6d2f16a7ae)
2018-12-06 00:31:53 +01:00
zimbatm
b535770bd4 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.

(cherry picked from commit 40b279e3a3)
2018-12-06 00:31:53 +01:00
Wael M. Nasreddine
7ab6441ab7 keybase: install the keybase package
(cherry picked from commit 9686d93ff6)
2018-12-06 00:31:13 +01:00
zimbatm
2297450ec8 termite: setup the shell hook
This fixes Ctrl+Shift+T not working.

(cherry picked from commit 67ebe16b40)
2018-12-06 00:31:13 +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
159 changed files with 9455 additions and 788 deletions

1
.gitignore vendored Normal file
View File

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

14
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,14 @@
image: nixos/nix:latest
pages:
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

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 18.09 (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-18.09.tar.gz home-manager
$ nix-channel --update
```
depending on whether you follow Nixpkgs unstable or version 17.09.
if you follow a Nixpkgs version 18.09 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/

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

236
doc/installation.xml Normal file
View File

@@ -0,0 +1,236 @@
<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-18.09.tar.gz home-manager</userinput>
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 18.09 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-18.09.tar.gz home-manager</userinput>
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
</screen>
<para>
if you follow a Nixpkgs version 18.09 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>
To be done.
</para>
</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,13 @@
<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-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,67 @@
<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 (unstable)</title>
<para>
This is the current unstable branch and the information in this section is
therefore not final.
</para>
<para>
Scheduled released is March, 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>
</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>

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

@@ -12,23 +12,26 @@ let
in
pkgs.stdenv.mkDerivation {
name = "home-manager";
buildCommand = ''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
pkgs.runCommand
"home-manager"
{
preferLocalBuild = true;
allowSubstitutes = false;
meta = with pkgs.stdenv.lib; {
description = "A user environment configurator";
maintainers = [ maintainers.rycee ];
platforms = platforms.unix;
license = licenses.mit;
};
}
''
install -v -D -m755 ${./home-manager} $out/bin/home-manager
substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${pkgs.bash}" \
--subst-var-by coreutils "${pkgs.coreutils}" \
--subst-var-by findutils "${pkgs.findutils}" \
--subst-var-by gnused "${pkgs.gnused}" \
--subst-var-by less "${pkgs.less}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
'';
meta = with pkgs.stdenv.lib; {
description = "A user environment configurator";
maintainers = [ maintainers.rycee ];
platforms = platforms.unix;
license = licenses.mit;
};
}
''

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,14 @@ function errorEcho() {
echo $* >&2
}
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 +38,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 +75,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 +129,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 +167,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 +199,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
@@ -200,6 +246,23 @@ function doRmGenerations() {
popd > /dev/null
}
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 +290,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
@@ -284,6 +365,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,6 +377,11 @@ 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"
@@ -311,8 +399,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"
;;
@@ -352,6 +443,9 @@ cmd="$1"
shift 1
case "$cmd" in
edit)
doEdit
;;
build)
doBuild
;;
@@ -364,6 +458,9 @@ case "$cmd" in
remove-generations)
doRmGenerations "$@"
;;
expire-generations)
doExpireGenerations "$@"
;;
packages)
doListPackages
;;

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

@@ -4,7 +4,26 @@ pkgs.runCommand
"home-manager-install"
{
propagatedBuildInputs = [ home-manager ];
preferLocalBuild = true;
allowSubstitutes = false;
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 +34,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.

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

@@ -0,0 +1,414 @@
{ config, lib, ... }:
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.ints.positive;
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.ints.positive;
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.";
};
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)
(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"] (
@@ -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,7 +166,7 @@ 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>
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "$FOO World!";
@@ -161,7 +175,7 @@ in
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>
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!";
@@ -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,7 +366,6 @@ in
pkgs.gnugrep
pkgs.gnused
pkgs.ncurses # For `tput`.
pkgs.nix
]
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
@@ -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;
@@ -59,23 +85,17 @@ in
};
};
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 ])
];
};
# 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" "";
};
}

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

@@ -0,0 +1,83 @@
{ 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 "[" + concatMapStringsSep "," tweakVal v + "]"
else if isBool v then (if v then "true" else "false")
else toString v;
in
"${key}=${tweakVal value}";
primitive = with types; either bool (either int 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 = 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>.
'';
};
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,471 @@ 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-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 = "2019-01-07T17:35:19+00:00";
message = ''
A new module is available: 'programs.vscode'.
'';
}
{
time = "2019-01-14T17:37:23+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-04-23T19:15:07+00:00";
message = ''
As of May 1, 2019 the release-18.09 branch of Home Manager
will no longer be supported. You are encouraged to switch to
the release-19.03 branch as soon as possible.
Some brief notes about the 19.03 branch is available at
https://rycee.gitlab.io/home-manager/release-notes.html#sec-release-19.03
'';
}
];
};
}

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,28 @@ 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 +111,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 +144,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";
};
}

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

@@ -0,0 +1,41 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qt;
dag = config.lib.dag;
in
{
meta.maintainers = [ maintainers.rycee ];
options = {
qt = {
enable = mkEnableOption "Qt 4 and 5 configuration";
useGtkTheme = mkOption {
type = types.bool;
default = false;
description = ''
Whether Qt 4 and 5 should be set up to use the GTK theme
settings.
'';
};
};
};
config = mkIf (cfg.enable && cfg.useGtkTheme) {
home.sessionVariables.QT_QPA_PLATFORMTHEME = "gtk2";
home.packages = [ pkgs.libsForQt5.qtstyleplugins ];
xsession.profileExtra =
"systemctl --user import-environment QT_QPA_PLATFORMTHEME";
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" ];
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,134 @@
# 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/alot.nix { })
(loadModule ./programs/astroid.nix { })
(loadModule ./programs/autorandr.nix { })
(loadModule ./programs/bash.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/lesspipe.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/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/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/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,32 @@
{ 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>.
'';
};
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
);
};
}

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

@@ -0,0 +1,167 @@
# 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 (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");
}
)
)
+ "\n"
+ alot.extraConfig;
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,277 @@
{ 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.
'';
};
};
};
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.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.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 {
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

@@ -84,8 +84,7 @@ in
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;
};
@@ -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}

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
@@ -33,10 +38,34 @@ in
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
description = "Extra packages available to Emacs.";
};
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

@@ -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;
@@ -60,5 +78,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 ${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,10 @@ 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
'';
profileColorsSubModule = types.submodule (
{ ... }: {
@@ -91,19 +94,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;
@@ -136,25 +126,6 @@ let
)
);
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
{
@@ -181,20 +152,26 @@ 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;
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,12 @@ in
};
};
config = mkIf (cfg.enable && !config.nixosSubmodule) {
config = mkIf (cfg.enable && !config.submoduleSupport.enable) {
home.packages = [
(import ../../home-manager {
inherit pkgs;
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.int;
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,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 = 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" ]
++ accountsConfig
++ groupsConfig
++ optional (cfg.extraConfig != "") cfg.extraConfig
) + "\n";
home.activation.createMaildir =
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
}
'';
};
}

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,22 @@ 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.
'';
};
withPython = mkOption {
type = types.bool;
default = true;
@@ -23,12 +57,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 +85,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 +128,11 @@ in
config = mkIf cfg.enable {
home.packages = [
(pkgs.neovim.override {
(pkgs.wrapNeovim cfg.package {
inherit (cfg)
extraPython3Packages withPython3
extraPythonPackages withPython
withRuby;
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,196 @@
{ 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 "address" secondaries;
};
search = {
exclude_tags = [ "deleted" "spam" ];
};
}
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.
'';
};
};
};
};
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.stdenv.shell}
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 string 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;
};
};
}

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 {
@@ -24,6 +26,15 @@ let
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;
};
}

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

@@ -0,0 +1,148 @@
{ 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 = "";
};
};
};
in
{
options = {
programs.tmux = {
enable = mkEnableOption "tmux";
package = mkOption {
type = types.package;
default = pkgs.tmux;
defaultText = "pkgs.tmux";
example = literalExample "pkgs.tmux";
description = "The tmux package to install";
};
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.
'';
};
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
''';
}
]
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional configuration to add to
<filename>tmux.conf</filename>.
'';
};
};
};
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 = cfg.extraConfig;
}
(mkIf cfg.sensibleOnTop {
home.file.".tmux.conf".text = mkBefore ''
# ============================================= #
# Start with defaults from the Sensible plugin #
# --------------------------------------------- #
run-shell ${pkgs.tmuxPlugins.sensible.rtp}
# ============================================= #
'';
})
(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,52 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.vscode;
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
<filename>~/.config/Code/User/settings.json</filename>.
'';
};
extensions = mkOption {
type = types.listOf types.package;
default = [];
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;
})
];
xdg.configFile."Code/User/settings.json".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";
};
}

View File

@@ -11,14 +11,21 @@ let
pluginsDir = if cfg.dotDir != null then
relToDotDir "plugins" else ".zsh/plugins";
envVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables;
localVarsStr = config.lib.zsh.defineAll cfg.localVariables;
aliasesStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
mapAttrsToList (k: v: "alias ${k}=${lib.escapeShellArg v}") cfg.shellAliases
);
zdotdir = "$HOME/" + cfg.dotDir;
bindkeyCommands = {
emacs = "bindkey -e";
viins = "bindkey -v";
vicmd = "bindkey -a";
};
historyModule = types.submodule ({ config, ... }: {
options = {
size = mkOption {
@@ -50,6 +57,18 @@ let
'';
};
expireDuplicatesFirst = mkOption {
type = types.bool;
default = false;
description = "Expire duplicates first.";
};
extended = mkOption {
type = types.bool;
default = false;
description = "Save timestamp into the history file.";
};
share = mkOption {
type = types.bool;
default = true;
@@ -155,7 +174,7 @@ in
default = true;
description = ''
Enable zsh completion. Don't forget to add
<programlisting>
<programlisting language="nix">
environment.pathsToLink = [ "/share/zsh" ];
</programlisting>
to your system configuration to get completion for system packages (e.g. systemd).
@@ -174,6 +193,13 @@ in
description = "Options related to commands history configuration.";
};
defaultKeymap = mkOption {
type = types.nullOr (types.enum (attrNames bindkeyCommands));
default = null;
example = "emacs";
description = "The default base keymap to use.";
};
sessionVariables = mkOption {
default = {};
type = types.attrs;
@@ -240,6 +266,15 @@ in
default = {};
description = "Options to configure oh-my-zsh.";
};
localVariables = mkOption {
type = types.attrs;
default = {};
example = { POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=["dir" "vcs"]; };
description = ''
Extra local variables defined at the top of <filename>.zshrc</filename>.
'';
};
};
};
@@ -291,6 +326,13 @@ in
HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help"
${optionalString (cfg.defaultKeymap != null) ''
# Use ${cfg.defaultKeymap} keymap as the default.
${getAttr cfg.defaultKeymap bindkeyCommands}
''}
${localVarsStr}
${concatStrings (map (plugin: ''
path+="$HOME/${pluginsDir}/${plugin.name}"
fpath+="$HOME/${pluginsDir}/${plugin.name}"
@@ -302,7 +344,7 @@ in
}
# Environment variables
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
${envVarsStr}
${optionalString cfg.oh-my-zsh.enable ''
@@ -320,7 +362,9 @@ in
''}
${concatStrings (map (plugin: ''
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
if [ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]; then
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
fi
'') cfg.plugins)}
# History options should be set in .zshrc and after oh-my-zsh sourcing.
@@ -331,7 +375,9 @@ in
setopt HIST_FCNTL_LOCK
${if cfg.history.ignoreDups then "setopt" else "unsetopt"} HIST_IGNORE_DUPS
${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
${cfg.initExtra}

View File

@@ -24,11 +24,21 @@ let
shadow-offset-y = ${toString (elemAt cfg.shadowOffsets 1)};
shadow-opacity = ${cfg.shadowOpacity};
shadow-exclude = ${toJSON cfg.shadowExclude};
no-dock-shadow = ${toJSON cfg.noDockShadow};
no-dnd-shadow = ${toJSON cfg.noDNDShadow};
'' +
optionalString cfg.blur ''
# blur
blur-background = true;
blur-background-exclude = ${toJSON cfg.blurExclude};
'' + ''
# opacity
active-opacity = ${cfg.activeOpacity};
inactive-opacity = ${cfg.inactiveOpacity};
menu-opacity = ${cfg.menuOpacity};
opacity-rule = ${toJSON cfg.opacityRule};
# other options
backend = ${toJSON cfg.backend};
@@ -41,6 +51,32 @@ in {
options.services.compton = {
enable = mkEnableOption "Compton X11 compositor";
blur = mkOption {
type = types.bool;
default = false;
description = ''
Enable background blur on transparent windows.
'';
};
blurExclude = mkOption {
type = types.listOf types.str;
default = [];
example = [
"class_g = 'slop'"
"class_i = 'polybar'"
];
description = ''
List of windows to exclude background blur.
See the
<citerefentry>
<refentrytitle>compton</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
man page for more examples.
'';
};
fade = mkOption {
type = types.bool;
default = false;
@@ -77,7 +113,12 @@ in {
];
description = ''
List of conditions of windows that should not be faded.
See <literal>compton(1)</literal> man page for more examples.
See the
<citerefentry>
<refentrytitle>compton</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
man page for more examples.
'';
};
@@ -94,7 +135,7 @@ in {
default = [ (-15) (-15) ];
example = [ (-10) (-15) ];
description = ''
Left and right offset for shadows (in pixels).
Horizontal and vertical offsets for shadows (in pixels).
'';
};
@@ -117,7 +158,28 @@ in {
];
description = ''
List of conditions of windows that should have no shadow.
See <literal>compton(1)</literal> man page for more examples.
See the
<citerefentry>
<refentrytitle>compton</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
man page for more examples.
'';
};
noDockShadow = mkOption {
type = types.bool;
default = true;
description = ''
Avoid shadow on docks.
'';
};
noDNDShadow = mkOption {
type = types.bool;
default = true;
description = ''
Avoid shadow on drag-and-drop windows.
'';
};
@@ -148,6 +210,24 @@ in {
'';
};
opacityRule = mkOption {
type = types.listOf types.str;
default = [];
example = [
"87:class_i ?= 'scratchpad'"
"91:class_i ?= 'xterm'"
];
description = ''
List of opacity rules.
See the
<citerefentry>
<refentrytitle>compton</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
man page for more examples.
'';
};
backend = mkOption {
type = types.str;
default = "glx";
@@ -157,13 +237,18 @@ in {
};
vSync = mkOption {
type = types.str;
default = "none";
example = "opengl-swc";
description = ''
Enable vertical synchronization using the specified method.
See <literal>compton(1)</literal> man page available methods.
'';
type = types.str;
default = "none";
example = "opengl-swc";
description = ''
Enable vertical synchronization using the specified method.
See the
<citerefentry>
<refentrytitle>compton</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
man page for available methods.
'';
};
refreshRate = mkOption {
@@ -199,25 +284,28 @@ in {
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
systemd.user.services.compton = {
Unit = {
Description = "Compton X11 compositor";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Unit = {
Description = "Compton X11 compositor";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
Restart = "always";
RestartSec = 3;
};
Service = {
ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
Restart = "always";
RestartSec = 3;
}
// optionalAttrs (cfg.backend == "glx") {
# Temporarily fixes corrupt colours with Mesa 18.
Environment = [ "allow_rgb10_configs=false" ];
};
};
};
}

View File

@@ -5,6 +5,9 @@ with lib;
let
cfg = config.services.dunst;
eitherStrBoolIntList = with types; either str (either bool (either int (listOf str)));
toDunstIni = generators.toINI {
mkKeyValue = key: value:
let
@@ -61,7 +64,7 @@ in
};
settings = mkOption {
type = types.attrsOf types.attrs;
type = with types; attrsOf (attrsOf eitherStrBoolIntList);
default = {};
description = "Configuration written to ~/.config/dunstrc";
example = literalExample ''
@@ -90,7 +93,7 @@ in
xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source =
"${pkgs.dunst}/share/dbus-1/services/org.knopwob.dunst.service";
services.dunst.settings.global.icon_folders =
services.dunst.settings.global.icon_path =
let
useCustomTheme =
cfg.iconTheme.package != hicolorTheme.package
@@ -99,7 +102,7 @@ in
basePaths = [
"/run/current-system/sw"
"${config.home.homeDirectory}/.nix-profile"
config.home.profileDirectory
cfg.iconTheme.package
] ++ optional useCustomTheme hicolorTheme.package;
@@ -152,7 +155,17 @@ in
}
(mkIf (cfg.settings != {}) {
xdg.configFile."dunst/dunstrc".text = toDunstIni cfg.settings;
xdg.configFile."dunst/dunstrc" = {
text = toDunstIni cfg.settings;
onChange = ''
pkillVerbose=""
if [[ -v VERBOSE ]]; then
pkillVerbose="-e"
fi
$DRY_RUN_CMD ${pkgs.procps}/bin/pkill -u $USER $pkillVerbose dunst || true
unset pkillVerbose
'';
};
})
]
);

View File

@@ -0,0 +1,44 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.emacs;
emacsCfg = config.programs.emacs;
emacsBinPath = "${emacsCfg.finalPackage}/bin";
in
{
options.services.emacs = {
enable = mkEnableOption "the Emacs daemon";
};
config = mkIf cfg.enable {
assertions = [
{
assertion = emacsCfg.enable;
message = "The Emacs service module requires"
+ " 'programs.emacs.enable = true'.";
}
];
systemd.user.services.emacs = {
Unit = {
Description = "Emacs: the extensible, self-documenting text editor";
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
};
Service = {
ExecStart = "${pkgs.stdenv.shell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs)'";
Restart = "on-failure";
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
}

View File

@@ -0,0 +1,47 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.flameshot;
package = pkgs.flameshot;
in
{
meta.maintainers = [ maintainers.hamhut1066 ];
options = {
services.flameshot = {
enable = mkEnableOption "Flameshot";
};
};
config = mkIf cfg.enable {
home.packages = [ package ];
systemd.user.services.flameshot = {
Unit = {
Description = "Powerful yet simple to use screenshot software";
After = [
"graphical-session-pre.target"
"polybar.service"
"stalonetray.service"
"taffybar.service"
];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Environment = "PATH=${config.home.profileDirectory}/bin";
ExecStart = "${package}/bin/flameshot";
Restart = "on-abort";
};
};
};
}

View File

@@ -9,8 +9,9 @@ let
gpgInitStr = ''
GPG_TTY="$(tty)"
export GPG_TTY
${pkgs.gnupg}/bin/gpg-connect-agent updatestartuptty /bye > /dev/null
'';
''
+ optionalString cfg.enableSshSupport
"${pkgs.gnupg}/bin/gpg-connect-agent updatestartuptty /bye > /dev/null";
in
@@ -39,6 +40,28 @@ in
'';
};
maxCacheTtl = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
Set the maximum time a cache entry is valid to n seconds. After this
time a cache entry will be expired even if it has been accessed
recently or has been set using gpg-preset-passphrase. The default is
2 hours (7200 seconds).
'';
};
maxCacheTtlSsh = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
Set the maximum time a cache entry used for SSH keys is valid to n
seconds. After this time a cache entry will be expired even if it has
been accessed recently or has been set using gpg-preset-passphrase.
The default is 2 hours (7200 seconds).
'';
};
enableSshSupport = mkOption {
type = types.bool;
default = false;
@@ -47,6 +70,23 @@ in
'';
};
enableExtraSocket = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable extra socket of the GnuPG key agent (useful for GPG
Agent forwarding).
'';
};
verbose = mkOption {
type = types.bool;
default = false;
description = ''
Whether to produce verbose output.
'';
};
grabKeyboardAndMouse = mkOption {
type = types.bool;
default = true;
@@ -68,6 +108,19 @@ in
<option>disable-scdaemon</option> setting to gpg-agent.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
allow-emacs-pinentry
allow-loopback-pinentry
'';
description = ''
Extra configuration lines to append to the gpg-agent
configuration file.
'';
};
};
};
@@ -85,6 +138,14 @@ in
++
optional (cfg.defaultCacheTtlSsh != null)
"default-cache-ttl-ssh ${toString cfg.defaultCacheTtlSsh}"
++
optional (cfg.maxCacheTtl != null)
"max-cache-ttl ${toString cfg.maxCacheTtl}"
++
optional (cfg.maxCacheTtlSsh != null)
"max-cache-ttl-ssh ${toString cfg.maxCacheTtlSsh}"
++
[ cfg.extraConfig ]
);
home.sessionVariables =
@@ -114,7 +175,8 @@ in
};
Service = {
ExecStart = "${pkgs.gnupg}/bin/gpg-agent --supervised";
ExecStart = "${pkgs.gnupg}/bin/gpg-agent --supervised"
+ optionalString cfg.verbose " --verbose";
ExecReload = "${pkgs.gnupg}/bin/gpgconf --reload gpg-agent";
};
};
@@ -158,5 +220,26 @@ in
};
};
})
(mkIf cfg.enableExtraSocket {
systemd.user.sockets.gpg-agent-extra = {
Unit = {
Description = "GnuPG cryptographic agent and passphrase cache (restricted)";
Documentation = "man:gpg-agent(1) man:ssh(1)";
};
Socket = {
ListenStream = "%t/gnupg/S.gpg-agent.extra";
FileDescriptorName = "extra";
Service = "gpg-agent.service";
SocketMode = "0600";
DirectoryMode = "0700";
};
Install = {
WantedBy = [ "sockets.target" ];
};
};
})
]);
}

View File

@@ -48,7 +48,7 @@ in
let
mountPoint = "\"%h/${cfg.mountPoint}\"";
in {
Environment = "PATH=/run/wrappers KEYBASE_SYSTEMD=1";
Environment = "PATH=/run/wrappers/bin KEYBASE_SYSTEMD=1";
ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${mountPoint}";
ExecStart ="${pkgs.kbfs}/bin/kbfsfuse ${toString cfg.extraFlags} ${mountPoint}";
ExecStopPost = "/run/wrappers/bin/fusermount -u ${mountPoint}";

View File

@@ -0,0 +1,75 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.kdeconnect;
package = pkgs.kdeconnect;
in
{
meta.maintainers = [ maintainers.adisbladis ];
options = {
services.kdeconnect = {
enable = mkEnableOption "KDE connect";
indicator = mkOption {
type = types.bool;
default = false;
description = "Whether to enable kdeconnect-indicator service.";
};
};
};
config = mkMerge [
(mkIf cfg.enable {
home.packages = [ package ];
systemd.user.services.kdeconnect = {
Unit = {
Description = "Adds communication between your desktop and your smartphone";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Environment = "PATH=${config.home.profileDirectory}/bin";
ExecStart = "${package}/lib/libexec/kdeconnectd";
Restart = "on-abort";
};
};
})
(mkIf cfg.indicator {
systemd.user.services.kdeconnect-indicator = {
Unit = {
Description = "kdeconnect-indicator";
After = [ "graphical-session-pre.target"
"polybar.service"
"taffybar.service"
"stalonetray.service" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Environment = "PATH=${config.home.profileDirectory}/bin";
ExecStart = "${package}/bin/kdeconnect-indicator";
Restart = "on-abort";
};
};
})
];
}

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