Compare commits

...

201 Commits

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

Closes #841

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

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

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

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

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

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

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

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

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

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

that will update Home Manager in NUR.

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

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

Fixes #771.

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

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

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

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

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

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

Fixes #748

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

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

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

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

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

Closes #702

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

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

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

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

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

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

example will cause an infinite recursion.

This commit restores the option type of

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

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

Fixes #659

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

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

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

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

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

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

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

This is taken from

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

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

    users.users.<name?>.packages

option.

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

    programs.git.aliases

or

    programs.git.extraConfig

are merged as expected.

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

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

Also adds a test case.

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

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

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

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

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

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

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

    home-manager edit

opens `$HOME_MANAGER_CONFIG` in `$EDITOR`.

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

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

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

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

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

Without this change, if a connection was established with the first
github.com alias, then the user would try to pull a repo from the second
account, ssh would re-use the SSH connection which doesn't have access
to that repository.
2018-11-30 00:13:50 +01:00
Lee Henson
5d8b089188 neovim: support withNodeJs option 2018-11-29 00:54:27 +01:00
Wael M. Nasreddine
9686d93ff6 keybase: install the keybase package 2018-11-29 00:51:58 +01:00
zimbatm
67ebe16b40 termite: setup the shell hook
This fixes Ctrl+Shift+T not working.
2018-11-26 21:28:06 +01:00
hyperfekt
6ab6488e5a vscode: add module 2018-11-26 00:01:01 +01:00
153 changed files with 4836 additions and 774 deletions

View File

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

View File

@@ -6,8 +6,7 @@ os:
before_script:
- mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
- mkdir -p ~/.config/nixpkgs
- echo "{}" > ~/.config/nixpkgs/home.nix
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.
[1]: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/
Why do I get an error message about `ca.desrt.dconf`?
-----------------------------------------------------
You are most likely trying to configure the GTK or Gnome Terminal but
the DBus session is not aware of the dconf service. The full error you
might get is
error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt.dconf was not provided by any .service files
The solution on NixOS is to add
services.dbus.packages = with pkgs; [ gnome3.dconf ];
to your system configuration.

View File

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

View File

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

View File

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

View File

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

310
doc/installation.xml Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,20 @@ function errorEcho() {
echo $* >&2
}
function setVerboseAndDryRun() {
if [[ -v VERBOSE ]]; then
export VERBOSE_ARG="--verbose"
else
export VERBOSE_ARG=""
fi
if [[ -v DRY_RUN ]] ; then
export DRY_RUN_CMD=echo
else
export DRY_RUN_CMD=""
fi
}
function setWorkDir() {
if [[ ! -v WORK_DIR ]]; then
WORK_DIR="$(mktemp --tmpdir -d home-manager-build.XXXXXXXXXX)"
@@ -129,6 +143,17 @@ function presentNews() {
fi
}
function doEdit() {
if [[ ! -v EDITOR || -z $EDITOR ]]; then
errorEcho "Please set the \$EDITOR environment variable"
return 1
fi
setConfigFile
exec "$EDITOR" "$HOME_MANAGER_CONFIG"
}
function doBuild() {
if [[ ! -w . ]]; then
errorEcho "Cannot run build in read-only directory";
@@ -205,17 +230,7 @@ function doListGens() {
# Removes linked generations. Takes as arguments identifiers of
# generations to remove.
function doRmGenerations() {
if [[ -v VERBOSE ]]; then
export VERBOSE_ARG="--verbose"
else
export VERBOSE_ARG=""
fi
if [[ -v DRY_RUN ]] ; then
export DRY_RUN_CMD=echo
else
export DRY_RUN_CMD=""
fi
setVerboseAndDryRun
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
@@ -235,6 +250,11 @@ function doRmGenerations() {
popd > /dev/null
}
function doRmAllGenerations() {
$DRY_RUN_CMD rm $VERBOSE_ARG \
"/nix/var/nix/profiles/per-user/$USER/home-manager"*
}
function doExpireGenerations() {
local profileDir="/nix/var/nix/profiles/per-user/$USER"
@@ -336,6 +356,56 @@ function doShowNews() {
fi
}
function doUninstall() {
setVerboseAndDryRun
echo "This will remove Home Manager from your system."
if [[ -v DRY_RUN ]]; then
echo "This is a dry run, nothing will actually be uninstalled."
fi
local confirmation
read -r -n 1 -p "Really uninstall Home Manager? [y/n] " confirmation
echo
case $confirmation in
y|Y)
echo "Switching to empty Home Manager configuration..."
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
echo "{}" > "$HOME_MANAGER_CONFIG"
doSwitch
rm "$HOME_MANAGER_CONFIG"
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
$DRY_RUN_CMD rm $VERBOSE_ARG \
"/nix/var/nix/gcroots/per-user/$USER/current-home"
;;
*)
echo "Yay!"
exit 0
;;
esac
local deleteProfiles
read -r -n 1 \
-p 'Remove all Home Manager generations? [y/n] ' \
deleteProfiles
echo
case $deleteProfiles in
y|Y)
doRmAllGenerations
echo "All generations are now eligible for garbage collection."
;;
*)
echo "Leaving generations but they may still be garbage collected."
;;
esac
echo "Home Manager is uninstalled but your home.nix is left untouched."
}
function doHelp() {
echo "Usage: $0 [OPTION] COMMAND"
echo
@@ -354,6 +424,8 @@ function doHelp() {
echo
echo " help Print this help"
echo
echo " edit Open the home configuration in \$EDITOR"
echo
echo " build Build configuration into result directory"
echo
echo " switch Build and activate configuration"
@@ -372,6 +444,8 @@ function doHelp() {
echo " packages List all packages installed in home-manager-path"
echo
echo " news Show news entries in a pager"
echo
echo " uninstall Remove Home Manager"
}
EXTRA_NIX_PATH=()
@@ -411,7 +485,6 @@ while getopts 2f:I:A:vnh opt; do
exit 0
;;
*)
errorEcho "Unknown option -$OPTARG"
doHelp >&2
exit 1
;;
@@ -430,6 +503,9 @@ cmd="$1"
shift 1
case "$cmd" in
edit)
doEdit
;;
build)
doBuild
;;
@@ -451,6 +527,9 @@ case "$cmd" in
news)
doShowNews --all
;;
uninstall)
doUninstall
;;
help|--help)
doHelp
;;

View File

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

View File

@@ -1,12 +1,30 @@
{ home-manager, pkgs }:
{ home-manager, runCommand }:
pkgs.runCommand
runCommand
"home-manager-install"
{
propagatedBuildInputs = [ home-manager ];
preferLocalBuild = true;
allowSubstitutes = false;
shellHookOnly = true;
shellHook = ''
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
if [[ ! -e $confFile ]]; then
echo
echo "Creating initial Home Manager configuration..."
mkdir -p "$(dirname "$confFile")"
cat > $confFile <<EOF
{ config, pkgs, ... }:
{
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
}
EOF
fi
echo
echo "Creating initial Home Manager generation..."
echo
@@ -17,7 +35,7 @@ pkgs.runCommand
All done! The home-manager tool should now be installed and you
can edit
''${XDG_CONFIG_HOME:-~/.config}/nixpkgs/home.nix
$confFile
to configure Home Manager. Run 'man home-configuration.nix' to
see all available options.
@@ -36,4 +54,7 @@ pkgs.runCommand
fi
'';
}
""
''
echo This derivation is not buildable, instead run it using nix-shell.
exit 1
''

View File

