mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-11 17:39:37 +08:00
Compare commits
168 Commits
release-19
...
release-19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b78b5fa4a0 | ||
|
|
7aa2bd5bf4 | ||
|
|
57f3b72d3a | ||
|
|
0d1ca254d0 | ||
|
|
3166ae7993 | ||
|
|
2b71762384 | ||
|
|
1261ffee91 | ||
|
|
f5c9303ced | ||
|
|
8d663335eb | ||
|
|
72400b2c29 | ||
|
|
1d38ffc372 | ||
|
|
10d2c4e7e4 | ||
|
|
b646623a39 | ||
|
|
af2303526d | ||
|
|
11f8b1c1ce | ||
|
|
94c0367dd8 | ||
|
|
24c6d8dfc5 | ||
|
|
8fb1ed5919 | ||
|
|
829b688827 | ||
|
|
9e69b0d8b9 | ||
|
|
9bdfdfe14e | ||
|
|
b41fc9e6e8 | ||
|
|
5e7a4c55ed | ||
|
|
22076437f3 | ||
|
|
0d7b515a65 | ||
|
|
eafc8897e6 | ||
|
|
415f12bae5 | ||
|
|
06f1b13c21 | ||
|
|
a0653a7fb0 | ||
|
|
dff5f07952 | ||
|
|
b905de5833 | ||
|
|
ecf333d27a | ||
|
|
e413a1408e | ||
|
|
06ae8792e7 | ||
|
|
f856c78a4a | ||
|
|
31e84945d5 | ||
|
|
8bddc1adab | ||
|
|
e8dbc35613 | ||
|
|
3d546e0d01 | ||
|
|
a5999a62cd | ||
|
|
761b3d0c12 | ||
|
|
bdb4cf6c59 | ||
|
|
7205d3b2d2 | ||
|
|
bb5c29107e | ||
|
|
3f45630180 | ||
|
|
51581b7e43 | ||
|
|
b0544c8cde | ||
|
|
e347e932af | ||
|
|
0dfa1eef25 | ||
|
|
aa5ba177cc | ||
|
|
41f918499b | ||
|
|
d3e316eec5 | ||
|
|
45ec65e1cc | ||
|
|
05d91c5f50 | ||
|
|
d6b36f12ff | ||
|
|
824d31a21c | ||
|
|
0083087e01 | ||
|
|
1923ac3358 | ||
|
|
698d0f0a44 | ||
|
|
ec0459e139 | ||
|
|
d5e73c39fc | ||
|
|
a144c723a1 | ||
|
|
a28614e65d | ||
|
|
8ab1d22a82 | ||
|
|
b6289f7022 | ||
|
|
875eea1330 | ||
|
|
7c76ae1814 | ||
|
|
c142e5264d | ||
|
|
5d7eabb93f | ||
|
|
f1146a1fef | ||
|
|
55b71223d4 | ||
|
|
db86bd6c01 | ||
|
|
13fa61744c | ||
|
|
8fe4e0879c | ||
|
|
6bec9547c6 | ||
|
|
bfc28cacbe | ||
|
|
b2a787ca69 | ||
|
|
eb1b86a5ec | ||
|
|
7159c293af | ||
|
|
eb0ccf7286 | ||
|
|
35752e07fa | ||
|
|
57925c50bf | ||
|
|
0e871b490e | ||
|
|
ed4f66185f | ||
|
|
3d645c0ce1 | ||
|
|
8830b8d082 | ||
|
|
73641e492c | ||
|
|
c2429ca0cf | ||
|
|
7834ffbbf1 | ||
|
|
fa82ced414 | ||
|
|
9cc30b18f7 | ||
|
|
db0dfb4b08 | ||
|
|
5eed33ef08 | ||
|
|
31ae1bc2ff | ||
|
|
6932e6330e | ||
|
|
a124dae35a | ||
|
|
5203340b64 | ||
|
|
ed0e40dee8 | ||
|
|
8b759c24e6 | ||
|
|
1499b85ac6 | ||
|
|
fcdab6a62d | ||
|
|
5c94538c7d | ||
|
|
2eae9daae7 | ||
|
|
55c962fda2 | ||
|
|
eb7f39f0aa | ||
|
|
7310cfc557 | ||
|
|
42ad0effdd | ||
|
|
bce63e4dff | ||
|
|
9302523d34 | ||
|
|
a9ecef1fa9 | ||
|
|
e59b8b0c37 | ||
|
|
3743e8995a | ||
|
|
4c9b40ca0e | ||
|
|
d625186ce5 | ||
|
|
caf3349f01 | ||
|
|
6239ce20af | ||
|
|
54de0e1d79 | ||
|
|
056443ccbd | ||
|
|
7d68c46feb | ||
|
|
734128930f | ||
|
|
cc0cd538e6 | ||
|
|
ca4f22be85 | ||
|
|
c3520bfa52 | ||
|
|
2029e104d4 | ||
|
|
7c76f4a71f | ||
|
|
95382060eb | ||
|
|
472d7731d6 | ||
|
|
28f2dd612e | ||
|
|
8467e7e10a | ||
|
|
8f7cd53204 | ||
|
|
68fe8623ad | ||
|
|
8243cc0a5d | ||
|
|
95d55b8da1 | ||
|
|
f83c49baa3 | ||
|
|
cf0aad391c | ||
|
|
42732990cd | ||
|
|
f82246171b | ||
|
|
5b50eb18fc | ||
|
|
29824a8cf6 | ||
|
|
0db26fc3ab | ||
|
|
8991fe2e90 | ||
|
|
2211770d8b | ||
|
|
e25113bcf0 | ||
|
|
e1535d2bd8 | ||
|
|
d5bf68d77d | ||
|
|
5b95fd0521 | ||
|
|
fcacba268d | ||
|
|
d7eaeaf636 | ||
|
|
2e13c3cdfd | ||
|
|
d726afd9e4 | ||
|
|
1480a6ca14 | ||
|
|
02a07f19a1 | ||
|
|
d2ed39f103 | ||
|
|
8b15f18993 | ||
|
|
b256e3a44f | ||
|
|
939274281a | ||
|
|
be4b100ae5 | ||
|
|
f99d4ba7c4 | ||
|
|
1f4e9681f7 | ||
|
|
f56256f488 | ||
|
|
f18e2933d4 | ||
|
|
2f819d1647 | ||
|
|
821df406c9 | ||
|
|
3bb7c75db3 | ||
|
|
c94eaa0e6c | ||
|
|
a16439e38e | ||
|
|
b6e613c771 | ||
|
|
c5f230e682 |
@@ -1,6 +1,18 @@
|
||||
image: nixos/nix:latest
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
Run tests:
|
||||
stage: test
|
||||
script:
|
||||
- nix-shell tests -A run.files-text
|
||||
only:
|
||||
- release-19.09
|
||||
|
||||
pages:
|
||||
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.09
|
||||
|
||||
@@ -139,15 +139,18 @@ If you do have a change worthy of a news entry then please add one in
|
||||
> use 'services.myservice.bar' instead.
|
||||
|
||||
- A new module, say `foo.nix`, should always include a news entry
|
||||
(without any condition) that has a message along the lines of
|
||||
that has a message along the lines of
|
||||
|
||||
> A new service is available: 'services.foo'.
|
||||
> A new module is available: 'services.foo'.
|
||||
|
||||
or
|
||||
If the module is platform specific, e.g., a service module using
|
||||
systemd, then a condition like
|
||||
|
||||
> A new program configuration is available: 'program.foo'.
|
||||
```
|
||||
condition = hostPlatform.isLinux;
|
||||
```
|
||||
|
||||
depending on the type of module.
|
||||
should be added.
|
||||
|
||||
[open issues]: https://github.com/rycee/home-manager/issues
|
||||
[new issue]: https://github.com/rycee/home-manager/issues/new
|
||||
|
||||
30
FAQ.md
30
FAQ.md
@@ -119,3 +119,33 @@ The solution on NixOS is to add
|
||||
services.dbus.packages = with pkgs; [ gnome3.dconf ];
|
||||
|
||||
to your system configuration.
|
||||
|
||||
How do I install packages from Nixpkgs unstable?
|
||||
------------------------------------------------
|
||||
|
||||
If you are using a stable version of Nixpkgs but would like to install
|
||||
some particular packages from Nixpkgs unstable then you can import the
|
||||
unstable Nixpkgs and refer to its packages within your configuration.
|
||||
Something like
|
||||
|
||||
```nix
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
home.packages = [
|
||||
pkgsUnstable.foo
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
```
|
||||
|
||||
should work provided you have a Nix channel called `nixpkgs-unstable`.
|
||||
Note, the package will not be affected by any package overrides,
|
||||
overlays, etc.
|
||||
|
||||
@@ -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 19.03 (the
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 19.09 (the
|
||||
current stable version), it may or may not work on other Linux
|
||||
distributions and NixOS versions.
|
||||
|
||||
@@ -72,11 +72,11 @@ Currently the easiest way to install Home Manager is as follows:
|
||||
if you are following Nixpkgs master or an unstable channel and
|
||||
|
||||
```console
|
||||
$ nix-channel --add https://github.com/rycee/home-manager/archive/release-19.03.tar.gz home-manager
|
||||
$ nix-channel --add https://github.com/rycee/home-manager/archive/release-19.09.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
if you follow a Nixpkgs version 19.03 channel.
|
||||
if you follow a Nixpkgs version 19.09 channel.
|
||||
|
||||
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
|
||||
|
||||
360
doc/default.nix
360
doc/default.nix
@@ -1,328 +1,72 @@
|
||||
{ pkgs, options, config, version, revision, extraSources ? [] }:
|
||||
|
||||
with pkgs;
|
||||
{ pkgs }:
|
||||
|
||||
let
|
||||
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Remove invisible and internal options.
|
||||
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
||||
nmdSrc = pkgs.fetchFromGitLab {
|
||||
name = "nmd";
|
||||
owner = "rycee";
|
||||
repo = "nmd";
|
||||
rev = "9751ca5ef6eb2ef27470010208d4c0a20e89443d";
|
||||
sha256 = "0rbx10n8kk0bvp1nl5c8q79lz1w0p1b8103asbvwps3gmqd070hi";
|
||||
};
|
||||
|
||||
# Replace functions by the string <function>
|
||||
substFunction = x:
|
||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||
else if builtins.isList x then map substFunction x
|
||||
else if lib.isFunction x then "<function>"
|
||||
else x;
|
||||
nmd = import nmdSrc { inherit pkgs; };
|
||||
|
||||
# Generate DocBook documentation for a list of packages. This is
|
||||
# what `relatedPackages` option of `mkOption` from
|
||||
# ../../../lib/options.nix influences.
|
||||
#
|
||||
# Each element of `relatedPackages` can be either
|
||||
# - a string: that will be interpreted as an attribute name from `pkgs`,
|
||||
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
||||
# - an attrset: that can specify `name`, `path`, `package`, `comment`
|
||||
# (either of `name`, `path` is required, the rest are optional).
|
||||
genRelatedPackages = packages:
|
||||
let
|
||||
unpack = p: if lib.isString p then { name = p; }
|
||||
else if lib.isList p then { path = p; }
|
||||
else p;
|
||||
describe = args:
|
||||
let
|
||||
name = args.name or (lib.concatStringsSep "." args.path);
|
||||
path = args.path or [ args.name ];
|
||||
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
|
||||
in "<listitem>"
|
||||
+ "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
|
||||
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
|
||||
+ ": ${package.meta.description or "???"}.</para>"
|
||||
+ lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
|
||||
# Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
|
||||
+ lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
|
||||
+ "</listitem>";
|
||||
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
|
||||
# Make sure the used package is scrubbed to avoid actually
|
||||
# instantiating derivations.
|
||||
scrubbedPkgsModule = {
|
||||
imports = [
|
||||
{
|
||||
_module.args = {
|
||||
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
|
||||
pkgs_i686 = lib.mkForce { };
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
|
||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||
declarations = map stripAnyPrefixes opt.declarations;
|
||||
}
|
||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
||||
// lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
|
||||
hmModulesDocs = nmd.buildModulesDocs {
|
||||
modules =
|
||||
import ../modules/modules.nix { inherit lib pkgs; }
|
||||
++ [ scrubbedPkgsModule ];
|
||||
moduleRootPaths = [ ./.. ];
|
||||
mkModuleUrl = path:
|
||||
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
|
||||
channelName = "home-manager";
|
||||
docBook.id = "home-manager-options";
|
||||
};
|
||||
|
||||
# We need to strip references to /nix/store/* from options,
|
||||
# including any `extraSources` if some modules came from elsewhere,
|
||||
# or else the build will fail.
|
||||
#
|
||||
# E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
|
||||
# you'd need to include `extraSources = [ pkgs.customModules ]`
|
||||
prefixesToStrip = map (p: "${toString p}/") ([ ./.. ] ++ extraSources);
|
||||
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
|
||||
|
||||
# Custom "less" that pushes up all the things ending in ".enable*"
|
||||
# and ".package*"
|
||||
optionLess = a: b:
|
||||
let
|
||||
ise = lib.hasPrefix "enable";
|
||||
isp = lib.hasPrefix "package";
|
||||
cmp = lib.splitByAndCompare ise lib.compare
|
||||
(lib.splitByAndCompare isp lib.compare lib.compare);
|
||||
in lib.compareLists cmp a.loc b.loc < 0;
|
||||
|
||||
# Customly sort option list for the man page.
|
||||
optionsList = lib.sort optionLess optionsListDesc;
|
||||
|
||||
# Convert the list of options into an XML file.
|
||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
|
||||
|
||||
optionsDocBook = runCommand "options-db.xml"
|
||||
{
|
||||
nativeBuildInputs = [ buildPackages.libxslt.bin ];
|
||||
}
|
||||
''
|
||||
optionsXML=${optionsXML}
|
||||
xsltproc \
|
||||
--stringparam program 'home-manager' \
|
||||
--stringparam revision '${revision}' \
|
||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
||||
'';
|
||||
|
||||
sources = lib.sourceFilesBySuffices ./. [".xml"];
|
||||
|
||||
modulesDoc = builtins.toFile "modules.xml" ''
|
||||
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules">
|
||||
${(lib.concatMapStrings (path: ''
|
||||
<xi:include href="${path}" />
|
||||
'') (lib.catAttrs "value" config.meta.doc))}
|
||||
</section>
|
||||
'';
|
||||
|
||||
generatedSources = runCommand "generated-docbook" {} ''
|
||||
mkdir $out
|
||||
ln -s ${modulesDoc} $out/modules.xml
|
||||
ln -s ${optionsDocBook} $out/options-db.xml
|
||||
printf "%s" "${version}" > $out/version
|
||||
'';
|
||||
|
||||
copySources =
|
||||
''
|
||||
cp -prd $sources/* . # */
|
||||
ln -s ${generatedSources} ./generated
|
||||
chmod -R u+w .
|
||||
'';
|
||||
|
||||
toc = builtins.toFile "toc.xml"
|
||||
''
|
||||
<toc role="chunk-toc">
|
||||
docs = nmd.buildDocBookDocs {
|
||||
pathName = "home-manager";
|
||||
modulesDocs = [ hmModulesDocs ];
|
||||
documentsDirectory = ./.;
|
||||
chunkToc = ''
|
||||
<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-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
|
||||
</d:tocentry>
|
||||
</toc>
|
||||
'';
|
||||
};
|
||||
|
||||
manualXsltprocOptions = toString [
|
||||
"--param section.autolabel 1"
|
||||
"--param section.label.includes.component.label 1"
|
||||
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
|
||||
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
|
||||
"--param xref.with.number.and.title 1"
|
||||
"--param toc.section.depth 3"
|
||||
"--stringparam admon.style ''"
|
||||
"--stringparam callout.graphics.extension .svg"
|
||||
"--stringparam current.docid manual"
|
||||
"--param chunk.section.depth 0"
|
||||
"--param chunk.first.sections 1"
|
||||
"--param use.id.as.filename 1"
|
||||
"--stringparam generate.toc 'book toc appendix toc'"
|
||||
"--stringparam chunk.toc ${toc}"
|
||||
];
|
||||
in
|
||||
|
||||
manual-combined = runCommand "home-manager-manual-combined"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The Home Manager manual as plain docbook XML";
|
||||
}
|
||||
''
|
||||
${copySources}
|
||||
{
|
||||
inherit nmdSrc;
|
||||
|
||||
xmllint --xinclude --output ./manual-combined.xml ./manual.xml
|
||||
xmllint --xinclude --noxincludenode \
|
||||
--output ./man-pages-combined.xml ./man-pages.xml
|
||||
options = {
|
||||
json = hmModulesDocs.json.override {
|
||||
path = "share/doc/home-manager/options.json";
|
||||
};
|
||||
};
|
||||
|
||||
# outputs the context of an xmllint error output
|
||||
# LEN lines around the failing line are printed
|
||||
function context {
|
||||
# length of context
|
||||
local LEN=6
|
||||
# lines to print before error line
|
||||
local BEFORE=4
|
||||
|
||||
# xmllint output lines are:
|
||||
# file.xml:1234: there was an error on line 1234
|
||||
while IFS=':' read -r file line rest; do
|
||||
echo
|
||||
if [[ -n "$rest" ]]; then
|
||||
echo "$file:$line:$rest"
|
||||
local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1))
|
||||
# number lines & filter context
|
||||
nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p"
|
||||
else
|
||||
if [[ -n "$line" ]]; then
|
||||
echo "$file:$line"
|
||||
else
|
||||
echo "$file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function lintrng {
|
||||
xmllint --debug --noout --nonet \
|
||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||
"$1" \
|
||||
2>&1 | context 1>&2
|
||||
# ^ redirect assumes xmllint doesn’t print to stdout
|
||||
}
|
||||
|
||||
lintrng manual-combined.xml
|
||||
lintrng man-pages-combined.xml
|
||||
|
||||
mkdir $out
|
||||
cp manual-combined.xml $out/
|
||||
cp man-pages-combined.xml $out/
|
||||
'';
|
||||
|
||||
olinkDB = runCommand "manual-olinkdb"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
}
|
||||
''
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam collect.xref.targets only \
|
||||
--stringparam targets.filename "$out/manual.db" \
|
||||
--nonet \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
cat > "$out/olinkdb.xml" <<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE targetset SYSTEM
|
||||
"file://${docbook5_xsl}/xml/xsl/docbook/common/targetdatabase.dtd" [
|
||||
<!ENTITY manualtargets SYSTEM "file://$out/manual.db">
|
||||
]>
|
||||
<targetset>
|
||||
<targetsetinfo>
|
||||
Allows for cross-referencing olinks between the manpages
|
||||
and manual.
|
||||
</targetsetinfo>
|
||||
|
||||
<document targetdoc="manual">&manualtargets;</document>
|
||||
</targetset>
|
||||
EOF
|
||||
'';
|
||||
|
||||
in rec {
|
||||
inherit generatedSources;
|
||||
|
||||
# The Home Manager options in JSON format.
|
||||
optionsJSON = runCommand "options-json"
|
||||
{ meta.description = "List of Home Manager options in JSON format";
|
||||
}
|
||||
''
|
||||
# Export list of options in different format.
|
||||
dst=$out/share/doc/home-manager
|
||||
mkdir -p $dst
|
||||
|
||||
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
|
||||
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
|
||||
} $dst/options.json
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
|
||||
# Generate the Home Manager manual.
|
||||
manual = runCommand "home-manager-manual"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The Home Manager manual in HTML format";
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
# Generate the HTML manual.
|
||||
dst=$out/share/doc/home-manager
|
||||
mkdir -p $dst
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--nonet --output $dst/ \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
mkdir -p $dst/images/callouts
|
||||
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
|
||||
|
||||
cp ${./style.css} $dst/style.css
|
||||
cp ${./overrides.css} $dst/overrides.css
|
||||
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
|
||||
echo "doc manual $dst" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
|
||||
|
||||
manualEpub = runCommand "home-manager-manual-epub"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2.bin libxslt.bin zip ];
|
||||
}
|
||||
''
|
||||
# Generate the epub manual.
|
||||
dst=$out/share/doc/home-manager
|
||||
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--nonet --xinclude --output $dst/epub/ \
|
||||
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
mkdir -p $dst/epub/OEBPS/images/callouts
|
||||
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
|
||||
echo "application/epub+zip" > mimetype
|
||||
manual="$dst/home-manager-manual.epub"
|
||||
zip -0Xq "$manual" mimetype
|
||||
cd $dst/epub && zip -Xr9D "$manual" *
|
||||
|
||||
rm -rf $dst/epub
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
|
||||
|
||||
# Generate the Home Manager manpages.
|
||||
manpages = runCommand "home-manager-manpages"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
# Generate manpages.
|
||||
mkdir -p $out/share/man
|
||||
xsltproc --nonet \
|
||||
--param man.output.in.separate.dir 1 \
|
||||
--param man.output.base.dir "'$out/share/man/'" \
|
||||
--param man.endnotes.are.numbered 0 \
|
||||
--param man.break.after.slash 1 \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
||||
${manual-combined}/man-pages-combined.xml
|
||||
'';
|
||||
manPages = docs.manPages;
|
||||
|
||||
manual = {
|
||||
inherit (docs) html htmlOpenTool;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -79,11 +79,11 @@
|
||||
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 --add https://github.com/rycee/home-manager/archive/release-19.09.tar.gz home-manager</userinput>
|
||||
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
if you follow a Nixpkgs version 19.03 channel.
|
||||
if you follow a Nixpkgs version 19.09 channel.
|
||||
</para>
|
||||
<para>
|
||||
On NixOS you may need to log out and back in for the channel to become
|
||||
@@ -169,12 +169,12 @@ $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
</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 --add https://github.com/rycee/home-manager/archive/release-19.09.tar.gz home-manager</userinput>
|
||||
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
if you follow a Nixpkgs version 19.03 channel.
|
||||
if you follow a Nixpkgs version 19.09 channel.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -230,7 +230,81 @@ home-manager.useUserPackages = true;
|
||||
<title>nix-darwin module</title>
|
||||
|
||||
<para>
|
||||
To be done.
|
||||
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.09.tar.gz home-manager</userinput>
|
||||
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
if you follow a Nixpkgs version 19.09 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>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
You can use the following options in
|
||||
<filename>home-configuration.nix</filename>:
|
||||
</para>
|
||||
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
|
||||
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>See also</title>
|
||||
|
||||
@@ -2,46 +2,141 @@
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<refmeta>
|
||||
<refentrytitle><command>home-manager</command></refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refentrytitle><command>home-manager</command>
|
||||
</refentrytitle><manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Home Manager</refmiscinfo>
|
||||
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><command>home-manager</command></refname>
|
||||
<refpurpose>reconfigure a user environment</refpurpose>
|
||||
<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>
|
||||
build
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
<option>build</option>
|
||||
edit
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
<option>switch</option>
|
||||
expire-generations <replaceable>timestamp</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
<option>generations</option>
|
||||
generations
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
<option>remove-generations</option>
|
||||
help
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
<option>packages</option>
|
||||
news
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
<option>news</option>
|
||||
packages
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
remove-generations <replaceable>ID …</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
switch
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
uninstall
|
||||
</arg>
|
||||
</group>
|
||||
<sbr />
|
||||
<arg>
|
||||
-A <replaceable>attrPath</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
-I <replaceable>path</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
-b <replaceable>ext</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<group choice="req">
|
||||
<arg choice="plain">
|
||||
-f
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--file
|
||||
</arg>
|
||||
</group> <replaceable>path</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<group choice="req">
|
||||
<arg choice="plain">
|
||||
-h
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--help
|
||||
</arg>
|
||||
</group>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<group choice="req">
|
||||
<arg choice="plain">
|
||||
-n
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--dry-run
|
||||
</arg>
|
||||
</group>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--option <replaceable>name</replaceable> <replaceable>value</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--cores <replaceable>number</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--max-jobs <replaceable>number</replaceable>
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--keep-failed
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--keep-going
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
--show-trace
|
||||
</arg>
|
||||
|
||||
<arg>
|
||||
<group choice="req">
|
||||
<arg choice="plain">
|
||||
-v
|
||||
</arg>
|
||||
|
||||
<arg choice="plain">
|
||||
--verbose
|
||||
</arg>
|
||||
</group>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
<refsection>
|
||||
@@ -50,6 +145,321 @@
|
||||
This command updates the user environment so that it corresponds to the
|
||||
configuration specified in <filename>~/.config/nixpkgs/home.nix</filename>.
|
||||
</para>
|
||||
<para>
|
||||
All operations using this tool expects a sub-command that indicates the
|
||||
operation to perform. It must be one of
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>build</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Build configuration into a <filename>result</filename> directory.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>edit</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Open the home configuration using the editor indicated by
|
||||
<envar>EDITOR</envar>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>expire-generations <replaceable>timestamp</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Remove generations older than <replaceable>timestamp</replaceable> where
|
||||
<replaceable>timestamp</replaceable> is interpreted as in the
|
||||
<option>-d</option> argument of the <citerefentry>
|
||||
<refentrytitle>date</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry> tool. For example <literal>-30
|
||||
days</literal> or <literal>2018-01-01</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>generations</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List all home environment generations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>help</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print tool help.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>news</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Show news entries in a pager.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>packages</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List all packages installed in <varname>home-manager-path</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>remove-generations <replaceable>ID …</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Remove indicated generations. Use the <option>generations</option>
|
||||
sub-command to find suitable generation numbers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>switch</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Build and activate the configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>uninstall</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Remove Home Manager from the user environment. This will
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
remove all managed files from the home directory,
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
remove packages installed through Home Manager from the user profile,
|
||||
and
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
optionally remove all Home Manager generations and make them
|
||||
available for immediate garbage collection.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>Options</title>
|
||||
<para>
|
||||
The tool accepts the options
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-A <replaceable>attrPath</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Optional attribute that selects a configuration expression in the
|
||||
configuration file. That is, if <filename>home.nix</filename> contains
|
||||
<programlisting language="nix">
|
||||
{
|
||||
joe-at-work = {pkgs, ...}: { home.packages = [ pkgs.fortune ]; };
|
||||
joe-at-home = {pkgs, ...}: { home.packages = [ pkgs.cowsay ]; };
|
||||
}
|
||||
</programlisting>
|
||||
then the command <command>home-manager switch -A joe-at-work</command>
|
||||
will activate the profile containing the fortune program.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-I <replaceable>path</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Add a path to the Nix expression search path. For example, to build a
|
||||
Home Manager profile using a specific Nixpkgs run <command>home-manager
|
||||
-I nixpkgs=/absolute/path/to/nixpkgs build</command>. By default
|
||||
<literal><nixpkgs></literal> is used.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-b <replaceable>extension</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable automatic resolution of collisions between unmanaged and managed
|
||||
files. The name of the original file will be suffixed by the given
|
||||
extension. For example,
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>home-manager -b bck switch</userinput>
|
||||
</screen>
|
||||
will cause a colliding file <filename>~/.config/foo.conf</filename> to be
|
||||
moved to <filename>~/.config/foo.conf.bck</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-f <replaceable>path</replaceable></option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--file <replaceable>path</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Indicates the path to the Home Manager configuration file. If not given,
|
||||
<filename>~/.config/nixpkgs/home.nix</filename> is used.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-h</option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--help</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Prints usage information for the <command>home-manager</command> tool.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-n</option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--dry-run</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Perform a dry-run of the given operation, only prints what actions would
|
||||
be taken.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--option <replaceable>name</replaceable> <replaceable>value</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--cores <replaceable>number</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--max-jobs <replaceable>number</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--keep-failed</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--keep-going</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--show-trace</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Passed on to <citerefentry>
|
||||
<refentrytitle>nix-build</refentrytitle>
|
||||
<manvolnum>1</manvolnum> </citerefentry>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-v</option>
|
||||
</term>
|
||||
<term>
|
||||
<option>--verbose</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Activates verbose output.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>Files</title>
|
||||
@@ -77,12 +487,11 @@
|
||||
</para>
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>See also</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>home-configuration.nix</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>
|
||||
</para>
|
||||
<title>See also</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>home-configuration.nix</refentrytitle>
|
||||
<manvolnum>5</manvolnum> </citerefentry>
|
||||
</para>
|
||||
</refsection>
|
||||
</refentry>
|
||||
|
||||
@@ -28,7 +28,11 @@
|
||||
<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" />
|
||||
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||
</appendix>
|
||||
<appendix xml:id="ch-tools">
|
||||
<title>Tools</title>
|
||||
<xi:include href="./man-home-manager.xml" />
|
||||
</appendix>
|
||||
<xi:include href="./release-notes/release-notes.xml" />
|
||||
</book>
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:str="http://exslt.org/strings"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
extension-element-prefixes="str"
|
||||
>
|
||||
|
||||
<xsl:output method='xml' encoding="UTF-8" />
|
||||
|
||||
<xsl:param name="revision" />
|
||||
<xsl:param name="program" />
|
||||
|
||||
|
||||
<xsl:template match="/expr/list">
|
||||
<appendix>
|
||||
<title>Configuration Options</title>
|
||||
<variablelist xml:id="configuration-variable-list">
|
||||
<xsl:for-each select="attrs">
|
||||
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
||||
<varlistentry>
|
||||
<term xlink:href="#{$id}">
|
||||
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
||||
<option>
|
||||
<xsl:value-of select="attr[@name = 'name']/string/@value" />
|
||||
</option>
|
||||
</term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>
|
||||
<xsl:value-of disable-output-escaping="yes"
|
||||
select="attr[@name = 'description']/string/@value" />
|
||||
</para>
|
||||
|
||||
<xsl:if test="attr[@name = 'type']">
|
||||
<para>
|
||||
<emphasis>Type:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="attr[@name = 'type']/string/@value"/>
|
||||
<xsl:if test="attr[@name = 'readOnly']/bool/@value = 'true'">
|
||||
<xsl:text> </xsl:text>
|
||||
<emphasis>(read only)</emphasis>
|
||||
</xsl:if>
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="attr[@name = 'default']">
|
||||
<para>
|
||||
<emphasis>Default:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:apply-templates select="attr[@name = 'default']" mode="top" />
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="attr[@name = 'example']">
|
||||
<para>
|
||||
<emphasis>Example:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:choose>
|
||||
<xsl:when test="attr[@name = 'example']/attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
||||
<programlisting><xsl:value-of select="attr[@name = 'example']/attrs/attr[@name = 'text']/string/@value" /></programlisting>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates select="attr[@name = 'example']" mode="top" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="attr[@name = 'relatedPackages']">
|
||||
<para>
|
||||
<emphasis>Related packages:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of disable-output-escaping="yes"
|
||||
select="attr[@name = 'relatedPackages']/string/@value" />
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
|
||||
<para>
|
||||
<emphasis>Declared by:</emphasis>
|
||||
</para>
|
||||
<xsl:apply-templates select="attr[@name = 'declarations']" />
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="count(attr[@name = 'definitions']/list/*) != 0">
|
||||
<para>
|
||||
<emphasis>Defined by:</emphasis>
|
||||
</para>
|
||||
<xsl:apply-templates select="attr[@name = 'definitions']" />
|
||||
</xsl:if>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</xsl:for-each>
|
||||
|
||||
</variablelist>
|
||||
</appendix>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="*" mode="top">
|
||||
<xsl:choose>
|
||||
<xsl:when test="string[contains(@value, '
')]">
|
||||
<programlisting>
|
||||
<xsl:text>''
|
||||
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "''${")' /><xsl:text>''</xsl:text></programlisting>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<literal><xsl:apply-templates /></literal>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="null">
|
||||
<xsl:text>null</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="string">
|
||||
<xsl:choose>
|
||||
<xsl:when test="(contains(@value, '"') or contains(@value, '\')) and not(contains(@value, '
'))">
|
||||
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "''${")' /><xsl:text>''</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>"</xsl:text><xsl:value-of select="str:replace(str:replace(str:replace(str:replace(@value, '\', '\\'), '"', '\"'), '
', '\n'), '$', '\$')" /><xsl:text>"</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="int">
|
||||
<xsl:value-of select="@value" />
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="bool[@value = 'true']">
|
||||
<xsl:text>true</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="bool[@value = 'false']">
|
||||
<xsl:text>false</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="list">
|
||||
[
|
||||
<xsl:for-each select="*">
|
||||
<xsl:apply-templates select="." />
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
]
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
||||
<xsl:value-of select="attr[@name = 'text']/string/@value" />
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="attrs">
|
||||
{
|
||||
<xsl:for-each select="attr">
|
||||
<xsl:value-of select="@name" />
|
||||
<xsl:text> = </xsl:text>
|
||||
<xsl:apply-templates select="*" /><xsl:text>; </xsl:text>
|
||||
</xsl:for-each>
|
||||
}
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="derivation">
|
||||
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
|
||||
<simplelist>
|
||||
<xsl:for-each select="list/string">
|
||||
<member><filename>
|
||||
<!-- Hyperlink the filename either to the NixOS Subversion
|
||||
repository (if it’s a module and we have a revision number),
|
||||
or to the local filesystem. -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="not(starts-with(@value, '/'))">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$program = 'home-manager'">
|
||||
<xsl:attribute name="xlink:href">https://github.com/rycee/home-manager/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/>#blob-path</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:when test="$revision = 'local'">
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/master/<xsl:value-of select="@value"/></xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/></xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:when test="$revision != 'local' and $program = 'nixops' and contains(@value, '/nix/')">
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xlink:href">file://<xsl:value-of select="@value"/></xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<!-- Print the filename and make it user-friendly by replacing the
|
||||
/nix/store/<hash> prefix by the default location of nixos
|
||||
sources. -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$program = 'home-manager'">
|
||||
<home-manager/<xsl:value-of select="@value"/>>
|
||||
</xsl:when>
|
||||
<xsl:when test="not(starts-with(@value, '/'))">
|
||||
<nixpkgs/<xsl:value-of select="@value"/>>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains(@value, 'nixops') and contains(@value, '/nix/')">
|
||||
<nixops/<xsl:value-of select="substring-after(@value, '/nix/')"/>>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="@value" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</filename></member>
|
||||
</xsl:for-each>
|
||||
</simplelist>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="function">
|
||||
<xsl:text>λ</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
</xsl:stylesheet>
|
||||
@@ -1,9 +0,0 @@
|
||||
.docbook .xref img[src^=images\/callouts\/],
|
||||
.screen img,
|
||||
.programlisting img {
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.calloutlist img {
|
||||
width: 1.5em;
|
||||
}
|
||||
4
doc/release-notes/rl-1809.adoc
Normal file
4
doc/release-notes/rl-1809.adoc
Normal file
@@ -0,0 +1,4 @@
|
||||
[[sec-release-18.09]]
|
||||
== Release 18.09
|
||||
|
||||
The 18.09 release branch became the stable branch in September, 2018.
|
||||
@@ -1,11 +0,0 @@
|
||||
<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>
|
||||
59
doc/release-notes/rl-1903.adoc
Normal file
59
doc/release-notes/rl-1903.adoc
Normal file
@@ -0,0 +1,59 @@
|
||||
[[sec-release-19.03]]
|
||||
== Release 19.03
|
||||
|
||||
The 19.03 release branch became the stable branch in April, 2019.
|
||||
|
||||
[[sec-release-19.03-highlights]]
|
||||
=== Highlights
|
||||
:opt-home-file-source: opt-home.file._name__.source
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* The <<{opt-home-file-source}>> option now allows source files to be
|
||||
hidden, that is, having a name starting with the `.` 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
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
home.file."my file".source = ./. + "/file with spaces!";
|
||||
----
|
||||
|
||||
* The type used for the systemd unit options under
|
||||
<<opt-systemd.user.services>>, <<opt-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.
|
||||
+
|
||||
In particular, if you get an error saying that a ``unique option'' is
|
||||
``defined multiple times'' then you need to use the
|
||||
https://nixos.org/nixos/manual/#sec-option-definitions-setting-priorities[`mkForce`]
|
||||
function. For example,
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
|
||||
----
|
||||
+
|
||||
becomes
|
||||
+
|
||||
[source,nix]
|
||||
----
|
||||
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.
|
||||
|
||||
[[sec-release-19.03-state-version-changes]]
|
||||
=== State Version Changes
|
||||
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the <<opt-home.stateVersion>> option is set
|
||||
to ``19.03'' or later.
|
||||
|
||||
* There is now an option <<opt-programs.beets.enable>> that defaults
|
||||
to `false`. Before the module would be active if the
|
||||
<<opt-programs.beets.settings>> option was non-empty.
|
||||
@@ -1,88 +0,0 @@
|
||||
<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>
|
||||
31
doc/release-notes/rl-1909.adoc
Normal file
31
doc/release-notes/rl-1909.adoc
Normal file
@@ -0,0 +1,31 @@
|
||||
[[sec-release-19.09]]
|
||||
== Release 19.09
|
||||
|
||||
The 19.09 release branch became the stable branch in October, 2019.
|
||||
|
||||
[[sec-release-19.09-highlights]]
|
||||
=== Highlights
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
* The <<opt-programs.firefox.enableGoogleTalk>> and
|
||||
<<opt-programs.firefox.enableIcedTea>> options are now deprecated
|
||||
and will only work if Firefox ESR 52.x is used.
|
||||
|
||||
* The `home-manager` tool now provides an `uninstall` sub-command that
|
||||
can be used to uninstall Home Manager, if used in the standalone
|
||||
mode. That is, not as a NixOS module.
|
||||
|
||||
[[sec-release-19.09-state-version-changes]]
|
||||
=== State Version Changes
|
||||
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the `home.stateVersion` option is set to
|
||||
"19.09" or later.
|
||||
|
||||
* The <<opt-programs.firefox.package>> option now expects a wrapped
|
||||
Firefox package and defaults to `pkgs.firefox`.
|
||||
|
||||
* The options <<opt-home.keyboard.layout>> and
|
||||
<<opt-home.keyboard.variant>> now default to `null`, which indicates
|
||||
that the system value should be used.
|
||||
@@ -1,12 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-19.09">
|
||||
<title>Release 19.09 (unreleased)</title>
|
||||
|
||||
<para>
|
||||
This is the current unstable branch and the information in this section is
|
||||
therefore not final.
|
||||
</para>
|
||||
</section>
|
||||
271
doc/style.css
271
doc/style.css
@@ -1,271 +0,0 @@
|
||||
/* Copied from http://bakefile.sourceforge.net/, which appears
|
||||
licensed under the GNU GPL. */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Basic headers and text:
|
||||
***************************************************************************/
|
||||
|
||||
body
|
||||
{
|
||||
font-family: "Nimbus Sans L", sans-serif;
|
||||
background: white;
|
||||
margin: 2em 1em 2em 1em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4
|
||||
{
|
||||
color: #005aa0;
|
||||
}
|
||||
|
||||
h1 /* title */
|
||||
{
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
h2 /* chapters, appendices, subtitle */
|
||||
{
|
||||
font-size: 180%;
|
||||
}
|
||||
|
||||
/* Extra space between chapters, appendices. */
|
||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
||||
{
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.section > div.titlepage h2 /* sections */
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
h3 /* subsections */
|
||||
{
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.simplesect h2
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.appendix h3
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
|
||||
{
|
||||
margin-top: 1.4em;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.refsection h3
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Examples:
|
||||
***************************************************************************/
|
||||
|
||||
div.example
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 6px 6px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
background: #f4f4f8;
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
div.example p.title
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.example pre
|
||||
{
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Screen dumps:
|
||||
***************************************************************************/
|
||||
|
||||
pre.screen, pre.programlisting
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
|
||||
background: #f4f4f8;
|
||||
font-family: monospace;
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
div.example pre.programlisting
|
||||
{
|
||||
border: 0px;
|
||||
padding: 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Notes, warnings etc:
|
||||
***************************************************************************/
|
||||
|
||||
.note, .warning
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0.3em 0.3em 0.3em 0.3em;
|
||||
background: #fffff5;
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
div.note, div.warning
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.note h3, div.warning h3
|
||||
{
|
||||
color: red;
|
||||
font-size: 100%;
|
||||
padding-right: 0.5em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note p, div.warning p
|
||||
{
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
div.note h3 + p, div.warning h3 + p
|
||||
{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note h3
|
||||
{
|
||||
color: blue;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
div.navfooter *
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Links colors and highlighting:
|
||||
***************************************************************************/
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
a:link { color: #0048b3; }
|
||||
a:visited { color: #002a6a; }
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Table of contents:
|
||||
***************************************************************************/
|
||||
|
||||
div.toc
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.toc dl
|
||||
{
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Special elements:
|
||||
***************************************************************************/
|
||||
|
||||
tt, code
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
.term
|
||||
{
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
div.variablelist dd p, div.glosslist dd p
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.variablelist dd, div.glosslist dd
|
||||
{
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
div.glosslist dt
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.varname
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
span.command strong
|
||||
{
|
||||
font-weight: normal;
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
div.calloutlist table
|
||||
{
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border-collapse: collapse;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
table.simplelist
|
||||
{
|
||||
text-align: left;
|
||||
color: #005aa0;
|
||||
border: 0;
|
||||
padding: 5px;
|
||||
background: #fffff5;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
box-shadow: none;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.navheader table, div.navfooter table {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
div.affiliation
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
356
home-manager/completion.bash
Normal file
356
home-manager/completion.bash
Normal file
@@ -0,0 +1,356 @@
|
||||
#!/bin/env bash
|
||||
|
||||
##################################################
|
||||
|
||||
# « home-manager » command-line completion
|
||||
#
|
||||
# © 2019 "Sam Boosalis" <samboosalis@gmail.com>
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
|
||||
##################################################
|
||||
# Contributing:
|
||||
|
||||
# Compatibility — Bash 3.
|
||||
#
|
||||
# OSX won't update Bash 3 (last updated circa 2009) to Bash 4,
|
||||
# and we'd like this completion script to work on both Linux and Mac.
|
||||
#
|
||||
# For example, OSX Yosemite (released circa 2014) ships with Bash 3:
|
||||
#
|
||||
# $ echo $BASH_VERSION
|
||||
# 3.2
|
||||
#
|
||||
# While Ubuntu LTS 14.04 (a.k.a. Trusty, also released circa 2016)
|
||||
# ships with the latest version, Bash 4 (updated circa 2016):
|
||||
#
|
||||
# $ echo $BASH_VERSION
|
||||
# 4.3
|
||||
#
|
||||
|
||||
# Testing
|
||||
#
|
||||
# (1) Invoke « shellcheck »
|
||||
#
|
||||
# * source: « https://github.com/koalaman/shellcheck »
|
||||
# * run: « shellcheck ./share/bash-completion/completions/home-manager »
|
||||
#
|
||||
# (2) Interpret via Bash 3
|
||||
#
|
||||
# * run: « bash --noprofile --norc ./share/bash-completion/completions/home-manager »
|
||||
#
|
||||
|
||||
##################################################
|
||||
# Examples:
|
||||
|
||||
# $ home-manager <TAB>
|
||||
#
|
||||
# -A
|
||||
# -I
|
||||
# -f
|
||||
# --file
|
||||
# -h
|
||||
# --help
|
||||
# -n
|
||||
# --dry-run
|
||||
# -v
|
||||
# --verbose
|
||||
# build
|
||||
# edit
|
||||
# expire-generations
|
||||
# generations
|
||||
# help
|
||||
# news
|
||||
# packages
|
||||
# remove-generations
|
||||
# switch
|
||||
# uninstall
|
||||
|
||||
# $ home-manager e<TAB>
|
||||
#
|
||||
# edit
|
||||
# expire-generations
|
||||
|
||||
# $ home-manager remove-generations 20<TAB>
|
||||
#
|
||||
# 200
|
||||
# 201
|
||||
# 202
|
||||
# 203
|
||||
|
||||
##################################################
|
||||
# Notes:
|
||||
|
||||
# « home-manager » Subcommands:
|
||||
#
|
||||
# help
|
||||
# edit
|
||||
# build
|
||||
# switch
|
||||
# generations
|
||||
# remove-generations
|
||||
# expire-generations
|
||||
# packages
|
||||
# news
|
||||
# uninstall
|
||||
|
||||
# « home-manager » Options:
|
||||
#
|
||||
# -b EXT
|
||||
# -f FILE
|
||||
# --file FILE
|
||||
# -A ATTRIBUTE
|
||||
# -I PATH
|
||||
# -v
|
||||
# --verbose
|
||||
# -n
|
||||
# --dry-run
|
||||
# -h
|
||||
# --help
|
||||
|
||||
# $ home-manager
|
||||
#
|
||||
# Usage: /home/sboo/.nix-profile/bin/home-manager [OPTION] COMMAND
|
||||
#
|
||||
# Options
|
||||
#
|
||||
# -f FILE The home configuration file.
|
||||
# Default is '~/.config/nixpkgs/home.nix'.
|
||||
# -A ATTRIBUTE Optional attribute that selects a configuration
|
||||
# expression in the configuration file.
|
||||
# -I PATH Add a path to the Nix expression search path.
|
||||
# -b EXT Move existing files to new path rather than fail.
|
||||
# -v Verbose output
|
||||
# -n Do a dry run, only prints what actions would be taken
|
||||
# -h Print this help
|
||||
#
|
||||
# Commands
|
||||
#
|
||||
# help Print this help
|
||||
#
|
||||
# edit Open the home configuration in $EDITOR
|
||||
#
|
||||
# build Build configuration into result directory
|
||||
#
|
||||
# switch Build and activate configuration
|
||||
#
|
||||
# generations List all home environment generations
|
||||
#
|
||||
# remove-generations ID...
|
||||
# Remove indicated generations. Use 'generations' command to
|
||||
# find suitable generation numbers.
|
||||
#
|
||||
# expire-generations TIMESTAMP
|
||||
# Remove generations older than TIMESTAMP where TIMESTAMP is
|
||||
# interpreted as in the -d argument of the date tool. For
|
||||
# example "-30 days" or "2018-01-01".
|
||||
#
|
||||
# packages List all packages installed in home-manager-path
|
||||
#
|
||||
# news Show news entries in a pager
|
||||
#
|
||||
# uninstall Remove Home Manager
|
||||
#
|
||||
##################################################
|
||||
# Dependencies:
|
||||
|
||||
command -v home-manager >/dev/null
|
||||
command -v grep >/dev/null
|
||||
command -v sed >/dev/null
|
||||
|
||||
##################################################
|
||||
# Code:
|
||||
|
||||
_home-manager_list-generation-identifiers ()
|
||||
|
||||
{
|
||||
|
||||
home-manager generations | sed -n -e 's/^................ : id \([[:alnum:]]\+\) -> .*/\1/p'
|
||||
|
||||
}
|
||||
|
||||
# NOTES
|
||||
#
|
||||
# (1) the « sed -n -e 's/.../.../p' » invocation:
|
||||
#
|
||||
# * the « -e '...' » option takes a Sed Script.
|
||||
# * the « -n » option only prints when « .../p » would print.
|
||||
# * the « s/xxx/yyy/ » Sed Script substitutes « yyy » whenever « xxx » is matched.
|
||||
#
|
||||
# (2) the « '^................ : id \([[:alnum:]]\+\) -> .*' » regular expression:
|
||||
#
|
||||
# * matches « 199 », for example, in the line « 2019-03-13 15:26 : id 199 -> /nix/store/mv619y9pzgsx3kndq0q7fjfvbqqdy5k8-home-manager-generation »
|
||||
#
|
||||
#
|
||||
|
||||
#------------------------------------------------#
|
||||
|
||||
# shellcheck disable=SC2120
|
||||
_home-manager_list-nix-attributes ()
|
||||
|
||||
{
|
||||
local HomeFile
|
||||
local HomeAttrsString
|
||||
# local HomeAttrsArray
|
||||
# local HomeAttr
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
HomeFile=$(readlink -f "$(_home-manager_get-default-home-file)")
|
||||
else
|
||||
HomeFile="$1"
|
||||
fi
|
||||
|
||||
HomeAttrsString=$(nix-instantiate --eval -E "let home = import ${HomeFile}; in (builtins.trace (builtins.toString (builtins.attrNames home)) null)" |& grep '^trace: ')
|
||||
HomeAttrsString="${HomeAttrsString#trace: }"
|
||||
|
||||
echo "${HomeAttrsString}"
|
||||
|
||||
# IFS=" " read -ar HomeAttrsArray <<< "${HomeAttrsString}"
|
||||
#
|
||||
# local HomeAttr
|
||||
# for HomeAttr in "${HomeAttrsArray[@]}"
|
||||
# do
|
||||
# echo "${HomeAttr}"
|
||||
# done
|
||||
|
||||
}
|
||||
|
||||
# e.g.:
|
||||
#
|
||||
# $ nix-instantiate --eval -E 'let home = import /home/sboo/configuration/configs/nixpkgs/home-attrs.nix; in (builtins.trace (builtins.toString (builtins.attrNames home)) null)' 1>/dev/null
|
||||
# trace: darwin linux
|
||||
#
|
||||
# $ _home-manager_list-nix-attributes
|
||||
# linux darwin
|
||||
#
|
||||
|
||||
#------------------------------------------------#
|
||||
|
||||
_home-manager_get-default-home-file ()
|
||||
|
||||
{
|
||||
local HomeFileDefault
|
||||
|
||||
HomeFileDefault="$(_home-manager_xdg-get-config-home)/nixpkgs/home.nix"
|
||||
|
||||
echo "${HomeFileDefault}"
|
||||
}
|
||||
|
||||
# e.g.:
|
||||
#
|
||||
# $ _home-manager_get-default-home-file
|
||||
# ~/.config/nixpkgs/home.nix
|
||||
#
|
||||
|
||||
##################################################
|
||||
# XDG-BaseDirs:
|
||||
|
||||
_home-manager_xdg-get-config-home () {
|
||||
|
||||
echo "${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------#
|
||||
|
||||
_home-manager_xdg-get-data-home () {
|
||||
|
||||
echo "${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------#
|
||||
_home-manager_xdg-get-cache-home () {
|
||||
|
||||
echo "${XDG_CACHE_HOME:-$HOME/.cache}"
|
||||
|
||||
}
|
||||
|
||||
##################################################
|
||||
|
||||
# shellcheck disable=SC2207
|
||||
_home-manager_completions ()
|
||||
{
|
||||
|
||||
#--------------------------#
|
||||
|
||||
local Subcommands
|
||||
Subcommands=( "help" "edit" "build" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" )
|
||||
|
||||
# ^ « home-manager »'s subcommands.
|
||||
|
||||
#--------------------------#
|
||||
|
||||
local Options
|
||||
Options=( "-f" "--file" "-b" "-A" "-I" "-h" "--help" "-n" "--dry-run" "-v" "--verbose" "--show-trace" )
|
||||
|
||||
# ^ « home-manager »'s options.
|
||||
|
||||
#--------------------------#
|
||||
|
||||
local CurrentWord
|
||||
CurrentWord="${COMP_WORDS[$COMP_CWORD]}"
|
||||
|
||||
# ^ the word currently being completed
|
||||
|
||||
local PreviousWord
|
||||
if [ "$COMP_CWORD" -ge 1 ]
|
||||
then
|
||||
PreviousWord="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
else
|
||||
PreviousWord=""
|
||||
fi
|
||||
|
||||
# ^ the word to the left of the current word.
|
||||
#
|
||||
# e.g. in « home-manager -v -f ./<TAB> »:
|
||||
#
|
||||
# PreviousWord="-f"
|
||||
# CurrentWord="./"
|
||||
|
||||
#--------------------------#
|
||||
|
||||
COMPREPLY=()
|
||||
|
||||
case "$PreviousWord" in
|
||||
|
||||
"-f"|"--file")
|
||||
|
||||
COMPREPLY+=( $( compgen -A file -- "$CurrentWord") )
|
||||
;;
|
||||
|
||||
"-I")
|
||||
|
||||
COMPREPLY+=( $( compgen -A directory -- "$CurrentWord") )
|
||||
;;
|
||||
|
||||
"-A")
|
||||
|
||||
# shellcheck disable=SC2119
|
||||
COMPREPLY+=( $( compgen -W "$(_home-manager_list-nix-attributes)" -- "$CurrentWord") )
|
||||
;;
|
||||
|
||||
"remove-generations")
|
||||
|
||||
COMPREPLY+=( $( compgen -W "$(_home-manager_list-generation-identifiers)" -- "$CurrentWord" ) )
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
COMPREPLY+=( $( compgen -W "${Subcommands[*]}" -- "$CurrentWord" ) )
|
||||
COMPREPLY+=( $( compgen -W "${Options[*]}" -- "$CurrentWord" ) )
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
#--------------------------#
|
||||
}
|
||||
|
||||
##################################################
|
||||
|
||||
complete -F _home-manager_completions -o default home-manager
|
||||
|
||||
#complete -W "help edit build switch generations remove-generations expire-generations packages news" home-manager
|
||||
@@ -34,4 +34,7 @@ runCommand
|
||||
--subst-var-by gnused "${gnused}" \
|
||||
--subst-var-by less "${less}" \
|
||||
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
|
||||
|
||||
install -D -m755 ${./completion.bash} \
|
||||
$out/share/bash-completion/completions/home-manager
|
||||
''
|
||||
|
||||
@@ -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)"
|
||||
@@ -79,12 +93,14 @@ function doBuildAttr() {
|
||||
nix build \
|
||||
-f "<home-manager/home-manager/home-manager.nix>" \
|
||||
$extraArgs \
|
||||
"${PASSTHROUGH_OPTS[@]}" \
|
||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||
else
|
||||
nix-build \
|
||||
"<home-manager/home-manager/home-manager.nix>" \
|
||||
$extraArgs \
|
||||
"${PASSTHROUGH_OPTS[@]}" \
|
||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||
fi
|
||||
@@ -216,17 +232,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
|
||||
|
||||
@@ -246,6 +252,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"
|
||||
|
||||
@@ -347,6 +358,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
|
||||
@@ -357,10 +418,20 @@ function doHelp() {
|
||||
echo " -A ATTRIBUTE Optional attribute that selects a configuration"
|
||||
echo " expression in the configuration file."
|
||||
echo " -I PATH Add a path to the Nix expression search path."
|
||||
echo " -b EXT Move existing files to new path rather than fail."
|
||||
echo " -v Verbose output"
|
||||
echo " -n Do a dry run, only prints what actions would be taken"
|
||||
echo " -h Print this help"
|
||||
echo
|
||||
echo "Options passed on to nix-build(1)"
|
||||
echo
|
||||
echo " --cores NUM"
|
||||
echo " --keep-failed"
|
||||
echo " --keep-going"
|
||||
echo " --max-jobs NUM"
|
||||
echo " --option NAME VALUE"
|
||||
echo " --show-trace"
|
||||
echo
|
||||
echo "Commands"
|
||||
echo
|
||||
echo " help Print this help"
|
||||
@@ -385,63 +456,84 @@ 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=()
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE=""
|
||||
PASSTHROUGH_OPTS=()
|
||||
COMMAND=""
|
||||
COMMAND_ARGS=()
|
||||
|
||||
# As a special case, if the user has given --help anywhere on the
|
||||
# command line then print help and exit.
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == "--help" ]]; then
|
||||
doHelp
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
while getopts 2f:I:A:vnh opt; do
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$1"
|
||||
shift
|
||||
case $opt in
|
||||
2)
|
||||
build|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
|
||||
COMMAND="$opt"
|
||||
;;
|
||||
-2)
|
||||
USE_NIX2_COMMAND=1
|
||||
;;
|
||||
f)
|
||||
HOME_MANAGER_CONFIG="$OPTARG"
|
||||
-A)
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
|
||||
shift
|
||||
;;
|
||||
I)
|
||||
EXTRA_NIX_PATH+=("$OPTARG")
|
||||
-I)
|
||||
EXTRA_NIX_PATH+=("$1")
|
||||
shift
|
||||
;;
|
||||
A)
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
|
||||
-b)
|
||||
export HOME_MANAGER_BACKUP_EXT="$1"
|
||||
shift
|
||||
;;
|
||||
v)
|
||||
export VERBOSE=1
|
||||
-f|--file)
|
||||
HOME_MANAGER_CONFIG="$1"
|
||||
shift
|
||||
;;
|
||||
n)
|
||||
export DRY_RUN=1
|
||||
;;
|
||||
h)
|
||||
-h|--help)
|
||||
doHelp
|
||||
exit 0
|
||||
;;
|
||||
-n|--dry-run)
|
||||
export DRY_RUN=1
|
||||
;;
|
||||
--option)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||
shift 2
|
||||
;;
|
||||
--max-jobs|--cores)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||
shift
|
||||
;;
|
||||
--keep-failed|--keep-going|--show-trace)
|
||||
PASSTHROUGH_OPTS+=("$opt")
|
||||
;;
|
||||
-v|--verbose)
|
||||
export VERBOSE=1
|
||||
;;
|
||||
*)
|
||||
doHelp >&2
|
||||
exit 1
|
||||
case $COMMAND in
|
||||
expire-generations|remove-generations)
|
||||
COMMAND_ARGS+=("$opt")
|
||||
;;
|
||||
*)
|
||||
errorEcho "$0: unknown option '$opt'"
|
||||
errorEcho "Run '$0 --help' for usage help"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get rid of the options.
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
if [[ -z $COMMAND ]]; then
|
||||
doHelp >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd="$1"
|
||||
shift 1
|
||||
|
||||
case "$cmd" in
|
||||
case $COMMAND in
|
||||
edit)
|
||||
doEdit
|
||||
;;
|
||||
@@ -455,10 +547,15 @@ case "$cmd" in
|
||||
doListGens
|
||||
;;
|
||||
remove-generations)
|
||||
doRmGenerations "$@"
|
||||
doRmGenerations "${COMMAND_ARGS[@]}"
|
||||
;;
|
||||
expire-generations)
|
||||
doExpireGenerations "$@"
|
||||
if [[ ${#COMMAND_ARGS[@]} != 1 ]]; then
|
||||
errorEcho "expire-generations expects one argument, got ${#COMMAND_ARGS[@]}."
|
||||
exit 1
|
||||
else
|
||||
doExpireGenerations "${COMMAND_ARGS[@]}"
|
||||
fi
|
||||
;;
|
||||
packages)
|
||||
doListPackages
|
||||
@@ -466,11 +563,14 @@ case "$cmd" in
|
||||
news)
|
||||
doShowNews --all
|
||||
;;
|
||||
help|--help)
|
||||
uninstall)
|
||||
doUninstall
|
||||
;;
|
||||
help)
|
||||
doHelp
|
||||
;;
|
||||
*)
|
||||
errorEcho "Unknown command: $cmd"
|
||||
errorEcho "Unknown command: $COMMAND"
|
||||
doHelp >&2
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -6,6 +6,7 @@ runCommand
|
||||
propagatedBuildInputs = [ home-manager ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
shellHookOnly = true;
|
||||
shellHook = ''
|
||||
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
|
||||
|
||||
@@ -20,6 +21,16 @@ runCommand
|
||||
{
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
# This value determines the Home Manager release that your
|
||||
# configuration is compatible with. This helps avoid breakage
|
||||
# when a new Home Manager release introduces backwards
|
||||
# incompatible changes.
|
||||
#
|
||||
# You can update Home Manager without changing this value. See
|
||||
# the Home Manager release notes for a list of state version
|
||||
# changes in each release.
|
||||
home.stateVersion = "19.09";
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
@@ -53,4 +64,7 @@ runCommand
|
||||
fi
|
||||
'';
|
||||
}
|
||||
""
|
||||
''
|
||||
echo This derivation is not buildable, instead run it using nix-shell.
|
||||
exit 1
|
||||
''
|
||||
|
||||
@@ -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 = ''
|
||||
@@ -388,6 +388,7 @@ in
|
||||
mailAccountOpts
|
||||
(import ../programs/alot-accounts.nix pkgs)
|
||||
(import ../programs/astroid-accounts.nix)
|
||||
(import ../programs/getmail-accounts.nix)
|
||||
(import ../programs/mbsync-accounts.nix)
|
||||
(import ../programs/msmtp-accounts.nix)
|
||||
(import ../programs/notmuch-accounts.nix)
|
||||
|
||||
@@ -23,10 +23,6 @@ let
|
||||
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/*";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -49,23 +45,57 @@ in
|
||||
# overwrite an existing file.
|
||||
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
|
||||
let
|
||||
# Paths that should be forcibly overwritten by Home Manager.
|
||||
# Caveat emptor!
|
||||
forcedPaths =
|
||||
concatMapStringsSep " " (p: ''"$HOME/${p}"'')
|
||||
(mapAttrsToList (n: v: v.target)
|
||||
(filterAttrs (n: v: v.force) cfg));
|
||||
|
||||
check = pkgs.writeText "check" ''
|
||||
. ${./lib-bash/color-echo.sh}
|
||||
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
|
||||
|
||||
forcedPaths=(${forcedPaths})
|
||||
|
||||
newGenFiles="$1"
|
||||
shift
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" \
|
||||
&& ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
|
||||
errorEcho "Existing file '$targetPath' is in the way"
|
||||
collision=1
|
||||
|
||||
forced=""
|
||||
for forcedPath in "''${forcedPaths[@]}"; do
|
||||
if [[ $targetPath == $forcedPath* ]]; then
|
||||
forced="yeah"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n $forced ]]; then
|
||||
$VERBOSE_ECHO "Skipping collision check for $targetPath"
|
||||
elif [[ -e "$targetPath" \
|
||||
&& ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
if [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
if [[ -e "$backup" ]]; then
|
||||
errorEcho "Existing file '$backup' would be clobbered by backing up '$targetPath'"
|
||||
collision=1
|
||||
else
|
||||
warnEcho "Existing file '$targetPath' is in the way, will be moved to '$backup'"
|
||||
fi
|
||||
else
|
||||
errorEcho "Existing file '$targetPath' is in the way"
|
||||
collision=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -v collision ]] ; then
|
||||
errorEcho "Please move the above files and try again"
|
||||
errorEcho "Please move the above files and try again or use -b <ext> to move automatically."
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
@@ -74,8 +104,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
|
||||
@@ -111,6 +141,10 @@ in
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
$DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
|
||||
fi
|
||||
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
|
||||
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath"
|
||||
done
|
||||
@@ -119,13 +153,17 @@ in
|
||||
cleanup = pkgs.writeText "cleanup" ''
|
||||
. ${./lib-bash/color-echo.sh}
|
||||
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
|
||||
|
||||
newGenFiles="$1"
|
||||
shift 1
|
||||
for relativePath in "$@" ; do
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
||||
$VERBOSE_ECHO "Checking $targetPath: exists"
|
||||
elif [[ ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
|
||||
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
|
||||
else
|
||||
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
|
||||
@@ -155,8 +193,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() {
|
||||
@@ -222,6 +260,9 @@ in
|
||||
(''
|
||||
mkdir -p $out
|
||||
|
||||
# Needed in case /nix is a symbolic link.
|
||||
realOut="$(realpath -m "$out")"
|
||||
|
||||
function insertFile() {
|
||||
local source="$1"
|
||||
local relTarget="$2"
|
||||
@@ -230,10 +271,10 @@ in
|
||||
|
||||
# Figure out the real absolute path to the target.
|
||||
local target
|
||||
target="$(realpath -m "$out/$relTarget")"
|
||||
target="$(realpath -m "$realOut/$relTarget")"
|
||||
|
||||
# Target path must be within $HOME.
|
||||
if [[ ! $target == $out* ]] ; then
|
||||
if [[ ! $target == $realOut* ]] ; then
|
||||
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -55,16 +55,24 @@ let
|
||||
keyboardSubModule = types.submodule {
|
||||
options = {
|
||||
layout = mkOption {
|
||||
type = types.str;
|
||||
default = "us";
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "us";
|
||||
defaultText = literalExample "null";
|
||||
description = ''
|
||||
Keyboard layout.
|
||||
Keyboard layout. If <literal>null</literal>, then the system
|
||||
configuration will be used.
|
||||
</para><para>
|
||||
This defaults to <literal>null</literal> for state
|
||||
version ≥ 19.09 and <literal>"us"</literal> otherwise.
|
||||
'';
|
||||
};
|
||||
|
||||
model = mkOption {
|
||||
type = types.str;
|
||||
default = "pc104";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "presario";
|
||||
description = ''
|
||||
Keyboard model.
|
||||
@@ -81,11 +89,19 @@ let
|
||||
};
|
||||
|
||||
variant = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "";
|
||||
defaultText = literalExample "null";
|
||||
example = "colemak";
|
||||
description = ''
|
||||
X keyboard variant.
|
||||
X keyboard variant. If <literal>null</literal>, then the
|
||||
system configuration will be used.
|
||||
</para><para>
|
||||
This defaults to <literal>null</literal> for state
|
||||
version ≥ 19.09 and <literal>""</literal> otherwise.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -149,7 +165,7 @@ in
|
||||
|
||||
home.sessionVariables = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (either int str);
|
||||
type = types.attrs;
|
||||
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
||||
description = ''
|
||||
Environment variables to always set at login.
|
||||
@@ -167,19 +183,19 @@ in
|
||||
variable may have a runtime dependency on another session
|
||||
variable. In particular code like
|
||||
<programlisting language="nix">
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "$FOO World!";
|
||||
};
|
||||
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 language="nix">
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
@@ -370,7 +386,7 @@ in
|
||||
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||
|
||||
activationScript = pkgs.writeScript "activation-script" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
@@ -86,6 +86,18 @@ in
|
||||
into place.
|
||||
'';
|
||||
};
|
||||
|
||||
force = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
visible = false;
|
||||
description = ''
|
||||
Whether the target path should be unconditionally replaced
|
||||
by the managed file source. Warning, this will silently
|
||||
delete the target regardless of whether it is a file or
|
||||
link.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
28
modules/lib/types.nix
Normal file
28
modules/lib/types.nix
Normal file
@@ -0,0 +1,28 @@
|
||||
{ lib }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
selectorFunction = mkOptionType {
|
||||
name = "selectorFunction";
|
||||
description =
|
||||
"Function that takes an attribute set and returns a list"
|
||||
+ " containing a selection of the values of the input set";
|
||||
check = isFunction;
|
||||
merge = _loc: defs:
|
||||
as: concatMap (select: select as) (getValues defs);
|
||||
};
|
||||
|
||||
overlayFunction = mkOptionType {
|
||||
name = "overlayFunction";
|
||||
description =
|
||||
"An overlay function, takes self and super and returns"
|
||||
+ " an attribute set overriding the desired attributes.";
|
||||
check = isFunction;
|
||||
merge = _loc: defs:
|
||||
self: super:
|
||||
foldl' (res: def: mergeAttrs res (def.value self super)) {} defs;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{ config, lib, pkgs, baseModules, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@@ -6,55 +6,7 @@ let
|
||||
|
||||
cfg = config.manual;
|
||||
|
||||
/* For the purpose of generating docs, evaluate options with each derivation
|
||||
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
|
||||
It isn't perfect, but it seems to cover a vast majority of use cases.
|
||||
Caveat: even if the package is reached by a different means,
|
||||
the path above will be shown and not e.g. `${config.services.foo.package}`. */
|
||||
homeManagerManual = import ../doc {
|
||||
inherit pkgs config;
|
||||
version = "0.1";
|
||||
revision = "master";
|
||||
options =
|
||||
let
|
||||
scrubbedEval = evalModules {
|
||||
modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules;
|
||||
args = (config._module.args) // { modules = [ ]; };
|
||||
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
|
||||
};
|
||||
scrubDerivations = namePrefix: pkgSet: mapAttrs
|
||||
(name: value:
|
||||
let wholeName = "${namePrefix}.${name}"; in
|
||||
if isAttrs value then
|
||||
scrubDerivations wholeName value
|
||||
// (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
|
||||
else value
|
||||
)
|
||||
pkgSet;
|
||||
in scrubbedEval.options;
|
||||
};
|
||||
|
||||
manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";
|
||||
|
||||
helpScript = pkgs.writeShellScriptBin "home-manager-help" ''
|
||||
#!${pkgs.bash}/bin/bash -e
|
||||
|
||||
if [ -z "$BROWSER" ]; then
|
||||
for candidate in xdg-open open w3m; do
|
||||
BROWSER="$(type -P $candidate || true)"
|
||||
if [ -x "$BROWSER" ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$BROWSER" ]; then
|
||||
echo "$0: unable to start a web browser; please set \$BROWSER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec "$BROWSER" ${manualHtmlRoot}
|
||||
'';
|
||||
docs = import ../doc { inherit pkgs; };
|
||||
|
||||
in
|
||||
|
||||
@@ -100,15 +52,17 @@ in
|
||||
|
||||
config = {
|
||||
home.packages = mkMerge [
|
||||
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
|
||||
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
|
||||
(mkIf cfg.json.enable [ homeManagerManual.optionsJSON ])
|
||||
(mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ])
|
||||
(mkIf cfg.manpages.enable [ docs.manPages ])
|
||||
(mkIf cfg.json.enable [ docs.options.json ])
|
||||
];
|
||||
|
||||
# Whether a dependency on nmd should be introduced.
|
||||
home.extraBuilderCommands =
|
||||
mkIf (cfg.html.enable || cfg.manpages.enable || cfg.json.enable) ''
|
||||
mkdir $out/lib
|
||||
ln -s ${docs.nmdSrc} $out/lib/nmd
|
||||
'';
|
||||
};
|
||||
|
||||
# To fix error during manpage build.
|
||||
meta = {
|
||||
maintainers = [ maintainers.rycee ];
|
||||
doc = builtins.toFile "nothingness" "";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,9 +13,15 @@ let
|
||||
let
|
||||
tweakVal = v:
|
||||
if isString v then "'${v}'"
|
||||
else if isList v then "[" + concatMapStringsSep "," tweakVal 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}";
|
||||
|
||||
|
||||
@@ -6,36 +6,100 @@ let
|
||||
|
||||
cfg = config.fonts.fontconfig;
|
||||
|
||||
profileDirectory = config.home.profileDirectory;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule
|
||||
[ "fonts" "fontconfig" "enableProfileFonts" ]
|
||||
[ "fonts" "fontconfig" "enable" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
fonts.fontconfig = {
|
||||
enableProfileFonts = mkOption {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Configure fontconfig to discover fonts installed through
|
||||
Whether to enable fontconfig configuration. This will, for
|
||||
example, allow fontconfig to discover fonts and
|
||||
configurations installed through
|
||||
<varname>home.packages</varname> and
|
||||
<command>nix-env</command>.
|
||||
</para><para>
|
||||
Note, this is only necessary on non-NixOS systems.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enableProfileFonts {
|
||||
xdg.configFile."fontconfig/conf.d/10-nix-profile-fonts.conf".text = ''
|
||||
config = mkIf cfg.enable {
|
||||
# Create two dummy files in /lib/fontconfig to make sure that
|
||||
# buildEnv creates a real directory path. These files are removed
|
||||
# in home.extraProfileCommands below so the packages will not
|
||||
# become "runtime" dependencies.
|
||||
home.packages = [
|
||||
(pkgs.writeTextFile {
|
||||
name = "hm-dummy1";
|
||||
destination = "/lib/fontconfig/hm-dummy1";
|
||||
text = "dummy";
|
||||
})
|
||||
|
||||
(pkgs.writeTextFile {
|
||||
name = "hm-dummy2";
|
||||
destination = "/lib/fontconfig/hm-dummy2";
|
||||
text = "dummy";
|
||||
})
|
||||
];
|
||||
|
||||
home.extraProfileCommands = ''
|
||||
if [[ -d $out/lib/X11/fonts || -d $out/share/fonts ]]; then
|
||||
export FONTCONFIG_FILE="$(pwd)/fonts.conf"
|
||||
|
||||
cat > $FONTCONFIG_FILE << EOF
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<dir>${config.home.profileDirectory}/lib/X11/fonts</dir>
|
||||
<dir>${config.home.profileDirectory}/share/fonts</dir>
|
||||
<dir>$out/lib/X11/fonts</dir>
|
||||
<dir>$out/share/fonts</dir>
|
||||
<cachedir>$out/lib/fontconfig/cache</cachedir>
|
||||
</fontconfig>
|
||||
EOF
|
||||
|
||||
${getBin pkgs.fontconfig}/bin/fc-cache -f
|
||||
rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG
|
||||
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig/cache
|
||||
|
||||
rm "$FONTCONFIG_FILE"
|
||||
unset FONTCONFIG_FILE
|
||||
fi
|
||||
|
||||
# Remove hacky dummy files.
|
||||
rm $out/lib/fontconfig/hm-dummy?
|
||||
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
|
||||
'';
|
||||
|
||||
xdg.configFile = {
|
||||
"fontconfig/conf.d/10-hm-fonts.conf".text = ''
|
||||
<?xml version='1.0'?>
|
||||
|
||||
<!-- Generated by Home Manager. -->
|
||||
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/conf.d</include>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/fonts.conf</include>
|
||||
|
||||
<dir>${config.home.path}/lib/X11/fonts</dir>
|
||||
<dir>${config.home.path}/share/fonts</dir>
|
||||
<dir>${profileDirectory}/lib/X11/fonts</dir>
|
||||
<dir>${profileDirectory}/share/fonts</dir>
|
||||
|
||||
<cachedir>${config.home.path}/lib/fontconfig/cache</cachedir>
|
||||
</fontconfig>
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1065,6 +1065,189 @@ in
|
||||
A new module is available: 'programs.alacritty'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-04-26T22:53:48+00:00";
|
||||
condition = config.programs.vscode.enable;
|
||||
message = ''
|
||||
A new module is available: 'programs.vscode.haskell'.
|
||||
|
||||
Enable to add Haskell IDE Engine and syntax highlighting
|
||||
support to your VSCode.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-05-04T23:56:39+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.rsibreak'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-05-07T20:49:29+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.mpv'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-05-30T17:49:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.xsuspender'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-06-03T21:47:10+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.gpg'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-06-09T12:19:18+00:00";
|
||||
message = ''
|
||||
Collisions between unmanaged and managed files can now be
|
||||
automatically resolved by moving the target file to a new
|
||||
path instead of failing the switch operation. To enable
|
||||
this, use the new '-b' command line argument. For example,
|
||||
|
||||
home-manager -b bck switch
|
||||
|
||||
where 'bck' is the suffix to give the moved file. In this
|
||||
case a colliding file 'foo.conf' will be moved to
|
||||
'foo.conf.bck'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-06-19T17:49:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: `services.getmail`.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-07-02T09:27:56+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.broot'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-07-17T19:30:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.taskwarrior-sync'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-07-17T20:05:29+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.kakoune'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-08T11:49:35+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.hound'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-17T12:24:58+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.muchsync'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-18T14:22:41+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.dwm-status'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-28T10:18:07+00:00";
|
||||
condition = config.programs.vim.enable;
|
||||
message = ''
|
||||
The 'programs.vim.plugins' option now accepts packages.
|
||||
Specifying them as strings is deprecated.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-09-17T19:33:49+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.sxhkd'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-09-26T21:05:24+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.starship'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-09-26T21:47:13+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.rtorrent'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-12-10T19:58:00+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.lorri'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-02-16T17:07:44+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.readline'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-15T16:55:28+00:00";
|
||||
condition = config.programs.firefox.enable;
|
||||
message = ''
|
||||
In anticipation of Firefox dropping support for extension
|
||||
sideloading[1], we now install extensions directly to
|
||||
Firefox profiles managed through Home Manager's
|
||||
|
||||
'programs.firefox.profiles'
|
||||
|
||||
option.
|
||||
|
||||
Unfortunately this will most likely trigger an "Existing
|
||||
file is in the way" error when activating your configuration
|
||||
since Firefox keeps a copy of the add-on in the location
|
||||
Home Manager wants to overwrite. If this is the case, remove
|
||||
the listed '.xpi' files and try again.
|
||||
|
||||
This change also means that extensions installed through
|
||||
Home Manager may disappear from unmanaged profiles in future
|
||||
Firefox releases.
|
||||
|
||||
[1] https://blog.mozilla.org/addons/2019/10/31/firefox-to-discontinue-sideloaded-extensions/
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,8 +82,7 @@ in
|
||||
|
||||
<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.
|
||||
|
||||
35
modules/misc/numlock.nix
Normal file
35
modules/misc/numlock.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xsession.numlock;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
xsession.numlock.enable = mkEnableOption "Num Lock";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.numlockx = {
|
||||
Unit = {
|
||||
Description = "NumLockX";
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${pkgs.numlockx}/bin/numlockx";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -14,7 +14,7 @@ in
|
||||
options = {
|
||||
pam.sessionVariables = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (either int str);
|
||||
type = types.attrs;
|
||||
example = { EDITOR = "vim"; };
|
||||
description = ''
|
||||
Environment variables that will be set for the PAM session.
|
||||
|
||||
@@ -65,8 +65,7 @@ in
|
||||
then [ pkgs.qgnomeplatform ]
|
||||
else [ pkgs.libsForQt5.qtstyleplugins ];
|
||||
|
||||
xsession.profileExtra =
|
||||
"systemctl --user import-environment QT_QPA_PLATFORMTHEME";
|
||||
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ];
|
||||
|
||||
# Enable GTK+ style for Qt4 in either case.
|
||||
# It doesn’t support the platform theme packages.
|
||||
|
||||
@@ -25,7 +25,7 @@ with lib;
|
||||
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>.
|
||||
<option>users.users.‹name?›.packages</option>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
92
modules/misc/xdg-mime-apps.nix
Normal file
92
modules/misc/xdg-mime-apps.nix
Normal file
@@ -0,0 +1,92 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.mimeApps;
|
||||
|
||||
strListOrSingleton = with types;
|
||||
coercedTo (either (listOf str) str) toList (listOf str);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
|
||||
options.xdg.mimeApps = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to manage <filename>$XDG_CONFIG_HOME/mimeapps.list</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The generated file is read-only.
|
||||
'';
|
||||
};
|
||||
|
||||
# descriptions from
|
||||
# https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-1.0.1.html
|
||||
|
||||
associations.added = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"mimetype1" = [ "foo1.desktop" "foo2.desktop" "foo3.desktop" ];
|
||||
"mimetype2" = "foo4.desktop";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Defines additional associations of applications with
|
||||
mimetypes, as if the .desktop file was listing this mimetype
|
||||
in the first place.
|
||||
'';
|
||||
};
|
||||
|
||||
associations.removed = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = { "mimetype1" = "foo5.desktop"; };
|
||||
description = ''
|
||||
Removes associations of applications with mimetypes, as if the
|
||||
.desktop file was <emphasis>not</emphasis> listing this
|
||||
mimetype in the first place.
|
||||
'';
|
||||
};
|
||||
|
||||
defaultApplications = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"mimetype1" = [ "default1.desktop" "default2.desktop" ];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
The default application to be used for a given mimetype. This
|
||||
is, for instance, the one that will be started when
|
||||
double-clicking on a file in a file manager. If the
|
||||
application is no longer installed, the next application in
|
||||
the list is attempted, and so on.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Deprecated but still used by some applications.
|
||||
home.file.".local/share/applications/mimeapps.list".source =
|
||||
config.xdg.configFile."mimeapps.list".source;
|
||||
|
||||
xdg.configFile."mimeapps.list".text =
|
||||
let
|
||||
joinValues = mapAttrs (n: concatStringsSep ";");
|
||||
in
|
||||
generators.toINI {} {
|
||||
"Added Associations" = joinValues cfg.associations.added;
|
||||
"Removed Associations" = joinValues cfg.associations.removed;
|
||||
"Default Applications" = joinValues cfg.defaultApplications;
|
||||
};
|
||||
};
|
||||
}
|
||||
100
modules/misc/xdg-user-dirs.nix
Normal file
100
modules/misc/xdg-user-dirs.nix
Normal file
@@ -0,0 +1,100 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.userDirs;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
|
||||
options.xdg.userDirs = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to manage <filename>$XDG_CONFIG_HOME/user-dirs.dirs</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The generated file is read-only.
|
||||
'';
|
||||
};
|
||||
|
||||
# Well-known directory list from
|
||||
# https://gitlab.freedesktop.org/xdg/xdg-user-dirs/blob/master/man/user-dirs.dirs.xml
|
||||
|
||||
desktop = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Desktop";
|
||||
description = "The Desktop directory.";
|
||||
};
|
||||
|
||||
documents = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Documents";
|
||||
description = "The Documents directory.";
|
||||
};
|
||||
|
||||
download = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Downloads";
|
||||
description = "The Downloads directory.";
|
||||
};
|
||||
|
||||
music = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Music";
|
||||
description = "The Music directory.";
|
||||
};
|
||||
|
||||
pictures = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Pictures";
|
||||
description = "The Pictures directory.";
|
||||
};
|
||||
|
||||
publishShare = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Public";
|
||||
description = "The Public share directory.";
|
||||
};
|
||||
|
||||
templates = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Templates";
|
||||
description = "The Templates directory.";
|
||||
};
|
||||
|
||||
videos = mkOption {
|
||||
type = types.str;
|
||||
default = "$HOME/Videos";
|
||||
description = "The Videos directory.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
default = { };
|
||||
example = { XDG_MISC_DIR = "$HOME/Misc"; };
|
||||
description = "Other user directories.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
xdg.configFile."user-dirs.dirs".text = generators.toKeyValue {} (
|
||||
{
|
||||
XDG_DESKTOP_DIR = cfg.desktop;
|
||||
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||
XDG_DOWNLOAD_DIR = cfg.download;
|
||||
XDG_MUSIC_DIR = cfg.music;
|
||||
XDG_PICTURES_DIR = cfg.pictures;
|
||||
XDG_PUBLICSHARE_DIR = cfg.publishShare;
|
||||
XDG_TEMPLATES_DIR = cfg.templates;
|
||||
XDG_VIDEOS_DIR = cfg.videos;
|
||||
}
|
||||
// cfg.extraConfig
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -92,10 +92,13 @@ in
|
||||
})
|
||||
|
||||
{
|
||||
home.file = mkMerge [ cfg.configFile cfg.dataFile ];
|
||||
home.activation.xdgCreateCache = dag.entryAfter [ "writeBoundary" ] ''
|
||||
$DRY_RUN_CMD mkdir $VERBOSE_ARG -m0700 -p "${config.xdg.cacheHome}"
|
||||
'';
|
||||
home.file = mkMerge [
|
||||
cfg.configFile
|
||||
cfg.dataFile
|
||||
{
|
||||
"${config.xdg.cacheHome}/.keep".text = "";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -28,10 +28,13 @@ let
|
||||
(loadModule ./misc/lib.nix { })
|
||||
(loadModule ./misc/news.nix { })
|
||||
(loadModule ./misc/nixpkgs.nix { })
|
||||
(loadModule ./misc/numlock.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/pam.nix { })
|
||||
(loadModule ./misc/qt.nix { })
|
||||
(loadModule ./misc/submodule-support.nix { })
|
||||
(loadModule ./misc/version.nix { })
|
||||
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg.nix { })
|
||||
(loadModule ./programs/afew.nix { })
|
||||
(loadModule ./programs/alacritty.nix { })
|
||||
@@ -41,6 +44,7 @@ let
|
||||
(loadModule ./programs/bash.nix { })
|
||||
(loadModule ./programs/bat.nix { })
|
||||
(loadModule ./programs/beets.nix { })
|
||||
(loadModule ./programs/broot.nix { })
|
||||
(loadModule ./programs/browserpass.nix { })
|
||||
(loadModule ./programs/chromium.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/command-not-found/command-not-found.nix { })
|
||||
@@ -51,14 +55,17 @@ let
|
||||
(loadModule ./programs/firefox.nix { })
|
||||
(loadModule ./programs/fish.nix { })
|
||||
(loadModule ./programs/fzf.nix { })
|
||||
(loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/git.nix { })
|
||||
(loadModule ./programs/gnome-terminal.nix { })
|
||||
(loadModule ./programs/go.nix { })
|
||||
(loadModule ./programs/gpg.nix { })
|
||||
(loadModule ./programs/home-manager.nix { })
|
||||
(loadModule ./programs/htop.nix { })
|
||||
(loadModule ./programs/info.nix { })
|
||||
(loadModule ./programs/irssi.nix { })
|
||||
(loadModule ./programs/jq.nix { })
|
||||
(loadModule ./programs/kakoune.nix { })
|
||||
(loadModule ./programs/keychain.nix { })
|
||||
(loadModule ./programs/lesspipe.nix { })
|
||||
(loadModule ./programs/lsd.nix { })
|
||||
@@ -66,6 +73,7 @@ let
|
||||
(loadModule ./programs/matplotlib.nix { })
|
||||
(loadModule ./programs/mbsync.nix { })
|
||||
(loadModule ./programs/mercurial.nix { })
|
||||
(loadModule ./programs/mpv.nix { })
|
||||
(loadModule ./programs/msmtp.nix { })
|
||||
(loadModule ./programs/neovim.nix { })
|
||||
(loadModule ./programs/newsboat.nix { })
|
||||
@@ -75,8 +83,11 @@ let
|
||||
(loadModule ./programs/offlineimap.nix { })
|
||||
(loadModule ./programs/opam.nix { })
|
||||
(loadModule ./programs/pidgin.nix { })
|
||||
(loadModule ./programs/readline.nix { })
|
||||
(loadModule ./programs/rofi.nix { })
|
||||
(loadModule ./programs/rtorrent.nix { })
|
||||
(loadModule ./programs/skim.nix { })
|
||||
(loadModule ./programs/starship.nix { })
|
||||
(loadModule ./programs/ssh.nix { })
|
||||
(loadModule ./programs/taskwarrior.nix { })
|
||||
(loadModule ./programs/termite.nix { })
|
||||
@@ -85,22 +96,30 @@ let
|
||||
(loadModule ./programs/urxvt.nix { })
|
||||
(loadModule ./programs/vim.nix { })
|
||||
(loadModule ./programs/vscode.nix { })
|
||||
(loadModule ./programs/vscode/haskell.nix { })
|
||||
(loadModule ./programs/z-lua.nix { })
|
||||
(loadModule ./programs/zathura.nix { })
|
||||
(loadModule ./programs/zsh.nix { })
|
||||
(loadModule ./services/blueman-applet.nix { })
|
||||
(loadModule ./services/compton.nix { })
|
||||
(loadModule ./services/dunst.nix { })
|
||||
(loadModule ./services/dwm-status.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/emacs.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/flameshot.nix { })
|
||||
(loadModule ./services/getmail.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/gnome-keyring.nix { })
|
||||
(loadModule ./services/gpg-agent.nix { })
|
||||
(loadModule ./services/hound.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/kbfs.nix { })
|
||||
(loadModule ./services/kdeconnect.nix { })
|
||||
(loadModule ./services/keepassx.nix { })
|
||||
(loadModule ./services/keybase.nix { })
|
||||
(loadModule ./services/lorri.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/mbsync.nix { })
|
||||
(loadModule ./services/mpd.nix { })
|
||||
(loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/muchsync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/network-manager-applet.nix { })
|
||||
(loadModule ./services/nextcloud-client.nix { })
|
||||
(loadModule ./services/owncloud-client.nix { })
|
||||
@@ -109,12 +128,15 @@ let
|
||||
(loadModule ./services/polybar.nix { })
|
||||
(loadModule ./services/random-background.nix { })
|
||||
(loadModule ./services/redshift.nix { })
|
||||
(loadModule ./services/rsibreak.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/screen-locker.nix { })
|
||||
(loadModule ./services/stalonetray.nix { })
|
||||
(loadModule ./services/status-notifier-watcher.nix { })
|
||||
(loadModule ./services/sxhkd.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/syncthing.nix { })
|
||||
(loadModule ./services/taffybar.nix { })
|
||||
(loadModule ./services/tahoe-lafs.nix { })
|
||||
(loadModule ./services/taskwarrior-sync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/udiskie.nix { })
|
||||
(loadModule ./services/unclutter.nix { })
|
||||
(loadModule ./services/window-managers/awesome.nix { })
|
||||
@@ -123,6 +145,7 @@ let
|
||||
(loadModule ./services/xcape.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/xembed-sni-proxy.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/xscreensaver.nix { })
|
||||
(loadModule ./services/xsuspender.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./systemd.nix { })
|
||||
(loadModule ./xcursor.nix { })
|
||||
(loadModule ./xresources.nix { })
|
||||
|
||||
@@ -41,10 +41,13 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.alacritty ];
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
home.packages = [ pkgs.alacritty ];
|
||||
|
||||
xdg.configFile."alacritty/alacritty.yml".text =
|
||||
replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings);
|
||||
};
|
||||
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != {}) {
|
||||
text = replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ let
|
||||
realname = realName;
|
||||
sendmail_command =
|
||||
optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
|
||||
sent_box = "maildir" + "://" + maildir.absPath + "/" + folders.sent;
|
||||
draft_box = "maildir" + "://"+ maildir.absPath + "/" + folders.drafts;
|
||||
}
|
||||
// optionalAttrs (aliases != []) {
|
||||
aliases = concatStringsSep "," aliases;
|
||||
@@ -36,11 +38,10 @@ let
|
||||
boolStr (signature.showSignature == "attach");
|
||||
}
|
||||
)
|
||||
++ [ alot.extraConfig ]
|
||||
++ [ "[[[abook]]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion
|
||||
)
|
||||
+ "\n"
|
||||
+ alot.extraConfig;
|
||||
);
|
||||
|
||||
configFile =
|
||||
let
|
||||
|
||||
@@ -20,9 +20,9 @@ let
|
||||
sendmail = astroid.sendMailCommand;
|
||||
additional_sent_tags = "";
|
||||
default = boolOpt primary;
|
||||
save_drafts_to = folders.drafts;
|
||||
save_drafts_to = "${maildir.absPath}/${folders.drafts}";
|
||||
save_sent = "true";
|
||||
save_sent_to = folders.sent;
|
||||
save_sent_to = "${maildir.absPath}/${folders.sent}";
|
||||
select_query = "";
|
||||
}
|
||||
// optionalAttrs (signature.showSignature != "none") {
|
||||
@@ -106,14 +106,6 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.programs.notmuch.maildir.synchronizeFlags;
|
||||
message = "The astroid module requires"
|
||||
+ " 'programs.notmuch.maildir.synchronizeFlags = true'.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = [ pkgs.astroid ];
|
||||
|
||||
xdg.configFile."astroid/config".source =
|
||||
|
||||
@@ -72,7 +72,7 @@ in
|
||||
|
||||
sessionVariables = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (either int str);
|
||||
type = types.attrs;
|
||||
example = { MAILCHECK = 30; };
|
||||
description = ''
|
||||
Environment variables that will be set for the Bash session.
|
||||
@@ -123,6 +123,15 @@ in
|
||||
interactive shell.
|
||||
'';
|
||||
};
|
||||
|
||||
logoutExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Extra commands that should be run when logging out of an
|
||||
interactive shell.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -195,6 +204,14 @@ in
|
||||
${cfg.bashrcExtra}
|
||||
'';
|
||||
|
||||
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
|
||||
text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
${cfg.logoutExtra}
|
||||
'';
|
||||
};
|
||||
|
||||
home.packages =
|
||||
optional (cfg.enableAutojump) pkgs.autojump;
|
||||
}
|
||||
|
||||
261
modules/programs/broot.nix
Normal file
261
modules/programs/broot.nix
Normal file
@@ -0,0 +1,261 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.broot;
|
||||
|
||||
configFile = config:
|
||||
pkgs.runCommand "conf.toml"
|
||||
{
|
||||
buildInputs = [ pkgs.remarshal ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
''
|
||||
remarshal -if json -of toml \
|
||||
< ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \
|
||||
> $out
|
||||
'';
|
||||
|
||||
brootConf = {
|
||||
verbs =
|
||||
mapAttrsToList
|
||||
(name: value: value // { invocation = name; })
|
||||
cfg.verbs;
|
||||
skin = cfg.skin;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.aheaume ];
|
||||
|
||||
options.programs.broot = {
|
||||
enable = mkEnableOption "Broot, a better way to navigate directories";
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
verbs = mkOption {
|
||||
type = with types; attrsOf (attrsOf (either bool str));
|
||||
default = {
|
||||
"p" = { execution = ":parent"; };
|
||||
"edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; };
|
||||
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
|
||||
"view" = { execution = "less {file}"; };
|
||||
};
|
||||
example = literalExample ''
|
||||
{
|
||||
"p" = { execution = ":parent"; };
|
||||
"edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; };
|
||||
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
|
||||
"view" = { execution = "less {file}"; };
|
||||
"blop {name}\\.{type}" = {
|
||||
execution = "/bin/mkdir {parent}/{type} && /usr/bin/nvim {parent}/{type}/{name}.{type}";
|
||||
from_shell = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Define new verbs. The attribute name indicates how the verb is
|
||||
called by the user, with placeholders for arguments.
|
||||
</para><para>
|
||||
The possible attributes are:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>execution</literal> (mandatory)</term>
|
||||
<listitem><para>how the verb is executed</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>shortcut</literal> (optional)</term>
|
||||
<listitem><para>an alternate way to call the verb (without
|
||||
the arguments part)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>leave_broot</literal> (optional)</term>
|
||||
<listitem><para>whether to quit broot on execution
|
||||
(default: <literal>true</literal>)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>from_shell</literal> (optional)</term>
|
||||
<listitem><para>whether the verb must be executed from the
|
||||
parent shell (default:
|
||||
<literal>false</literal>)</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
};
|
||||
|
||||
skin = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
status_normal_fg = "grayscale(18)";
|
||||
status_normal_bg = "grayscale(3)";
|
||||
status_error_fg = "red";
|
||||
status_error_bg = "yellow";
|
||||
tree_fg = "red";
|
||||
selected_line_bg = "grayscale(7)";
|
||||
permissions_fg = "grayscale(12)";
|
||||
size_bar_full_bg = "red";
|
||||
size_bar_void_bg = "black";
|
||||
directory_fg = "lightyellow";
|
||||
input_fg = "cyan";
|
||||
flag_value_fg = "lightyellow";
|
||||
table_border_fg = "red";
|
||||
code_fg = "lightyellow";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Color configuration.
|
||||
</para><para>
|
||||
Complete list of keys (expected to change before the v1 of broot):
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>char_match</literal></para></listitem>
|
||||
<listitem><para><literal>code</literal></para></listitem>
|
||||
<listitem><para><literal>directory</literal></para></listitem>
|
||||
<listitem><para><literal>exe</literal></para></listitem>
|
||||
<listitem><para><literal>file</literal></para></listitem>
|
||||
<listitem><para><literal>file_error</literal></para></listitem>
|
||||
<listitem><para><literal>flag_label</literal></para></listitem>
|
||||
<listitem><para><literal>flag_value</literal></para></listitem>
|
||||
<listitem><para><literal>input</literal></para></listitem>
|
||||
<listitem><para><literal>link</literal></para></listitem>
|
||||
<listitem><para><literal>permissions</literal></para></listitem>
|
||||
<listitem><para><literal>selected_line</literal></para></listitem>
|
||||
<listitem><para><literal>size_bar_full</literal></para></listitem>
|
||||
<listitem><para><literal>size_bar_void</literal></para></listitem>
|
||||
<listitem><para><literal>size_text</literal></para></listitem>
|
||||
<listitem><para><literal>spinner</literal></para></listitem>
|
||||
<listitem><para><literal>status_error</literal></para></listitem>
|
||||
<listitem><para><literal>status_normal</literal></para></listitem>
|
||||
<listitem><para><literal>table_border</literal></para></listitem>
|
||||
<listitem><para><literal>tree</literal></para></listitem>
|
||||
<listitem><para><literal>unlisted</literal></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>
|
||||
Add <literal>_fg</literal> for a foreground color and
|
||||
<literal>_bg</literal> for a background colors.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.broot ];
|
||||
|
||||
xdg.configFile."broot/conf.toml".source = configFile brootConf;
|
||||
|
||||
# Dummy file to prevent broot from trying to reinstall itself
|
||||
xdg.configFile."broot/launcher/installed".text = "";
|
||||
|
||||
programs.bash.initExtra =
|
||||
mkIf cfg.enableBashIntegration (
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br {
|
||||
f=$(mktemp)
|
||||
(
|
||||
set +e
|
||||
broot --outcmd "$f" "$@"
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
rm -f "$f"
|
||||
exit "$code"
|
||||
fi
|
||||
)
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
return "$code"
|
||||
fi
|
||||
d=$(cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
}
|
||||
''
|
||||
);
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br {
|
||||
f=$(mktemp)
|
||||
(
|
||||
set +e
|
||||
broot --outcmd "$f" "$@"
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
rm -f "$f"
|
||||
exit "$code"
|
||||
fi
|
||||
)
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
return "$code"
|
||||
fi
|
||||
d=$(cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
}
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br
|
||||
set f (mktemp)
|
||||
broot --outcmd $f $argv
|
||||
if test $status -ne 0
|
||||
rm -f "$f"
|
||||
return "$code"
|
||||
end
|
||||
set d (cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
end
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -32,11 +32,11 @@ in {
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
]
|
||||
else if x == "chromium" then
|
||||
@@ -46,11 +46,11 @@ in {
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
]
|
||||
else if x == "firefox" then
|
||||
@@ -59,7 +59,7 @@ in {
|
||||
then "Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else ".mozilla/native-messaging-hosts")
|
||||
+ "/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/lib/mozilla/native-messaging-hosts/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
|
||||
} ]
|
||||
else if x == "vivaldi" then
|
||||
let dir = if isDarwin
|
||||
@@ -68,11 +68,11 @@ in {
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.github.browserpass.native.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
source = "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
]
|
||||
else throw "unknown browser ${x}") config.programs.browserpass.browsers);
|
||||
|
||||
@@ -21,7 +21,7 @@ let
|
||||
inherit visible;
|
||||
type = types.package;
|
||||
default = defaultPkg;
|
||||
defaultText = "pkgs.${browser}";
|
||||
defaultText = literalExample "pkgs.${browser}";
|
||||
description = "The ${name} package to use.";
|
||||
};
|
||||
|
||||
|
||||
@@ -4,13 +4,15 @@ with lib;
|
||||
|
||||
let
|
||||
|
||||
hmTypes = import ../lib/types.nix { inherit lib; };
|
||||
|
||||
cfg = config.programs.emacs;
|
||||
|
||||
# Copied from all-packages.nix, with modifications to support
|
||||
# overrides.
|
||||
emacsPackages =
|
||||
let
|
||||
epkgs = pkgs.emacsPackagesNgGen cfg.package;
|
||||
epkgs = pkgs.emacsPackagesGen cfg.package;
|
||||
in
|
||||
epkgs.overrideScope' cfg.overrides;
|
||||
emacsWithPackages = emacsPackages.emacsWithPackages;
|
||||
@@ -27,20 +29,26 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.emacs;
|
||||
defaultText = "pkgs.emacs";
|
||||
defaultText = literalExample "pkgs.emacs";
|
||||
example = literalExample "pkgs.emacs25-nox";
|
||||
description = "The Emacs package to use.";
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
default = self: [];
|
||||
type = hmTypes.selectorFunction;
|
||||
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 emacsPackages</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
overrides = mkOption {
|
||||
default = self: super: {};
|
||||
type = hmTypes.overlayFunction;
|
||||
defaultText = "self: super: {}";
|
||||
example = literalExample ''
|
||||
self: super: rec {
|
||||
|
||||
@@ -6,8 +6,47 @@ let
|
||||
|
||||
cfg = config.programs.firefox;
|
||||
|
||||
mozillaConfigPath = ".mozilla";
|
||||
|
||||
firefoxConfigPath = "${mozillaConfigPath}/firefox";
|
||||
|
||||
profilesPath = firefoxConfigPath;
|
||||
|
||||
# The extensions path shared by all profiles; will not be supported
|
||||
# by future Firefox versions.
|
||||
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
|
||||
|
||||
extensionsEnvPkg = pkgs.buildEnv {
|
||||
name = "hm-firefox-extensions";
|
||||
paths = cfg.extensions;
|
||||
};
|
||||
|
||||
profiles =
|
||||
flip mapAttrs' cfg.profiles (_: profile:
|
||||
nameValuePair "Profile${toString profile.id}" {
|
||||
Name = profile.name;
|
||||
Path = profile.path;
|
||||
IsRelative = 1;
|
||||
Default = if profile.isDefault then 1 else 0;
|
||||
}
|
||||
) // {
|
||||
General = {
|
||||
StartWithLastProfile = 1;
|
||||
};
|
||||
};
|
||||
|
||||
profilesIni = generators.toINI {} profiles;
|
||||
|
||||
mkUserJs = prefs: extraPrefs: ''
|
||||
// Generated by Home Manager.
|
||||
|
||||
${concatStrings (mapAttrsToList (name: value: ''
|
||||
user_pref("${name}", ${builtins.toJSON value});
|
||||
'') prefs)}
|
||||
|
||||
${extraPrefs}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -19,9 +58,16 @@ in
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.firefox-unwrapped;
|
||||
defaultText = "pkgs.firefox-unwrapped";
|
||||
description = "The unwrapped Firefox package to use.";
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then pkgs.firefox
|
||||
else pkgs.firefox-unwrapped;
|
||||
defaultText = literalExample "pkgs.firefox";
|
||||
description = ''
|
||||
The Firefox package to use. If state version ≥ 19.09 then
|
||||
this should be a wrapped Firefox package. For earlier state
|
||||
versions it should be an unwrapped Firefox package.
|
||||
'';
|
||||
};
|
||||
|
||||
extensions = mkOption {
|
||||
@@ -40,6 +86,84 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
profiles = mkOption {
|
||||
type = types.attrsOf (types.submodule ({config, name, ...}: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Profile name.";
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
Profile ID. This should be set to a unique number per profile.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
"browser.startup.homepage" = "https://nixos.org";
|
||||
"browser.search.region" = "GB";
|
||||
"browser.search.isUS" = false;
|
||||
"distribution.searchplugins.defaultLocale" = "en-GB";
|
||||
"general.useragent.locale" = "en-GB";
|
||||
"browser.bookmarks.showMobileBookmarks" = true;
|
||||
}
|
||||
'';
|
||||
description = "Attribute set of Firefox preferences.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra preferences to add to <filename>user.js</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
userChrome = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Custom Firefox CSS.";
|
||||
example = ''
|
||||
/* Hide tab bar in FF Quantum */
|
||||
@-moz-document url("chrome://browser/content/browser.xul") {
|
||||
#TabsToolbar {
|
||||
visibility: collapse !important;
|
||||
margin-bottom: 21px !important;
|
||||
}
|
||||
|
||||
#sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"] #sidebar-header {
|
||||
visibility: collapse !important;
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Profile path.";
|
||||
};
|
||||
|
||||
isDefault = mkOption {
|
||||
type = types.bool;
|
||||
default = config.id == 0;
|
||||
defaultText = "true if profile ID is 0";
|
||||
description = "Whether this is a default profile.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = {};
|
||||
description = "Attribute set of Firefox profiles.";
|
||||
};
|
||||
|
||||
enableAdobeFlash = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -49,47 +173,122 @@ 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.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(
|
||||
let
|
||||
defaults =
|
||||
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
|
||||
in {
|
||||
assertion = cfg.profiles == {} || length defaults == 1;
|
||||
message =
|
||||
"Must have exactly one default Firefox profile but found "
|
||||
+ toString (length defaults)
|
||||
+ optionalString (length defaults > 1)
|
||||
(", namely " + concatStringsSep ", " defaults);
|
||||
}
|
||||
)
|
||||
|
||||
(
|
||||
let
|
||||
duplicates =
|
||||
filterAttrs (_: v: length v != 1)
|
||||
(zipAttrs
|
||||
(mapAttrsToList (n: v: { "${toString v.id}" = n; })
|
||||
(cfg.profiles)));
|
||||
|
||||
mkMsg = n: v: " - ID ${n} is used by ${concatStringsSep ", " v}";
|
||||
in {
|
||||
assertion = duplicates == {};
|
||||
message =
|
||||
"Must not have Firefox profiles with duplicate IDs but\n"
|
||||
+ concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
home.packages =
|
||||
let
|
||||
# A bit of hackery to force a config into the wrapper.
|
||||
browserName = cfg.package.browserName
|
||||
or (builtins.parseDrvName cfg.package.name).name;
|
||||
|
||||
fcfg = setAttrByPath [browserName] {
|
||||
# The configuration expected by the Firefox wrapper.
|
||||
fcfg = {
|
||||
enableAdobeFlash = cfg.enableAdobeFlash;
|
||||
enableGoogleTalkPlugin = cfg.enableGoogleTalk;
|
||||
icedtea = cfg.enableIcedTea;
|
||||
};
|
||||
|
||||
wrapper = pkgs.wrapFirefox.override {
|
||||
config = fcfg;
|
||||
};
|
||||
in
|
||||
[ (wrapper cfg.package { }) ];
|
||||
# A bit of hackery to force a config into the wrapper.
|
||||
browserName = cfg.package.browserName
|
||||
or (builtins.parseDrvName cfg.package.name).name;
|
||||
|
||||
home.file.".mozilla/${extensionPath}" = mkIf (cfg.extensions != []) (
|
||||
let
|
||||
extensionsEnv = pkgs.buildEnv {
|
||||
name = "hm-firefox-extensions";
|
||||
paths = cfg.extensions;
|
||||
};
|
||||
# The configuration expected by the Firefox wrapper builder.
|
||||
bcfg = setAttrByPath [browserName] fcfg;
|
||||
|
||||
package =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then cfg.package.override { cfg = fcfg; }
|
||||
else (pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
|
||||
in
|
||||
{
|
||||
source = "${extensionsEnv}/share/mozilla/${extensionPath}";
|
||||
[ package ];
|
||||
|
||||
home.file = mkMerge (
|
||||
[{
|
||||
"${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != []) {
|
||||
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
|
||||
recursive = true;
|
||||
}
|
||||
};
|
||||
|
||||
"${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) {
|
||||
text = profilesIni;
|
||||
};
|
||||
}]
|
||||
++ flip mapAttrsToList cfg.profiles (_: profile: {
|
||||
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
|
||||
mkIf (profile.userChrome != "") {
|
||||
text = profile.userChrome;
|
||||
};
|
||||
|
||||
"${profilesPath}/${profile.path}/user.js" =
|
||||
mkIf (profile.settings != {} || profile.extraConfig != "") {
|
||||
text = mkUserJs profile.settings profile.extraConfig;
|
||||
};
|
||||
|
||||
"${profilesPath}/${profile.path}/extensions" = mkIf (cfg.extensions != []) {
|
||||
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
|
||||
recursive = true;
|
||||
force = true;
|
||||
};
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ in
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.fish;
|
||||
defaultText = "pkgs.fish";
|
||||
defaultText = literalExample "pkgs.fish";
|
||||
description = ''
|
||||
The fish package to install. May be used to change the version.
|
||||
'';
|
||||
|
||||
49
modules/programs/getmail-accounts.nix
Normal file
49
modules/programs/getmail-accounts.nix
Normal file
@@ -0,0 +1,49 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.getmail = {
|
||||
enable = mkEnableOption "the getmail mail retriever for this account";
|
||||
|
||||
destinationCommand = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "\${pkgs.maildrop}/bin/maildrop";
|
||||
description = ''
|
||||
Specify a command delivering the incoming mail to your maildir.
|
||||
'';
|
||||
};
|
||||
|
||||
mailboxes = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = [];
|
||||
example = ["INBOX" "INBOX.spam"];
|
||||
description = ''
|
||||
A non-empty list of mailboxes. To download all mail you can
|
||||
use the <literal>ALL</literal> mailbox.
|
||||
'';
|
||||
};
|
||||
|
||||
delete = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable if you want to delete read messages from the server. Most
|
||||
users should either enable <literal>delete</literal> or disable
|
||||
<literal>readAll</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
readAll = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable if you want to fetch all, even the read messages from the
|
||||
server. Most users should either enable <literal>delete</literal> or
|
||||
disable <literal>readAll</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
60
modules/programs/getmail.nix
Normal file
60
modules/programs/getmail.nix
Normal file
@@ -0,0 +1,60 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
accounts = filter (a: a.getmail.enable)
|
||||
(attrValues config.accounts.email.accounts);
|
||||
|
||||
renderAccountConfig = account: with account;
|
||||
let
|
||||
passCmd = concatMapStringsSep ", " (x: "'${x}'") passwordCommand;
|
||||
renderedMailboxes = concatMapStringsSep ", " (x: "'${x}'") getmail.mailboxes;
|
||||
retrieverType = if imap.tls.enable
|
||||
then "SimpleIMAPSSLRetriever"
|
||||
else "SimpleIMAPRetriever";
|
||||
destination = if getmail.destinationCommand != null
|
||||
then
|
||||
{
|
||||
destinationType = "MDA_external";
|
||||
destinationPath = getmail.destinationCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
destinationType = "Maildir";
|
||||
destinationPath = "${maildir.absPath}/";
|
||||
};
|
||||
renderGetmailBoolean = v: if v then "true" else "false";
|
||||
in ''
|
||||
# Generated by Home-Manager.
|
||||
[retriever]
|
||||
type = ${retrieverType}
|
||||
server = ${imap.host}
|
||||
${optionalString (imap.port != null) "port = ${toString imap.port}"}
|
||||
username = ${userName}
|
||||
password_command = (${passCmd})
|
||||
mailboxes = ( ${renderedMailboxes} )
|
||||
|
||||
[destination]
|
||||
type = ${destination.destinationType}
|
||||
path = ${destination.destinationPath}
|
||||
|
||||
[options]
|
||||
delete = ${renderGetmailBoolean getmail.delete}
|
||||
read_all = ${renderGetmailBoolean getmail.readAll}
|
||||
'';
|
||||
getmailEnabled = length (filter (a: a.getmail.enable) accounts) > 0;
|
||||
# Watch out! This is used by the getmail.service too!
|
||||
renderConfigFilepath = a: ".getmail/getmail${if a.primary then "rc" else a.name}";
|
||||
in
|
||||
|
||||
{
|
||||
config = mkIf getmailEnabled {
|
||||
home.file = map (a:
|
||||
{ target = renderConfigFilepath a;
|
||||
text = renderAccountConfig a;
|
||||
}) accounts;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -6,11 +6,53 @@ let
|
||||
|
||||
cfg = config.programs.git;
|
||||
|
||||
# create [section "subsection"] keys from "section.subsection" attrset names
|
||||
mkSectionName = name:
|
||||
let
|
||||
containsQuote = strings.hasInfix ''"'' name;
|
||||
sections = splitString "." name;
|
||||
section = head sections;
|
||||
subsections = tail sections;
|
||||
subsection = concatStringsSep "." subsections;
|
||||
in
|
||||
if containsQuote || subsections == []
|
||||
then name
|
||||
else "${section} \"${subsection}\"";
|
||||
|
||||
# generation for multiple ini values
|
||||
mkKeyValue = k: v:
|
||||
let
|
||||
mkKeyValue = generators.mkKeyValueDefault {} "=" k;
|
||||
in
|
||||
concatStringsSep "\n" (map mkKeyValue (toList v));
|
||||
|
||||
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
|
||||
gitFlattenAttrs =
|
||||
let
|
||||
recurse = path: value:
|
||||
if isAttrs value then
|
||||
mapAttrsToList (name: value: recurse ([name] ++ path) value) value
|
||||
else if length path > 1 then
|
||||
{ ${concatStringsSep "." (reverseList (tail path))}.${head path} = value; }
|
||||
else
|
||||
{ ${head path} = value; };
|
||||
in
|
||||
attrs: foldl recursiveUpdate {} (flatten (recurse [] attrs));
|
||||
|
||||
gitToIni = attrs:
|
||||
let
|
||||
toIni = generators.toINI { inherit mkKeyValue mkSectionName; };
|
||||
in
|
||||
toIni (gitFlattenAttrs attrs);
|
||||
|
||||
gitIniType = with types;
|
||||
let
|
||||
primitiveType = either bool (either int str);
|
||||
primitiveType = either str (either bool int);
|
||||
multipleType = either primitiveType (listOf primitiveType);
|
||||
sectionType = attrsOf multipleType;
|
||||
supersectionType = attrsOf (either multipleType sectionType);
|
||||
in
|
||||
attrsOf (attrsOf primitiveType);
|
||||
attrsOf supersectionType;
|
||||
|
||||
signModule = types.submodule {
|
||||
options = {
|
||||
@@ -64,7 +106,7 @@ let
|
||||
};
|
||||
|
||||
config.path = mkIf (config.contents != {}) (
|
||||
mkDefault (pkgs.writeText "contents" (generators.toINI {} config.contents))
|
||||
mkDefault (pkgs.writeText "contents" (gitToIni config.contents))
|
||||
);
|
||||
});
|
||||
|
||||
@@ -80,7 +122,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.git;
|
||||
defaultText = "pkgs.git";
|
||||
defaultText = literalExample "pkgs.git";
|
||||
description = ''
|
||||
Git package to install. Use <varname>pkgs.gitAndTools.gitFull</varname>
|
||||
to gain access to <command>git send-email</command> for instance.
|
||||
@@ -117,8 +159,12 @@ in
|
||||
default = {};
|
||||
example = {
|
||||
core = { whitespace = "trailing-space,space-before-tab"; };
|
||||
url."ssh://git@host".insteadOf = "otherhost";
|
||||
};
|
||||
description = "Additional configuration to add.";
|
||||
description = ''
|
||||
Additional configuration to add. The use of string values is
|
||||
deprecated and will be removed in the future.
|
||||
'';
|
||||
};
|
||||
|
||||
iniContent = mkOption {
|
||||
@@ -133,6 +179,13 @@ in
|
||||
description = "List of paths that should be globally ignored.";
|
||||
};
|
||||
|
||||
attributes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "*.pdf diff=pdf" ];
|
||||
description = "List of defining attributes set globally.";
|
||||
};
|
||||
|
||||
includes = mkOption {
|
||||
type = types.listOf includeModule;
|
||||
default = [];
|
||||
@@ -175,11 +228,15 @@ in
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"git/config".text = generators.toINI {} cfg.iniContent;
|
||||
"git/config".text = gitToIni cfg.iniContent;
|
||||
|
||||
"git/ignore" = mkIf (cfg.ignores != []) {
|
||||
text = concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
|
||||
"git/attributes" = mkIf (cfg.attributes != []) {
|
||||
text = concatStringsSep "\n" cfg.attributes + "\n";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -189,7 +246,7 @@ in
|
||||
hasSmtp = name: account: account.smtp != null;
|
||||
|
||||
genIdentity = name: account: with account;
|
||||
nameValuePair "sendemail \"${name}\"" ({
|
||||
nameValuePair "sendemail.${name}" ({
|
||||
smtpEncryption = if smtp.tls.enable then "tls" else "";
|
||||
smtpServer = smtp.host;
|
||||
smtpUser = userName;
|
||||
@@ -220,23 +277,35 @@ in
|
||||
})
|
||||
|
||||
(mkIf (lib.isString cfg.extraConfig) {
|
||||
warnings = [
|
||||
''
|
||||
Using programs.git.extraConfig as a string option is
|
||||
deprecated and will be removed in the future. Please
|
||||
change to using it as an attribute set instead.
|
||||
''
|
||||
];
|
||||
|
||||
xdg.configFile."git/config".text = cfg.extraConfig;
|
||||
})
|
||||
|
||||
(mkIf (cfg.includes != []) {
|
||||
xdg.configFile."git/config".text = mkAfter
|
||||
(concatMapStringsSep "\n"
|
||||
(i: with i; ''
|
||||
[${if (condition == null) then "include" else "includeIf \"${condition}\""}]
|
||||
path = ${path}
|
||||
'')
|
||||
cfg.includes);
|
||||
xdg.configFile."git/config".text =
|
||||
let
|
||||
include = i: with i;
|
||||
if condition != null
|
||||
then { includeIf.${condition}.path = "${path}"; }
|
||||
else { include.path = "${path}"; };
|
||||
in
|
||||
mkAfter
|
||||
(concatStringsSep "\n"
|
||||
(map gitToIni
|
||||
(map include cfg.includes)));
|
||||
})
|
||||
|
||||
(mkIf cfg.lfs.enable {
|
||||
home.packages = [ pkgs.git-lfs ];
|
||||
|
||||
programs.git.iniContent."filter \"lfs\"" =
|
||||
programs.git.iniContent.filter.lfs =
|
||||
let
|
||||
skipArg = optional cfg.lfs.skipSmudge "--skip";
|
||||
in
|
||||
|
||||
@@ -18,7 +18,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.go;
|
||||
defaultText = "pkgs.go";
|
||||
defaultText = literalExample "pkgs.go";
|
||||
description = "The Go package to use.";
|
||||
};
|
||||
|
||||
|
||||
61
modules/programs/gpg.nix
Normal file
61
modules/programs/gpg.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.gpg;
|
||||
|
||||
cfgText =
|
||||
concatStringsSep "\n"
|
||||
(attrValues
|
||||
(mapAttrs (key: value:
|
||||
if isString value
|
||||
then "${key} ${value}"
|
||||
else optionalString value key)
|
||||
cfg.settings));
|
||||
|
||||
in {
|
||||
options.programs.gpg = {
|
||||
enable = mkEnableOption "GnuPG";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf (types.either types.str types.bool);
|
||||
example = {
|
||||
no-comments = false;
|
||||
s2k-cipher-algo = "AES128";
|
||||
};
|
||||
description = ''
|
||||
GnuPG configuration options. Available options are described
|
||||
in the gpg manpage:
|
||||
<link xlink:href="https://gnupg.org/documentation/manpage.html"/>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.gpg.settings = {
|
||||
personal-cipher-preferences = mkDefault "AES256 AES192 AES";
|
||||
personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256";
|
||||
personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed";
|
||||
default-preference-list = mkDefault "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
|
||||
cert-digest-algo = mkDefault "SHA512";
|
||||
s2k-digest-algo = mkDefault "SHA512";
|
||||
s2k-cipher-algo = mkDefault "AES256";
|
||||
charset = mkDefault "utf-8";
|
||||
fixed-list-mode = mkDefault true;
|
||||
no-comments = mkDefault true;
|
||||
no-emit-version = mkDefault true;
|
||||
keyid-format = mkDefault "0xlong";
|
||||
list-options = mkDefault "show-uid-validity";
|
||||
verify-options = mkDefault "show-uid-validity";
|
||||
with-fingerprint = mkDefault true;
|
||||
require-cross-certification = mkDefault true;
|
||||
no-symkey-cache = mkDefault true;
|
||||
use-agent = mkDefault true;
|
||||
};
|
||||
|
||||
home.packages = [ pkgs.gnupg ];
|
||||
|
||||
home.file.".gnupg/gpg.conf".text = cfgText;
|
||||
};
|
||||
}
|
||||
@@ -101,7 +101,7 @@ let
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
type = types.port;
|
||||
default = 6667;
|
||||
description = "Port of the chat server.";
|
||||
};
|
||||
|
||||
575
modules/programs/kakoune.nix
Normal file
575
modules/programs/kakoune.nix
Normal file
@@ -0,0 +1,575 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.kakoune;
|
||||
|
||||
hook = types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.enum [
|
||||
"NormalBegin" "NormalIdle" "NormalEnd" "NormalKey"
|
||||
"InsertBegin" "InsertIdle" "InsertEnd" "InsertKey"
|
||||
"InsertChar" "InsertDelete" "InsertMove" "WinCreate"
|
||||
"WinClose" "WinResize" "WinDisplay" "WinSetOption"
|
||||
"BufSetOption" "BufNewFile" "BufOpenFile" "BufCreate"
|
||||
"BufWritePre" "BufWritePost" "BufReload" "BufClose"
|
||||
"BufOpenFifo" "BufReadFifo" "BufCloseFifo" "RuntimeError"
|
||||
"ModeChange" "PromptIdle" "GlobalSetOption" "KakBegin"
|
||||
"KakEnd" "FocusIn" "FocusOut" "RawKey"
|
||||
"InsertCompletionShow" "InsertCompletionHide"
|
||||
"InsertCompletionSelect"
|
||||
];
|
||||
example = "SetOption";
|
||||
description = ''
|
||||
The name of the hook. For a description, see
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc#default-hooks"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
once = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Remove the hook after running it once.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Add the hook to the named group.
|
||||
'';
|
||||
};
|
||||
|
||||
option = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "filetype=latex";
|
||||
description = ''
|
||||
Additional option to pass to the hook.
|
||||
'';
|
||||
};
|
||||
|
||||
commands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "set-option window indentwidth 2";
|
||||
description = ''
|
||||
Commands to run when the hook is activated.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
keyMapping = types.submodule {
|
||||
options = {
|
||||
mode = mkOption {
|
||||
type = types.enum [
|
||||
"insert"
|
||||
"normal"
|
||||
"prompt"
|
||||
"menu"
|
||||
"user"
|
||||
"goto"
|
||||
"view"
|
||||
"object"
|
||||
];
|
||||
example = "user";
|
||||
description = ''
|
||||
The mode in which the mapping takes effect.
|
||||
'';
|
||||
};
|
||||
|
||||
docstring = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Optional documentation text to display in info boxes.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
example = "<a-x>";
|
||||
description = ''
|
||||
The key to be mapped. See
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc#mappable-keys"/>
|
||||
for possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
effect = mkOption {
|
||||
type = types.str;
|
||||
example = ":wq<ret>";
|
||||
description = ''
|
||||
The sequence of keys to be mapped.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configModule = types.submodule {
|
||||
options = {
|
||||
colorScheme = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Set the color scheme. To see available schemes, enter
|
||||
<command>colorscheme</command> at the kakoune prompt.
|
||||
'';
|
||||
};
|
||||
|
||||
tabStop = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
The width of a tab in spaces. The kakoune default is
|
||||
<literal>6</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
indentWidth = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
The width of an indentation in spaces.
|
||||
The kakoune default is <literal>4</literal>.
|
||||
If <literal>0</literal>, a tab will be used instead.
|
||||
'';
|
||||
};
|
||||
|
||||
incrementalSearch = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Execute a search as it is being typed.
|
||||
'';
|
||||
};
|
||||
|
||||
alignWithTabs = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use tabs for the align command.
|
||||
'';
|
||||
};
|
||||
|
||||
autoInfo = mkOption {
|
||||
type = types.nullOr (types.listOf (types.enum [ "command" "onkey" "normal" ]));
|
||||
default = null;
|
||||
example = [ "command" "normal" ];
|
||||
description = ''
|
||||
Contexts in which to display automatic information box.
|
||||
The kakoune default is <literal>[ "command" "onkey" ]</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
autoComplete = mkOption {
|
||||
type = types.nullOr(types.listOf (types.enum [ "insert" "prompt" ]));
|
||||
default = null;
|
||||
description = ''
|
||||
Modes in which to display possible completions.
|
||||
The kakoune default is <literal>[ "insert" "prompt" ]</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
autoReload = mkOption {
|
||||
type = types.nullOr (types.enum [ "yes" "no" "ask" ]);
|
||||
default = null;
|
||||
description = ''
|
||||
Reload buffers when an external modification is detected.
|
||||
The kakoune default is <literal>"ask"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
scrollOff = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
lines = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
The number of lines to keep visible around the cursor.
|
||||
'';
|
||||
};
|
||||
|
||||
columns = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
The number of columns to keep visible around the cursor.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
How many lines and columns to keep visible around the cursor.
|
||||
'';
|
||||
};
|
||||
|
||||
ui = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
setTitle = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Change the title of the terminal emulator.
|
||||
'';
|
||||
};
|
||||
|
||||
statusLine = mkOption {
|
||||
type = types.enum [ "top" "bottom" ];
|
||||
default = "bottom";
|
||||
description = ''
|
||||
Where to display the status line.
|
||||
'';
|
||||
};
|
||||
|
||||
assistant = mkOption {
|
||||
type = types.enum [ "clippy" "cat" "dilbert" "none" ];
|
||||
default = "clippy";
|
||||
description = ''
|
||||
The assistant displayed in info boxes.
|
||||
'';
|
||||
};
|
||||
|
||||
enableMouse = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable mouse support.
|
||||
'';
|
||||
};
|
||||
|
||||
changeColors = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Change color palette.
|
||||
'';
|
||||
};
|
||||
|
||||
wheelDownButton = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Button to send for wheel down events.
|
||||
'';
|
||||
};
|
||||
|
||||
wheelUpButton = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Button to send for wheel up events.
|
||||
'';
|
||||
};
|
||||
|
||||
shiftFunctionKeys = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
Amount by which shifted function keys are offset. That
|
||||
is, if the terminal sends F13 for Shift-F1, this
|
||||
should be <literal>12</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
useBuiltinKeyParser = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Bypass ncurses key parser and use an internal one.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the ncurses interface.
|
||||
'';
|
||||
};
|
||||
|
||||
showMatching = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Highlight the matching char of the character under the
|
||||
selections' cursor using the <literal>MatchingChar</literal>
|
||||
face.
|
||||
'';
|
||||
};
|
||||
|
||||
wrapLines = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "the wrap lines highlighter";
|
||||
|
||||
word = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Wrap at word boundaries instead of codepoint boundaries.
|
||||
'';
|
||||
};
|
||||
|
||||
indent = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Preserve line indentation when wrapping.
|
||||
'';
|
||||
};
|
||||
|
||||
maxWidth = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
Wrap text at maxWidth, even if the window is wider.
|
||||
'';
|
||||
};
|
||||
|
||||
marker = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "⏎";
|
||||
description = ''
|
||||
Prefix wrapped lines with marker text.
|
||||
If not <literal>null</literal>,
|
||||
the marker text will be displayed in the indentation if possible.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the wrap lines highlighter.
|
||||
'';
|
||||
};
|
||||
|
||||
numberLines = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "the number lines highlighter";
|
||||
|
||||
relative = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Show line numbers relative to the main cursor line.
|
||||
'';
|
||||
};
|
||||
|
||||
highlightCursor = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Highlight the cursor line with a separate face.
|
||||
'';
|
||||
};
|
||||
|
||||
separator = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
String that separates the line number column from the
|
||||
buffer contents. The kakoune default is
|
||||
<literal>"|"</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the number lines highlighter.
|
||||
'';
|
||||
};
|
||||
|
||||
showWhitespace = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "the show whitespace highlighter";
|
||||
|
||||
lineFeed = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for line feeds.
|
||||
The kakoune default is <literal>"¬"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
space = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for spaces.
|
||||
The kakoune default is <literal>"·"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
nonBreakingSpace = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for non-breaking spaces.
|
||||
The kakoune default is <literal>"⍽"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
tab = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for tabs.
|
||||
The kakoune default is <literal>"→"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
tabStop = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to append to tabs to reach the width of a tabstop.
|
||||
The kakoune default is <literal>" "</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the show whitespaces highlighter.
|
||||
'';
|
||||
};
|
||||
|
||||
keyMappings = mkOption {
|
||||
type = types.listOf keyMapping;
|
||||
default = [];
|
||||
description = ''
|
||||
User-defined key mappings. For documentation, see
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
hooks = mkOption {
|
||||
type = types.listOf hook;
|
||||
default = [];
|
||||
description = ''
|
||||
Global hooks. For documentation, see
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc"/>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configFile =
|
||||
let
|
||||
wrapOptions = with cfg.config.wrapLines; concatStrings [
|
||||
"${optionalString word " -word"}"
|
||||
"${optionalString indent " -indent"}"
|
||||
"${optionalString (marker != null) " -marker ${marker}"}"
|
||||
"${optionalString (maxWidth != null) " -width ${toString maxWidth}"}"
|
||||
];
|
||||
|
||||
numberLinesOptions = with cfg.config.numberLines; concatStrings [
|
||||
"${optionalString relative " -relative "}"
|
||||
"${optionalString highlightCursor " -hlcursor"}"
|
||||
"${optionalString (separator != null) " -separator ${separator}"}"
|
||||
];
|
||||
|
||||
uiOptions = with cfg.config.ui; concatStringsSep " " [
|
||||
"ncurses_set_title=${if setTitle then "true" else "false"}"
|
||||
"ncurses_status_on_top=${if (statusLine == "top") then "true" else "false"}"
|
||||
"ncurses_assistant=${assistant}"
|
||||
"ncurses_enable_mouse=${if enableMouse then "true" else "false"}"
|
||||
"ncurses_change_colors=${if changeColors then "true" else "false"}"
|
||||
"${optionalString (wheelDownButton != null)
|
||||
"ncurses_wheel_down_button=${wheelDownButton}"}"
|
||||
"${optionalString (wheelUpButton != null)
|
||||
"ncurses_wheel_up_button=${wheelUpButton}"}"
|
||||
"${optionalString (shiftFunctionKeys != null)
|
||||
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
|
||||
"ncurses_builtin_key_parser=${if useBuiltinKeyParser then "true" else "false"}"
|
||||
];
|
||||
|
||||
keyMappingString = km: concatStringsSep " " [
|
||||
"map global"
|
||||
"${km.mode} ${km.key} '${km.effect}'"
|
||||
"${optionalString (km.docstring != null) "-docstring '${km.docstring}'"}"
|
||||
];
|
||||
|
||||
hookString = h: concatStringsSep " " [
|
||||
"hook" "${optionalString (h.group != null) "-group ${group}"}"
|
||||
"${optionalString (h.once) "-once"}" "global"
|
||||
"${h.name}" "${optionalString (h.option != null) h.option}"
|
||||
"%{ ${h.commands} }"
|
||||
];
|
||||
|
||||
cfgStr = with cfg.config; concatStringsSep "\n" (
|
||||
[ "# Generated by home-manager" ]
|
||||
++ optional (colorScheme != null) "colorscheme ${colorScheme}"
|
||||
++ optional (tabStop != null) "set-option global tabstop ${toString tabStop}"
|
||||
++ optional (indentWidth != null) "set-option global indentwidth ${toString indentWidth}"
|
||||
++ optional (!incrementalSearch) "set-option global incsearch false"
|
||||
++ optional (alignWithTabs) "set-option global aligntab true"
|
||||
++ optional (autoInfo != null) "set-option global autoinfo ${concatStringsSep "|" autoInfo}"
|
||||
++ optional (autoComplete != null) "set-option global autocomplete ${concatStringsSep "|" autoComplete}"
|
||||
++ optional (autoReload != null) "set-option global/ autoreload ${autoReload}"
|
||||
++ optional (wrapLines != null && wrapLines.enable) "add-highlighter global/ wrap${wrapOptions}"
|
||||
++ optional (numberLines != null && numberLines.enable)
|
||||
"add-highlighter global/ number-lines${numberLinesOptions}"
|
||||
++ optional showMatching "add-highlighter global/ show-matching"
|
||||
++ optional (scrollOff != null)
|
||||
"set-option global scrolloff ${toString scrollOff.lines},${toString scrollOff.columns}"
|
||||
|
||||
++ [ "# UI options" ]
|
||||
++ optional (ui != null) "set-option global ui_options ${uiOptions}"
|
||||
|
||||
++ [ "# Key mappings" ]
|
||||
++ map keyMappingString keyMappings
|
||||
|
||||
++ [ "# Hooks" ]
|
||||
++ map hookString hooks
|
||||
);
|
||||
in
|
||||
pkgs.writeText "kakrc" (
|
||||
optionalString (cfg.config != null) cfgStr
|
||||
+ "\n"
|
||||
+ cfg.extraConfig
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.kakoune = {
|
||||
enable = mkEnableOption "the kakoune text editor";
|
||||
|
||||
config = mkOption {
|
||||
type = types.nullOr configModule;
|
||||
default = {};
|
||||
description = "kakoune configuration options.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add to
|
||||
<filename>~/.config/kak/kakrc</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.kakoune ];
|
||||
xdg.configFile."kak/kakrc".source = configFile;
|
||||
};
|
||||
}
|
||||
@@ -25,7 +25,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.keychain;
|
||||
defaultText = "pkgs.keychain";
|
||||
defaultText = literalExample "pkgs.keychain";
|
||||
description = ''
|
||||
Keychain package to install.
|
||||
'';
|
||||
|
||||
@@ -20,7 +20,7 @@ let
|
||||
}
|
||||
//
|
||||
optionalAttrs (tls.enable && tls.certificatesFile != null) {
|
||||
CertificateFile = tls.certificatesFile;
|
||||
CertificateFile = toString tls.certificatesFile;
|
||||
};
|
||||
|
||||
masterSlaveMapping = {
|
||||
@@ -112,7 +112,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.isync;
|
||||
defaultText = "pkgs.isync";
|
||||
defaultText = literalExample "pkgs.isync";
|
||||
example = literalExample "pkgs.isync";
|
||||
description = "The package to use for the mbsync binary.";
|
||||
};
|
||||
@@ -173,16 +173,18 @@ 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" ] ''
|
||||
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
|
||||
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
|
||||
}
|
||||
'';
|
||||
home.activation = mkIf (mbsyncAccounts != []) {
|
||||
createMaildir =
|
||||
dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${
|
||||
concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.mercurial;
|
||||
defaultText = "pkgs.mercurial";
|
||||
defaultText = literalExample "pkgs.mercurial";
|
||||
description = "Mercurial package to install.";
|
||||
};
|
||||
|
||||
|
||||
152
modules/programs/mpv.nix
Normal file
152
modules/programs/mpv.nix
Normal file
@@ -0,0 +1,152 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
inherit (builtins) typeOf stringLength;
|
||||
|
||||
cfg = config.programs.mpv;
|
||||
|
||||
mpvOption = with types; either str (either int (either bool float));
|
||||
mpvOptions = with types; attrsOf mpvOption;
|
||||
mpvProfiles = with types; attrsOf mpvOptions;
|
||||
mpvBindings = with types; attrsOf str;
|
||||
|
||||
renderOption = option:
|
||||
rec {
|
||||
int = toString option;
|
||||
float = int;
|
||||
|
||||
bool = if option then "yes" else "no";
|
||||
|
||||
string = option;
|
||||
}.${typeOf option};
|
||||
|
||||
renderOptions = options:
|
||||
concatStringsSep "\n"
|
||||
(mapAttrsToList
|
||||
(name: value:
|
||||
let
|
||||
rendered = renderOption value;
|
||||
length = toString (stringLength rendered);
|
||||
in
|
||||
"${name}=%${length}%${rendered}")
|
||||
options);
|
||||
|
||||
renderProfiles = profiles:
|
||||
concatStringsSep "\n"
|
||||
(mapAttrsToList
|
||||
(name: value: ''
|
||||
[${name}]
|
||||
${renderOptions value}
|
||||
'')
|
||||
profiles);
|
||||
|
||||
renderBindings = bindings:
|
||||
concatStringsSep "\n"
|
||||
(mapAttrsToList
|
||||
(name: value:
|
||||
"${name} ${value}")
|
||||
bindings);
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.mpv = {
|
||||
enable = mkEnableOption "mpv";
|
||||
|
||||
scripts = mkOption {
|
||||
type = with types; listOf (either package str);
|
||||
default = [];
|
||||
example = literalExample "[ pkgs.mpvScripts.mpris ]";
|
||||
description = ''
|
||||
List of scripts to use with mpv.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/mpv/mpv.conf</filename>. See
|
||||
<citerefentry>
|
||||
<refentrytitle>mpv</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
for the full list of options.
|
||||
'';
|
||||
type = mpvOptions;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
profile = "gpu-hq";
|
||||
force-window = "yes";
|
||||
ytdl-format = "bestvideo+bestaudio";
|
||||
cache-default = 4000000;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
profiles = mkOption {
|
||||
description = ''
|
||||
Sub-configuration options for specific profiles written to
|
||||
<filename>~/.config/mpv/mpv.conf</filename>. See
|
||||
<option>programs.mpv.config</option> for more information.
|
||||
'';
|
||||
type = mpvProfiles;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
fast = {
|
||||
vo = "vdpau";
|
||||
};
|
||||
"protocol.dvd" = {
|
||||
profile-desc = "profile for dvd:// streams";
|
||||
alang = "en";
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
bindings = mkOption {
|
||||
description = ''
|
||||
Input configuration written to
|
||||
<filename>~/.config/mpv/input.conf</filename>. See
|
||||
<citerefentry>
|
||||
<refentrytitle>mpv</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
for the full list of options.
|
||||
'';
|
||||
type = mpvBindings;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
WHEEL_UP = "seek 10";
|
||||
WHEEL_DOWN = "seek -10";
|
||||
"Alt+0" = "set window-scale 0.5";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
home.packages = [(
|
||||
if cfg.scripts == []
|
||||
then pkgs.mpv
|
||||
else pkgs.mpv-with-scripts.override { scripts = cfg.scripts; }
|
||||
)];
|
||||
}
|
||||
(mkIf (cfg.config != {} || cfg.profiles != {}) {
|
||||
xdg.configFile."mpv/mpv.conf".text = ''
|
||||
${optionalString (cfg.config != {}) (renderOptions cfg.config)}
|
||||
${optionalString (cfg.profiles != {}) (renderProfiles cfg.profiles)}
|
||||
'';
|
||||
})
|
||||
(mkIf (cfg.bindings != {}) {
|
||||
xdg.configFile."mpv/input.conf".text = renderBindings cfg.bindings;
|
||||
})
|
||||
]);
|
||||
|
||||
meta.maintainers = with maintainers; [ tadeokondrak ];
|
||||
}
|
||||
@@ -22,6 +22,17 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
tls.fingerprint = mkOption {
|
||||
type = types.nullOr (types.strMatching "([[:alnum:]]{2}\:)+[[:alnum:]]{2}");
|
||||
default = null;
|
||||
example = "my:SH:a2:56:ha:sh";
|
||||
description = ''
|
||||
Fingerprint of a trusted TLS certificate.
|
||||
The fingerprint can be obtained by executing
|
||||
<command>msmtp --serverinfo --tls --tls-certcheck=off</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
|
||||
@@ -24,6 +24,9 @@ let
|
||||
tls_starttls = onOff smtp.tls.useStartTls;
|
||||
tls_trust_file = smtp.tls.certificatesFile;
|
||||
}
|
||||
// optionalAttrs (msmtp.tls.fingerprint != null) {
|
||||
tls_fingerprint = msmtp.tls.fingerprint;
|
||||
}
|
||||
// optionalAttrs (smtp.port != null) {
|
||||
port = toString smtp.port;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,14 @@ let
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
|
||||
moduleConfigure =
|
||||
optionalAttrs (cfg.extraConfig != "") {
|
||||
customRC = cfg.extraConfig;
|
||||
}
|
||||
// optionalAttrs (cfg.plugins != []) {
|
||||
packages.home-manager.start = cfg.plugins;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -107,10 +115,17 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.neovim-unwrapped;
|
||||
defaultText = "pkgs.neovim-unwrapped";
|
||||
defaultText = literalExample "pkgs.neovim-unwrapped";
|
||||
description = "The package to use for the neovim binary.";
|
||||
};
|
||||
|
||||
finalPackage = mkOption {
|
||||
type = types.package;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
description = "Resulting customized neovim package.";
|
||||
};
|
||||
|
||||
configure = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
@@ -130,19 +145,63 @@ in
|
||||
description = ''
|
||||
Generate your init file from your list of plugins and custom commands,
|
||||
and loads it from the store via <command>nvim -u /nix/store/hash-vimrc</command>
|
||||
|
||||
</para><para>
|
||||
|
||||
This option is mutually exclusive with <varname>extraConfig</varname>
|
||||
and <varname>plugins</varname>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
set nocompatible
|
||||
set nobackup
|
||||
'';
|
||||
description = ''
|
||||
Custom vimrc lines.
|
||||
|
||||
</para><para>
|
||||
|
||||
This option is mutually exclusive with <varname>configure</varname>.
|
||||
'';
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = [ ];
|
||||
example = literalExample "[ pkgs.vimPlugins.yankring ]";
|
||||
description = ''
|
||||
List of vim plugins to install.
|
||||
|
||||
</para><para>
|
||||
|
||||
This option is mutually exclusive with <varname>configure</varname>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [
|
||||
(pkgs.wrapNeovim cfg.package {
|
||||
inherit (cfg)
|
||||
extraPython3Packages withPython3
|
||||
extraPythonPackages withPython
|
||||
withNodeJs withRuby viAlias vimAlias configure;
|
||||
})
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.configure == { } || moduleConfigure == { };
|
||||
message = "The programs.neovim option configure is mutually exclusive"
|
||||
+ " with extraConfig and plugins.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = [ cfg.finalPackage ];
|
||||
|
||||
programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package {
|
||||
inherit (cfg)
|
||||
extraPython3Packages withPython3
|
||||
extraPythonPackages withPython
|
||||
withNodeJs withRuby viAlias vimAlias;
|
||||
|
||||
configure = cfg.configure // moduleConfigure;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -188,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"
|
||||
|
||||
@@ -17,7 +17,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.opam;
|
||||
defaultText = "pkgs.opam";
|
||||
defaultText = literalExample "pkgs.opam";
|
||||
description = "Opam package to install.";
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.pidgin;
|
||||
defaultText = "pkgs.pidgin";
|
||||
defaultText = literalExample "pkgs.pidgin";
|
||||
description = "The Pidgin package to use.";
|
||||
};
|
||||
|
||||
|
||||
78
modules/programs/readline.nix
Normal file
78
modules/programs/readline.nix
Normal file
@@ -0,0 +1,78 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.readline;
|
||||
|
||||
mkSetVariableStr = n: v:
|
||||
let
|
||||
mkValueStr = v:
|
||||
if v == true then "on"
|
||||
else if v == false then "off"
|
||||
else if isInt v then toString v
|
||||
else if isString v then v
|
||||
else abort ("values ${toPretty v} is of unsupported type");
|
||||
in
|
||||
"set ${n} ${mkValueStr v}";
|
||||
|
||||
mkBindingStr = k: v: "\"${k}\": ${v}";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options.programs.readline = {
|
||||
enable = mkEnableOption "readline";
|
||||
|
||||
bindings = mkOption {
|
||||
default = {};
|
||||
type = types.attrsOf types.str;
|
||||
example = literalExample ''
|
||||
{ "\\C-h" = "backward-kill-word"; }
|
||||
'';
|
||||
description = "Readline bindings.";
|
||||
};
|
||||
|
||||
variables = mkOption {
|
||||
type = with types; attrsOf (either str (either int bool));
|
||||
default = {};
|
||||
example = { expand-tilde = true; };
|
||||
description = ''
|
||||
Readline customization variable assignments.
|
||||
'';
|
||||
};
|
||||
|
||||
includeSystemConfig = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to include the system-wide configuration.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Configuration lines appended unchanged to the end of the
|
||||
<filename>~/.inputrc</filename> file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.file.".inputrc".text =
|
||||
let
|
||||
configStr = concatStringsSep "\n" (
|
||||
optional cfg.includeSystemConfig "$include /etc/inputrc"
|
||||
++ mapAttrsToList mkSetVariableStr cfg.variables
|
||||
++ mapAttrsToList mkBindingStr cfg.bindings
|
||||
);
|
||||
in
|
||||
''
|
||||
# Generated by Home Manager.
|
||||
|
||||
${configStr}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
|
||||
37
modules/programs/rtorrent.nix
Normal file
37
modules/programs/rtorrent.nix
Normal file
@@ -0,0 +1,37 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.rtorrent;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.marsam ];
|
||||
|
||||
options.programs.rtorrent = {
|
||||
enable = mkEnableOption "rTorrent";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/rtorrent/rtorrent.rc</filename>. See
|
||||
<link xlink:href="https://github.com/rakshasa/rtorrent/wiki/Config-Guide" />
|
||||
for explanation about possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.rtorrent ];
|
||||
|
||||
xdg.configFile."rtorrent/rtorrent.rc" = mkIf (cfg.settings != "") {
|
||||
text = cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -107,7 +107,7 @@ in
|
||||
SKIM_CTRL_T_COMMAND = cfg.fileWidgetCommand;
|
||||
SKIM_CTRL_T_OPTS = cfg.fileWidgetOptions;
|
||||
SKIM_DEFAULT_COMMAND = cfg.defaultCommand;
|
||||
SKIM_DEFAULT_OPTS = cfg.defaultOptions;
|
||||
SKIM_DEFAULT_OPTIONS = cfg.defaultOptions;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -6,10 +6,56 @@ let
|
||||
|
||||
cfg = config.programs.ssh;
|
||||
|
||||
isPath = x: builtins.substring 0 1 (toString x) == "/";
|
||||
|
||||
addressPort = entry:
|
||||
if isPath entry.address
|
||||
then " ${entry.address}"
|
||||
else " [${entry.address}]:${toString entry.port}";
|
||||
|
||||
yn = flag: if flag then "yes" else "no";
|
||||
|
||||
unwords = builtins.concatStringsSep " ";
|
||||
|
||||
bindOptions = {
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
example = "example.org";
|
||||
description = "The address where to bind the port.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
example = 8080;
|
||||
description = "Specifies port number to bind on bind address.";
|
||||
};
|
||||
};
|
||||
|
||||
dynamicForwardModule = types.submodule {
|
||||
options = bindOptions;
|
||||
};
|
||||
|
||||
forwardModule = types.submodule {
|
||||
options = {
|
||||
bind = bindOptions;
|
||||
|
||||
host = {
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
example = "example.org";
|
||||
description = "The address where to forward the traffic to.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
example = 80;
|
||||
description = "Specifies port number to forward the traffic to.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
matchBlockModule = types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
host = mkOption {
|
||||
@@ -21,7 +67,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.";
|
||||
};
|
||||
@@ -152,6 +198,63 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
localForwards = mkOption {
|
||||
type = types.listOf forwardModule;
|
||||
default = [];
|
||||
example = literalExample ''
|
||||
[
|
||||
{
|
||||
bind.port = 8080;
|
||||
host.address = "10.0.0.13";
|
||||
host.port = 80;
|
||||
}
|
||||
];
|
||||
'';
|
||||
description = ''
|
||||
Specify local port forwardings. See
|
||||
<citerefentry>
|
||||
<refentrytitle>ssh_config</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry> for <literal>LocalForward</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
remoteForwards = mkOption {
|
||||
type = types.listOf forwardModule;
|
||||
default = [];
|
||||
example = literalExample ''
|
||||
[
|
||||
{
|
||||
bind.port = 8080;
|
||||
host.address = "10.0.0.13";
|
||||
host.port = 80;
|
||||
}
|
||||
];
|
||||
'';
|
||||
description = ''
|
||||
Specify remote port forwardings. See
|
||||
<citerefentry>
|
||||
<refentrytitle>ssh_config</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry> for <literal>RemoteForward</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
dynamicForwards = mkOption {
|
||||
type = types.listOf dynamicForwardModule;
|
||||
default = [];
|
||||
example = literalExample ''
|
||||
[ { port = 8080; } ];
|
||||
'';
|
||||
description = ''
|
||||
Specify dynamic port forwardings. See
|
||||
<citerefentry>
|
||||
<refentrytitle>ssh_config</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry> for <literal>DynamicForward</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
@@ -181,6 +284,9 @@ let
|
||||
++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}"
|
||||
++ optional (cf.proxyJump != null) " ProxyJump ${cf.proxyJump}"
|
||||
++ map (file: " IdentityFile ${file}") cf.identityFile
|
||||
++ map (f: " LocalForward" + addressPort f.bind + addressPort f.host) cf.localForwards
|
||||
++ map (f: " RemoteForward" + addressPort f.bind + addressPort f.host) cf.remoteForwards
|
||||
++ map (f: " DynamicForward" + addressPort f) cf.dynamicForwards
|
||||
++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions
|
||||
);
|
||||
|
||||
@@ -308,6 +414,25 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
# `builtins.any`/`lib.lists.any` does not return `true` if there are no elements.
|
||||
any' = pred: items: if items == [] then true else any pred items;
|
||||
# Check that if `entry.address` is defined, and is a path, that `entry.port` has not
|
||||
# been defined.
|
||||
noPathWithPort = entry: entry ? address && isPath entry.address -> !(entry ? port);
|
||||
checkDynamic = block: any' noPathWithPort block.dynamicForwards;
|
||||
checkBindAndHost = fwd: noPathWithPort fwd.bind && noPathWithPort fwd.host;
|
||||
checkLocal = block: any' checkBindAndHost block.localForwards;
|
||||
checkRemote = block: any' checkBindAndHost block.remoteForwards;
|
||||
checkMatchBlock = block: all (fn: fn block) [ checkLocal checkRemote checkDynamic ];
|
||||
in any' checkMatchBlock (builtins.attrValues cfg.matchBlocks);
|
||||
message = "Forwarded paths cannot have ports.";
|
||||
}
|
||||
];
|
||||
|
||||
home.file.".ssh/config".text = ''
|
||||
${concatStringsSep "\n" (
|
||||
mapAttrsToList (n: v: "${n} ${v}") cfg.extraOptionOverrides)}
|
||||
|
||||
91
modules/programs/starship.nix
Normal file
91
modules/programs/starship.nix
Normal file
@@ -0,0 +1,91 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.starship;
|
||||
|
||||
configFile = config:
|
||||
pkgs.runCommand "config.toml"
|
||||
{
|
||||
buildInputs = [ pkgs.remarshal ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
''
|
||||
remarshal -if json -of toml \
|
||||
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
|
||||
> $out
|
||||
'';
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.marsam ];
|
||||
|
||||
options.programs.starship = {
|
||||
enable = mkEnableOption "starship";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/starship.toml</filename>.
|
||||
</para><para>
|
||||
See <link xlink:href="https://starship.rs/config/" /> for the full list
|
||||
of options.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.starship ];
|
||||
|
||||
xdg.configFile."starship.toml" = mkIf (cfg.settings != {}) {
|
||||
source = configFile cfg.settings;
|
||||
};
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ -z $INSIDE_EMACS ]]; then
|
||||
eval "$(${pkgs.starship}/bin/starship init bash)"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
if [ -z "$INSIDE_EMACS" ]; then
|
||||
eval "$(${pkgs.starship}/bin/starship init zsh)"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
if test -z "$INSIDE_EMACS"
|
||||
eval (${pkgs.starship}/bin/starship init fish)
|
||||
end
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -178,7 +178,7 @@ in
|
||||
scrollbar = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr (types.enum [ "off" "left" "right" ]);
|
||||
description = "Scroll to the bottom when the shell generates output.";
|
||||
description = "Scrollbar position.";
|
||||
};
|
||||
|
||||
backgroundColor = mkOption {
|
||||
|
||||
@@ -65,6 +65,11 @@ let
|
||||
bind C-${cfg.shortcut} last-window
|
||||
''}
|
||||
|
||||
${optionalString cfg.disableConfirmationPrompt ''
|
||||
bind-key & kill-window
|
||||
bind-key x kill-pane
|
||||
''}
|
||||
|
||||
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}
|
||||
@@ -109,6 +114,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
disableConfirmationPrompt = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Disable confirmation prompt before killing a pane or window
|
||||
'';
|
||||
};
|
||||
|
||||
enable = mkEnableOption "tmux";
|
||||
|
||||
escapeTime = mkOption {
|
||||
@@ -156,7 +169,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.tmux;
|
||||
defaultText = "pkgs.tmux";
|
||||
defaultText = literalExample "pkgs.tmux";
|
||||
example = literalExample "pkgs.tmux";
|
||||
description = "The tmux package to install";
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.rxvt_unicode;
|
||||
defaultText = "pkgs.rxvt_unicode";
|
||||
defaultText = literalExample "pkgs.rxvt_unicode";
|
||||
description = "rxvt-unicode package to install.";
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ with lib;
|
||||
let
|
||||
|
||||
cfg = config.programs.vim;
|
||||
defaultPlugins = [ "sensible" ];
|
||||
defaultPlugins = [ pkgs.vimPlugins.sensible ];
|
||||
|
||||
knownSettings = {
|
||||
background = types.enum [ "dark" "light" ];
|
||||
@@ -55,6 +55,16 @@ let
|
||||
in
|
||||
optionalString (value != null) ("set " + v);
|
||||
|
||||
plugins =
|
||||
let
|
||||
vpkgs = pkgs.vimPlugins;
|
||||
getPkg = p:
|
||||
if isDerivation p
|
||||
then [ p ]
|
||||
else optional (isString p && hasAttr p vpkgs) vpkgs.${p};
|
||||
in
|
||||
concatMap getPkg cfg.plugins;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -63,12 +73,16 @@ in
|
||||
enable = mkEnableOption "Vim";
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.str;
|
||||
type = with types; listOf (either str package);
|
||||
default = defaultPlugins;
|
||||
example = [ "YankRing" ];
|
||||
example = literalExample ''[ pkgs.vimPlugins.YankRing ]'';
|
||||
description = ''
|
||||
List of vim plugins to install. To get a list of supported plugins run:
|
||||
<command>nix-env -f '<nixpkgs>' -qaP -A vimPlugins</command>.
|
||||
|
||||
</para><para>
|
||||
|
||||
Note: String values are deprecated, please use actual packages.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -135,16 +149,43 @@ in
|
||||
|
||||
vim = pkgs.vim_configurable.customize {
|
||||
name = "vim";
|
||||
vimrcConfig.customRC = customRC;
|
||||
vimrcConfig.vam.knownPlugins = pkgs.vimPlugins;
|
||||
vimrcConfig.vam.pluginDictionaries = [
|
||||
{ names = defaultPlugins ++ cfg.plugins; }
|
||||
];
|
||||
};
|
||||
vimrcConfig = {
|
||||
inherit customRC;
|
||||
|
||||
in mkIf cfg.enable {
|
||||
programs.vim.package = vim;
|
||||
home.packages = [ cfg.package ];
|
||||
}
|
||||
packages.home-manager.start = plugins;
|
||||
};
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
assertions =
|
||||
let
|
||||
packagesNotFound = filter (p: isString p && (!hasAttr p pkgs.vimPlugins)) cfg.plugins;
|
||||
in
|
||||
[
|
||||
{
|
||||
assertion = packagesNotFound == [];
|
||||
message = "Following VIM plugin not found in pkgs.vimPlugins: ${
|
||||
concatMapStringsSep ", " (p: ''"${p}"'') packagesNotFound
|
||||
}";
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
let
|
||||
stringPlugins = filter isString cfg.plugins;
|
||||
in
|
||||
optional (stringPlugins != []) ''
|
||||
Specifying VIM plugins using strings is deprecated, found ${
|
||||
concatMapStringsSep ", " (p: ''"${p}"'') stringPlugins
|
||||
} as strings.
|
||||
'';
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
programs.vim = {
|
||||
package = vim;
|
||||
plugins = defaultPlugins;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@ 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
|
||||
|
||||
{
|
||||
@@ -23,14 +29,15 @@ in
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/Code/User/settings.json</filename>.
|
||||
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.
|
||||
@@ -46,7 +53,6 @@ in
|
||||
})
|
||||
];
|
||||
|
||||
xdg.configFile."Code/User/settings.json".text =
|
||||
builtins.toJSON cfg.userSettings;
|
||||
home.file."${configFilePath}".text = builtins.toJSON cfg.userSettings;
|
||||
};
|
||||
}
|
||||
|
||||
66
modules/programs/vscode/haskell.nix
Normal file
66
modules/programs/vscode/haskell.nix
Normal file
@@ -0,0 +1,66 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.vscode.haskell;
|
||||
|
||||
defaultHieNixExe = hie-nix.hies + "/bin/hie-wrapper";
|
||||
defaultHieNixExeText = literalExample
|
||||
"\"\${pkgs.hie-nix.hies}/bin/hie-wrapper\"";
|
||||
|
||||
hie-nix = pkgs.hie-nix or (abort ''
|
||||
vscode.haskell: pkgs.hie-nix missing. Please add an overlay such as:
|
||||
${exampleOverlay}
|
||||
'');
|
||||
|
||||
exampleOverlay = ''
|
||||
nixpkgs.overlays = [
|
||||
(self: super: { hie-nix = import ~/src/hie-nix {}; })
|
||||
]
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options.programs.vscode.haskell = {
|
||||
enable = mkEnableOption "Haskell integration for Visual Studio Code";
|
||||
|
||||
hie.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable Haskell IDE engine integration.";
|
||||
};
|
||||
|
||||
hie.executablePath = mkOption {
|
||||
type = types.path;
|
||||
default = defaultHieNixExe;
|
||||
defaultText = defaultHieNixExeText;
|
||||
description = ''
|
||||
The path to the Haskell IDE Engine executable.
|
||||
</para><para>
|
||||
Because hie-nix is not packaged in Nixpkgs, you need to add it as an
|
||||
overlay or set this option. Example overlay configuration:
|
||||
<programlisting language="nix">${exampleOverlay}</programlisting>
|
||||
'';
|
||||
example = literalExample ''
|
||||
(import ~/src/haskell-ide-engine {}).hies + "/bin/hie-wrapper";
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.vscode.userSettings = mkIf cfg.hie.enable {
|
||||
"languageServerHaskell.enableHIE" = true;
|
||||
"languageServerHaskell.hieExecutablePath" = cfg.hie.executablePath;
|
||||
};
|
||||
|
||||
programs.vscode.extensions =
|
||||
[
|
||||
pkgs.vscode-extensions.justusadam.language-haskell
|
||||
]
|
||||
++ lib.optional cfg.hie.enable
|
||||
pkgs.vscode-extensions.alanz.vscode-hie-server;
|
||||
};
|
||||
}
|
||||
86
modules/programs/z-lua.nix
Normal file
86
modules/programs/z-lua.nix
Normal file
@@ -0,0 +1,86 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.z-lua;
|
||||
|
||||
aliases = {
|
||||
zz = "z -c"; # restrict matches to subdirs of $PWD
|
||||
zi = "z -i"; # cd with interactive selection
|
||||
zf = "z -I"; # use fzf to select in multiple matches
|
||||
zb = "z -b"; # quickly cd to the parent directory
|
||||
zh = "z -I -t ."; # fzf
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.marsam ];
|
||||
|
||||
options.programs.z-lua = {
|
||||
enable = mkEnableOption "z.lua";
|
||||
|
||||
options = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "enhanced" "once" "fzf" ];
|
||||
description = ''
|
||||
List of options to pass to z.lua.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableAliases = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable recommended z.lua aliases.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.z-lua ];
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
eval "$(${pkgs.z-lua}/bin/z --init bash ${concatStringsSep " " cfg.options})"
|
||||
'';
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${pkgs.z-lua}/bin/z --init zsh ${concatStringsSep " " cfg.options})"
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
source (${pkgs.z-lua}/bin/z --init fish ${concatStringsSep " " cfg.options} | psub)
|
||||
'';
|
||||
|
||||
programs.bash.shellAliases = mkIf cfg.enableAliases aliases;
|
||||
|
||||
programs.zsh.shellAliases = mkIf cfg.enableAliases aliases;
|
||||
};
|
||||
}
|
||||
@@ -149,6 +149,14 @@ in
|
||||
programs.zsh = {
|
||||
enable = mkEnableOption "Z shell (Zsh)";
|
||||
|
||||
autocd = mkOption {
|
||||
default = null;
|
||||
description = ''
|
||||
Automatically enter into a directory if typed directly into shell.
|
||||
'';
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
|
||||
dotDir = mkOption {
|
||||
default = null;
|
||||
example = ".config/zsh";
|
||||
@@ -202,17 +210,29 @@ in
|
||||
|
||||
sessionVariables = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (either int str);
|
||||
type = types.attrs;
|
||||
example = { MAILCHECK = 30; };
|
||||
description = "Environment variables that will be set for zsh session.";
|
||||
};
|
||||
|
||||
initExtraBeforeCompInit = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to <filename>.zshrc</filename> before compinit.";
|
||||
};
|
||||
|
||||
initExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to <filename>.zshrc</filename>.";
|
||||
};
|
||||
|
||||
envExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to <filename>.zshenv</filename>.";
|
||||
};
|
||||
|
||||
profileExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
@@ -279,6 +299,10 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
(mkIf (cfg.envExtra != "") {
|
||||
home.file."${relToDotDir ".zshenv"}".text = cfg.envExtra;
|
||||
})
|
||||
|
||||
(mkIf (cfg.profileExtra != "") {
|
||||
home.file."${relToDotDir ".zprofile"}".text = cfg.profileExtra;
|
||||
})
|
||||
@@ -294,7 +318,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";
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -333,12 +357,20 @@ in
|
||||
|
||||
${localVarsStr}
|
||||
|
||||
${cfg.initExtraBeforeCompInit}
|
||||
|
||||
${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"
|
||||
}
|
||||
@@ -378,6 +410,7 @@ in
|
||||
${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST
|
||||
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
|
||||
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
|
||||
${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}
|
||||
|
||||
${cfg.initExtra}
|
||||
|
||||
@@ -387,10 +420,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,15 +5,18 @@ with lib;
|
||||
{
|
||||
options = {
|
||||
services.blueman-applet = {
|
||||
enable = mkEnableOption ''
|
||||
Blueman applet.
|
||||
|
||||
Note, for the applet to work, 'blueman' package should also be installed system-wide
|
||||
since it requires running 'blueman-mechanism' service activated via dbus.
|
||||
You can add it to the dbus packages in system configuration:
|
||||
|
||||
services.dbus.packages = [ pkgs.blueman ];
|
||||
'';
|
||||
enable = mkEnableOption "" // {
|
||||
description = ''
|
||||
Whether to enable the Blueman applet.
|
||||
</para><para>
|
||||
Note, for the applet to work, the 'blueman' service should
|
||||
be enabled system-wide. You can enable it in the system
|
||||
configuration using
|
||||
<programlisting language="nix">
|
||||
services.blueman.enable = true;
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ in {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.compton;
|
||||
defaultText = "pkgs.compton";
|
||||
defaultText = literalExample "pkgs.compton";
|
||||
example = literalExample "pkgs.compton";
|
||||
description = ''
|
||||
Compton derivation to use.
|
||||
|
||||
70
modules/services/dwm-status.nix
Normal file
70
modules/services/dwm-status.nix
Normal file
@@ -0,0 +1,70 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.dwm-status;
|
||||
|
||||
features = [ "audio" "backlight" "battery" "cpu_load" "network" "time" ];
|
||||
|
||||
configText = builtins.toJSON ({ inherit (cfg) order; } // cfg.extraConfig);
|
||||
|
||||
configFile = pkgs.writeText "dwm-status.json" configText;
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.dwm-status = {
|
||||
enable = mkEnableOption "dwm-status user service";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.dwm-status;
|
||||
defaultText = literalExample "pkgs.dwm-status";
|
||||
example = "pkgs.dwm-status.override { enableAlsaUtils = false; }";
|
||||
description = "Which dwm-status package to use.";
|
||||
};
|
||||
|
||||
order = mkOption {
|
||||
type = types.listOf (types.enum features);
|
||||
description = "List of enabled features in order.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
separator = "#";
|
||||
|
||||
battery = {
|
||||
notifier_levels = [ 2 5 10 15 20 ];
|
||||
};
|
||||
|
||||
time = {
|
||||
format = "%H:%M";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = "Extra config of dwm-status.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.dwm-status = {
|
||||
Unit = {
|
||||
Description = "DWM status service";
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${cfg.package}/bin/dwm-status ${configFile}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -35,7 +35,7 @@ in
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.stdenv.shell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
|
||||
ExecStart = "${pkgs.runtimeShell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
|
||||
ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs)'";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@ in
|
||||
|
||||
systemd.user.services.flameshot = {
|
||||
Unit = {
|
||||
Description = "Powerful yet simple to use screenshot software";
|
||||
Description = "Flameshot screenshot tool";
|
||||
After = [
|
||||
"graphical-session-pre.target"
|
||||
"polybar.service"
|
||||
|
||||
61
modules/services/getmail.nix
Normal file
61
modules/services/getmail.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.getmail;
|
||||
|
||||
accounts = filter (a: a.getmail.enable)
|
||||
(attrValues config.accounts.email.accounts);
|
||||
|
||||
# Note: The getmail service does not expect a path, but just the filename!
|
||||
renderConfigFilepath = a: if a.primary then "getmailrc" else "getmail${a.name}";
|
||||
configFiles = concatMapStringsSep " " (a: " --rcfile ${renderConfigFilepath a}") accounts;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.getmail = {
|
||||
enable = mkEnableOption "the getmail systemd service to automatically retrieve mail";
|
||||
|
||||
frequency = mkOption {
|
||||
type = types.str;
|
||||
default = "*:0/5";
|
||||
example = "hourly";
|
||||
description = ''
|
||||
The refresh frequency. Check <literal>man systemd.time</literal> for
|
||||
more information on the syntax. If you use a gpg-agent in
|
||||
combination with the passwordCommand, keep the poll
|
||||
frequency below the cache-ttl value (as set by the
|
||||
<literal>default</literal>) to avoid pinentry asking
|
||||
permanently for a password.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.getmail = {
|
||||
Unit = {
|
||||
Description = "getmail email fetcher";
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.getmail}/bin/getmail ${configFiles}";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.timers.getmail = {
|
||||
Unit = {
|
||||
Description = "getmail email fetcher";
|
||||
};
|
||||
Timer = {
|
||||
OnCalendar = "${cfg.frequency}";
|
||||
Unit = "getmail.service";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
@@ -70,6 +70,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sshKeys = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
Which GPG keys (by keygrip) to expose as SSH keys.
|
||||
'';
|
||||
};
|
||||
|
||||
enableExtraSocket = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -157,6 +165,11 @@ in
|
||||
programs.zsh.initExtra = gpgInitStr;
|
||||
}
|
||||
|
||||
(mkIf (cfg.sshKeys != null) {
|
||||
# Trailing newlines are important
|
||||
home.file.".gnupg/sshcontrol".text = concatMapStrings (s: "${s}\n") cfg.sshKeys;
|
||||
})
|
||||
|
||||
# The systemd units below are direct translations of the
|
||||
# descriptions in the
|
||||
#
|
||||
|
||||
84
modules/services/hound.nix
Normal file
84
modules/services/hound.nix
Normal file
@@ -0,0 +1,84 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.hound;
|
||||
|
||||
configFile = pkgs.writeText "hound-config.json" (
|
||||
builtins.toJSON {
|
||||
max-concurrent-indexers = cfg.maxConcurrentIndexers;
|
||||
dbpath = cfg.databasePath;
|
||||
repos = cfg.repositories;
|
||||
health-check-url = "/healthz";
|
||||
}
|
||||
);
|
||||
|
||||
houndOptions = [
|
||||
"--addr ${cfg.listenAddress}"
|
||||
"--conf ${configFile}"
|
||||
];
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.adisbladis ];
|
||||
|
||||
options.services.hound = {
|
||||
enable = mkEnableOption "hound";
|
||||
|
||||
maxConcurrentIndexers = mkOption {
|
||||
type = types.ints.positive;
|
||||
default = 2;
|
||||
description = "Limit the amount of concurrent indexers.";
|
||||
};
|
||||
|
||||
databasePath = mkOption {
|
||||
type = types.path;
|
||||
default = "${config.xdg.dataHome}/hound";
|
||||
defaultText = "\$XDG_DATA_HOME/hound";
|
||||
description = "The Hound database path.";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost:6080";
|
||||
description = "Listen address of the Hound daemon.";
|
||||
};
|
||||
|
||||
repositories = mkOption {
|
||||
type = types.attrsOf (types.uniq types.attrs);
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
SomeGitRepo = {
|
||||
url = "https://www.github.com/YourOrganization/RepoOne.git";
|
||||
ms-between-poll = 10000;
|
||||
exclude-dot-files = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = "The repository configuration.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.hound ];
|
||||
|
||||
systemd.user.services.hound = {
|
||||
Unit = {
|
||||
Description = "Hound source code search engine";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Environment = "PATH=${makeBinPath [ pkgs.mercurial pkgs.git ]}";
|
||||
ExecStart = "${pkgs.hound}/bin/houndd ${concatStringsSep " " houndOptions}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
30
modules/services/imapnotify-accounts.nix
Normal file
30
modules/services/imapnotify-accounts.nix
Normal file
@@ -0,0 +1,30 @@
|
||||
{ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.imapnotify = {
|
||||
enable = mkEnableOption "imapnotify";
|
||||
|
||||
onNotify = mkOption {
|
||||
type = with types; either str (attrsOf str);
|
||||
default = "";
|
||||
example = "\${pkgs.isync}/bin/mbsync test-%s";
|
||||
description = "Shell commands to run on any event.";
|
||||
};
|
||||
|
||||
onNotifyPost = mkOption {
|
||||
type = with types; either str (attrsOf str);
|
||||
default = "";
|
||||
example = { mail = "\${pkgs.notmuch}/bin/notmuch new && \${pkgs.libnotify}/bin/notify-send 'New mail arrived'"; };
|
||||
description = "Shell commands to run after onNotify event.";
|
||||
};
|
||||
|
||||
boxes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "Inbox" "[Gmail]/MyLabel" ];
|
||||
description = "IMAP folders to watch.";
|
||||
};
|
||||
};
|
||||
}
|
||||
107
modules/services/imapnotify.nix
Normal file
107
modules/services/imapnotify.nix
Normal file
@@ -0,0 +1,107 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.imapnotify;
|
||||
|
||||
safeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""];
|
||||
|
||||
imapnotifyAccounts =
|
||||
filter (a: a.imapnotify.enable)
|
||||
(attrValues config.accounts.email.accounts);
|
||||
|
||||
genAccountUnit = account:
|
||||
let
|
||||
name = safeName account.name;
|
||||
in
|
||||
{
|
||||
name = "imapnotify-${name}";
|
||||
value = {
|
||||
Unit = {
|
||||
Description = "imapnotify for ${name}";
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.imapnotify}/bin/imapnotify -c ${genAccountConfig account}";
|
||||
} // optionalAttrs account.notmuch.enable {
|
||||
Environment = "NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
genAccountConfig = account:
|
||||
pkgs.writeText "imapnotify-${safeName account.name}-config.js" (
|
||||
let
|
||||
port =
|
||||
if account.imap.port != null then account.imap.port
|
||||
else if account.imap.tls.enable then 993
|
||||
else 143;
|
||||
|
||||
toJSON = builtins.toJSON;
|
||||
in
|
||||
''
|
||||
var child_process = require('child_process');
|
||||
|
||||
function getStdout(cmd) {
|
||||
var stdout = child_process.execSync(cmd);
|
||||
return stdout.toString().trim();
|
||||
}
|
||||
|
||||
exports.host = ${toJSON account.imap.host}
|
||||
exports.port = ${toJSON port};
|
||||
exports.tls = ${toJSON account.imap.tls.enable};
|
||||
exports.username = ${toJSON account.userName};
|
||||
exports.password = getStdout("${toString account.passwordCommand}");
|
||||
exports.onNotify = ${toJSON account.imapnotify.onNotify};
|
||||
exports.onNotifyPost = ${toJSON account.imapnotify.onNotifyPost};
|
||||
exports.boxes = ${toJSON account.imapnotify.boxes};
|
||||
''
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.nickhu ];
|
||||
|
||||
options = {
|
||||
services.imapnotify = {
|
||||
enable = mkEnableOption "imapnotify";
|
||||
};
|
||||
|
||||
accounts.email.accounts = mkOption {
|
||||
type = with types; attrsOf (submodule (
|
||||
import ./imapnotify-accounts.nix
|
||||
));
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions =
|
||||
let
|
||||
checkAccounts = pred: msg:
|
||||
let
|
||||
badAccounts = filter pred imapnotifyAccounts;
|
||||
in
|
||||
{
|
||||
assertion = badAccounts == [];
|
||||
message = "imapnotify: Missing ${msg} for accounts: "
|
||||
+ concatMapStringsSep ", " (a: a.name) badAccounts;
|
||||
};
|
||||
in
|
||||
[
|
||||
(checkAccounts (a: a.maildir == null) "maildir configuration")
|
||||
(checkAccounts (a: a.imap == null) "IMAP configuration")
|
||||
(checkAccounts (a: a.passwordCommand == null) "password command")
|
||||
(checkAccounts (a: a.userName == null) "username")
|
||||
];
|
||||
|
||||
systemd.user.services =
|
||||
listToAttrs (map genAccountUnit imapnotifyAccounts);
|
||||
};
|
||||
}
|
||||
@@ -42,7 +42,7 @@ in
|
||||
|
||||
Service = {
|
||||
Environment = "PATH=${config.home.profileDirectory}/bin";
|
||||
ExecStart = "${package}/lib/libexec/kdeconnectd";
|
||||
ExecStart = "${package}/libexec/kdeconnectd";
|
||||
Restart = "on-abort";
|
||||
};
|
||||
};
|
||||
|
||||
58
modules/services/lorri.nix
Normal file
58
modules/services/lorri.nix
Normal file
@@ -0,0 +1,58 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.lorri;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.gerschtli ];
|
||||
|
||||
options = {
|
||||
services.lorri.enable = mkEnableOption "lorri build daemon";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.lorri ];
|
||||
|
||||
systemd.user = {
|
||||
services.lorri = {
|
||||
Unit = {
|
||||
Description = "lorri build daemon";
|
||||
Requires = "lorri.socket";
|
||||
After = "lorri.socket";
|
||||
RefuseManualStart = true;
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.lorri}/bin/lorri daemon";
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = "read-only";
|
||||
Restart = "on-failure";
|
||||
Environment =
|
||||
let path = with pkgs; makeSearchPath "bin" [ nix gitMinimal gnutar gzip ];
|
||||
in "PATH=${path}";
|
||||
};
|
||||
};
|
||||
|
||||
sockets.lorri = {
|
||||
Unit = {
|
||||
Description = "Socket for lorri build daemon";
|
||||
};
|
||||
|
||||
Socket = {
|
||||
ListenStream = "%t/lorri/daemon.socket";
|
||||
RuntimeDirectory = "lorri";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "sockets.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -22,7 +22,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.isync;
|
||||
defaultText = "pkgs.isync";
|
||||
defaultText = literalExample "pkgs.isync";
|
||||
example = literalExample "pkgs.isync";
|
||||
description = "The package to use for the mbsync binary.";
|
||||
};
|
||||
@@ -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.
|
||||
@@ -83,7 +83,6 @@ in
|
||||
systemd.user.services.mbsync = {
|
||||
Unit = {
|
||||
Description = "mbsync mailbox synchronization";
|
||||
PartOf = [ "network-online.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
|
||||
@@ -16,7 +16,6 @@ let
|
||||
''}
|
||||
state_file "${cfg.dataDir}/state"
|
||||
sticker_file "${cfg.dataDir}/sticker.sql"
|
||||
log_file "syslog"
|
||||
|
||||
${optionalString (cfg.network.listenAddress != "any")
|
||||
''bind_to_address "${cfg.network.listenAddress}"''}
|
||||
@@ -46,6 +45,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 +55,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 +80,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 +100,7 @@ in {
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.ints.positive;
|
||||
type = types.port;
|
||||
default = 6600;
|
||||
description = ''
|
||||
The TCP port on which the the daemon will listen.
|
||||
|
||||
@@ -42,7 +42,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.mpdris2;
|
||||
defaultText = "pkgs.mpdris2";
|
||||
defaultText = literalExample "pkgs.mpdris2";
|
||||
description = "The mpDris2 package to use.";
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ in
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.ints.positive;
|
||||
type = types.port;
|
||||
default = config.services.mpd.network.port;
|
||||
defaultText = "config.services.mpd.network.port";
|
||||
description = ''
|
||||
@@ -86,15 +86,21 @@ in
|
||||
xdg.configFile."mpDris2/mpDris2.conf".text = toIni mpdris2Conf;
|
||||
|
||||
systemd.user.services.mpdris2 = {
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
Unit = {
|
||||
Description = "MPRIS 2 support for MPD";
|
||||
After = [ "graphical-session-pre.target" "mpd.service" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
After = [ "mpd.service" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "simple";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
ExecStart = "${cfg.package}/bin/mpDris2";
|
||||
BusName = "org.mpris.MediaPlayer2.mpd";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
211
modules/services/muchsync.nix
Normal file
211
modules/services/muchsync.nix
Normal file
@@ -0,0 +1,211 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
# Documentation was partially copied from the muchsync manual.
|
||||
# See http://www.muchsync.org/muchsync.html
|
||||
|
||||
let
|
||||
cfg = config.services.muchsync;
|
||||
syncOptions = {
|
||||
options = {
|
||||
frequency = mkOption {
|
||||
type = types.str;
|
||||
default = "*:0/5";
|
||||
description = ''
|
||||
How often to run <command>muchsync</command>. This
|
||||
value is passed to the systemd timer configuration as the
|
||||
<literal>OnCalendar</literal> option. See
|
||||
<citerefentry>
|
||||
<refentrytitle>systemd.time</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
</citerefentry>
|
||||
for more information about the format.
|
||||
'';
|
||||
};
|
||||
|
||||
sshCommand = mkOption {
|
||||
type = types.str;
|
||||
default = "${pkgs.openssh}/bin/ssh -CTaxq";
|
||||
defaultText = "ssh -CTaxq";
|
||||
description = ''
|
||||
Specifies a command line to pass to <command>/bin/sh</command>
|
||||
to execute a command on another machine.
|
||||
</para><para>
|
||||
Note that because this string is passed to the shell,
|
||||
special characters including spaces may need to be escaped.
|
||||
'';
|
||||
};
|
||||
|
||||
upload = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to propagate local changes to the remote.
|
||||
'';
|
||||
};
|
||||
|
||||
local = {
|
||||
checkForModifiedFiles = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Check for locally modified files.
|
||||
Without this option, muchsync assumes that files in a maildir are
|
||||
never edited.
|
||||
</para><para>
|
||||
<option>checkForModifiedFiles</option> disables certain
|
||||
optimizations so as to make muchsync at least check the timestamp on
|
||||
every file, which will detect modified files at the cost of a longer
|
||||
startup time.
|
||||
</para><para>
|
||||
This option is useful if your software regularly modifies the
|
||||
contents of mail files (e.g., because you are running offlineimap
|
||||
with "synclabels = yes").
|
||||
'';
|
||||
};
|
||||
|
||||
importNew = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to begin the synchronisation by running
|
||||
<command>notmuch new</command> locally.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
remote = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Remote SSH host to synchronize with.
|
||||
'';
|
||||
};
|
||||
|
||||
muchsyncPath = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
defaultText = "$PATH/muchsync";
|
||||
description = ''
|
||||
Specifies the path to muchsync on the server.
|
||||
Ordinarily, muchsync should be in the default PATH on the server
|
||||
so this option is not required.
|
||||
However, this option is useful if you have to install muchsync in
|
||||
a non-standard place or wish to test development versions of the
|
||||
code.
|
||||
'';
|
||||
};
|
||||
|
||||
checkForModifiedFiles = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Check for modified files on the remote side.
|
||||
Without this option, muchsync assumes that files in a maildir are
|
||||
never edited.
|
||||
</para><para>
|
||||
<option>checkForModifiedFiles</option> disables certain
|
||||
optimizations so as to make muchsync at least check the timestamp on
|
||||
every file, which will detect modified files at the cost of a longer
|
||||
startup time.
|
||||
</para><para>
|
||||
This option is useful if your software regularly modifies the
|
||||
contents of mail files (e.g., because you are running offlineimap
|
||||
with "synclabels = yes").
|
||||
'';
|
||||
};
|
||||
|
||||
importNew = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to begin the synchronisation by running
|
||||
<command>notmuch new</command> on the remote side.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
|
||||
options.services.muchsync = {
|
||||
remotes = mkOption {
|
||||
type = with types; attrsOf (submodule syncOptions);
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
server = {
|
||||
frequency = "*:0/10";
|
||||
remote.host = "server.tld";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Muchsync remotes to synchronise with.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
mapRemotes = gen: with attrsets; mapAttrs'
|
||||
(name: remoteCfg: nameValuePair "muchsync-${name}" (gen name remoteCfg))
|
||||
cfg.remotes;
|
||||
in mkIf (cfg.remotes != { }) {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.programs.notmuch.enable;
|
||||
message = ''
|
||||
The muchsync module requires 'programs.notmuch.enable = true'.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
systemd.user.services = mapRemotes (name: remoteCfg: {
|
||||
Unit = {
|
||||
Description = "muchsync sync service (${name})";
|
||||
};
|
||||
Service = {
|
||||
CPUSchedulingPolicy = "idle";
|
||||
IOSchedulingClass = "idle";
|
||||
Environment = [
|
||||
''"PATH=${pkgs.notmuch}/bin"''
|
||||
''"NOTMUCH_CONFIG=${config.home.sessionVariables.NOTMUCH_CONFIG}"''
|
||||
''"NMBGIT=${config.home.sessionVariables.NMBGIT}"''
|
||||
];
|
||||
ExecStart = concatStringsSep " " (
|
||||
[ "${pkgs.muchsync}/bin/muchsync" ]
|
||||
++ [ "-s ${escapeShellArg remoteCfg.sshCommand}" ]
|
||||
++ optional (!remoteCfg.upload) "--noup"
|
||||
|
||||
# local configuration
|
||||
++ optional remoteCfg.local.checkForModifiedFiles "-F"
|
||||
++ optional (!remoteCfg.local.importNew) "--nonew"
|
||||
|
||||
# remote configuration
|
||||
++ [ (escapeShellArg remoteCfg.remote.host) ]
|
||||
++ optional (remoteCfg.remote.muchsyncPath != "")
|
||||
"-r ${escapeShellArg remoteCfg.remote.muchsyncPath}"
|
||||
++ optional remoteCfg.remote.checkForModifiedFiles "-F"
|
||||
++ optional (!remoteCfg.remote.importNew) "--nonew"
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
systemd.user.timers = mapRemotes (name: remoteCfg: {
|
||||
Unit = {
|
||||
Description = "muchsync periodic sync (${name})";
|
||||
};
|
||||
Timer = {
|
||||
Unit = "muchsync-${name}.service";
|
||||
OnCalendar = remoteCfg.frequency;
|
||||
Persistent = true;
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "timers.target" ];
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -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"
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.polybar;
|
||||
defaultText = "pkgs.polybar";
|
||||
defaultText = literalExample "pkgs.polybar";
|
||||
description = "Polybar package to install.";
|
||||
example = literalExample ''
|
||||
pkgs.polybar.override {
|
||||
@@ -131,6 +131,7 @@ in
|
||||
scriptPkg = pkgs.writeShellScriptBin "polybar-start" cfg.script;
|
||||
in
|
||||
"${scriptPkg}/bin/polybar-start";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
Install = {
|
||||
|
||||
@@ -6,6 +6,15 @@ let
|
||||
|
||||
cfg = config.services.random-background;
|
||||
|
||||
flags = lib.concatStringsSep " " (
|
||||
[
|
||||
"--bg-${cfg.display}"
|
||||
"--no-fehbg"
|
||||
"--randomize"
|
||||
]
|
||||
++ lib.optional (!cfg.enableXinerama) "--no-xinerama"
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -13,7 +22,17 @@ in
|
||||
|
||||
options = {
|
||||
services.random-background = {
|
||||
enable = mkEnableOption "random desktop background";
|
||||
enable = mkEnableOption "" // {
|
||||
description = ''
|
||||
Whether to enable random desktop background.
|
||||
</para><para>
|
||||
Note, if you are using NixOS and have set up a custom
|
||||
desktop manager session for Home Manager, then the session
|
||||
configuration must have the <option>bgSupport</option>
|
||||
option set to <literal>true</literal> or the background
|
||||
image set by this module may be overwritten.
|
||||
'';
|
||||
};
|
||||
|
||||
imageDirectory = mkOption {
|
||||
type = types.str;
|
||||
@@ -25,6 +44,12 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
display = mkOption {
|
||||
type = types.enum [ "center" "fill" "max" "scale" "tile" ];
|
||||
default = "fill";
|
||||
description = "Display background images according to this option.";
|
||||
};
|
||||
|
||||
interval = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
@@ -35,6 +60,16 @@ in
|
||||
as a duration understood by systemd.
|
||||
'';
|
||||
};
|
||||
|
||||
enableXinerama = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Will place a separate image per screen when enabled,
|
||||
otherwise a single image will be stretched across all
|
||||
screens.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -50,7 +85,7 @@ in
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.feh}/bin/feh --randomize --bg-fill ${cfg.imageDirectory}";
|
||||
ExecStart = "${pkgs.feh}/bin/feh ${flags} ${cfg.imageDirectory}";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user