mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-11 17:39:37 +08:00
Compare commits
201 Commits
release-18
...
release-19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef64bc598f | ||
|
|
8def383511 | ||
|
|
c13c1b33d9 | ||
|
|
d74320012e | ||
|
|
aa2f70def7 | ||
|
|
76ba4bedff | ||
|
|
46eaee3262 | ||
|
|
f8187816a4 | ||
|
|
f9ac2671bb | ||
|
|
2307cb280a | ||
|
|
14c5a22cfb | ||
|
|
0f85326dee | ||
|
|
35d31c390d | ||
|
|
176e82ee1c | ||
|
|
634a909ddc | ||
|
|
33c6230dac | ||
|
|
1d8b6e7d9e | ||
|
|
cf5e08cfb8 | ||
|
|
45a73067ac | ||
|
|
ef906c5a92 | ||
|
|
bb18d4c746 | ||
|
|
6d5246f49f | ||
|
|
5d054abe6a | ||
|
|
a85f22164d | ||
|
|
dd6d8e278b | ||
|
|
9291923e84 | ||
|
|
b8bbd242f8 | ||
|
|
413ac52bed | ||
|
|
4f13f06b01 | ||
|
|
d714740961 | ||
|
|
81d600d948 | ||
|
|
3daa1da497 | ||
|
|
41d2a16f99 | ||
|
|
24b734500f | ||
|
|
de9fc235d0 | ||
|
|
14a0dce9e8 | ||
|
|
ef78cae6a4 | ||
|
|
e3c4ec12cc | ||
|
|
f73c6ed74f | ||
|
|
de0dae5666 | ||
|
|
162a65f029 | ||
|
|
ba0375bf06 | ||
|
|
13ad532412 | ||
|
|
8ecc311bcc | ||
|
|
e3831d8ecc | ||
|
|
9c0536deda | ||
|
|
6b42bd7abf | ||
|
|
0d246aa435 | ||
|
|
c5f35b7ff9 | ||
|
|
ff602cb906 | ||
|
|
1806e5511e | ||
|
|
cb93316fed | ||
|
|
a6f0fa90f7 | ||
|
|
30a16e3a87 | ||
|
|
3db46fa9bf | ||
|
|
12cb82af91 | ||
|
|
d49b514aa6 | ||
|
|
b6e1d82685 | ||
|
|
6cd5c8fca5 | ||
|
|
67aee78fdf | ||
|
|
c48db4fbba | ||
|
|
f8b03f5750 | ||
|
|
2c07829be2 | ||
|
|
652c694244 | ||
|
|
995fa3af36 | ||
|
|
4323b35198 | ||
|
|
fd50f5465f | ||
|
|
13d2c470be | ||
|
|
b690a8be2f | ||
|
|
e85804efa2 | ||
|
|
e26ad2026c | ||
|
|
03162970cd | ||
|
|
bc2b7d4f09 | ||
|
|
f77d6b7a2d | ||
|
|
1fdb16866b | ||
|
|
6ebf14143a | ||
|
|
cf5dac9563 | ||
|
|
2e1c825b90 | ||
|
|
a974ce6257 | ||
|
|
5d81cb6ac7 | ||
|
|
41356ac267 | ||
|
|
86af599a18 | ||
|
|
95e36dfe74 | ||
|
|
24b5f62090 | ||
|
|
989e636d98 | ||
|
|
eec78fbd1e | ||
|
|
70d4cf2cd9 | ||
|
|
52692e299d | ||
|
|
fd2bc150d8 | ||
|
|
267afa5a3b | ||
|
|
7ec153889c | ||
|
|
efc795920b | ||
|
|
d3fd287efb | ||
|
|
0fa19ed555 | ||
|
|
52fdf5b7ec | ||
|
|
a09196c4ae | ||
|
|
1d8997633c | ||
|
|
0898b6b482 | ||
|
|
848b8b983e | ||
|
|
465d08d99f | ||
|
|
f07510e2b6 | ||
|
|
b8b391ad18 | ||
|
|
81dae2f88e | ||
|
|
74811679b7 | ||
|
|
93f5fcae1e | ||
|
|
92d4e3e75a | ||
|
|
03f1aea069 | ||
|
|
6da88339f5 | ||
|
|
e0e8d5061d | ||
|
|
62e73b17d2 | ||
|
|
799a90ecfa | ||
|
|
ef168979bf | ||
|
|
2093cf425f | ||
|
|
a3462daeb1 | ||
|
|
a334a941c4 | ||
|
|
1cdb8abf30 | ||
|
|
fbdb5beb59 | ||
|
|
2f372ab4d6 | ||
|
|
524ce43e23 | ||
|
|
7f8e139413 | ||
|
|
99d79d0a80 | ||
|
|
0ca1bf3cfd | ||
|
|
c18984c452 | ||
|
|
445c0b1482 | ||
|
|
0590c2a4f6 | ||
|
|
81ec856a0f | ||
|
|
2410bc603b | ||
|
|
45cadbd4f3 | ||
|
|
02a5a678f6 | ||
|
|
98f534e172 | ||
|
|
a68c8cf5f1 | ||
|
|
604fc92943 | ||
|
|
008d93928f | ||
|
|
601619660d | ||
|
|
4aa07c3547 | ||
|
|
f3f7c5cc57 | ||
|
|
c035046999 | ||
|
|
e15cd64ac9 | ||
|
|
59a4ac71f9 | ||
|
|
7c04351a57 | ||
|
|
46f787950a | ||
|
|
6a244b3a8d | ||
|
|
3cf8b9ea86 | ||
|
|
df8a14e12a | ||
|
|
f6ec26075d | ||
|
|
c42206db02 | ||
|
|
bb64012914 | ||
|
|
d5cc53a4e1 | ||
|
|
55100918cc | ||
|
|
faee571850 | ||
|
|
6f422785c3 | ||
|
|
a7affc93ba | ||
|
|
9052131aef | ||
|
|
6b5e0efd1e | ||
|
|
62eb7ebeba | ||
|
|
c48fd9d842 | ||
|
|
e150dd4a66 | ||
|
|
b3d73e0aff | ||
|
|
16946a6f00 | ||
|
|
a4383075af | ||
|
|
20a60be550 | ||
|
|
7afefcf75d | ||
|
|
40b3443c8f | ||
|
|
e3167068d9 | ||
|
|
cc964b4609 | ||
|
|
370a84192e | ||
|
|
4104ff2b6a | ||
|
|
a0162dacf6 | ||
|
|
b2cc186d22 | ||
|
|
235a6617c4 | ||
|
|
218a8c4d90 | ||
|
|
e68d6e7924 | ||
|
|
dc72aa2305 | ||
|
|
93b10bcf3c | ||
|
|
4971e3735e | ||
|
|
6d56abcec1 | ||
|
|
5d63abb473 | ||
|
|
6e67bb7ae6 | ||
|
|
d67835260d | ||
|
|
b085344b91 | ||
|
|
c108eaba42 | ||
|
|
6ce3ce69b9 | ||
|
|
6826521ec5 | ||
|
|
5fe62660aa | ||
|
|
7a28f68ad0 | ||
|
|
ea9d44bede | ||
|
|
fd3692b36f | ||
|
|
cd7b6fdbc1 | ||
|
|
571e17410a | ||
|
|
797fbbf826 | ||
|
|
a37b5c9c61 | ||
|
|
30f3baabaf | ||
|
|
ef29f321e0 | ||
|
|
15bca92b2c | ||
|
|
71f6bc41eb | ||
|
|
6d2f16a7ae | ||
|
|
40b279e3a3 | ||
|
|
5d8b089188 | ||
|
|
9686d93ff6 | ||
|
|
67ebe16b40 | ||
|
|
6ab6488e5a |
@@ -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
|
||||
|
||||
@@ -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
15
FAQ.md
@@ -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.
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -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
|
||||
|
||||
81
README.md
81
README.md
@@ -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/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
310
doc/installation.xml
Normal 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 '<nixpkgs>' -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 '<home-manager>' -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">
|
||||
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
</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 = [ <home-manager/nixos> ];
|
||||
</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 = [ <home-manager/nix-darwin> ];
|
||||
</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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>2017–2019</year><holder>Home Manager contributors</holder>
|
||||
</copyright>
|
||||
</info>
|
||||
<xi:include href="man-configuration.xml" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
14
doc/release-notes/release-notes.xml
Normal file
14
doc/release-notes/release-notes.xml
Normal 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>
|
||||
11
doc/release-notes/rl-1809.xml
Normal file
11
doc/release-notes/rl-1809.xml
Normal 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>
|
||||
88
doc/release-notes/rl-1903.xml
Normal file
88
doc/release-notes/rl-1903.xml
Normal 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.<name?>.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>
|
||||
12
doc/release-notes/rl-1909.xml
Normal file
12
doc/release-notes/rl-1909.xml
Normal 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>
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
''
|
||||
|
||||
@@ -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
|
||||
;;
|
||||
|
||||
@@ -9,7 +9,7 @@ with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
env = import <home-manager/modules> {
|
||||
env = import ../modules {
|
||||
configuration =
|
||||
if confAttr == ""
|
||||
then confPath
|
||||
|
||||
@@ -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
|
||||
''
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -23,6 +23,9 @@ let
|
||||
modules =
|
||||
[ configuration ]
|
||||
++ (import ./modules.nix { inherit check lib pkgs; });
|
||||
specialArgs = {
|
||||
modulesPath = builtins.toString ./.;
|
||||
};
|
||||
};
|
||||
|
||||
module = showWarnings (
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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; };
|
||||
}
|
||||
|
||||
@@ -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
27
modules/lib/strings.nix
Normal 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
28
modules/lib/zsh.nix
Normal 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);
|
||||
}
|
||||
@@ -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><profile directory>/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
89
modules/misc/dconf.nix
Normal 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
|
||||
''
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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'.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 { };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 doesn’t 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+
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
32
modules/misc/submodule-support.nix
Normal file
32
modules/misc/submodule-support.nix
Normal 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.<name?>.packages</option>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
53
modules/programs/alacritty.nix
Normal file
53
modules/programs/alacritty.nix
Normal 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);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -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 = "";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
40
modules/programs/bat.nix
Normal 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
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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 =
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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 '<nixpkgs>' -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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" ]
|
||||
);
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 terminal’s 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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
211
modules/programs/irssi.nix
Normal 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
76
modules/programs/jq.nix
Normal 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}";
|
||||
};
|
||||
};
|
||||
}
|
||||
88
modules/programs/keychain.nix
Normal file
88
modules/programs/keychain.nix
Normal 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
41
modules/programs/lsd.nix
Normal 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;
|
||||
};
|
||||
}
|
||||
64
modules/programs/matplotlib.nix
Normal file
64
modules/programs/matplotlib.nix
Normal 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";
|
||||
};
|
||||
}
|
||||
@@ -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" ] ''
|
||||
|
||||
@@ -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.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
@@ -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\"";
|
||||
|
||||
@@ -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
52
modules/programs/opam.nix
Normal 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)"
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -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
128
modules/programs/skim.nix
Normal 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
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -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.
|
||||
'';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
58
modules/programs/vscode.nix
Normal file
58
modules/programs/vscode.nix
Normal 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;
|
||||
};
|
||||
}
|
||||
@@ -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 != []) {
|
||||
|
||||
@@ -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
|
||||
'';
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
|
||||
48
modules/services/emacs.nix
Normal file
48
modules/services/emacs.nix
Normal 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" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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" ];
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.keybase ];
|
||||
|
||||
systemd.user.services.keybase = {
|
||||
Unit = {
|
||||
Description = "Keybase service";
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
101
modules/services/mpdris2.nix
Normal file
101
modules/services/mpdris2.nix
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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"
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ with lib;
|
||||
};
|
||||
|
||||
Service = {
|
||||
Environment =
|
||||
let
|
||||
toolPaths = makeBinPath [ pkgs.paprefs pkgs.pavucontrol ];
|
||||
in
|
||||
[ "PATH=${toolPaths}" ];
|
||||
ExecStart = "${pkgs.pasystray}/bin/pasystray";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ in
|
||||
|
||||
Service = {
|
||||
ExecStart = "${cfg.package}/bin/taffybar";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
Install = {
|
||||
|
||||
@@ -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}
|
||||
|
||||
76
modules/services/xcape.nix
Normal file
76
modules/services/xcape.nix
Normal 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" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
49
modules/services/xembed-sni-proxy.nix
Normal file
49
modules/services/xembed-sni-proxy.nix
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
'';
|
||||
|
||||
@@ -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.<name?>.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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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.<name?>.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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
43
tests/default.nix
Normal 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;
|
||||
}
|
||||
27
tests/modules/accounts/email-test-accounts.nix
Normal file
27
tests/modules/accounts/email-test-accounts.nix
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
1
tests/modules/files/.hidden
Normal file
1
tests/modules/files/.hidden
Normal 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
Reference in New Issue
Block a user