Compare commits

...

121 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
102 changed files with 2905 additions and 602 deletions

View file

@ -6,8 +6,7 @@ os:
before_script: before_script:
- mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER - mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
- mkdir -p ~/.config/nixpkgs
- echo "{}" > ~/.config/nixpkgs/home.nix
script: script:
nix-shell . -A install - nix-shell . -A install
- nix-shell tests -A run.all

15
FAQ.md
View file

@ -104,3 +104,18 @@ You can get some inspiration from the [Post your home-manager home.nix
file!][1] Reddit thread. file!][1] Reddit thread.
[1]: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/ [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 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal 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 that it is about to be overwrite was from a previous Home Manager
generation or from manual configuration. generation or from manual configuration.
Home Manager targets [NixOS][] unstable and NixOS version 18.03 (the Home Manager targets [NixOS][] unstable and NixOS version 18.09 (the
current stable version), it may or may not work on other Linux current stable version), it may or may not work on other Linux
distributions and NixOS versions. 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 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. 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 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 Also make sure that your user is able to build and install Nix
packages. For example, you should be able to successfully run a packages. For example, you should be able to successfully run a
command like `nix-instantiate '<nixpkgs>' -A hello`. For a command like `nix-instantiate '<nixpkgs>' -A hello` without having
multi-user install of Nix this means that your user must be to switch to the root user. For a multi-user install of Nix this
covered by the [`allowed-users`][nixAllowedUsers] Nix option. On means that your user must be covered by the
NixOS you can control this option using the [`allowed-users`][nixAllowedUsers] Nix option. On NixOS you can
control this option using the
[`nix.allowedUsers`][nixosAllowedUsers] system option. [`nix.allowedUsers`][nixosAllowedUsers] system option.
2. Assign a temporary variable holding the URL to the appropriate 2. Add the appropriate Home Manager channel. Typically this is
archive. Typically this is
```console ```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
``` ```
if you are following Nixpkgs master or an unstable channel and if you are following Nixpkgs master or an unstable channel and
```console ```console
$ HM_PATH=https://github.com/rycee/home-manager/archive/release-18.03.tar.gz $ nix-channel --add https://github.com/rycee/home-manager/archive/release-18.09.tar.gz home-manager
$ nix-channel --update
``` ```
if you follow a Nixpkgs version 18.03 channel. 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 ```console
$ cat > ~/.config/nixpkgs/home.nix <<EOF $ nix-shell '<home-manager>' -A install
{
programs.home-manager.enable = true;
programs.home-manager.path = $HM_PATH;
}
EOF
``` ```
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 3. If you do not plan on having Home Manager manage your shell
$ 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
configuration then you must source the 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 file in your shell configuration. Unfortunately, in this specific
support POSIX.2-like shells such as [Bash][] or [Z shell][]. case we currently only support POSIX.2-like shells such as
[Bash][] or [Z shell][].
For example, if you use Bash then add 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. to your `~/.profile` file.
Note, because the `HM_PATH` variable above points to the live Home If instead of using channels you want to run Home Manager from a Git
Manager repository you will automatically get updates whenever you checkout of the repository then you can use the
build a new generation. If you dislike automatic updates then perform `programs.home-manager.path` option to specify the absolute path to
a Git clone of the desired branch and instead do the above steps with the repository.
`HM_PATH` set to the _absolute path_ of your clone.
Usage Usage
----- -----
@ -232,7 +239,7 @@ such collision is detected the activation will terminate before
changing anything on your computer. changing anything on your computer.
For example, suppose you have a wonderful, painstakingly created For example, suppose you have a wonderful, painstakingly created
`~/.gitconfig` and add `~/.config/git/config` and add
```nix ```nix
{ {
@ -301,3 +308,7 @@ in your Home Manager configuration.
[nixosAllowedUsers]: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers [nixosAllowedUsers]: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers
[Z shell]: http://zsh.sourceforge.net/ [Z shell]: http://zsh.sourceforge.net/
[configuration options]: https://rycee.gitlab.io/home-manager/options.html [configuration options]: https://rycee.gitlab.io/home-manager/options.html
[#home-manager]: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager
[freenode]: https://freenode.net/
[channel logs]: https://logs.nix.samueldr.com/home-manager/
[samueldr]: https://github.com/samueldr/

View file

@ -119,6 +119,7 @@ let
<toc role="chunk-toc"> <toc role="chunk-toc">
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-home-manager-manual"><?dbhtml filename="index.html"?> <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-options"><?dbhtml filename="options.html"?></d:tocentry>
<d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
</d:tocentry> </d:tocentry>
</toc> </toc>
''; '';

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>

View file

@ -7,22 +7,19 @@
<refmiscinfo class="source">Home Manager</refmiscinfo> <refmiscinfo class="source">Home Manager</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> --> <!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname><filename>home-configuration.nix</filename></refname> <refname><filename>home-configuration.nix</filename></refname>
<refpurpose>Home Manager configuration specification</refpurpose> <refpurpose>Home Manager configuration specification</refpurpose>
</refnamediv> </refnamediv>
<refsection> <refsection>
<title>Description</title> <title>Description</title>
<para> <para>
The file <filename>~/.config/nixpkgs/home.nix</filename> contains The file <filename>~/.config/nixpkgs/home.nix</filename> contains the
the declarative specification of your Home Manager configuration. declarative specification of your Home Manager configuration. The command
The command <command>home-manager</command> takes this file and <command>home-manager</command> takes this file and realises the user
realises the user environment configuration specified therein. environment configuration specified therein.
</para> </para>
</refsection> </refsection>
<refsection> <refsection>
<title>Options</title> <title>Options</title>
<para> <para>
@ -31,4 +28,13 @@
</para> </para>
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" /> <xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
</refsection> </refsection>
<refsection>
<title>See also</title>
<para>
<citerefentry>
<refentrytitle>home-manager</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
</para>
</refsection>
</refentry> </refentry>

View file

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

View file

@ -3,12 +3,8 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Home Manager Reference Pages</title> <title>Home Manager Reference Pages</title>
<info> <info>
<author> <author><personname>Home Manager contributors</personname></author>
<personname>Home Manager contributors</personname> <copyright><year>20172019</year><holder>Home Manager contributors</holder>
<contrib>Author</contrib>
</author>
<copyright>
<year>2017-2018</year><holder>Home Manager contributors</holder>
</copyright> </copyright>
</info> </info>
<xi:include href="man-configuration.xml" /> <xi:include href="man-configuration.xml" />

View file

@ -9,12 +9,13 @@
<preface> <preface>
<title>Preface</title> <title>Preface</title>
<para> <para>
This manual will eventually describes how to install, use, and This manual will eventually describes how to install, use, and extend Home
extend Home Manager. Manager.
</para> </para>
<para> <para>
If you encounter problems or bugs then please report them on the 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>. <link xlink:href="https://github.com/rycee/home-manager/issues">Home Manager
issue tracker</link>.
</para> </para>
<note> <note>
<para> <para>
@ -24,8 +25,10 @@
</para> </para>
</note> </note>
</preface> </preface>
<xi:include href="installation.xml" />
<appendix xml:id="ch-options"> <appendix xml:id="ch-options">
<title>Configuration Options</title> <title>Configuration Options</title>
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" /> <xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
</appendix> </appendix>
<xi:include href="./release-notes/release-notes.xml" />
</book> </book>

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>

View file

@ -12,11 +12,20 @@ let
in in
pkgs.stdenv.mkDerivation { pkgs.runCommand
name = "home-manager"; "home-manager"
{
buildCommand = '' preferLocalBuild = true;
install -v -D -m755 ${./home-manager} $out/bin/home-manager 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 \ substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${pkgs.bash}" \ --subst-var-by bash "${pkgs.bash}" \
@ -25,12 +34,4 @@ pkgs.stdenv.mkDerivation {
--subst-var-by gnused "${pkgs.gnused}" \ --subst-var-by gnused "${pkgs.gnused}" \
--subst-var-by less "${pkgs.less}" \ --subst-var-by less "${pkgs.less}" \
--subst-var-by HOME_MANAGER_PATH '${pathStr}' --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

@ -129,6 +129,17 @@ function presentNews() {
fi 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() { function doBuild() {
if [[ ! -w . ]]; then if [[ ! -w . ]]; then
errorEcho "Cannot run build in read-only directory"; errorEcho "Cannot run build in read-only directory";
@ -354,6 +365,8 @@ function doHelp() {
echo echo
echo " help Print this help" echo " help Print this help"
echo echo
echo " edit Open the home configuration in \$EDITOR"
echo
echo " build Build configuration into result directory" echo " build Build configuration into result directory"
echo echo
echo " switch Build and activate configuration" echo " switch Build and activate configuration"
@ -430,6 +443,9 @@ cmd="$1"
shift 1 shift 1
case "$cmd" in case "$cmd" in
edit)
doEdit
;;
build) build)
doBuild doBuild
;; ;;

View file

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

View file

@ -7,6 +7,23 @@ pkgs.runCommand
preferLocalBuild = true; preferLocalBuild = true;
allowSubstitutes = false; allowSubstitutes = false;
shellHook = '' 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
echo "Creating initial Home Manager generation..." echo "Creating initial Home Manager generation..."
echo echo
@ -17,7 +34,7 @@ pkgs.runCommand
All done! The home-manager tool should now be installed and you All done! The home-manager tool should now be installed and you
can edit can edit
''${XDG_CONFIG_HOME:-~/.config}/nixpkgs/home.nix $confFile
to configure Home Manager. Run 'man home-configuration.nix' to to configure Home Manager. Run 'man home-configuration.nix' to
see all available options. see all available options.

View file

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

View file

@ -14,6 +14,15 @@ let
inherit homeDirectory lib pkgs; inherit homeDirectory lib pkgs;
}).fileType; }).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 # A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation. # considered part of a Home Manager generation.
homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*"; homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*";
@ -36,20 +45,6 @@ in
}; };
config = { 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 # This verifies that the links we are about to create will not
# overwrite an existing file. # overwrite an existing file.
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] ( home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
@ -201,7 +196,7 @@ in
'' ''
declare -A changedFiles declare -A changedFiles
'' + concatMapStrings (v: '' '' + concatMapStrings (v: ''
cmp --quiet "${v.source}" "${config.home.homeDirectory}/${v.target}" \ cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \
&& changedFiles["${v.target}"]=0 \ && changedFiles["${v.target}"]=0 \
|| changedFiles["${v.target}"]=1 || changedFiles["${v.target}"]=1
'') (filter (v: v.onChange != "") (attrValues cfg)) '') (filter (v: v.onChange != "") (attrValues cfg))
@ -215,17 +210,16 @@ in
'') (filter (v: v.onChange != "") (attrValues cfg)) '') (filter (v: v.onChange != "") (attrValues cfg))
); );
home-files = pkgs.stdenv.mkDerivation { # Symlink directories and files that have the right execute bit.
name = "home-manager-files"; # Copy files that need their execute bit changed.
home-files = pkgs.runCommand
nativeBuildInputs = [ pkgs.xlibs.lndir ]; "home-manager-files"
{
preferLocalBuild = true; nativeBuildInputs = [ pkgs.xlibs.lndir ];
allowSubstitutes = false; preferLocalBuild = true;
allowSubstitutes = false;
# Symlink directories and files that have the right execute bit. }
# Copy files that need their execute bit changed. (''
buildCommand = ''
mkdir -p $out mkdir -p $out
function insertFile() { function insertFile() {
@ -277,14 +271,13 @@ in
} }
'' + concatStrings ( '' + concatStrings (
mapAttrsToList (n: v: '' mapAttrsToList (n: v: ''
insertFile "${v.source}" \ insertFile "${sourceStorePath v}" \
"${v.target}" \ "${v.target}" \
"${if v.executable == null "${if v.executable == null
then "inherit" then "inherit"
else builtins.toString v.executable}" \ else builtins.toString v.executable}" \
"${builtins.toString v.recursive}" "${builtins.toString v.recursive}"
'') cfg '') cfg
); ));
};
}; };
} }

View file

@ -139,9 +139,12 @@ in
}; };
home.keyboard = mkOption { home.keyboard = mkOption {
type = keyboardSubModule; type = types.nullOr keyboardSubModule;
default = {}; default = {};
description = "Keyboard configuration."; description = ''
Keyboard configuration. Set to <literal>null</literal> to
disable Home Manager keyboard management.
'';
}; };
home.sessionVariables = mkOption { home.sessionVariables = mkOption {
@ -163,7 +166,7 @@ in
Note, these variables may be set in any order so no session Note, these variables may be set in any order so no session
variable may have a runtime dependency on another session variable may have a runtime dependency on another session
variable. In particular code like variable. In particular code like
<programlisting> <programlisting language="nix">
home.sessionVariables = { home.sessionVariables = {
FOO = "Hello"; FOO = "Hello";
BAR = "$FOO World!"; BAR = "$FOO World!";
@ -172,7 +175,7 @@ in
may not work as expected. If you need to reference another may not work as expected. If you need to reference another
session variable, then do so inside Nix instead. The above session variable, then do so inside Nix instead. The above
example then becomes example then becomes
<programlisting> <programlisting language="nix">
home.sessionVariables = { home.sessionVariables = {
FOO = "Hello"; FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!"; BAR = "''${config.home.sessionVariables.FOO} World!";
@ -269,7 +272,11 @@ in
home.username = mkDefault (builtins.getEnv "USER"); home.username = mkDefault (builtins.getEnv "USER");
home.homeDirectory = mkDefault (builtins.getEnv "HOME"); home.homeDirectory = mkDefault (builtins.getEnv "HOME");
home.profileDirectory = cfg.homeDirectory + "/.nix-profile"; home.profileDirectory =
if config.submoduleSupport.enable
&& config.submoduleSupport.externalPackageInstall
then config.home.path
else cfg.homeDirectory + "/.nix-profile";
home.sessionVariables = home.sessionVariables =
let let
@ -307,9 +314,33 @@ in
home.activation.writeBoundary = dag.entryAnywhere ""; home.activation.writeBoundary = dag.entryAnywhere "";
# Install packages to the user environment. # 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 = home.activationPackage =
let let
@ -355,13 +386,13 @@ in
${activationCmds} ${activationCmds}
''; '';
in in
pkgs.stdenv.mkDerivation { pkgs.runCommand
name = "home-manager-generation"; "home-manager-generation"
{
preferLocalBuild = true; preferLocalBuild = true;
allowSubstitutes = false; allowSubstitutes = false;
}
buildCommand = '' ''
mkdir -p $out mkdir -p $out
cp ${activationScript} $out/activate cp ${activationScript} $out/activate
@ -374,7 +405,6 @@ in
${cfg.extraBuilderCommands} ${cfg.extraBuilderCommands}
''; '';
};
home.path = pkgs.buildEnv { home.path = pkgs.buildEnv {
name = "home-manager-path"; name = "home-manager-path";

View file

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

View file

@ -4,27 +4,7 @@ with lib;
let let
# Figures out a valid Nix store name for the given path. stringsExtra = import ./strings.nix { inherit lib; };
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;
in in
@ -113,7 +93,7 @@ in
source = mkIf (config.text != null) ( source = mkIf (config.text != null) (
mkDefault (pkgs.writeTextFile { mkDefault (pkgs.writeTextFile {
inherit (config) executable text; 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

@ -36,7 +36,7 @@ let
manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html"; manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";
helpScript = pkgs.writeScriptBin "home-manager-help" '' helpScript = pkgs.writeShellScriptBin "home-manager-help" ''
#!${pkgs.bash}/bin/bash -e #!${pkgs.bash}/bin/bash -e
if [ -z "$BROWSER" ]; then if [ -z "$BROWSER" ]; then

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

@ -8,8 +8,6 @@ let
cfg2 = config.gtk.gtk2; cfg2 = config.gtk.gtk2;
cfg3 = config.gtk.gtk3; cfg3 = config.gtk.gtk3;
dag = config.lib.dag;
toGtk3Ini = generators.toINI { toGtk3Ini = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
@ -29,16 +27,6 @@ let
in in
"${n} = ${v'}"; "${n} = ${v'}";
toDconfIni = generators.toINI {
mkKeyValue = key: value:
let
tweakVal = v:
if isString v then "'${v}'"
else toString v;
in
"${key}=${tweakVal value}";
};
fontType = types.submodule { fontType = types.submodule {
options = { options = {
package = mkOption { package = mkOption {
@ -88,6 +76,12 @@ in
{ {
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
imports = [
(mkRemovedOptionModule ["gtk" "gtk3" "waylandSupport"] ''
This options is not longer needed and can be removed.
'')
];
options = { options = {
gtk = { gtk = {
enable = mkEnableOption "GTK 2/3 configuration"; enable = mkEnableOption "GTK 2/3 configuration";
@ -112,63 +106,36 @@ in
description = "The GTK+2/3 theme to use."; description = "The GTK+2/3 theme to use.";
}; };
gtk2 = mkOption { gtk2 = {
description = "Options specific to GTK+ 2"; extraConfig = mkOption {
default = {}; type = types.lines;
type = types.submodule { default = "";
options = { example = "gtk-can-change-accels = 1";
extraConfig = mkOption { description = ''
type = types.lines; Extra configuration lines to add verbatim to
default = ""; <filename>~/.gtkrc-2.0</filename>.
example = "gtk-can-change-accels = 1"; '';
description = ''
Extra configuration lines to add verbatim to
<filename>~/.gtkrc-2.0</filename>.
'';
};
};
}; };
}; };
gtk3 = mkOption { gtk3 = {
description = "Options specific to GTK+ 3"; extraConfig = mkOption {
default = {}; type = types.attrs;
type = types.submodule { default = {};
options = { example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
extraConfig = mkOption { description = ''
type = types.attrs; Extra configuration options to add to
default = {}; <filename>~/.config/gtk-3.0/settings.ini</filename>.
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 { extraCss = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
description = '' description = ''
Extra configuration lines to add verbatim to Extra configuration lines to add verbatim to
<filename>~/.config/gtk-3.0/gtk.css</filename>. <filename>~/.config/gtk-3.0/gtk.css</filename>.
''; '';
};
waylandSupport = mkOption {
type = types.bool;
default = false;
description = ''
Support GSettings provider (dconf) in addition to
GtkSettings (INI file). This is needed for Wayland.
</para><para>
Note, on NixOS the following line must be in the
system configuration:
<programlisting>
services.dbus.packages = [ pkgs.gnome3.dconf ];
</programlisting>
'';
};
};
}; };
}; };
}; };
@ -200,7 +167,6 @@ in
optional (opt != null && opt.package != null) opt.package; optional (opt != null && opt.package != null) opt.package;
in in
{ {
home.packages = home.packages =
optionalPackage cfg.font optionalPackage cfg.font
++ optionalPackage cfg.theme ++ optionalPackage cfg.theme
@ -216,22 +182,7 @@ in
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss; xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
home.activation = mkIf cfg3.waylandSupport { dconf.settings."org/gnome/desktop/interface" = dconfIni;
gtk3 = dag.entryAfter ["installPackages"] (
let
iniText = toDconfIni { "/" = dconfIni; };
iniFile = pkgs.writeText "gtk3.ini" iniText;
dconfPath = "/org/gnome/desktop/interface/";
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
''
);
};
} }
); );
} }

View file

@ -6,6 +6,8 @@ let
cfg = config.news; cfg = config.news;
hostPlatform = pkgs.stdenv.hostPlatform;
entryModule = types.submodule ({ config, ... }: { entryModule = types.submodule ({ config, ... }: {
options = { options = {
id = mkOption { id = mkOption {
@ -734,7 +736,7 @@ in
{ {
time = "2018-08-19T20:46:09+00:00"; time = "2018-08-19T20:46:09+00:00";
condition = pkgs.stdenv.isLinux; condition = hostPlatform.isLinux;
message = '' message = ''
A new modules is available: 'programs.chromium'. A new modules is available: 'programs.chromium'.
''; '';
@ -871,6 +873,130 @@ in
A new module is available: 'services.nextcloud-client'. 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

@ -80,7 +80,7 @@ in
inside and outside Home Manager you can put it in a separate inside and outside Home Manager you can put it in a separate
file and include something like file and include something like
<programlisting> <programlisting language="nix">
nixpkgs.config = import ./nixpkgs-config.nix; nixpkgs.config = import ./nixpkgs-config.nix;
xdg.configFile."nixpkgs/config.nix".source = xdg.configFile."nixpkgs/config.nix".source =
./nixpkgs-config.nix; ./nixpkgs-config.nix;
@ -144,7 +144,10 @@ in
config = { config = {
_module.args = { _module.args = {
pkgs = _pkgs; pkgs = _pkgs;
pkgs_i686 = if _pkgs.stdenv.isLinux then _pkgs.pkgsi686Linux else {}; pkgs_i686 =
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
then _pkgs.pkgsi686Linux
else { };
}; };
}; };
} }

View file

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

View file

@ -35,7 +35,7 @@ in
home.activation.useGtkThemeInQt4 = dag.entryAfter ["writeBoundary"] '' home.activation.useGtkThemeInQt4 = dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \ $DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
--set $HOME/.config/Trolltech.conf Qt style GTK+ --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>.
'';
};
};
}

View file

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

View file

@ -6,10 +6,25 @@ let
cfg = config.programs.autorandr; 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 { profileModule = types.submodule {
options = { options = {
fingerprint = mkOption { fingerprint = mkOption {
type = types.attrsOf types.string; type = types.attrsOf types.str;
description = '' description = ''
Output name to EDID mapping. Output name to EDID mapping.
Use <code>autorandr --fingerprint</code> to get current setup values. Use <code>autorandr --fingerprint</code> to get current setup values.
@ -46,28 +61,28 @@ let
}; };
position = mkOption { position = mkOption {
type = types.string; type = types.str;
description = "Output position"; description = "Output position";
default = ""; default = "";
example = "5760x0"; example = "5760x0";
}; };
mode = mkOption { mode = mkOption {
type = types.string; type = types.str;
description = "Output resolution."; description = "Output resolution.";
default = ""; default = "";
example = "3840x2160"; example = "3840x2160";
}; };
rate = mkOption { rate = mkOption {
type = types.string; type = types.str;
description = "Output framerate."; description = "Output framerate.";
default = ""; default = "";
example = "60.00"; example = "60.00";
}; };
gamma = mkOption { gamma = mkOption {
type = types.string; type = types.str;
description = "Output gamma configuration."; description = "Output gamma configuration.";
default = ""; default = "";
example = "1.0:0.909:0.833"; example = "1.0:0.909:0.833";
@ -79,6 +94,26 @@ let
default = null; default = null;
example = "left"; 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.
'';
};
}; };
}; };
@ -150,6 +185,9 @@ let
${optionalString (config.mode != "") "mode ${config.mode}"} ${optionalString (config.mode != "") "mode ${config.mode}"}
${optionalString (config.rate != "") "rate ${config.rate}"} ${optionalString (config.rate != "") "rate ${config.rate}"}
${optionalString (config.rotate != null) "rotate ${config.rotate}"} ${optionalString (config.rotate != null) "rotate ${config.rotate}"}
${optionalString (config.transform != null) (
"transform " + concatMapStringsSep "," toString (flatten config.transform)
)}
'' else '' '' else ''
output ${name} output ${name}
off off

View file

@ -13,6 +13,21 @@ in
options = { options = {
programs.beets = { 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 { settings = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = {};
@ -24,7 +39,7 @@ in
}; };
}; };
config = mkIf (cfg.settings != {}) { config = mkIf cfg.enable {
home.packages = [ pkgs.beets ]; home.packages = [ pkgs.beets ];
xdg.configFile."beets/config.yaml".text = xdg.configFile."beets/config.yaml".text =

View file

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

View file

@ -6,8 +6,13 @@ let
cfg = config.programs.emacs; cfg = config.programs.emacs;
# Copied from all-packages.nix. # Copied from all-packages.nix, with modifications to support
emacsPackages = pkgs.emacsPackagesNgGen cfg.package; # overrides.
emacsPackages =
let
epkgs = pkgs.emacsPackagesNgGen cfg.package;
in
epkgs.overrideScope' cfg.overrides;
emacsWithPackages = emacsPackages.emacsWithPackages; emacsWithPackages = emacsPackages.emacsWithPackages;
in in
@ -34,18 +39,33 @@ in
description = "Extra packages available to Emacs."; 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 { finalPackage = mkOption {
type = types.package; type = types.package;
internal = true; visible = false;
readOnly = true; readOnly = true;
description = "The Emacs package including any extra packages."; description = ''
The Emacs package including any overrides and extra packages.
'';
}; };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ cfg.finalPackage ]; home.packages = [ cfg.finalPackage ];
programs.emacs.finalPackage = emacsWithPackages cfg.extraPackages; programs.emacs.finalPackage = emacsWithPackages cfg.extraPackages;
}; };
} }

View file

@ -6,6 +6,8 @@ let
cfg = config.programs.firefox; cfg = config.programs.firefox;
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
in in
{ {
@ -22,6 +24,22 @@ in
description = "The unwrapped Firefox package to use."; 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 { enableAdobeFlash = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -60,5 +78,18 @@ in
}; };
in in
[ (wrapper cfg.package { }) ]; [ (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;
}
);
}; };
} }

View file

@ -21,6 +21,15 @@ in
programs.fish = { programs.fish = {
enable = mkEnableOption "fish friendly interactive shell"; 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 { shellAliases = mkOption {
default = {}; default = {};
description = '' description = ''
@ -74,7 +83,70 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.fish ]; 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 = '' xdg.configFile."fish/config.fish".text = ''
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically. # ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.

View file

@ -6,6 +6,12 @@ let
cfg = config.programs.git; cfg = config.programs.git;
gitIniType = with types;
let
primitiveType = either bool (either int str);
in
attrsOf (attrsOf primitiveType);
signModule = types.submodule { signModule = types.submodule {
options = { options = {
key = mkOption { key = mkOption {
@ -28,7 +34,7 @@ let
}; };
}; };
includeModule = types.submodule { includeModule = types.submodule ({ config, ... }: {
options = { options = {
condition = mkOption { condition = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
@ -44,11 +50,23 @@ let
}; };
path = mkOption { path = mkOption {
type = types.str; type = with types; either str path;
description = "Path of the configuration file to include."; 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 in
@ -63,22 +81,28 @@ in
type = types.package; type = types.package;
default = pkgs.git; default = pkgs.git;
defaultText = "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 { userName = mkOption {
type = types.str; type = types.nullOr types.str;
default = null;
description = "Default user name to use."; description = "Default user name to use.";
}; };
userEmail = mkOption { userEmail = mkOption {
type = types.str; type = types.nullOr types.str;
default = null;
description = "Default user email to use."; description = "Default user email to use.";
}; };
aliases = mkOption { aliases = mkOption {
type = types.attrs; type = types.attrsOf types.str;
default = {}; default = {};
example = { co = "checkout"; };
description = "Git aliases to define."; description = "Git aliases to define.";
}; };
@ -89,13 +113,16 @@ in
}; };
extraConfig = mkOption { extraConfig = mkOption {
type = types.either types.attrs types.lines; type = types.either types.lines gitIniType;
default = {}; default = {};
example = {
core = { whitespace = "trailing-space,space-before-tab"; };
};
description = "Additional configuration to add."; description = "Additional configuration to add.";
}; };
iniContent = mkOption { iniContent = mkOption {
type = types.attrsOf types.attrs; type = gitIniType;
internal = true; internal = true;
}; };
@ -120,6 +147,20 @@ in
''; '';
description = "List of configuration files to include."; 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.
'';
};
};
}; };
}; };
@ -129,8 +170,8 @@ in
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
programs.git.iniContent.user = { programs.git.iniContent.user = {
name = cfg.userName; name = mkIf (cfg.userName != null) cfg.userName;
email = cfg.userEmail; email = mkIf (cfg.userEmail != null) cfg.userEmail;
}; };
xdg.configFile = { xdg.configFile = {
@ -142,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) { (mkIf (cfg.signing != null) {
programs.git.iniContent = { programs.git.iniContent = {
user.signingKey = cfg.signing.key; user.signingKey = cfg.signing.key;
@ -171,6 +232,25 @@ in
'') '')
cfg.includes); 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; 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 ( 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: buildProfileSet = pcfg:
{ {
visible-name = pcfg.visibleName; 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 in
{ {
@ -181,20 +152,26 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.gnome3.gnome_terminal ]; home.packages = [ pkgs.gnome3.gnome_terminal ];
# The dconf service needs to be installed and prepared. dconf.settings =
home.activation.gnomeTerminal = dag.entryAfter ["installPackages"] (
let let
iniText = toDconfIni (buildIniSet cfg); dconfPath = "org/gnome/terminal/legacy";
iniFile = pkgs.writeText "gnome-terminal.ini" iniText;
dconfPath = "/org/gnome/terminal/legacy/";
in in
'' {
if [[ -v DRY_RUN ]]; then "${dconfPath}" = {
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile} default-show-menubar = cfg.showMenubar;
else schema-version = 3;
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile} };
fi
'' "${dconfPath}/profiles:" = {
); default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile;
};
}
// mapAttrs' (n: v:
nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v)
) cfg.profile;
programs.bash.initExtra = mkBefore vteInitStr;
programs.zsh.initExtra = vteInitStr;
}; };
} }

View file

@ -32,7 +32,7 @@ in
}; };
}; };
config = mkIf (cfg.enable && !config.nixosSubmodule) { config = mkIf (cfg.enable && !config.submoduleSupport.enable) {
home.packages = [ home.packages = [
(import ../../home-manager { (import ../../home-manager {
inherit pkgs; inherit pkgs;

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

@ -34,24 +34,24 @@ let
let let
escapeValue = escape [ "\"" ]; escapeValue = escape [ "\"" ];
hasSpace = v: builtins.match ".* .*" v != null; hasSpace = v: builtins.match ".* .*" v != null;
genValue = v: genValue = n: v:
if isList v if isList v
then concatMapStringsSep " " genValue v then concatMapStringsSep " " (genValue n) v
else if isBool v then (if v then "yes" else "no") else if isBool v then (if v then "yes" else "no")
else if isInt v then toString v else if isInt v then toString v
else if hasSpace v then "\"${escapeValue v}\"" else if isString v && hasSpace v then "\"${escapeValue v}\""
else v; else if isString v then v
else
let prettyV = lib.generators.toPretty {} v;
in throw "mbsync: unexpected value for option ${n}: '${prettyV}'";
in in
'' ''
${header} ${header}
${concatStringsSep "\n" ${concatStringsSep "\n"
(mapAttrsToList (n: v: "${n} ${genValue v}") entries)} (mapAttrsToList (n: v: "${n} ${genValue n v}") entries)}
''; '';
genAccountConfig = account: with account; genAccountConfig = account: with account;
if (imap == null || maildir == null)
then ""
else
genSection "IMAPAccount ${name}" ( genSection "IMAPAccount ${name}" (
{ {
Host = imap.host; Host = imap.host;
@ -144,29 +144,23 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions =
( let
let checkAccounts = pred: msg:
badAccounts = filter (a: a.maildir == null) mbsyncAccounts; let
in badAccounts = filter pred mbsyncAccounts;
{ in {
assertion = badAccounts == []; assertion = badAccounts == [];
message = "mbsync: Missing maildir configuration for accounts: " message = "mbsync: ${msg} for accounts: "
+ concatMapStringsSep ", " (a: a.name) badAccounts; + concatMapStringsSep ", " (a: a.name) badAccounts;
} };
) in
[
( (checkAccounts (a: a.maildir == null) "Missing maildir configuration")
let (checkAccounts (a: a.imap == null) "Missing IMAP configuration")
badAccounts = filter (a: a.imap == null) mbsyncAccounts; (checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
in (checkAccounts (a: a.userName == null) "Missing username")
{ ];
assertion = badAccounts == [];
message = "mbsync: Missing IMAP configuration for accounts: "
+ concatMapStringsSep ", " (a: a.name) badAccounts;
}
)
];
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
@ -182,7 +176,7 @@ in
++ accountsConfig ++ accountsConfig
++ groupsConfig ++ groupsConfig
++ optional (cfg.extraConfig != "") cfg.extraConfig ++ optional (cfg.extraConfig != "") cfg.extraConfig
); ) + "\n";
home.activation.createMaildir = home.activation.createMaildir =
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] '' dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''

View file

@ -11,14 +11,25 @@ with lib;
Whether to enable msmtp. Whether to enable msmtp.
</para><para> </para><para>
If enabled then it is possible to use the If enabled then it is possible to use the
<option>--account</option> command line option to send a <parameter class="command">--account</parameter> command line
message for a given account using the <command>msmtp</command> option to send a message for a given account using the
or <command>msmtpq</command> tool. For example, <command>msmtp</command> or <command>msmtpq</command> tool.
<command>msmtp --account=private</command> For example, <command>msmtp --account=private</command> would
would send using the account defined in send using the account defined in
<option>accounts.email.accounts.private</option>. If the <option>accounts.email.accounts.private</option>. If the
<option>--account</option> option is not given then the <parameter class="command">--account</parameter> option is not
primary account will be used. 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

@ -31,6 +31,7 @@ let
# msmtp requires the password to finish with a newline. # msmtp requires the password to finish with a newline.
passwordeval = ''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"''; passwordeval = ''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"'';
} }
// msmtp.extraConfig
) )
++ optional primary "\naccount default : ${name}" ++ optional primary "\naccount default : ${name}"
); );
@ -65,7 +66,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.msmtp ]; home.packages = [ pkgs.msmtp ];
home.file.".msmtprc".text = configFile msmtpAccounts; xdg.configFile."msmtp/config".text = configFile msmtpAccounts;
home.sessionVariables = { home.sessionVariables = {
MSMTP_QUEUE = "${config.xdg.dataHome}/msmtp/queue"; MSMTP_QUEUE = "${config.xdg.dataHome}/msmtp/queue";

View file

@ -95,6 +95,13 @@ in
''; '';
}; };
package = mkOption {
type = types.package;
default = pkgs.neovim-unwrapped;
defaultText = "pkgs.neovim-unwrapped";
description = "The package to use for the neovim binary.";
};
configure = mkOption { configure = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = {};
@ -121,7 +128,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ home.packages = [
(pkgs.neovim.override { (pkgs.wrapNeovim cfg.package {
inherit (cfg) inherit (cfg)
extraPython3Packages withPython3 extraPython3Packages withPython3
extraPythonPackages withPython extraPythonPackages withPython

View file

@ -45,13 +45,13 @@ in
}; };
browser = mkOption { browser = mkOption {
type = types.string; type = types.str;
default = "${pkgs.xdg_utils}/bin/xdg-open"; default = "${pkgs.xdg_utils}/bin/xdg-open";
description = "External browser to use."; description = "External browser to use.";
}; };
queries = mkOption { queries = mkOption {
type = types.attrsOf types.string; type = types.attrsOf types.str;
default = {}; default = {};
example = { example = {
"foo" = "rssurl =~ \"example.com\""; "foo" = "rssurl =~ \"example.com\"";

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

@ -8,7 +8,7 @@ let
cfg = config.programs.rofi; cfg = config.programs.rofi;
colorOption = description: mkOption { colorOption = description: mkOption {
type = types.string; type = types.str;
description = description; description = description;
}; };
@ -175,7 +175,7 @@ in
font = mkOption { font = mkOption {
default = null; default = null;
type = types.nullOr types.string; type = types.nullOr types.str;
example = "Droid Sans Mono 14"; example = "Droid Sans Mono 14";
description = "Font to use."; description = "Font to use.";
}; };
@ -188,7 +188,7 @@ in
terminal = mkOption { terminal = mkOption {
default = null; default = null;
type = types.nullOr types.string; type = types.nullOr types.str;
description = '' description = ''
Path to the terminal which will be used to run console applications Path to the terminal which will be used to run console applications
''; '';
@ -282,7 +282,7 @@ in
configPath = mkOption { configPath = mkOption {
default = "${config.xdg.configHome}/rofi/config"; default = "${config.xdg.configHome}/rofi/config";
defaultText = "$XDG_CONFIG_HOME/rofi/config"; defaultText = "$XDG_CONFIG_HOME/rofi/config";
type = types.string; type = types.str;
description = "Path where to put generated configuration file."; description = "Path where to put generated configuration file.";
}; };

View file

@ -66,10 +66,15 @@ let
}; };
identityFile = mkOption { identityFile = mkOption {
type = types.nullOr types.str; type = with types; either (listOf str) (nullOr str);
default = null; default = [];
apply = p:
if p == null then []
else if isString p then [p]
else p;
description = '' 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.
''; '';
}; };
@ -125,6 +130,28 @@ let
description = "The command to use to connect to the server."; 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 { extraOptions = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = {};
@ -137,20 +164,23 @@ let
matchBlockStr = cf: concatStringsSep "\n" ( matchBlockStr = cf: concatStringsSep "\n" (
["Host ${cf.host}"] ["Host ${cf.host}"]
++ optional (cf.port != null) " Port ${toString cf.port}" ++ optional (cf.port != null) " Port ${toString cf.port}"
++ optional (cf.forwardAgent != null) " ForwardAgent ${yn cf.forwardAgent}" ++ optional (cf.forwardAgent != null) " ForwardAgent ${yn cf.forwardAgent}"
++ optional cf.forwardX11 " ForwardX11 yes" ++ optional cf.forwardX11 " ForwardX11 yes"
++ optional cf.forwardX11Trusted " ForwardX11Trusted yes" ++ optional cf.forwardX11Trusted " ForwardX11Trusted yes"
++ optional cf.identitiesOnly " IdentitiesOnly yes" ++ optional cf.identitiesOnly " IdentitiesOnly yes"
++ optional (cf.user != null) " User ${cf.user}" ++ optional (cf.user != null) " User ${cf.user}"
++ optional (cf.identityFile != null) " IdentityFile ${cf.identityFile}" ++ optional (cf.certificateFile != null) " CertificateFile ${cf.certificateFile}"
++ optional (cf.hostname != null) " HostName ${cf.hostname}" ++ optional (cf.hostname != null) " HostName ${cf.hostname}"
++ optional (cf.sendEnv != []) " SendEnv ${unwords cf.sendEnv}" ++ optional (cf.addressFamily != null) " AddressFamily ${cf.addressFamily}"
++ optional (cf.sendEnv != []) " SendEnv ${unwords cf.sendEnv}"
++ optional (cf.serverAliveInterval != 0) ++ optional (cf.serverAliveInterval != 0)
" ServerAliveInterval ${toString cf.serverAliveInterval}" " ServerAliveInterval ${toString cf.serverAliveInterval}"
++ optional (cf.compression != null) " Compression ${yn cf.compression}" ++ optional (cf.compression != null) " Compression ${yn cf.compression}"
++ optional (!cf.checkHostIP) " CheckHostIP no" ++ optional (!cf.checkHostIP) " CheckHostIP no"
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}" ++ 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 ++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
); );
@ -219,7 +249,7 @@ in
controlPath = mkOption { controlPath = mkOption {
type = types.str; type = types.str;
default = "~/.ssh/master-%r@%h:%p"; default = "~/.ssh/master-%r@%n:%p";
description = '' description = ''
Specify path to the control socket used for connection sharing. Specify path to the control socket used for connection sharing.
''; '';

View file

@ -6,6 +6,13 @@ let
cfg = config.programs.termite; 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 in
{ {
@ -363,6 +370,9 @@ in
${cfg.hintsExtra} ${cfg.hintsExtra}
''; '';
programs.bash.initExtra = vteInitStr;
programs.zsh.initExtra = vteInitStr;
} }
); );
} }

View file

@ -6,6 +6,8 @@ let
cfg = config.programs.texlive; cfg = config.programs.texlive;
texlivePkgs = cfg.extraPackages pkgs.texlive;
in in
{ {
@ -16,7 +18,8 @@ in
enable = mkEnableOption "Texlive"; enable = mkEnableOption "Texlive";
extraPackages = mkOption { extraPackages = mkOption {
default = self: {}; default = tpkgs: { inherit (tpkgs) collection-basic; };
defaultText = "tpkgs: { inherit (tpkgs) collection-basic; }";
example = literalExample '' example = literalExample ''
tpkgs: { inherit (tpkgs) collection-fontsrecommended algorithms; } tpkgs: { inherit (tpkgs) collection-fontsrecommended algorithms; }
''; '';
@ -32,8 +35,16 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [
{
assertion = texlivePkgs != {};
message = "Must provide at least one extra package in"
+ " 'programs.texlive.extraPackages'.";
}
];
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
programs.texlive.package =
pkgs.texlive.combine (cfg.extraPackages pkgs.texlive); programs.texlive.package = pkgs.texlive.combine texlivePkgs;
}; };
} }

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

@ -11,14 +11,21 @@ let
pluginsDir = if cfg.dotDir != null then pluginsDir = if cfg.dotDir != null then
relToDotDir "plugins" else ".zsh/plugins"; 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" ( 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; zdotdir = "$HOME/" + cfg.dotDir;
bindkeyCommands = {
emacs = "bindkey -e";
viins = "bindkey -v";
vicmd = "bindkey -a";
};
historyModule = types.submodule ({ config, ... }: { historyModule = types.submodule ({ config, ... }: {
options = { options = {
size = mkOption { size = mkOption {
@ -167,7 +174,7 @@ in
default = true; default = true;
description = '' description = ''
Enable zsh completion. Don't forget to add Enable zsh completion. Don't forget to add
<programlisting> <programlisting language="nix">
environment.pathsToLink = [ "/share/zsh" ]; environment.pathsToLink = [ "/share/zsh" ];
</programlisting> </programlisting>
to your system configuration to get completion for system packages (e.g. systemd). to your system configuration to get completion for system packages (e.g. systemd).
@ -186,6 +193,13 @@ in
description = "Options related to commands history configuration."; 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 { sessionVariables = mkOption {
default = {}; default = {};
type = types.attrs; type = types.attrs;
@ -252,6 +266,15 @@ in
default = {}; default = {};
description = "Options to configure oh-my-zsh."; 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>.
'';
};
}; };
}; };
@ -303,6 +326,13 @@ in
HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help" 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: '' ${concatStrings (map (plugin: ''
path+="$HOME/${pluginsDir}/${plugin.name}" path+="$HOME/${pluginsDir}/${plugin.name}"
fpath+="$HOME/${pluginsDir}/${plugin.name}" fpath+="$HOME/${pluginsDir}/${plugin.name}"

View file

@ -5,6 +5,9 @@ with lib;
let let
cfg = config.services.dunst; cfg = config.services.dunst;
eitherStrBoolIntList = with types; either str (either bool (either int (listOf str)));
toDunstIni = generators.toINI { toDunstIni = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
@ -61,7 +64,7 @@ in
}; };
settings = mkOption { settings = mkOption {
type = types.attrsOf types.attrs; type = with types; attrsOf (attrsOf eitherStrBoolIntList);
default = {}; default = {};
description = "Configuration written to ~/.config/dunstrc"; description = "Configuration written to ~/.config/dunstrc";
example = literalExample '' example = literalExample ''
@ -90,7 +93,7 @@ in
xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source = xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source =
"${pkgs.dunst}/share/dbus-1/services/org.knopwob.dunst.service"; "${pkgs.dunst}/share/dbus-1/services/org.knopwob.dunst.service";
services.dunst.settings.global.icon_folders = services.dunst.settings.global.icon_path =
let let
useCustomTheme = useCustomTheme =
cfg.iconTheme.package != hicolorTheme.package cfg.iconTheme.package != hicolorTheme.package
@ -152,7 +155,17 @@ in
} }
(mkIf (cfg.settings != {}) { (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

@ -24,7 +24,12 @@ in
systemd.user.services.flameshot = { systemd.user.services.flameshot = {
Unit = { Unit = {
Description = "Powerful yet simple to use screenshot software"; Description = "Powerful yet simple to use screenshot software";
After = [ "graphical-session-pre.target" ]; After = [
"graphical-session-pre.target"
"polybar.service"
"stalonetray.service"
"taffybar.service"
];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };

View file

@ -16,6 +16,8 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.keybase ];
systemd.user.services.keybase = { systemd.user.services.keybase = {
Unit = { Unit = {
Description = "Keybase service"; Description = "Keybase service";

View file

@ -24,6 +24,11 @@ with lib;
}; };
Service = { Service = {
Environment =
let
toolPaths = makeBinPath [ pkgs.paprefs pkgs.pavucontrol ];
in
[ "PATH=${toolPaths}" ];
ExecStart = "${pkgs.pasystray}/bin/pasystray"; ExecStart = "${pkgs.pasystray}/bin/pasystray";
}; };
}; };

View file

@ -6,6 +6,8 @@ let
cfg = config.services.polybar; cfg = config.services.polybar;
eitherStrBoolIntList = with types; either str (either bool (either int (listOf str)));
toPolybarIni = generators.toINI { toPolybarIni = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
@ -25,12 +27,6 @@ let
configFile = pkgs.writeText "polybar.conf" configFile = pkgs.writeText "polybar.conf"
(toPolybarIni cfg.config + "\n" + cfg.extraConfig); (toPolybarIni cfg.config + "\n" + cfg.extraConfig);
script = ''
#!${pkgs.stdenv.shell}
${cfg.script}
'';
in in
{ {
@ -57,7 +53,7 @@ in
type = types.coercedTo type = types.coercedTo
types.path types.path
(p: { "section/base" = { include-file = "${p}"; }; }) (p: { "section/base" = { include-file = "${p}"; }; })
(types.attrsOf types.attrs); (types.attrsOf (types.attrsOf eitherStrBoolIntList));
description = '' description = ''
Polybar configuration. Can be either path to a file, or set of attributes Polybar configuration. Can be either path to a file, or set of attributes
that will be used to create the final configuration. that will be used to create the final configuration.
@ -127,8 +123,12 @@ in
Service = { Service = {
Type = "forking"; Type = "forking";
Environment = "PATH=${cfg.package}/bin"; Environment = "PATH=${cfg.package}/bin:/run/wrappers/bin";
ExecStart = ''${pkgs.writeScriptBin "polybar-start" script}/bin/polybar-start''; ExecStart =
let
scriptPkg = pkgs.writeShellScriptBin "polybar-start" cfg.script;
in
"${scriptPkg}/bin/polybar-start";
}; };
Install = { Install = {

View file

@ -17,22 +17,22 @@ in
imageDirectory = mkOption { imageDirectory = mkOption {
type = types.str; type = types.str;
description = example = "%h/backgrounds";
'' description = ''
The directory of images from which a background should be The directory of images from which a background should be
chosen. Should be formatted in a way understood by chosen. Should be formatted in a way understood by systemd,
systemd, e.g., '%h' is the home directory. e.g., '%h' is the home directory.
''; '';
}; };
interval = mkOption { interval = mkOption {
default = null; default = null;
type = types.nullOr types.str; type = types.nullOr types.str;
example = "1h";
description = '' description = ''
The duration between changing background image, set to null The duration between changing background image, set to null
to only set background when logging in. to only set background when logging in. Should be formatted
as a duration understood by systemd.
Should be formatted as a duration understood by systemd.
''; '';
}; };
}; };

View file

@ -35,6 +35,7 @@ in
Service = { Service = {
ExecStart = "${cfg.package}/bin/taffybar"; ExecStart = "${cfg.package}/bin/taffybar";
Restart = "on-failure";
}; };
Install = { Install = {

View file

@ -8,7 +8,7 @@ let
commonOptions = { commonOptions = {
fonts = mkOption { fonts = mkOption {
type = types.listOf types.string; type = types.listOf types.str;
default = ["monospace 8"]; default = ["monospace 8"];
description = '' description = ''
Font list used for window titles. Only FreeType fonts are supported. Font list used for window titles. Only FreeType fonts are supported.
@ -21,7 +21,7 @@ let
startupModule = types.submodule { startupModule = types.submodule {
options = { options = {
command = mkOption { command = mkOption {
type = types.string; type = types.str;
description = "Command that will be executed on startup."; description = "Command that will be executed on startup.";
}; };
@ -41,7 +41,7 @@ let
}; };
workspace = mkOption { workspace = mkOption {
type = types.nullOr types.string; type = types.nullOr types.str;
default = null; default = null;
description = '' description = ''
Launch application on a particular workspace. DEPRECATED: Launch application on a particular workspace. DEPRECATED:
@ -55,17 +55,17 @@ let
barColorSetModule = types.submodule { barColorSetModule = types.submodule {
options = { options = {
border = mkOption { border = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
background = mkOption { background = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
text = mkOption { text = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
}; };
@ -74,27 +74,27 @@ let
colorSetModule = types.submodule { colorSetModule = types.submodule {
options = { options = {
border = mkOption { border = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
childBorder = mkOption { childBorder = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
background = mkOption { background = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
text = mkOption { text = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
indicator = mkOption { indicator = mkOption {
type = types.string; type = types.str;
visible = false; visible = false;
}; };
}; };
@ -104,8 +104,14 @@ let
options = { options = {
inherit (commonOptions) fonts; inherit (commonOptions) fonts;
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra configuration lines for this bar.";
};
id = mkOption { id = mkOption {
type = types.nullOr types.string; type = types.nullOr types.str;
default = null; default = null;
description = '' description = ''
Specifies the bar ID for the configured bar instance. Specifies the bar ID for the configured bar instance.
@ -145,7 +151,7 @@ let
}; };
command = mkOption { command = mkOption {
type = types.string; type = types.str;
default = "${cfg.package}/bin/i3bar"; default = "${cfg.package}/bin/i3bar";
defaultText = "i3bar"; defaultText = "i3bar";
description = "Command that will be used to start a bar."; description = "Command that will be used to start a bar.";
@ -153,7 +159,7 @@ let
}; };
statusCommand = mkOption { statusCommand = mkOption {
type = types.string; type = types.str;
default = "${pkgs.i3status}/bin/i3status"; default = "${pkgs.i3status}/bin/i3status";
description = "Command that will be used to get status lines."; description = "Command that will be used to get status lines.";
}; };
@ -162,19 +168,19 @@ let
type = types.submodule { type = types.submodule {
options = { options = {
background = mkOption { background = mkOption {
type = types.string; type = types.str;
default = "#000000"; default = "#000000";
description = "Background color of the bar."; description = "Background color of the bar.";
}; };
statusline = mkOption { statusline = mkOption {
type = types.string; type = types.str;
default = "#ffffff"; default = "#ffffff";
description = "Text color to be used for the statusline."; description = "Text color to be used for the statusline.";
}; };
separator = mkOption { separator = mkOption {
type = types.string; type = types.str;
default = "#666666"; default = "#666666";
description = "Text color to be used for the separator."; description = "Text color to be used for the separator.";
}; };
@ -230,13 +236,19 @@ let
See <link xlink:href="https://i3wm.org/docs/userguide.html#_colors"/>. See <link xlink:href="https://i3wm.org/docs/userguide.html#_colors"/>.
''; '';
}; };
trayOutput = mkOption {
type = types.str;
default = "primary";
description = "Where to output tray.";
};
}; };
}; };
windowCommandModule = types.submodule { windowCommandModule = types.submodule {
options = { options = {
command = mkOption { command = mkOption {
type = types.string; type = types.str;
description = "i3wm command to execute."; description = "i3wm command to execute.";
example = "border pixel 1"; example = "border pixel 1";
}; };
@ -249,7 +261,7 @@ let
}; };
}; };
criteriaModule = types.attrs; criteriaModule = types.attrsOf types.str;
configModule = types.submodule { configModule = types.submodule {
options = { options = {
@ -394,9 +406,19 @@ let
example = "Mod4"; example = "Mod4";
}; };
workspaceLayout = mkOption {
type = types.enum [ "default" "stacked" "tabbed" ];
default = "default";
example = "tabbed";
description = ''
The mode in which new containers on workspace level will
start.
'';
};
keybindings = mkOption { keybindings = mkOption {
type = types.attrs; type = types.attrsOf (types.nullOr types.str);
default = { default = mapAttrs (n: mkOptionDefault) {
"${cfg.config.modifier}+Return" = "exec i3-sensible-terminal"; "${cfg.config.modifier}+Return" = "exec i3-sensible-terminal";
"${cfg.config.modifier}+Shift+q" = "kill"; "${cfg.config.modifier}+Shift+q" = "kill";
"${cfg.config.modifier}+d" = "exec ${pkgs.dmenu}/bin/dmenu_run"; "${cfg.config.modifier}+d" = "exec ${pkgs.dmenu}/bin/dmenu_run";
@ -470,7 +492,7 @@ let
}; };
keycodebindings = mkOption { keycodebindings = mkOption {
type = types.attrs; type = types.attrsOf (types.nullOr types.str);
default = {}; default = {};
description = '' description = ''
An attribute set that assigns keypress to an action using key code. An attribute set that assigns keypress to an action using key code.
@ -483,7 +505,7 @@ let
type = types.submodule { type = types.submodule {
options = { options = {
background = mkOption { background = mkOption {
type = types.string; type = types.str;
default = "#ffffff"; default = "#ffffff";
description = '' description = ''
Background color of the window. Only applications which do not cover Background color of the window. Only applications which do not cover
@ -555,7 +577,7 @@ let
}; };
modes = mkOption { modes = mkOption {
type = types.attrsOf types.attrs; type = types.attrsOf (types.attrsOf types.str);
default = { default = {
resize = { resize = {
"Left" = "resize shrink width 10 px or 10 ppt"; "Left" = "resize shrink width 10 px or 10 ppt";
@ -671,7 +693,7 @@ let
barStr = { barStr = {
id, fonts, mode, hiddenState, position, workspaceButtons, id, fonts, mode, hiddenState, position, workspaceButtons,
workspaceNumbers, command, statusCommand, colors, ... workspaceNumbers, command, statusCommand, colors, trayOutput, extraConfig, ...
}: '' }: ''
bar { bar {
${optionalString (id != null) "id ${id}"} ${optionalString (id != null) "id ${id}"}
@ -683,6 +705,7 @@ let
i3bar_command ${command} i3bar_command ${command}
workspace_buttons ${if workspaceButtons then "yes" else "no"} workspace_buttons ${if workspaceButtons then "yes" else "no"}
strip_workspace_numbers ${if !workspaceNumbers then "yes" else "no"} strip_workspace_numbers ${if !workspaceNumbers then "yes" else "no"}
tray_output ${trayOutput}
colors { colors {
background ${colors.background} background ${colors.background}
statusline ${colors.statusline} statusline ${colors.statusline}
@ -693,6 +716,7 @@ let
urgent_workspace ${barColorSetStr colors.urgentWorkspace} urgent_workspace ${barColorSetStr colors.urgentWorkspace}
binding_mode ${barColorSetStr colors.bindingMode} binding_mode ${barColorSetStr colors.bindingMode}
} }
${extraConfig}
} }
''; '';
@ -727,6 +751,7 @@ let
focus_follows_mouse ${if focus.followMouse then "yes" else "no"} focus_follows_mouse ${if focus.followMouse then "yes" else "no"}
focus_on_window_activation ${focus.newWindow} focus_on_window_activation ${focus.newWindow}
mouse_warping ${if focus.mouseWarping then "output" else "none"} mouse_warping ${if focus.mouseWarping then "output" else "none"}
workspace_layout ${workspaceLayout}
client.focused ${colorSetStr colors.focused} client.focused ${colorSetStr colors.focused}
client.focused_inactive ${colorSetStr colors.focusedInactive} client.focused_inactive ${colorSetStr colors.focusedInactive}

View file

@ -0,0 +1,49 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.xembed-sni-proxy;
in
{
meta.maintainers = [ maintainers.rycee ];
options = {
services.xembed-sni-proxy = {
enable = mkEnableOption "XEmbed SNI Proxy";
package = mkOption {
type = types.package;
default = pkgs.plasma-workspace;
defaultText = "pkgs.plasma-workspace";
description = ''
Package containing the <command>xembedsniproxy</command>
program.
'';
};
};
};
config = mkIf cfg.enable {
systemd.user.services.xembed-sni-proxy = {
Unit = {
Description = "XEmbed SNI Proxy";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Environment = "PATH=${config.home.profileDirectory}/bin";
ExecStart = "${cfg.package}/bin/xembedsniproxy";
Restart = "on-abort";
};
};
};
}

View file

@ -27,11 +27,17 @@ let
buildService = style: name: serviceCfg: buildService = style: name: serviceCfg:
let let
filename = "${name}.${style}"; filename = "${name}.${style}";
pathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"]
["-" "-" "-" "" "" ]
filename;
# Needed because systemd derives unit names from the ultimate # Needed because systemd derives unit names from the ultimate
# link target. # link target.
source = pkgs.writeTextDir filename (toSystemdIni serviceCfg) source = pkgs.writeTextFile {
+ "/" + filename; name = pathSafeName;
text = toSystemdIni serviceCfg;
destination = "/${filename}";
} + "/${filename}";
wantedBy = target: wantedBy = target:
{ {

View file

@ -66,39 +66,43 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.user.services.setxkbmap = { systemd.user = {
Unit = { services = mkIf (config.home.keyboard != null) {
Description = "Set up keyboard in X"; setxkbmap = {
After = [ "graphical-session-pre.target" ]; Unit = {
PartOf = [ "graphical-session.target" ]; Description = "Set up keyboard in X";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
ExecStart =
let
args = concatStringsSep " " (
[
"-layout '${config.home.keyboard.layout}'"
"-variant '${config.home.keyboard.variant}'"
] ++
(map (v: "-option '${v}'") config.home.keyboard.options)
);
in
"${pkgs.xorg.setxkbmap}/bin/setxkbmap ${args}";
};
};
}; };
Install = { # A basic graphical session target for Home Manager.
WantedBy = [ "graphical-session.target" ]; targets.hm-graphical-session = {
}; Unit = {
Description = "Home Manager X session";
Service = { Requires = [ "graphical-session-pre.target" ];
Type = "oneshot"; BindsTo = [ "graphical-session.target" ];
ExecStart = };
let
args = concatStringsSep " " (
[
"-layout '${config.home.keyboard.layout}'"
"-variant '${config.home.keyboard.variant}'"
] ++
(map (v: "-option '${v}'") config.home.keyboard.options)
);
in
"${pkgs.xorg.setxkbmap}/bin/setxkbmap ${args}";
};
};
# A basic graphical session target for Home Manager.
systemd.user.targets.hm-graphical-session = {
Unit = {
Description = "Home Manager X session";
Requires = [ "graphical-session-pre.target" ];
BindsTo = [ "graphical-session.target" ];
}; };
}; };

View file

@ -7,12 +7,12 @@ let
cfg = config.home-manager; cfg = config.home-manager;
hmModule = types.submodule ({name, ...}: { hmModule = types.submodule ({name, ...}: {
imports = import ../modules/modules.nix { imports = import ../modules/modules.nix { inherit lib pkgs; };
inherit lib pkgs;
nixosSubmodule = true;
};
config = { config = {
submoduleSupport.enable = true;
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
home.username = config.users.users.${name}.name; home.username = config.users.users.${name}.name;
home.homeDirectory = config.users.users.${name}.home; home.homeDirectory = config.users.users.${name}.home;
}; };
@ -22,20 +22,27 @@ in
{ {
options = { options = {
home-manager.users = mkOption { home-manager = {
type = types.attrsOf hmModule; useUserPackages = mkEnableOption ''
default = {}; installation of user packages through the
description = '' <option>users.users.&lt;name?&gt;.packages</option> option.
Per-user Home Manager configuration.
''; '';
users = mkOption {
type = types.attrsOf hmModule;
default = {};
description = ''
Per-user Home Manager configuration.
'';
};
}; };
}; };
config = mkIf (cfg.users != {}) { config = mkIf (cfg.users != {}) {
system.activationScripts.extraActivation.text = system.activationScripts.postActivation.text =
lib.concatStringsSep "\n" (lib.mapAttrsToList (username: usercfg: '' concatStringsSep "\n" (mapAttrsToList (username: usercfg: ''
echo Activating home-manager configuration for ${username} echo Activating home-manager configuration for ${username}
sudo -u ${username} ${usercfg.home.activationPackage}/activate sudo -u ${username} -i ${usercfg.home.activationPackage}/activate
'') cfg.users); '') cfg.users);
}; };
} }

View file

@ -7,12 +7,17 @@ let
cfg = config.home-manager; cfg = config.home-manager;
hmModule = types.submodule ({name, ...}: { hmModule = types.submodule ({name, ...}: {
imports = import ../modules/modules.nix { imports = import ../modules/modules.nix { inherit lib pkgs; };
inherit lib pkgs;
nixosSubmodule = true;
};
config = { config = {
submoduleSupport.enable = true;
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
# The per-user directory inside /etc/profiles is not known by
# fontconfig by default.
fonts.fontconfig.enableProfileFonts =
cfg.useUserPackages && config.fonts.fontconfig.enable;
home.username = config.users.users.${name}.name; home.username = config.users.users.${name}.name;
home.homeDirectory = config.users.users.${name}.home; home.homeDirectory = config.users.users.${name}.home;
}; };
@ -22,16 +27,39 @@ in
{ {
options = { options = {
home-manager.users = mkOption { home-manager = {
type = types.attrsOf hmModule; useUserPackages = mkEnableOption ''
default = {}; installation of user packages through the
description = '' <option>users.users.&lt;name?&gt;.packages</option> option.
Per-user Home Manager configuration.
''; '';
users = mkOption {
type = types.attrsOf hmModule;
default = {};
description = ''
Per-user Home Manager configuration.
'';
};
}; };
}; };
config = mkIf (cfg.users != {}) { config = mkIf (cfg.users != {}) {
assertions =
flatten (flip mapAttrsToList cfg.users (user: config:
flip map config.assertions (assertion:
{
inherit (assertion) assertion;
message = "${user} profile: ${assertion.message}";
}
)
));
users.users = mkIf cfg.useUserPackages (
mapAttrs (username: usercfg: {
packages = usercfg.home.packages;
}) cfg.users
);
systemd.services = mapAttrs' (username: usercfg: systemd.services = mapAttrs' (username: usercfg:
nameValuePair ("home-manager-${utils.escapeSystemdPath username}") { nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
description = "Home Manager environment for ${username}"; description = "Home Manager environment for ${username}";
@ -40,7 +68,7 @@ in
after = [ "nix-daemon.socket" ]; after = [ "nix-daemon.socket" ];
serviceConfig = { serviceConfig = {
User = username; User = usercfg.home.username;
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = "yes"; RemainAfterExit = "yes";
SyslogIdentifier = "hm-activate-${username}"; SyslogIdentifier = "hm-activate-${username}";

37
tests/default.nix Normal file
View file

@ -0,0 +1,37 @@
{ pkgs ? import <nixpkgs> {} }:
let
nmt = pkgs.fetchFromGitLab {
owner = "rycee";
repo = "nmt";
rev = "b6ab61e707ec1ca3839fef42f9960a1179d543c4";
sha256 = "097fm1hmsyhy8chf73wwrvafcxny37414fna3haxf0q5fvpv4jfb";
};
in
import nmt {
inherit pkgs;
modules = import ../modules/modules.nix { inherit pkgs; lib = pkgs.lib; };
testedAttrPath = [ "home" "activationPackage" ];
tests = {
files-executable = ./modules/files/executable.nix;
files-hidden-source = ./modules/files/hidden-source.nix;
files-source-with-spaces = ./modules/files/source-with-spaces.nix;
files-text = ./modules/files/text.nix;
git-with-email = ./modules/programs/git-with-email.nix;
git-with-most-options = ./modules/programs/git.nix;
git-with-str-extra-config = ./modules/programs/git-with-str-extra-config.nix;
mbsync = ./modules/programs/mbsync.nix;
texlive-minimal = ./modules/programs/texlive-minimal.nix;
xresources = ./modules/xresources.nix;
}
// pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux (
{
i3-keybindings = ./modules/services/window-managers/i3-keybindings.nix;
}
// import ./modules/systemd
)
// import ./modules/programs/ssh;
}

View file

@ -0,0 +1,27 @@
{ ... }:
{
accounts.email = {
maildirBasePath = "Mail";
accounts = {
"hm@example.com" = {
address = "hm@example.com";
userName = "home.manager";
realName = "H. M. Test";
passwordCommand = "password-command";
imap.host = "imap.example.com";
smtp.host = "smtp.example.com";
};
hm-account = {
address = "hm@example.org";
userName = "home.manager.jr";
realName = "H. M. Test Jr.";
passwordCommand = "password-command 2";
imap.host = "imap.example.org";
smtp.host = "smtp.example.org";
};
};
};
}

View file

@ -0,0 +1 @@
The name of this file has a dot prefix.

View file

@ -0,0 +1,17 @@
{ config, lib, ... }:
with lib;
{
config = {
home.file."executable" = {
text = "";
executable = true;
};
nmt.script = ''
assertFileExists home-files/executable
assertFileIsExecutable home-files/executable;
'';
};
}

View file

@ -0,0 +1,16 @@
{ config, lib, ... }:
with lib;
{
config = {
home.file.".hidden".source = ./.hidden;
nmt.script = ''
assertFileExists home-files/.hidden;
assertFileContent home-files/.hidden ${
builtins.path { path = ./.hidden; name = "expected"; }
}
'';
};
}

View file

@ -0,0 +1 @@
Source with spaces!

View file

@ -0,0 +1,20 @@
{ config, lib, ... }:
with lib;
{
config = {
home.file."source with spaces!".source = ./. + "/source with spaces!";
nmt.script = ''
assertFileExists 'home-files/source with spaces!';
assertFileContent 'home-files/source with spaces!' \
${
builtins.path {
path = ./. + "/source with spaces!";
name = "source-with-spaces-expected";
}
}
'';
};
}

View file

@ -0,0 +1,2 @@
This is the
expected text.

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
with lib;
{
config = {
home.file."using-text".text = ''
This is the
expected text.
'';
nmt.script = ''
assertFileExists home-files/using-text
assertFileIsNotExecutable home-files/using-text
assertFileContent home-files/using-text ${./text-expected.txt}
'';
};
}

View file

@ -0,0 +1,34 @@
[alias]
a1=foo
a2=baz
[commit]
gpgSign=true
[extra]
boolean=true
integer=38
name=value
[filter "lfs"]
clean=git-lfs clean -- %f
process=git-lfs filter-process
required=true
smudge=git-lfs smudge -- %f
[gpg]
program=path-to-gpg
[user]
email=user@example.org
name=John Doe
signingKey=00112233445566778899AABBCCDDEEFF
[include]
path = ~/path/to/config.inc
[includeIf "gitdir:~/src/dir"]
path = ~/path/to/conditional.inc
[includeIf "gitdir:~/src/dir"]
path = @git_include_path@

View file

@ -0,0 +1,15 @@
[sendemail "hm-account"]
from=hm@example.org
smtpEncryption=tls
smtpServer=smtp.example.org
smtpUser=home.manager.jr
[sendemail "hm@example.com"]
from=hm@example.com
smtpEncryption=tls
smtpServer=smtp.example.com
smtpUser=home.manager
[user]
email=hm@example.com
name=H. M. Test

View file

@ -0,0 +1,33 @@
{ config, lib, pkgs, ... }:
with lib;
{
imports = [ ../accounts/email-test-accounts.nix ];
config = {
programs.git = {
enable = true;
userEmail = "hm@example.com";
userName = "H. M. Test";
};
nmt.script = ''
function assertGitConfig() {
local value
value=$(${pkgs.git}/bin/git config \
--file $TESTED/home-files/.config/git/config \
--get $1)
if [[ $value != $2 ]]; then
fail "Expected option '$1' to have value '$2' but it was '$value'"
fi
}
assertFileExists home-files/.config/git/config
assertFileContent home-files/.config/git/config ${./git-with-email-expected.conf}
assertGitConfig "sendemail.hm@example.com.from" "hm@example.com"
assertGitConfig "sendemail.hm-account.from" "hm@example.org"
'';
};
}

View file

@ -0,0 +1,5 @@
This can be anything.
[user]
email=user@example.org
name=John Doe

View file

@ -0,0 +1,22 @@
{ config, lib, ... }:
with lib;
{
config = {
programs.git = {
enable = true;
extraConfig = ''
This can be anything.
'';
userEmail = "user@example.org";
userName = "John Doe";
};
nmt.script = ''
assertFileExists home-files/.config/git/config
assertFileContent home-files/.config/git/config \
${./git-with-str-extra-config-expected.conf}
'';
};
}

View file

@ -0,0 +1,70 @@
{ config, lib, pkgs, ... }:
with lib;
let
gitInclude = {
user = {
name = "John Doe";
email = "user@example.org";
};
};
substituteExpected = path: pkgs.substituteAll {
src = path;
git_include_path = pkgs.writeText "contents" (generators.toINI {} gitInclude);
};
in
{
config = {
programs.git = mkMerge [
{
enable = true;
aliases = {
a1 = "foo";
a2 = "bar";
};
extraConfig = {
extra = {
name = "value";
};
};
ignores = [ "*~" "*.swp" ];
includes = [
{ path = "~/path/to/config.inc"; }
{
path = "~/path/to/conditional.inc";
condition = "gitdir:~/src/dir";
}
{
condition = "gitdir:~/src/dir";
contents = gitInclude;
}
];
signing = {
gpgPath = "path-to-gpg";
key = "00112233445566778899AABBCCDDEEFF";
signByDefault = true;
};
userEmail = "user@example.org";
userName = "John Doe";
lfs.enable = true;
}
{
aliases.a2 = mkForce "baz";
extraConfig.extra.boolean = true;
extraConfig.extra.integer = 38;
}
];
nmt.script = ''
assertFileExists home-files/.config/git/config
assertFileContent home-files/.config/git/config ${substituteExpected ./git-expected.conf}
'';
};
}

View file

@ -0,0 +1,55 @@
# Generated by Home Manager.
IMAPAccount hm-account
CertificateFile /etc/ssl/certs/ca-certificates.crt
Host imap.example.org
PassCmd "password-command 2"
SSLType IMAPS
User home.manager.jr
IMAPStore hm-account-remote
Account hm-account
MaildirStore hm-account-local
Inbox /home/hm-user/Mail/hm-account/Inbox
Path /home/hm-user/Mail/hm-account/
SubFolders Verbatim
Channel hm-account
Create None
Expunge None
Master :hm-account-remote:
Patterns *
Remove None
Slave :hm-account-local:
SyncState *
IMAPAccount hm@example.com
CertificateFile /etc/ssl/certs/ca-certificates.crt
Host imap.example.com
PassCmd password-command
SSLType IMAPS
User home.manager
IMAPStore hm@example.com-remote
Account hm@example.com
MaildirStore hm@example.com-local
Inbox /home/hm-user/Mail/hm@example.com/Inbox
Path /home/hm-user/Mail/hm@example.com/
SubFolders Verbatim
Channel hm@example.com
Create None
Expunge None
Master :hm@example.com-remote:
Patterns *
Remove None
Slave :hm@example.com-local:
SyncState *
Group inboxes
Channel hm-account:Inbox
Channel hm@example.com:Inbox1,Inbox2

View file

@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
with lib;
{
imports = [ ../accounts/email-test-accounts.nix ];
config = {
home.username = "hm-user";
home.homeDirectory = "/home/hm-user";
programs.mbsync = {
enable = true;
groups.inboxes = {
"hm@example.com" = [ "Inbox1" "Inbox2" ];
hm-account = [ "Inbox" ];
};
};
accounts.email.accounts = {
"hm@example.com".mbsync = {
enable = true;
};
hm-account.mbsync = {
enable = true;
};
};
nmt.script = ''
assertFileExists home-files/.mbsyncrc
assertFileContent home-files/.mbsyncrc ${./mbsync-expected.conf}
'';
};
}

View file

@ -0,0 +1,15 @@
Host *
ForwardAgent no
Compression no
ServerAliveInterval 0
HashKnownHosts no
UserKnownHostsFile ~/.ssh/known_hosts
ControlMaster no
ControlPath ~/.ssh/master-%r@%n:%p
ControlPersist no

View file

@ -0,0 +1,16 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
programs.ssh = {
enable = true;
};
nmt.script = ''
assertFileExists home-files/.ssh/config
assertFileContent home-files/.ssh/config ${./default-config-expected.conf}
'';
};
}

View file

@ -0,0 +1,4 @@
{
ssh-defaults = ./default-config.nix;
ssh-match-blocks = ./match-blocks-attrs.nix;
}

View file

@ -0,0 +1,25 @@
Host * !github.com
Port 516
IdentityFile file1
IdentityFile file2
Host abc
ProxyJump jump-host
Host xyz
ServerAliveInterval 60
IdentityFile file
Host *
ForwardAgent no
Compression no
ServerAliveInterval 0
HashKnownHosts no
UserKnownHostsFile ~/.ssh/known_hosts
ControlMaster no
ControlPath ~/.ssh/master-%r@%n:%p
ControlPersist no

View file

@ -0,0 +1,34 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
programs.ssh = {
enable = true;
matchBlocks = {
abc = {
identityFile = null;
proxyJump = "jump-host";
};
xyz = {
identityFile = "file";
serverAliveInterval = 60;
};
"* !github.com" = {
identityFile = ["file1" "file2"];
port = 516;
};
};
};
nmt.script = ''
assertFileExists home-files/.ssh/config
assertFileContent \
home-files/.ssh/config \
${./match-blocks-attrs-expected.conf}
'';
};
}

View file

@ -0,0 +1,13 @@
{ config, lib, ... }:
with lib;
{
config = {
programs.texlive.enable = true;
nmt.script = ''
assertFileExists home-path/bin/tex
'';
};
}

View file

@ -0,0 +1,34 @@
{ config, lib, ... }:
with lib;
{
config = {
xsession.windowManager.i3 = {
enable = true;
config.keybindings =
let
modifier = config.xsession.windowManager.i3.config.modifier;
in
lib.mkOptionDefault {
"${modifier}+Left" = "overridden-command";
"${modifier}+Right" = null;
"${modifier}+Invented" = "invented-key-command";
};
};
nmt.script = ''
assertFileExists home-files/.config/i3/config
assertFileRegex home-files/.config/i3/config \
'bindsym Mod1+Left overridden-command'
assertFileNotRegex home-files/.config/i3/config \
'Mod1+Right'
assertFileRegex home-files/.config/i3/config \
'bindsym Mod1+Invented invented-key-command'
'';
};
}

View file

@ -0,0 +1,4 @@
{
systemd-services = ./services.nix;
systemd-timers = ./timers.nix;
}

View file

@ -0,0 +1,5 @@
[Service]
ExecStart=/some/exec/start/command --with-arguments "%i"
[Unit]
Description=A basic test service

View file

@ -0,0 +1,23 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
systemd.user.services."test-service@" = {
Unit = {
Description = "A basic test service";
};
Service = {
ExecStart = ''/some/exec/start/command --with-arguments "%i"'';
};
};
nmt.script = ''
local serviceFile=home-files/.config/systemd/user/test-service@.service
assertFileExists $serviceFile
assertFileContent $serviceFile ${./services-expected.conf}
'';
};
}

View file

@ -0,0 +1,8 @@
[Install]
WantedBy=timers.target
[Timer]
OnUnitActiveSec=1h 30m
[Unit]
Description=A basic test timer

View file

@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
systemd.user.timers.test-timer = {
Unit = {
Description = "A basic test timer";
};
Timer = {
OnUnitActiveSec = "1h 30m";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
nmt.script = ''
local unitDir=home-files/.config/systemd/user
local timerFile=$unitDir/test-timer.timer
assertFileExists $timerFile
assertFileContent $timerFile ${./timers-expected.conf}
assertFileExists $unitDir/timers.target.wants/test-timer.timer
'';
};
}

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