@@ -1,4 +1,4 @@
{ config, lib, ... }:
{ config, lib, pkgs, ... }:
with lib;
@@ -95,7 +95,7 @@ let
};
port = mkOption {
type = types.nullOr types.ints.positive;
type = types.nullOr types.port;
default = null;
example = 993;
description = ''
@@ -125,7 +125,7 @@ let
};
port = mkOption {
type = types.nullOr types.ints.positive;
type = types.nullOr types.port;
default = null;
example = 465;
description = ''
@@ -207,6 +207,13 @@ let
description = "The email address of this account.";
};
aliases = mkOption {
type = types.listOf (types.strMatching ".*@.*");
default = [];
example = [ "webmaster@example.org" "admin@example.org" ];
description = "Alternative email addresses of this account.";
};
realName = mkOption {
type = types.str;
example = "Jane Doe";
@@ -379,7 +386,7 @@ in
accounts = mkOption {
type = types.attrsOf (types.submodule [
mailAccountOpts
(import ../programs/alot-accounts.nix)
(import ../programs/alot-accounts.nix pkgs)
(import ../programs/astroid-accounts.nix)
(import ../programs/mbsync-accounts.nix)
(import ../programs/msmtp-accounts.nix)

View File

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

View File

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

View File

@@ -139,9 +139,12 @@ in
};
home.keyboard = mkOption {
type = keyboardSubModule;
type = types.nullOr keyboardSubModule;
default = {};
description = "Keyboard configuration.";
description = ''
Keyboard configuration. Set to <literal>null</literal> to
disable Home Manager keyboard management.
'';
};
home.sessionVariables = mkOption {
@@ -163,20 +166,20 @@ in
Note, these variables may be set in any order so no session
variable may have a runtime dependency on another session
variable. In particular code like
<programlisting>
home.sessionVariables = {
FOO = "Hello";
BAR = "$FOO World!";
};
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "$FOO World!";
};
</programlisting>
may not work as expected. If you need to reference another
session variable, then do so inside Nix instead. The above
example then becomes
<programlisting>
home.sessionVariables = {
FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!";
};
<programlisting language="nix">
home.sessionVariables = {
FOO = "Hello";
BAR = "''${config.home.sessionVariables.FOO} World!";
};
</programlisting>
'';
};
@@ -269,7 +272,11 @@ in
home.username = mkDefault (builtins.getEnv "USER");
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 =
let
@@ -307,9 +314,33 @@ in
home.activation.writeBoundary = dag.entryAnywhere "";
# Install packages to the user environment.
home.activation.installPackages = dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD nix-env -i ${cfg.path}
'';
#
# Note, sometimes our target may not allow modification of the Nix
# store and then we cannot rely on `nix-env -i`. This is the case,
# for example, if we are running as a NixOS module and building a
# virtual machine. Then we must instead rely on an external
# mechanism for installing packages, which in NixOS is provided by
# the `users.users.<name?>.packages` option. The activation
# command is still needed since some modules need to run their
# activation commands after the packages are guaranteed to be
# installed.
#
# In case the user has moved from a user-install of Home Manager
# to a submodule managed one we attempt to uninstall the
# `home-manager-path` package if it is installed.
home.activation.installPackages = dag.entryAfter ["writeBoundary"] (
if config.submoduleSupport.externalPackageInstall
then
''
if nix-env -q | grep '^home-manager-path$'; then
$DRY_RUN_CMD nix-env -e home-manager-path
fi
''
else
''
$DRY_RUN_CMD nix-env -i ${cfg.path}
''
);
home.activationPackage =
let
@@ -339,7 +370,7 @@ in
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
activationScript = pkgs.writeScript "activation-script" ''
#!${pkgs.stdenv.shell}
#!${pkgs.runtimeShell}
set -eu
set -o pipefail
@@ -355,13 +386,13 @@ in
${activationCmds}
'';
in
pkgs.stdenv.mkDerivation {
name = "home-manager-generation";
preferLocalBuild = true;
allowSubstitutes = false;
buildCommand = ''
pkgs.runCommand
"home-manager-generation"
{
preferLocalBuild = true;
allowSubstitutes = false;
}
''
mkdir -p $out
cp ${activationScript} $out/activate
@@ -374,7 +405,6 @@ in
${cfg.extraBuilderCommands}
'';
};
home.path = pkgs.buildEnv {
name = "home-manager-path";

View File

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

View File

@@ -4,27 +4,7 @@ with lib;
let
# Figures out a valid Nix store name for the given path.
storeFileName = path:
let
# All characters that are considered safe. Note "-" is not
# included to avoid "-" followed by digit being interpreted as a
# version.
safeChars =
[ "+" "." "_" "?" "=" ]
++ lowerChars
++ upperChars
++ stringToCharacters "0123456789";
empties = l: genList (x: "") (length l);
unsafeInName = stringToCharacters (
replaceStrings safeChars (empties safeChars) path
);
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
in
"home_file_" + safeName;
stringsExtra = import ./strings.nix { inherit lib; };
in
@@ -113,7 +93,7 @@ in
source = mkIf (config.text != null) (
mkDefault (pkgs.writeTextFile {
inherit (config) executable text;
name = storeFileName name;
name = stringsExtra.storeFileName name;
})
);
};

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

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

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

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

View File

@@ -36,7 +36,7 @@ let
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
if [ -z "$BROWSER" ]; then
@@ -83,13 +83,26 @@ in
Thanks!
'';
};
manual.json.enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to install a JSON formatted list of all Home Manager
options. This can be located at
<filename>&lt;profile directory&gt;/share/doc/home-manager/options.json</filename>,
and may be used for navigating definitions, auto-completing,
and other miscellaneous tasks.
'';
};
};
config = {
home.packages = mkMerge [
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
(mkIf cfg.json.enable [ homeManagerManual.optionsJSON ])
];
};

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

@@ -0,0 +1,89 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.dconf;
dag = config.lib.dag;
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
mkIniKeyValue = key: value:
let
tweakVal = v:
if isString v then "'${v}'"
else if isList v then tweakList v
else if isBool v then (if v then "true" else "false")
else toString v;
# Assume empty list is a list of strings, see #769
tweakList = v:
if v == [] then "@as []"
else "[" + concatMapStringsSep "," tweakVal v + "]";
in
"${key}=${tweakVal value}";
primitive = with types; either bool (either int (either float str));
in
{
meta.maintainers = [ maintainers.gnidorah maintainers.rycee ];
options = {
dconf = {
enable = mkOption {
type = types.bool;
default = true;
visible = false;
description = ''
Whether to enable dconf settings.
'';
};
settings = mkOption {
type = with types;
attrsOf (attrsOf (either primitive (listOf primitive)));
default = {};
example = literalExample ''
{
"org/gnome/calculator" = {
button-mode = "programming";
show-thousands = true;
base = 10;
word-size = 64;
};
}
'';
description = ''
Settings to write to the dconf configuration system.
'';
};
};
};
config = mkIf (cfg.enable && cfg.settings != {}) {
home.activation.dconfSettings = dag.entryAfter ["installPackages"] (
let
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
in
''
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
DCONF_DBUS_RUN_SESSION=""
else
DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session"
fi
if [[ -v DRY_RUN ]]; then
echo $DCONF_DBUS_RUN_SESSION ${pkgs.gnome3.dconf}/bin/dconf load / "<" ${iniFile}
else
$DCONF_DBUS_RUN_SESSION ${pkgs.gnome3.dconf}/bin/dconf load / < ${iniFile}
fi
unset DCONF_DBUS_RUN_SESSION
''
);
};
}

View File

@@ -8,8 +8,6 @@ let
cfg2 = config.gtk.gtk2;
cfg3 = config.gtk.gtk3;
dag = config.lib.dag;
toGtk3Ini = generators.toINI {
mkKeyValue = key: value:
let
@@ -29,16 +27,6 @@ let
in
"${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 {
options = {
package = mkOption {
@@ -88,6 +76,12 @@ in
{
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkRemovedOptionModule ["gtk" "gtk3" "waylandSupport"] ''
This options is not longer needed and can be removed.
'')
];
options = {
gtk = {
enable = mkEnableOption "GTK 2/3 configuration";
@@ -112,63 +106,36 @@ in
description = "The GTK+2/3 theme to use.";
};
gtk2 = mkOption {
description = "Options specific to GTK+ 2";
default = {};
type = types.submodule {
options = {
extraConfig = mkOption {
type = types.lines;
default = "";
example = "gtk-can-change-accels = 1";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.gtkrc-2.0</filename>.
'';
};
};
gtk2 = {
extraConfig = mkOption {
type = types.lines;
default = "";
example = "gtk-can-change-accels = 1";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.gtkrc-2.0</filename>.
'';
};
};
gtk3 = mkOption {
description = "Options specific to GTK+ 3";
default = {};
type = types.submodule {
options = {
extraConfig = mkOption {
type = types.attrs;
default = {};
example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
description = ''
Extra configuration options to add to
<filename>~/.config/gtk-3.0/settings.ini</filename>.
'';
};
gtk3 = {
extraConfig = mkOption {
type = with types; attrsOf (either bool (either int str));
default = {};
example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
description = ''
Extra configuration options to add to
<filename>~/.config/gtk-3.0/settings.ini</filename>.
'';
};
extraCss = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.config/gtk-3.0/gtk.css</filename>.
'';
};
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>
'';
};
};
extraCss = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add verbatim to
<filename>~/.config/gtk-3.0/gtk.css</filename>.
'';
};
};
};
@@ -200,7 +167,6 @@ in
optional (opt != null && opt.package != null) opt.package;
in
{
home.packages =
optionalPackage cfg.font
++ optionalPackage cfg.theme
@@ -216,22 +182,7 @@ in
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
home.activation = mkIf cfg3.waylandSupport {
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
''
);
};
dconf.settings."org/gnome/desktop/interface" = dconfIni;
}
);
}

View File

@@ -6,6 +6,8 @@ let
cfg = config.news;
hostPlatform = pkgs.stdenv.hostPlatform;
entryModule = types.submodule ({ config, ... }: {
options = {
id = mkOption {
@@ -734,7 +736,7 @@ in
{
time = "2018-08-19T20:46:09+00:00";
condition = pkgs.stdenv.isLinux;
condition = hostPlatform.isLinux;
message = ''
A new modules is available: 'programs.chromium'.
'';
@@ -871,6 +873,198 @@ in
A new module is available: 'services.nextcloud-client'.
'';
}
{
time = "2018-11-25T22:55:12+00:00";
message = ''
A new module is available: 'programs.vscode'.
'';
}
{
time = "2018-12-04T21:54:38+00:00";
condition = config.programs.beets.settings != {};
message = ''
A new option 'programs.beets.enable' has been added.
Starting with state version 19.03 this option defaults to
false. For earlier versions it defaults to true if
'programs.beets.settings' is non-empty.
It is recommended to explicitly add
programs.beets.enable = true;
to your configuration.
'';
}
{
time = "2018-12-12T21:02:05+00:00";
message = ''
A new module is available: 'programs.jq'.
'';
}
{
time = "2018-12-24T16:26:16+00:00";
message = ''
A new module is available: 'dconf'.
Note, on NixOS you may need to add
services.dbus.packages = with pkgs; [ gnome3.dconf ];
to the system configuration for this module to work as
expected. In particular if you get the error message
The name ca.desrt.dconf was not provided by any .service files
when activating your Home Manager configuration.
'';
}
{
time = "2018-12-28T12:32:30+00:00";
message = ''
A new module is available: 'programs.opam'.
'';
}
{
time = "2019-01-18T00:21:56+00:00";
message = ''
A new module is available: 'programs.matplotlib'.
'';
}
{
time = "2019-01-26T13:20:37+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.xembed-sni-proxy'.
'';
}
{
time = "2019-01-28T23:36:10+00:00";
message = ''
A new module is available: 'programs.irssi'.
'';
}
{
time = "2019-02-09T14:09:58+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.emacs'.
This module provides a user service that runs the Emacs
configured in
programs.emacs
as an Emacs daemon.
'';
}
{
time = "2019-02-16T20:33:56+00:00";
condition = hostPlatform.isLinux;
message = ''
When using Home Manager as a NixOS submodule it is now
possible to install packages using the NixOS
users.users.<name?>.packages
option. This is enabled by adding
home-manager.useUserPackages = true;
to your NixOS system configuration. This mode of operation
is necessary if you want to use 'nixos-rebuild build-vm'.
'';
}
{
time = "2019-02-17T21:11:24+00:00";
message = ''
A new module is available: 'programs.keychain'.
'';
}
{
time = "2019-02-24T00:32:23+00:00";
condition = hostPlatform.isLinux;
message = ''
A new service is available: 'services.mpdris2'.
'';
}
{
time = "2019-03-19T22:56:20+00:00";
message = ''
A new module is available: 'programs.bat'.
'';
}
{
time = "2019-03-19T23:07:34+00:00";
message = ''
A new module is available: 'programs.lsd'.
'';
}
{
time = "2019-04-09T20:10:22+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.xcape'.
'';
}
{
time = "2019-04-11T22:50:10+00:00";
condition = hostPlatform.isLinux;
message = ''
The type used for the systemd unit options under
systemd.user.services, systemd.user.sockets, etc.
has been changed to offer more robust merging of configurations.
If you don't override values within systemd units then you are not
affected by this change. Unfortunately, if you do override unit values
you may encounter errors due to this change.
In particular, if you get an error saying that a "unique option" is
"defined multiple times" then you need to use 'lib.mkForce'. For
example,
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
becomes
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
We had to make this change because the old merging was causing too
many confusing situations for people. Apologies for potentially
breaking your configuration!
'';
}
{
time = "2019-04-14T15:35:16+00:00";
message = ''
A new module is available: 'programs.skim'.
'';
}
{
time = "2019-04-22T12:43:20+00:00";
message = ''
A new module is available: 'programs.alacritty'.
'';
}
];
};
}

View File

@@ -80,10 +80,9 @@ in
inside and outside Home Manager you can put it in a separate
file and include something like
<programlisting>
<programlisting language="nix">
nixpkgs.config = import ./nixpkgs-config.nix;
xdg.configFile."nixpkgs/config.nix".source =
./nixpkgs-config.nix;
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
</programlisting>
in your Home Manager configuration.
@@ -144,7 +143,10 @@ in
config = {
_module.args = {
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 != {}) {
home.file.".pam_environment".text =
concatStringsSep "\n" (
mapAttrsToList (n: v: "${n} OVERRIDE=${toString v}") vars
mapAttrsToList (n: v: "${n} OVERRIDE=\"${toString v}\"") vars
) + "\n";
};
}

View File

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

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

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
pkgs:
{ config, lib, ... }:
with lib;
@@ -13,6 +14,34 @@ with lib;
'';
};
contactCompletion = mkOption {
type = types.attrsOf types.str;
default = {
type = "shellcommand";
command = "'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
regexp =
"'\\[?{"
+ ''"name": "(?P<name>.*)", ''
+ ''"address": "(?P<email>.+)", ''
+ ''"name-addr": ".*"''
+ "}[,\\]]?'";
shellcommand_external_filtering = "False";
};
example = literalExample ''
{
type = "shellcommand";
command = "abook --mutt-query";
regexp = "'^(?P<email>[^@]+@[^\t]+)\t+(?P<name>[^\t]+)'";
ignorecase = "True";
}
'';
description = ''
Contact completion configuration as expected per alot.
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
explanation about possible values.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";

View File

@@ -22,6 +22,9 @@ let
sendmail_command =
optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
}
// optionalAttrs (aliases != []) {
aliases = concatStringsSep "," aliases;
}
// optionalAttrs (gpg != null) {
gpg_key = gpg.key;
encrypt_by_default = if gpg.encryptByDefault then "all" else "none";
@@ -33,9 +36,10 @@ let
boolStr (signature.showSignature == "attach");
}
)
)
+ "\n"
+ alot.extraConfig;
++ [ alot.extraConfig ]
++ [ "[[[abook]]]" ]
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion
);
configFile =
let

View File

@@ -6,10 +6,25 @@ let
cfg = config.programs.autorandr;
matrixOf = n: m: elemType: mkOptionType rec {
name = "matrixOf";
description = "${toString n}×${toString m} matrix of ${elemType.description}s";
check = xss:
let
listOfSize = l: xs: isList xs && length xs == l;
in
listOfSize n xss && all (xs: listOfSize m xs && all elemType.check xs) xss;
merge = mergeOneOption;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*" "*"]);
getSubModules = elemType.getSubModules;
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
functor = (defaultFunctor name) // { wrapped = elemType; };
};
profileModule = types.submodule {
options = {
fingerprint = mkOption {
type = types.attrsOf types.string;
type = types.attrsOf types.str;
description = ''
Output name to EDID mapping.
Use <code>autorandr --fingerprint</code> to get current setup values.
@@ -46,28 +61,28 @@ let
};
position = mkOption {
type = types.string;
type = types.str;
description = "Output position";
default = "";
example = "5760x0";
};
mode = mkOption {
type = types.string;
type = types.str;
description = "Output resolution.";
default = "";
example = "3840x2160";
};
rate = mkOption {
type = types.string;
type = types.str;
description = "Output framerate.";
default = "";
example = "60.00";
};
gamma = mkOption {
type = types.string;
type = types.str;
description = "Output gamma configuration.";
default = "";
example = "1.0:0.909:0.833";
@@ -79,6 +94,80 @@ let
default = null;
example = "left";
};
transform = mkOption {
type = types.nullOr (matrixOf 3 3 types.float);
default = null;
example = literalExample ''
[
[ 0.6 0.0 0.0 ]
[ 0.0 0.6 0.0 ]
[ 0.0 0.0 1.0 ]
]
'';
description = ''
Refer to
<citerefentry>
<refentrytitle>xrandr</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
for the documentation of the transform matrix.
'';
};
dpi = mkOption {
type = types.nullOr types.ints.positive;
description = "Output DPI configuration.";
default = null;
example = 96;
};
scale = mkOption {
type = types.nullOr (types.submodule {
options = {
method = mkOption {
type = types.enum ["factor" "pixel" ];
description = "Output scaling method.";
default = "factor";
example = "pixel";
};
x = mkOption {
type = types.either types.float types.ints.positive;
description = "Horizontal scaling factor/pixels.";
};
y = mkOption {
type = types.either types.float types.ints.positive;
description = "Vertical scaling factor/pixels.";
};
};
});
description = ''
Output scale configuration.
</para><para>
Either configure by pixels or a scaling factor. When using pixel method the
<citerefentry>
<refentrytitle>xrandr</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
option
<parameter class="command">--scale-from</parameter>
will be used; when using factor method the option
<parameter class="command">--scale</parameter>
will be used.
</para><para>
This option is a shortcut version of the transform option and they are mutually
exclusive.
'';
default = null;
example = literalExample ''
{
x = 1.25;
y = 1.25;
}
'';
};
};
};
@@ -146,10 +235,18 @@ let
output ${name}
${optionalString (config.position != "") "pos ${config.position}"}
${optionalString config.primary "primary"}
${optionalString (config.dpi != null) "dpi ${toString config.dpi}"}
${optionalString (config.gamma != "") "gamma ${config.gamma}"}
${optionalString (config.mode != "") "mode ${config.mode}"}
${optionalString (config.rate != "") "rate ${config.rate}"}
${optionalString (config.rotate != null) "rotate ${config.rotate}"}
${optionalString (config.scale != null) (
(if config.scale.method == "factor" then "scale" else "scale-from")
+ " ${toString config.scale.x}x${toString config.scale.y}"
)}
${optionalString (config.transform != null) (
"transform " + concatMapStringsSep "," toString (flatten config.transform)
)}
'' else ''
output ${name}
off
@@ -226,6 +323,19 @@ in
};
config = mkIf cfg.enable {
assertions = flatten (mapAttrsToList (
profile: { config, ... }: mapAttrsToList (
output: opts: {
assertion = opts.scale == null || opts.transform == null;
message = ''
Cannot use the profile output options 'scale' and 'transform' simultaneously.
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
'';
})
config
)
cfg.profiles);
home.packages = [ pkgs.autorandr ];
xdg.configFile = mkMerge ([
(mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)

View File

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

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

@@ -0,0 +1,40 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.bat;
in
{
meta.maintainers = [ maintainers.marsam ];
options.programs.bat = {
enable = mkEnableOption "bat, a cat clone with wings";
config = mkOption {
type = types.attrsOf types.str;
default = {};
example = {
theme = "TwoDark";
pager = "less -FR";
};
description = ''
Bat configuration.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.bat ];
xdg.configFile."bat/config" = mkIf (cfg.config != {}) {
text = concatStringsSep "\n" (
mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config
);
};
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@ let
cfg = config.programs.fish;
abbrsStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "abbr --add ${k} '${v}'") cfg.shellAbbrs
mapAttrsToList (k: v: "abbr --add --global ${k} '${v}'") cfg.shellAbbrs
);
aliasesStr = concatStringsSep "\n" (
@@ -21,6 +21,15 @@ in
programs.fish = {
enable = mkEnableOption "fish friendly interactive shell";
package = mkOption {
default = pkgs.fish;
defaultText = "pkgs.fish";
description = ''
The fish package to install. May be used to change the version.
'';
type = types.package;
};
shellAliases = mkOption {
default = {};
description = ''
@@ -74,7 +83,70 @@ in
};
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 = ''
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.

View File

@@ -6,6 +6,12 @@ let
cfg = config.programs.git;
gitIniType = with types;
let
primitiveType = either bool (either int str);
in
attrsOf (attrsOf primitiveType);
signModule = types.submodule {
options = {
key = mkOption {
@@ -28,7 +34,7 @@ let
};
};
includeModule = types.submodule {
includeModule = types.submodule ({ config, ... }: {
options = {
condition = mkOption {
type = types.nullOr types.str;
@@ -44,11 +50,23 @@ let
};
path = mkOption {
type = types.str;
type = with types; either str path;
description = "Path of the configuration file to include.";
};
contents = mkOption {
type = types.attrs;
default = {};
description = ''
Configuration to include. If empty then a path must be given.
'';
};
};
};
config.path = mkIf (config.contents != {}) (
mkDefault (pkgs.writeText "contents" (generators.toINI {} config.contents))
);
});
in
@@ -63,22 +81,28 @@ in
type = types.package;
default = pkgs.git;
defaultText = "pkgs.git";
description = "Git package to install.";
description = ''
Git package to install. Use <varname>pkgs.gitAndTools.gitFull</varname>
to gain access to <command>git send-email</command> for instance.
'';
};
userName = mkOption {
type = types.str;
type = types.nullOr types.str;
default = null;
description = "Default user name to use.";
};
userEmail = mkOption {
type = types.str;
type = types.nullOr types.str;
default = null;
description = "Default user email to use.";
};
aliases = mkOption {
type = types.attrs;
type = types.attrsOf types.str;
default = {};
example = { co = "checkout"; };
description = "Git aliases to define.";
};
@@ -89,13 +113,16 @@ in
};
extraConfig = mkOption {
type = types.either types.attrs types.lines;
type = types.either types.lines gitIniType;
default = {};
example = {
core = { whitespace = "trailing-space,space-before-tab"; };
};
description = "Additional configuration to add.";
};
iniContent = mkOption {
type = types.attrsOf types.attrs;
type = gitIniType;
internal = true;
};
@@ -120,6 +147,20 @@ in
'';
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 ];
programs.git.iniContent.user = {
name = cfg.userName;
email = cfg.userEmail;
name = mkIf (cfg.userName != null) cfg.userName;
email = mkIf (cfg.userEmail != null) cfg.userEmail;
};
xdg.configFile = {
@@ -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) {
programs.git.iniContent = {
user.signingKey = cfg.signing.key;
@@ -171,6 +232,25 @@ in
'')
cfg.includes);
})
(mkIf cfg.lfs.enable {
home.packages = [ pkgs.git-lfs ];
programs.git.iniContent."filter \"lfs\"" =
let
skipArg = optional cfg.lfs.skipSmudge "--skip";
in
{
clean = "git-lfs clean -- %f";
process = concatStringsSep " " (
[ "git-lfs" "filter-process" ] ++ skipArg
);
required = true;
smudge = concatStringsSep " " (
[ "git-lfs" "smudge" ] ++ skipArg ++ [ "--" "%f" ]
);
};
})
]
);
}

View File

@@ -6,7 +6,26 @@ let
cfg = config.programs.gnome-terminal;
dag = config.lib.dag;
vteInitStr = ''
# gnome-terminal: Show current directory in the terminal window title.
. ${pkgs.gnome3.vte}/etc/profile.d/vte.sh
'';
backForeSubModule = types.submodule (
{ ... }: {
options = {
foreground = mkOption {
type = types.str;
description = "The foreground color.";
};
background = mkOption {
type = types.str;
description = "The background color.";
};
};
}
);
profileColorsSubModule = types.submodule (
{ ... }: {
@@ -31,6 +50,18 @@ let
type = types.listOf types.str;
description = "The terminal palette.";
};
cursor = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The color for the terminal cursor.";
};
highlight = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The colors for the terminals highlighted area.";
};
};
}
);
@@ -67,6 +98,15 @@ let
description = "The font name, null to use system default.";
};
allowBold = mkOption {
default = null;
type = types.nullOr types.bool;
description = ''
If <literal>true</literal>, allow applications in the
terminal to make text boldface.
'';
};
scrollOnOutput = mkOption {
default = true;
type = types.bool;
@@ -91,19 +131,6 @@ let
}
);
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
mkIniKeyValue = key: value:
let
tweakVal = v:
if isString v then "'${v}'"
else if isList v then "[" + concatStringsSep "," (map tweakVal v) + "]"
else if isBool v && v then "true"
else if isBool v && !v then "false"
else toString v;
in
"${key}=${tweakVal value}";
buildProfileSet = pcfg:
{
visible-name = pcfg.visibleName;
@@ -125,6 +152,9 @@ let
background-color = pcfg.colors.backgroundColor;
palette = pcfg.colors.palette;
}
// optionalAttrs (pcfg.allowBold != null) {
allow-bold = pcfg.allowBold;
}
// (
if (pcfg.colors.boldColor == null)
then { bold-color-same-as-fg = true; }
@@ -133,28 +163,27 @@ let
bold-color = pcfg.colors.boldColor;
}
)
// (
if (pcfg.colors.cursor != null)
then {
cursor-colors-set = true;
cursor-foreground-color = pcfg.colors.cursor.foreground;
cursor-background-color = pcfg.colors.cursor.background;
}
else { cursor-colors-set = false; }
)
// (
if (pcfg.colors.highlight != null)
then {
highlight-colors-set = true;
highlight-foreground-color = pcfg.colors.highlight.foreground;
highlight-background-color = pcfg.colors.highlight.background;
}
else { highlight-colors-set = false; }
)
)
);
buildIniSet = cfg:
{
"/" = {
default-show-menubar = cfg.showMenubar;
schema-version = 3;
};
}
//
{
"profiles:" = {
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile;
};
}
//
mapAttrs' (name: value:
nameValuePair ("profiles:/:${name}") (buildProfileSet value)
) cfg.profile;
in
{
@@ -170,6 +199,12 @@ in
description = "Whether to show the menubar by default";
};
themeVariant = mkOption {
default = "default";
type = types.enum [ "default" "light" "dark" ];
description = "The theme variation to request";
};
profile = mkOption {
default = {};
type = types.attrsOf profileSubModule;
@@ -181,20 +216,27 @@ in
config = mkIf cfg.enable {
home.packages = [ pkgs.gnome3.gnome_terminal ];
# The dconf service needs to be installed and prepared.
home.activation.gnomeTerminal = dag.entryAfter ["installPackages"] (
dconf.settings =
let
iniText = toDconfIni (buildIniSet cfg);
iniFile = pkgs.writeText "gnome-terminal.ini" iniText;
dconfPath = "/org/gnome/terminal/legacy/";
dconfPath = "org/gnome/terminal/legacy";
in
''
if [[ -v DRY_RUN ]]; then
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile}
else
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile}
fi
''
);
{
"${dconfPath}" = {
default-show-menubar = cfg.showMenubar;
theme-variant = cfg.themeVariant;
schema-version = 3;
};
"${dconfPath}/profiles:" = {
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile;
};
}
// mapAttrs' (n: v:
nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v)
) cfg.profile;
programs.bash.initExtra = mkBefore vteInitStr;
programs.zsh.initExtra = vteInitStr;
};
}

View File

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

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

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

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

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -47,6 +47,15 @@ in
'';
};
withNodeJs = mkOption {
type = types.bool;
default = false;
description = ''
Enable node provider. Set to <literal>true</literal> to
use Node plugins.
'';
};
withPython = mkOption {
type = types.bool;
default = true;
@@ -62,7 +71,7 @@ in
defaultText = "ps: []";
example = literalExample "(ps: with ps; [ pandas jedi ])";
description = ''
A function in python.withPackages format, which returns a
A function in python.withPackages format, which returns a
list of Python 2 packages required for your plugins to work.
'';
};
@@ -90,11 +99,18 @@ in
defaultText = "ps: []";
example = literalExample "(ps: with ps; [ python-language-server ])";
description = ''
A function in python.withPackages format, which returns a
A function in python.withPackages format, which returns a
list of Python 3 packages required for your plugins to work.
'';
};
package = mkOption {
type = types.package;
default = pkgs.neovim-unwrapped;
defaultText = "pkgs.neovim-unwrapped";
description = "The package to use for the neovim binary.";
};
configure = mkOption {
type = types.attrs;
default = {};
@@ -121,11 +137,11 @@ in
config = mkIf cfg.enable {
home.packages = [
(pkgs.neovim.override {
(pkgs.wrapNeovim cfg.package {
inherit (cfg)
extraPython3Packages withPython3
extraPythonPackages withPython
withRuby viAlias vimAlias configure;
withNodeJs withRuby viAlias vimAlias configure;
})
];
};

View File

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

View File

@@ -42,11 +42,13 @@ let
in {
name = catAttrs "realName" primary;
primary_email = catAttrs "address" primary;
other_email = catAttrs "address" secondaries;
other_email = catAttrs "aliases" primary
++ catAttrs "address" secondaries
++ catAttrs "aliases" secondaries;
};
search = {
exclude_tags = [ "deleted" "spam" ];
exclude_tags = cfg.search.excludeTags;
};
}
cfg.extraConfig;
@@ -138,6 +140,19 @@ in
'';
};
};
search = {
excludeTags = mkOption {
type = types.listOf types.str;
default = [ "deleted" "spam" ];
example = [ "trash" "spam" ];
description = ''
A list of tags that will be excluded from search results by
default. Using an excluded tag in a query will override that
exclusion.
'';
};
};
};
};
@@ -173,7 +188,7 @@ in
{
target = "${notmuchIni.database.path}/.notmuch/hooks/${name}";
source = pkgs.writeScript name ''
#!${pkgs.stdenv.shell}
#!${pkgs.runtimeShell}
export PATH="${pkgs.notmuch}/bin''${PATH:+:}$PATH"
export NOTMUCH_CONFIG="${config.xdg.configHome}/notmuch/notmuchrc"

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;
colorOption = description: mkOption {
type = types.string;
type = types.str;
description = description;
};
@@ -175,7 +175,7 @@ in
font = mkOption {
default = null;
type = types.nullOr types.string;
type = types.nullOr types.str;
example = "Droid Sans Mono 14";
description = "Font to use.";
};
@@ -188,7 +188,7 @@ in
terminal = mkOption {
default = null;
type = types.nullOr types.string;
type = types.nullOr types.str;
description = ''
Path to the terminal which will be used to run console applications
'';
@@ -270,7 +270,7 @@ in
theme = mkOption {
default = null;
type = with types; nullOr (either string path);
type = with types; nullOr (either str path);
example = "Arc";
description = ''
Name of theme or path to theme file in rasi format. Available
@@ -282,7 +282,7 @@ in
configPath = mkOption {
default = "${config.xdg.configHome}/rofi/config";
defaultText = "$XDG_CONFIG_HOME/rofi/config";
type = types.string;
type = types.str;
description = "Path where to put generated configuration file.";
};

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

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

View File

@@ -21,7 +21,7 @@ let
};
port = mkOption {
type = types.nullOr types.int;
type = types.nullOr types.port;
default = null;
description = "Specifies port number to connect on remote host.";
};
@@ -66,10 +66,15 @@ let
};
identityFile = mkOption {
type = types.nullOr types.str;
default = null;
type = with types; either (listOf str) (nullOr str);
default = [];
apply = p:
if p == null then []
else if isString p then [p]
else p;
description = ''
Specifies a file from which the user identity is read.
Specifies files from which the user identity is read.
Identities will be tried in the given order.
'';
};
@@ -125,6 +130,28 @@ let
description = "The command to use to connect to the server.";
};
proxyJump = mkOption {
type = types.nullOr types.str;
default = null;
description = "The proxy host to use to connect to the server.";
};
certificateFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Specifies a file from which the user certificate is read.
'';
};
addressFamily = mkOption {
default = null;
type = types.nullOr (types.enum ["any" "inet" "inet6"]);
description = ''
Specifies which address family to use when connecting.
'';
};
extraOptions = mkOption {
type = types.attrsOf types.str;
default = {};
@@ -137,20 +164,23 @@ let
matchBlockStr = cf: concatStringsSep "\n" (
["Host ${cf.host}"]
++ optional (cf.port != null) " Port ${toString cf.port}"
++ optional (cf.forwardAgent != null) " ForwardAgent ${yn cf.forwardAgent}"
++ optional cf.forwardX11 " ForwardX11 yes"
++ optional cf.forwardX11Trusted " ForwardX11Trusted yes"
++ optional cf.identitiesOnly " IdentitiesOnly yes"
++ optional (cf.user != null) " User ${cf.user}"
++ optional (cf.identityFile != null) " IdentityFile ${cf.identityFile}"
++ optional (cf.hostname != null) " HostName ${cf.hostname}"
++ optional (cf.sendEnv != []) " SendEnv ${unwords cf.sendEnv}"
++ optional (cf.port != null) " Port ${toString cf.port}"
++ optional (cf.forwardAgent != null) " ForwardAgent ${yn cf.forwardAgent}"
++ optional cf.forwardX11 " ForwardX11 yes"
++ optional cf.forwardX11Trusted " ForwardX11Trusted yes"
++ optional cf.identitiesOnly " IdentitiesOnly yes"
++ optional (cf.user != null) " User ${cf.user}"
++ optional (cf.certificateFile != null) " CertificateFile ${cf.certificateFile}"
++ optional (cf.hostname != null) " HostName ${cf.hostname}"
++ optional (cf.addressFamily != null) " AddressFamily ${cf.addressFamily}"
++ optional (cf.sendEnv != []) " SendEnv ${unwords cf.sendEnv}"
++ optional (cf.serverAliveInterval != 0)
" ServerAliveInterval ${toString cf.serverAliveInterval}"
++ optional (cf.compression != null) " Compression ${yn cf.compression}"
++ optional (!cf.checkHostIP) " CheckHostIP no"
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}"
++ optional (cf.compression != null) " Compression ${yn cf.compression}"
++ optional (!cf.checkHostIP) " CheckHostIP no"
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}"
++ optional (cf.proxyJump != null) " ProxyJump ${cf.proxyJump}"
++ map (file: " IdentityFile ${file}") cf.identityFile
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
);
@@ -219,7 +249,7 @@ in
controlPath = mkOption {
type = types.str;
default = "~/.ssh/master-%r@%h:%p";
default = "~/.ssh/master-%r@%n:%p";
description = ''
Specify path to the control socket used for connection sharing.
'';

View File

@@ -6,6 +6,13 @@ let
cfg = config.programs.termite;
vteInitStr = ''
# See https://github.com/thestinger/termite#id1
if [[ $TERM == xterm-termite ]]; then
. ${pkgs.gnome3.vte-ng}/etc/profile.d/vte.sh
fi
'';
in
{
@@ -363,6 +370,9 @@ in
${cfg.hintsExtra}
'';
programs.bash.initExtra = vteInitStr;
programs.zsh.initExtra = vteInitStr;
}
);
}

View File

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

View File

@@ -23,13 +23,136 @@ let
};
};
defaultKeyMode = "emacs";
defaultResize = 5;
defaultShortcut = "b";
defaultTerminal = "screen";
boolToStr = value: if value then "on" else "off";
tmuxConf = ''
set -g default-terminal "${cfg.terminal}"
set -g base-index ${toString cfg.baseIndex}
setw -g pane-base-index ${toString cfg.baseIndex}
${optionalString cfg.newSession "new-session"}
${optionalString cfg.reverseSplit ''
bind v split-window -h
bind s split-window -v
''}
set -g status-keys ${cfg.keyMode}
set -g mode-keys ${cfg.keyMode}
${optionalString (cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize) ''
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r H resize-pane -L ${toString cfg.resizeAmount}
bind -r J resize-pane -D ${toString cfg.resizeAmount}
bind -r K resize-pane -U ${toString cfg.resizeAmount}
bind -r L resize-pane -R ${toString cfg.resizeAmount}
''}
${optionalString (cfg.shortcut != defaultShortcut) ''
# rebind main key: C-${cfg.shortcut}
unbind C-${defaultShortcut}
set -g prefix C-${cfg.shortcut}
bind ${cfg.shortcut} send-prefix
bind C-${cfg.shortcut} last-window
''}
setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
set -s escape-time ${toString cfg.escapeTime}
set -g history-limit ${toString cfg.historyLimit}
${cfg.extraConfig}
'';
in
{
options = {
programs.tmux = {
aggressiveResize = mkOption {
default = false;
type = types.bool;
description = ''
Resize the window to the size of the smallest session for
which it is the current window.
'';
};
baseIndex = mkOption {
default = 0;
example = 1;
type = types.ints.unsigned;
description = "Base index for windows and panes.";
};
clock24 = mkOption {
default = false;
type = types.bool;
description = "Use 24 hour clock.";
};
customPaneNavigationAndResize = mkOption {
default = false;
type = types.bool;
description = ''
Override the hjkl and HJKL bindings for pane navigation and
resizing in VI mode.
'';
};
enable = mkEnableOption "tmux";
escapeTime = mkOption {
default = 500;
example = 0;
type = types.ints.unsigned;
description = ''
Time in milliseconds for which tmux waits after an escape is
input.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional configuration to add to
<filename>tmux.conf</filename>.
'';
};
historyLimit = mkOption {
default = 2000;
example = 5000;
type = types.ints.positive;
description = "Maximum number of lines held in window history.";
};
keyMode = mkOption {
default = defaultKeyMode;
example = "vi";
type = types.enum [ "emacs" "vi" ];
description = "VI or Emacs style shortcuts.";
};
newSession = mkOption {
default = false;
type = types.bool;
description = ''
Automatically spawn a session if trying to attach and none
are running.
'';
};
package = mkOption {
type = types.package;
default = pkgs.tmux;
@@ -38,6 +161,19 @@ in
description = "The tmux package to install";
};
reverseSplit = mkOption {
default = false;
type = types.bool;
description = "Reverse the window split shortcuts.";
};
resizeAmount = mkOption {
default = defaultResize;
example = 10;
type = types.ints.positive;
description = "Number of lines/columns when resizing.";
};
sensibleOnTop = mkOption {
type = types.bool;
default = true;
@@ -48,6 +184,32 @@ in
'';
};
shortcut = mkOption {
default = defaultShortcut;
example = "a";
type = types.str;
description = ''
CTRL following by this key is used as the main shortcut.
'';
};
terminal = mkOption {
default = defaultTerminal;
example = "screen-256color";
type = types.str;
description = "Set the $TERM variable.";
};
secureSocket = mkOption {
default = true;
type = types.bool;
description = ''
Store tmux socket under <filename>/run</filename>, which is more
secure than <filename>/tmp</filename>, but as a downside it doesn't
survive user logout.
'';
};
tmuxp.enable = mkEnableOption "tmuxp";
tmuxinator.enable = mkEnableOption "tmuxinator";
@@ -79,15 +241,6 @@ in
]
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional configuration to add to
<filename>tmux.conf</filename>.
'';
};
};
};
@@ -98,7 +251,7 @@ in
++ optional cfg.tmuxinator.enable pkgs.tmuxinator
++ optional cfg.tmuxp.enable pkgs.tmuxp;
home.file.".tmux.conf".text = cfg.extraConfig;
home.file.".tmux.conf".text = tmuxConf;
}
(mkIf cfg.sensibleOnTop {
@@ -111,6 +264,12 @@ in
'';
})
(mkIf cfg.secureSocket {
home.sessionVariables = {
TMUX_TMPDIR = ''''${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}'';
};
})
(mkIf (cfg.plugins != []) {
assertions = [(
let

View File

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

View File

@@ -11,14 +11,21 @@ let
pluginsDir = if cfg.dotDir != null then
relToDotDir "plugins" else ".zsh/plugins";
envVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables;
localVarsStr = config.lib.zsh.defineAll cfg.localVariables;
aliasesStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
mapAttrsToList (k: v: "alias ${k}=${lib.escapeShellArg v}") cfg.shellAliases
);
zdotdir = "$HOME/" + cfg.dotDir;
bindkeyCommands = {
emacs = "bindkey -e";
viins = "bindkey -v";
vicmd = "bindkey -a";
};
historyModule = types.submodule ({ config, ... }: {
options = {
size = mkOption {
@@ -160,14 +167,14 @@ in
An attribute set that maps aliases (the top level attribute names in
this option) to command strings or directly to build outputs.
'';
type = types.attrs;
type = types.attrsOf types.str;
};
enableCompletion = mkOption {
default = true;
description = ''
Enable zsh completion. Don't forget to add
<programlisting>
<programlisting language="nix">
environment.pathsToLink = [ "/share/zsh" ];
</programlisting>
to your system configuration to get completion for system packages (e.g. systemd).
@@ -186,6 +193,13 @@ in
description = "Options related to commands history configuration.";
};
defaultKeymap = mkOption {
type = types.nullOr (types.enum (attrNames bindkeyCommands));
default = null;
example = "emacs";
description = "The default base keymap to use.";
};
sessionVariables = mkOption {
default = {};
type = types.attrs;
@@ -252,6 +266,15 @@ in
default = {};
description = "Options to configure oh-my-zsh.";
};
localVariables = mkOption {
type = types.attrs;
default = {};
example = { POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=["dir" "vcs"]; };
description = ''
Extra local variables defined at the top of <filename>.zshrc</filename>.
'';
};
};
};
@@ -271,7 +294,7 @@ in
(mkIf cfg.oh-my-zsh.enable {
home.file."${relToDotDir ".zshenv"}".text = ''
ZSH="${pkgs.oh-my-zsh}/share/oh-my-zsh";
ZSH_CACHE_DIR="''${XDG_CACHE_HOME:-''$HOME/.cache}/oh-my-zsh";
ZSH_CACHE_DIR="${config.xdg.cacheHome}/oh-my-zsh";
'';
})
@@ -303,12 +326,25 @@ in
HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help"
${optionalString (cfg.defaultKeymap != null) ''
# Use ${cfg.defaultKeymap} keymap as the default.
${getAttr cfg.defaultKeymap bindkeyCommands}
''}
${localVarsStr}
${concatStrings (map (plugin: ''
path+="$HOME/${pluginsDir}/${plugin.name}"
fpath+="$HOME/${pluginsDir}/${plugin.name}"
'') cfg.plugins)}
${optionalString cfg.enableCompletion "autoload -U compinit && compinit"}
# Oh-My-Zsh calls compinit during initialization,
# calling it twice causes sight start up slowdown
# as all $fpath entries will be traversed again.
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable)
"autoload -U compinit && compinit"
}
${optionalString cfg.enableAutosuggestions
"source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
}
@@ -357,10 +393,9 @@ in
}
(mkIf cfg.oh-my-zsh.enable {
# Oh-My-Zsh calls compinit during initialization,
# calling it twice causes sight start up slowdown
# as all $fpath entries will be traversed again.
programs.zsh.enableCompletion = mkForce false;
# Make sure we create a cache directory since some plugins expect it to exist
# See: https://github.com/rycee/home-manager/issues/761
home.file."${config.xdg.cacheHome}/oh-my-zsh/.keep".text = "";
})
(mkIf (cfg.plugins != []) {

View File

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

View File

@@ -0,0 +1,48 @@
{ 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/";
# Avoid killing the Emacs session, which may be full of
# unsaved buffers.
X-RestartIfChanged = false;
};
Service = {
ExecStart = "${pkgs.runtimeShell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs)'";
Restart = "on-failure";
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
}

View File

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

View File

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

View File

@@ -71,7 +71,7 @@ in
postExec = mkOption {
type = types.nullOr types.str;
default = null;
example = "mu index";
example = "\${pkgs.mu}/bin/mu index";
description = ''
An optional command to run after mbsync executes successfully.
This is useful for running mailbox indexing tools.

View File

@@ -46,6 +46,7 @@ in {
type = types.path;
default = "${config.home.homeDirectory}/music";
defaultText = "$HOME/music";
apply = toString; # Prevent copies to Nix store.
description = ''
The directory where mpd reads music from.
'';
@@ -55,6 +56,7 @@ in {
type = types.path;
default = "${cfg.dataDir}/playlists";
defaultText = ''''${dataDir}/playlists'';
apply = toString; # Prevent copies to Nix store.
description = ''
The directory where mpd stores playlists.
'';
@@ -79,6 +81,7 @@ in {
type = types.path;
default = "${config.xdg.dataHome}/${name}";
defaultText = "$XDG_DATA_HOME/mpd";
apply = toString; # Prevent copies to Nix store.
description = ''
The directory where MPD stores its state, tag cache,
playlists etc.
@@ -98,7 +101,7 @@ in {
};
port = mkOption {
type = types.ints.positive;
type = types.port;
default = 6600;
description = ''
The TCP port on which the the daemon will listen.

View File

@@ -0,0 +1,101 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.mpdris2;
toIni = generators.toINI {
mkKeyValue = key: value:
let
value' =
if isBool value then (if value then "True" else "False")
else toString value;
in
"${key} = ${value'}";
};
mpdris2Conf = {
Connection = {
host = cfg.mpd.host;
port = cfg.mpd.port;
music_dir = cfg.mpd.musicDirectory;
};
Bling = {
notify = cfg.notifications;
mmkeys = cfg.multimediaKeys;
};
};
in
{
meta.maintainers = [ maintainers.pjones ];
options.services.mpdris2 = {
enable = mkEnableOption "mpDris2 the MPD to MPRIS2 bridge";
notifications = mkEnableOption "song change notifications";
multimediaKeys = mkEnableOption "multimedia key support";
package = mkOption {
type = types.package;
default = pkgs.mpdris2;
defaultText = "pkgs.mpdris2";
description = "The mpDris2 package to use.";
};
mpd = {
host = mkOption {
type = types.str;
default = config.services.mpd.network.listenAddress;
defaultText = "config.services.mpd.network.listenAddress";
example = "192.168.1.1";
description = "The address where MPD is listening for connections.";
};
port = mkOption {
type = types.port;
default = config.services.mpd.network.port;
defaultText = "config.services.mpd.network.port";
description = ''
The port number where MPD is listening for connections.
'';
};
musicDirectory = mkOption {
type = types.nullOr types.path;
default = config.services.mpd.musicDirectory;
defaultText = "config.services.mpd.musicDirectory";
description = ''
If set, mpDris2 will use this directory to access music artwork.
'';
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = config.services.mpd.enable;
message = "The mpdris2 module requires 'services.mpd.enable = true'.";
}
];
xdg.configFile."mpDris2/mpDris2.conf".text = toIni mpdris2Conf;
systemd.user.services.mpdris2 = {
Unit = {
Description = "MPRIS 2 support for MPD";
After = [ "graphical-session-pre.target" "mpd.service" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "simple";
ExecStart = "${cfg.package}/bin/mpDris2";
};
};
};
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -123,6 +123,18 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion =
cfg.provider == "manual"
-> cfg.latitude != null && cfg.longitude != null;
message =
"Must provide services.redshift.latitude and"
+ " services.redshift.latitude when"
+ " services.redshift.provider is set to \"manual\".";
}
];
systemd.user.services.redshift = {
Unit = {
Description = "Redshift colour temperature adjuster";

View File

@@ -58,13 +58,12 @@ in {
};
Service = {
ExecStart = ''
${pkgs.xautolock}/bin/xautolock \
-detectsleep \
-time ${toString cfg.inactiveInterval} \
-locker '${pkgs.systemd}/bin/loginctl lock-session $XDG_SESSION_ID' \
${concatStringsSep " " cfg.xautolockExtraOptions}
'';
ExecStart = concatStringsSep " " ([
"${pkgs.xautolock}/bin/xautolock"
"-detectsleep"
"-time ${toString cfg.inactiveInterval}"
"-locker '${pkgs.systemd}/bin/loginctl lock-session $XDG_SESSION_ID'"
] ++ cfg.xautolockExtraOptions);
};
};

View File

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

View File

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

View File

@@ -0,0 +1,76 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.xcape;
in
{
meta.maintainers = [ maintainers.nickhu ];
options = {
services.xcape = {
enable = mkEnableOption "xcape";
timeout = mkOption {
type = types.nullOr types.int;
default = null;
example = 500;
description = ''
If you hold a key longer than this timeout, xcape will not
generate a key event. Default is 500 ms.
'';
};
mapExpression = mkOption {
type = types.attrsOf types.str;
default = {};
example = { Shift_L = "Escape"; Control_L = "Control_L|O"; };
description = ''
The value has the grammar <literal>Key[|OtherKey]</literal>.
</para>
<para>
The list of key names is found in the header file
<filename>X11/keysymdef.h</filename> (remove the
<literal>XK_</literal> prefix). Note that due to limitations
of X11 shifted keys must be specified as a shift key
followed by the key to be pressed rather than the actual
name of the character. For example to generate "{" the
expression <literal>Shift_L|bracketleft</literal> could be
used (assuming that you have a key with "{" above "[").
</para>
<para>
You can also specify keys in decimal (prefix #), octal (#0),
or hexadecimal (#0x). They will be interpreted as keycodes
unless no corresponding key name is found.
'';
};
};
};
config = mkIf cfg.enable {
systemd.user.services.xcape = {
Unit = {
Description = "xcape";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "forking";
ExecStart = "${pkgs.xcape}/bin/xcape"
+ optionalString (cfg.timeout != null) " -t ${toString cfg.timeout}"
+ optionalString (cfg.mapExpression != {})
" -e '${builtins.concatStringsSep ";"
(attrsets.mapAttrsToList (n: v: "${n}=${v}") cfg.mapExpression)}'";
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
};
};
}

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

@@ -2,19 +2,41 @@
with lib;
let
cfg = config.services.xscreensaver;
in
{
meta.maintainers = [ maintainers.rycee ];
options = {
services.xscreensaver = {
enable = mkEnableOption "XScreenSaver";
settings = mkOption {
type = with types; attrsOf (either bool (either int str));
default = {};
example = {
mode = "blank";
lock = false;
fadeTicks = 20;
};
description = ''
The settings to use for XScreenSaver.
'';
};
};
};
config = mkIf config.services.xscreensaver.enable {
config = mkIf cfg.enable {
# To make the xscreensaver-command tool available.
home.packages = [ pkgs.xscreensaver ];
xresources.properties =
mapAttrs' (n: nameValuePair "xscreensaver.${n}") cfg.settings;
systemd.user.services.xscreensaver = {
Unit = {
Description = "XScreenSaver";

View File

@@ -1,5 +1,6 @@
require 'set'
require 'open3'
require 'shellwords'
@dry_run = ENV['DRY_RUN']
@verbose = ENV['VERBOSE']
@@ -40,11 +41,13 @@ def setup_services(old_gen_path, new_gen_path, start_timeout_ms_string)
raise "daemon-reload failed" unless run_cmd('systemctl --user daemon-reload')
# Exclude services that aren't allowed to be manually started or stopped
no_manual_start, no_manual_stop = get_restricted_units(to_stop + to_restart + to_start)
to_stop -= no_manual_stop
to_restart -= no_manual_stop + no_manual_start
no_manual_start, no_manual_stop, no_restart = get_restricted_units(to_stop + to_restart + to_start)
to_stop -= no_manual_stop + no_restart
to_restart -= no_manual_stop + no_manual_start + no_restart
to_start -= no_manual_start
puts "Not restarting: #{no_restart.join(' ')}" unless no_restart.empty?
if to_stop.empty? && to_start.empty? && to_restart.empty?
print_service_msg("All services are already running", services_to_run)
else
@@ -73,7 +76,7 @@ def get_services(dir)
end
def get_service_files(dir)
Dir.chdir(dir) { Dir['*.service'] }
Dir.chdir(dir) { Dir['*.{service,socket}'] }
end
def get_changed_services(dir_a, dir_b, services)
@@ -143,15 +146,17 @@ end
def get_units_by_activity(units, active)
return [] if units.empty?
units = units.to_a
is_active = `systemctl --user is-active #{units.join(' ')}`.split
is_active = `systemctl --user is-active #{units.shelljoin}`.split
units.select.with_index do |_, i|
(is_active[i] == 'active') == active
end
end
def get_restricted_units(units)
infos = `systemctl --user show -p RefuseManualStart -p RefuseManualStop #{units.to_a.join(' ')}`
units = units.to_a
infos = `systemctl --user show -p RefuseManualStart -p RefuseManualStop #{units.shelljoin}`
.split("\n\n")
no_restart = []
no_manual_start = []
no_manual_stop = []
infos.zip(units).each do |info, unit|
@@ -159,7 +164,15 @@ def get_restricted_units(units)
no_manual_start << unit if no_start.end_with?('yes')
no_manual_stop << unit if no_stop.end_with?('yes')
end
[no_manual_start, no_manual_stop]
# Regular expression that indicates that a service should not be
# restarted even if a change has been detected.
restartRe = /^[ \t]*X-RestartIfChanged[ \t]*=[ \t]*false[ \t]*(?:#.*)?$/
units.each do |unit|
if `systemctl --user cat #{unit.shellescape}` =~ restartRe
no_restart << unit
end
end
[no_manual_start, no_manual_stop, no_restart]
end
def wait_and_get_failed_services(services, start_timeout_ms)
@@ -173,7 +186,7 @@ end
def show_failed_services_status(services)
puts
services.each do |service|
run_cmd("systemctl --user status #{service}")
run_cmd("systemctl --user status #{service.shellescape}")
puts
end
end

View File

@@ -12,7 +12,8 @@ let
|| cfg.sockets != {}
|| cfg.targets != {}
|| cfg.timers != {}
|| cfg.paths != {};
|| cfg.paths != {}
|| cfg.sessionVariables != {};
toSystemdIni = generators.toINI {
mkKeyValue = key: value:
@@ -27,11 +28,17 @@ let
buildService = style: name: serviceCfg:
let
filename = "${name}.${style}";
pathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"]
["-" "-" "-" "" "" ]
filename;
# Needed because systemd derives unit names from the ultimate
# link target.
source = pkgs.writeTextDir filename (toSystemdIni serviceCfg)
+ "/" + filename;
source = pkgs.writeTextFile {
name = pathSafeName;
text = toSystemdIni serviceCfg;
destination = "/${filename}";
} + "/${filename}";
wantedBy = target:
{
@@ -51,9 +58,14 @@ let
servicesStartTimeoutMs = builtins.toString cfg.servicesStartTimeoutMs;
attrsRecursivelyMerged = types.attrs // {
merge = loc: foldl' (res: def: recursiveUpdate res def.value) {};
};
unitType = unitKind: with types;
let
primitive = either bool (either int str);
in
attrsOf (attrsOf (attrsOf (either primitive (listOf primitive))))
// {
description = "systemd ${unitKind} unit configuration";
};
unitDescription = type: ''
Definition of systemd per-user ${type} units. Attributes are
@@ -69,16 +81,26 @@ let
unitExample = type: literalExample ''
{
Unit = {
Description = "Example description";
};
${toLower type}-name = {
Unit = {
Description = "Example description";
Documentation = [ "man:example(1)" "man:example(5)" ];
};
${type} = {
};
}
${type} = {
};
}
};
'';
sessionVariables = mkIf (cfg.sessionVariables != {}) {
"environment.d/10-home-manager.conf".text =
concatStringsSep "\n" (
mapAttrsToList (n: v: "${n}=${toString v}") cfg.sessionVariables
) + "\n";
};
in
{
@@ -99,35 +121,35 @@ in
services = mkOption {
default = {};
type = attrsRecursivelyMerged;
type = unitType "service";
description = unitDescription "service";
example = unitExample "Service";
};
sockets = mkOption {
default = {};
type = attrsRecursivelyMerged;
type = unitType "socket";
description = unitDescription "socket";
example = unitExample "Socket";
};
targets = mkOption {
default = {};
type = attrsRecursivelyMerged;
type = unitType "target";
description = unitDescription "target";
example = unitExample "Target";
};
timers = mkOption {
default = {};
type = attrsRecursivelyMerged;
type = unitType "timer";
description = unitDescription "timer";
example = unitExample "Timer";
};
paths = mkOption {
default = {};
type = attrsRecursivelyMerged;
type = unitType "path";
description = unitDescription "path";
example = unitExample "Path";
};
@@ -150,6 +172,20 @@ in
start is considered successful.
'';
};
sessionVariables = mkOption {
default = {};
type = with types; attrsOf (either int str);
example = { EDITOR = "vim"; };
description = ''
Environment variables that will be set for the user session.
The variable values must be as described in
<citerefentry>
<refentrytitle>environment.d</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>.
'';
};
};
};
@@ -162,7 +198,7 @@ in
let
names = concatStringsSep ", " (
attrNames (
cfg.services // cfg.sockets // cfg.targets // cfg.timers // cfg.paths
cfg.services // cfg.sockets // cfg.targets // cfg.timers // cfg.paths // cfg.sessionVariables
)
);
in
@@ -174,8 +210,8 @@ in
# If we run under a Linux system we assume that systemd is
# available, in particular we assume that systemctl is in PATH.
(mkIf pkgs.stdenv.isLinux {
xdg.configFile =
listToAttrs (
xdg.configFile = mkMerge [
(listToAttrs (
(buildServices "service" cfg.services)
++
(buildServices "socket" cfg.sockets)
@@ -185,7 +221,10 @@ in
(buildServices "timer" cfg.timers)
++
(buildServices "path" cfg.paths)
);
))
sessionVariables
];
# Run systemd service reload if user is logged in. If we're
# running this from the NixOS module then XDG_RUNTIME_DIR is not

View File

@@ -66,46 +66,51 @@ in
};
config = mkIf cfg.enable {
systemd.user.services.setxkbmap = {
Unit = {
Description = "Set up keyboard in X";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
systemd.user = {
services = mkIf (config.home.keyboard != null) {
setxkbmap = {
Unit = {
Description = "Set up keyboard in X";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
RemainAfterExit = true;
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 = {
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}";
};
};
# 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" ];
# A basic graphical session target for Home Manager.
targets.hm-graphical-session = {
Unit = {
Description = "Home Manager X session";
Requires = [ "graphical-session-pre.target" ];
BindsTo = [ "graphical-session.target" ];
};
};
};
home.file.".xprofile".text = ''
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
if [[ -e "$HOME/.profile" ]]; then
if [ -e "$HOME/.profile" ]; then
. "$HOME/.profile"
fi
@@ -130,7 +135,7 @@ in
home.file.${cfg.scriptPath} = {
executable = true;
text = ''
if [[ ! -v HM_XPROFILE_SOURCED ]]; then
if [ -z "$HM_XPROFILE_SOURCED" ]; then
. ~/.xprofile
fi
unset HM_XPROFILE_SOURCED
@@ -145,7 +150,7 @@ in
systemctl --user stop graphical-session-pre.target
# Wait until the units actually stop.
while [[ -n "$(systemctl --user --no-legend --state=deactivating list-units)" ]]; do
while [ -n "$(systemctl --user --no-legend --state=deactivating list-units)" ]; do
sleep 0.5
done
'';

View File

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

View File

@@ -7,12 +7,17 @@ let
cfg = config.home-manager;
hmModule = types.submodule ({name, ...}: {
imports = import ../modules/modules.nix {
inherit lib pkgs;
nixosSubmodule = true;
};
imports = import ../modules/modules.nix { inherit lib pkgs; };
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.homeDirectory = config.users.users.${name}.home;
};
@@ -22,38 +27,71 @@ in
{
options = {
home-manager.users = mkOption {
type = types.attrsOf hmModule;
default = {};
description = ''
Per-user Home Manager configuration.
home-manager = {
useUserPackages = mkEnableOption ''
installation of user packages through the
<option>users.users.&lt;name?&gt;.packages</option> option.
'';
users = mkOption {
type = types.attrsOf hmModule;
default = {};
description = ''
Per-user Home Manager configuration.
'';
};
};
};
config = mkIf (cfg.users != {}) {
systemd.services = mapAttrs' (username: usercfg:
nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
description = "Home Manager environment for ${username}";
wantedBy = [ "multi-user.target" ];
wants = [ "nix-daemon.socket" ];
after = [ "nix-daemon.socket" ];
warnings =
flatten (flip mapAttrsToList cfg.users (user: config:
flip map config.warnings (warning:
"${user} profile: ${warning}"
)
));
serviceConfig = {
User = username;
Type = "oneshot";
RemainAfterExit = "yes";
SyslogIdentifier = "hm-activate-${username}";
assertions =
flatten (flip mapAttrsToList cfg.users (user: config:
flip map config.assertions (assertion:
{
inherit (assertion) assertion;
message = "${user} profile: ${assertion.message}";
}
)
));
# The activation script is run by a login shell to make sure
# that the user is given a sane Nix environment.
ExecStart = pkgs.writeScript "activate-${username}" ''
#! ${pkgs.stdenv.shell} -el
echo Activating home-manager configuration for ${username}
exec ${usercfg.home.activationPackage}/activate
'';
};
}
users.users = mkIf cfg.useUserPackages (
mapAttrs (username: usercfg: {
packages = usercfg.home.packages;
}) cfg.users
);
systemd.services = mapAttrs' (_: usercfg:
let
username = usercfg.home.username;
in
nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
description = "Home Manager environment for ${username}";
wantedBy = [ "multi-user.target" ];
wants = [ "nix-daemon.socket" ];
after = [ "nix-daemon.socket" ];
serviceConfig = {
User = usercfg.home.username;
Type = "oneshot";
RemainAfterExit = "yes";
SyslogIdentifier = "hm-activate-${username}";
# The activation script is run by a login shell to make sure
# that the user is given a sane Nix environment.
ExecStart = pkgs.writeScript "activate-${username}" ''
#! ${pkgs.runtimeShell} -el
echo Activating home-manager configuration for ${username}
exec ${usercfg.home.activationPackage}/activate
'';
};
}
) cfg.users;
};
}

View File

@@ -1,3 +1,5 @@
self: super: {
home-manager = import ./home-manager { pkgs = super; };
home-manager = super.callPackage ./home-manager {
path = toString ./.;
};
}

43
tests/default.nix Normal file
View File

@@ -0,0 +1,43 @@
{ pkgs ? import <nixpkgs> {} }:
let
nmt = pkgs.fetchFromGitLab {
owner = "rycee";
repo = "nmt";
rev = "89fb12a2aaa8ec671e22a033162c7738be714305";
sha256 = "07yc1jkgw8vhskzk937k9hfba401q8rn4sgj9baw3fkjl9zrbcyf";
};
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/misc/pam
// import ./modules/systemd
)
// import ./modules/home-environment
// import ./modules/programs/alacritty
// import ./modules/programs/bash
// import ./modules/programs/ssh
// import ./modules/programs/tmux
// import ./modules/programs/zsh;
}

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.

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