1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2024-12-14 11:57:55 +00:00

Apply nixfmt on many files

This commit is contained in:
Robert Helgesson 2020-02-02 00:39:17 +01:00
parent 9799d3de2d
commit 45abf3d38a
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
177 changed files with 2850 additions and 3565 deletions

View file

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

View file

@ -1,8 +1,6 @@
{ {
# Note, this should be "the standard library" + HM extensions. # Note, this should be "the standard library" + HM extensions.
lib lib, pkgs }:
, pkgs
}:
let let
@ -19,23 +17,19 @@ let
# Make sure the used package is scrubbed to avoid actually # Make sure the used package is scrubbed to avoid actually
# instantiating derivations. # instantiating derivations.
scrubbedPkgsModule = { scrubbedPkgsModule = {
imports = [ imports = [{
{ _module.args = {
_module.args = { pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs); pkgs_i686 = lib.mkForce { };
pkgs_i686 = lib.mkForce { }; };
}; }];
}
];
}; };
hmModulesDocs = nmd.buildModulesDocs { hmModulesDocs = nmd.buildModulesDocs {
modules = modules = import ../modules/modules.nix {
import ../modules/modules.nix { inherit lib pkgs;
inherit lib pkgs; check = false;
check = false; } ++ [ scrubbedPkgsModule ];
}
++ [ scrubbedPkgsModule ];
moduleRootPaths = [ ./.. ]; moduleRootPaths = [ ./.. ];
mkModuleUrl = path: mkModuleUrl = path:
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path"; "https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
@ -58,9 +52,7 @@ let
''; '';
}; };
in in {
{
inherit nmdSrc; inherit nmdSrc;
options = { options = {
@ -71,7 +63,5 @@ in
manPages = docs.manPages; manPages = docs.manPages;
manual = { manual = { inherit (docs) html htmlOpenTool; };
inherit (docs) html htmlOpenTool;
};
} }

View file

@ -1,70 +1,67 @@
{ home-manager, runCommand }: { home-manager, runCommand }:
runCommand runCommand "home-manager-install" {
"home-manager-install" propagatedBuildInputs = [ home-manager ];
{ preferLocalBuild = true;
propagatedBuildInputs = [ home-manager ]; allowSubstitutes = false;
preferLocalBuild = true; shellHookOnly = true;
allowSubstitutes = false; shellHook = ''
shellHookOnly = true; confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
shellHook = ''
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
if [[ ! -e $confFile ]]; then
echo
echo "Creating initial Home Manager configuration..."
mkdir -p "$(dirname "$confFile")"
cat > $confFile <<EOF
{ config, pkgs, ... }:
{
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
# 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
if [[ ! -e $confFile ]]; then
echo echo
echo "Creating initial Home Manager generation..." echo "Creating initial Home Manager configuration..."
echo
if home-manager switch; then mkdir -p "$(dirname "$confFile")"
cat <<EOF cat > $confFile <<EOF
{ config, pkgs, ... }:
All done! The home-manager tool should now be installed and you {
can edit # Let Home Manager install and manage itself.
programs.home-manager.enable = true;
$confFile # 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
to configure Home Manager. Run 'man home-configuration.nix' to echo
see all available options. echo "Creating initial Home Manager generation..."
EOF echo
exit 0
else
cat <<EOF
Uh oh, the installation failed! Please create an issue at if home-manager switch; then
cat <<EOF
https://github.com/rycee/home-manager/issues All done! The home-manager tool should now be installed and you
can edit
if the error seems to be the fault of Home Manager. $confFile
EOF
exit 1 to configure Home Manager. Run 'man home-configuration.nix' to
fi see all available options.
''; EOF
} exit 0
'' else
echo This derivation is not buildable, instead run it using nix-shell. cat <<EOF
exit 1
'' Uh oh, the installation failed! Please create an issue at
https://github.com/rycee/home-manager/issues
if the error seems to be the fault of Home Manager.
EOF
exit 1
fi
'';
} ''
echo This derivation is not buildable, instead run it using nix-shell.
exit 1
''

View file

@ -13,13 +13,11 @@ with lib;
rec { rec {
emptyDag = {}; emptyDag = { };
isDag = dag: isDag = dag:
let let isEntry = e: (e ? data) && (e ? after) && (e ? before);
isEntry = e: (e ? data) && (e ? after) && (e ? before); in builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
in
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
# Takes an attribute set containing entries built by # Takes an attribute set containing entries built by
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a # dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
@ -80,22 +78,19 @@ rec {
dagTopoSort = dag: dagTopoSort = dag:
let let
dagBefore = dag: name: dagBefore = dag: name:
mapAttrsToList (n: v: n) ( mapAttrsToList (n: v: n)
filterAttrs (n: v: any (a: a == name) v.before) dag (filterAttrs (n: v: any (a: a == name) v.before) dag);
); normalizedDag = mapAttrs (n: v: {
normalizedDag = name = n;
mapAttrs (n: v: { data = v.data;
name = n; after = v.after ++ dagBefore dag n;
data = v.data; }) dag;
after = v.after ++ dagBefore dag n;
}) dag;
before = a: b: any (c: a.name == c) b.after; before = a: b: any (c: a.name == c) b.after;
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag); sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
in in if sorted ? result then {
if sorted ? result then result = map (v: { inherit (v) name data; }) sorted.result;
{ result = map (v: { inherit (v) name data; }) sorted.result; } } else
else sorted;
sorted;
# Applies a function to each element of the given DAG. # Applies a function to each element of the given DAG.
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag; dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
@ -103,22 +98,20 @@ rec {
# Create a DAG entry with no particular dependency information. # Create a DAG entry with no particular dependency information.
dagEntryAnywhere = data: { dagEntryAnywhere = data: {
inherit data; inherit data;
before = []; before = [ ];
after = []; after = [ ];
}; };
dagEntryBetween = before: after: data: { dagEntryBetween = before: after: data: { inherit data before after; };
inherit data before after;
};
dagEntryAfter = after: data: { dagEntryAfter = after: data: {
inherit data after; inherit data after;
before = []; before = [ ];
}; };
dagEntryBefore = before: data: { dagEntryBefore = before: data: {
inherit data before; inherit data before;
after = []; after = [ ];
}; };
} }

View file

@ -2,7 +2,7 @@
rec { rec {
# Produces a Bourne shell like variable export statement. # Produces a Bourne shell like variable export statement.
export = n: v: "export ${n}=\"${toString v}\""; export = n: v: ''export ${n}="${toString v}"'';
# Given an attribute set containing shell variable names and their # Given an attribute set containing shell variable names and their
# assignment, this function produces a string containing an export # assignment, this function produces a string containing an export

View file

@ -3,9 +3,5 @@
nixpkgsLib: nixpkgsLib:
let let mkHmLib = import ./.;
mkHmLib = import ./.; in nixpkgsLib.extend (self: super: { hm = mkHmLib { lib = super; }; })
in
nixpkgsLib.extend (self: super: {
hm = mkHmLib { lib = super; };
})

View file

@ -9,19 +9,14 @@ with lib;
# All characters that are considered safe. Note "-" is not # All characters that are considered safe. Note "-" is not
# included to avoid "-" followed by digit being interpreted as a # included to avoid "-" followed by digit being interpreted as a
# version. # version.
safeChars = safeChars = [ "+" "." "_" "?" "=" ] ++ lowerChars ++ upperChars
[ "+" "." "_" "?" "=" ]
++ lowerChars
++ upperChars
++ stringToCharacters "0123456789"; ++ stringToCharacters "0123456789";
empties = l: genList (x: "") (length l); empties = l: genList (x: "") (length l);
unsafeInName = stringToCharacters ( unsafeInName =
replaceStrings safeChars (empties safeChars) path stringToCharacters (replaceStrings safeChars (empties safeChars) path);
);
safeName = replaceStrings unsafeInName (empties unsafeInName) path; safeName = replaceStrings unsafeInName (empties unsafeInName) path;
in in "hm_" + safeName;
"hm_" + safeName;
} }

View file

@ -6,41 +6,34 @@ let
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before); isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
dagContentType = elemType: types.submodule { dagContentType = elemType:
options = { types.submodule {
data = mkOption { type = elemType; }; options = {
after = mkOption { type = with types; uniq (listOf str); }; data = mkOption { type = elemType; };
before = mkOption { type = with types; uniq (listOf str); }; after = mkOption { type = with types; uniq (listOf str); };
before = mkOption { type = with types; uniq (listOf str); };
};
}; };
};
in in {
{
# A directed acyclic graph of some inner type. # A directed acyclic graph of some inner type.
dagOf = elemType: dagOf = elemType:
let let
convertAllToDags = convertAllToDags = let
let maybeConvert = n: v: if isDagEntry v then v else dag.entryAnywhere v;
maybeConvert = n: v: in map (def: def // { value = mapAttrs maybeConvert def.value; });
if isDagEntry v
then v
else dag.entryAnywhere v;
in
map (def: def // { value = mapAttrs maybeConvert def.value; });
attrEquivalent = types.attrsOf (dagContentType elemType); attrEquivalent = types.attrsOf (dagContentType elemType);
in in mkOptionType rec {
mkOptionType rec { name = "dagOf";
name = "dagOf"; description = "DAG of ${elemType.description}s";
description = "DAG of ${elemType.description}s"; check = isAttrs;
check = isAttrs; merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs); getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]); getSubModules = elemType.getSubModules;
getSubModules = elemType.getSubModules; substSubModules = m: dagOf (elemType.substSubModules m);
substSubModules = m: dagOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; };
functor = (defaultFunctor name) // { wrapped = elemType; }; };
};
# A directed acyclic graph of some inner type OR a list of that # A directed acyclic graph of some inner type OR a list of that
# inner type. This is a temporary hack for use by the # inner type. This is a temporary hack for use by the
@ -55,42 +48,37 @@ in
listOrDagOf = elemType: listOrDagOf = elemType:
let let
paddedIndexStr = list: i: paddedIndexStr = list: i:
let let padWidth = stringLength (toString (length list));
padWidth = stringLength (toString (length list)); in fixedWidthNumber padWidth i;
in
fixedWidthNumber padWidth i;
convertAllToDags = defs: convertAllToDags = defs:
let let
convertAttrValue = n: v: convertAttrValue = n: v:
if isDagEntry v then v if isDagEntry v then v else dag.entryAnywhere v;
else dag.entryAnywhere v;
convertListValue = namePrefix: vs: convertListValue = namePrefix: vs:
let let
pad = paddedIndexStr vs; pad = paddedIndexStr vs;
makeEntry = i: v: makeEntry = i: v:
nameValuePair "${namePrefix}.${pad i}" (dag.entryAnywhere v); nameValuePair "${namePrefix}.${pad i}" (dag.entryAnywhere v);
in in listToAttrs (imap1 makeEntry vs);
listToAttrs (imap1 makeEntry vs);
convertValue = i: value: convertValue = i: value:
if isList value if isList value then
then convertListValue "unnamed-${paddedIndexStr defs i}" value convertListValue "unnamed-${paddedIndexStr defs i}" value
else mapAttrs convertAttrValue value; else
in mapAttrs convertAttrValue value;
imap1 (i: def: def // { value = convertValue i def.value; }) defs; in imap1 (i: def: def // { value = convertValue i def.value; }) defs;
attrEquivalent = types.attrsOf (dagContentType elemType); attrEquivalent = types.attrsOf (dagContentType elemType);
in in mkOptionType rec {
mkOptionType rec { name = "dagOf";
name = "dagOf"; description = "DAG of ${elemType.description}s";
description = "DAG of ${elemType.description}s"; check = x: isAttrs x || isList x;
check = x: isAttrs x || isList x; merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs); getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]); getSubModules = elemType.getSubModules;
getSubModules = elemType.getSubModules; substSubModules = m: dagOf (elemType.substSubModules m);
substSubModules = m: dagOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; };
functor = (defaultFunctor name) // { wrapped = elemType; }; };
};
} }

View file

@ -2,13 +2,15 @@
rec { rec {
# Produces a Zsh shell like value # Produces a Zsh shell like value
toZshValue = v: if builtins.isBool v then toZshValue = v:
if v then "true" else "false" if builtins.isBool v then
else if builtins.isString v then if v then "true" else "false"
"\"${v}\"" else if builtins.isString v then
else if builtins.isList v then ''"${v}"''
"(${lib.concatStringsSep " " (map toZshValue v)})" else if builtins.isList v then
else "\"${toString v}\""; "(${lib.concatStringsSep " " (map toZshValue v)})"
else
''"${toString v}"'';
# Produces a Zsh shell like definition statement # Produces a Zsh shell like definition statement
define = n: v: "${n}=${toZshValue v}"; define = n: v: "${n}=${toZshValue v}";

View file

@ -8,15 +8,15 @@ let
profileDirectory = config.home.profileDirectory; profileDirectory = config.home.profileDirectory;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
imports = [ imports = [
(mkRenamedOptionModule (mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
[ "fonts" "fontconfig" "enableProfileFonts" ] "fonts"
[ "fonts" "fontconfig" "enable" ]) "fontconfig"
"enable"
])
]; ];
options = { options = {

View file

@ -4,7 +4,7 @@
options = { options = {
lib = lib.mkOption { lib = lib.mkOption {
type = lib.types.attrsOf lib.types.attrs; type = lib.types.attrsOf lib.types.attrs;
default = {}; default = { };
description = '' description = ''
This option allows modules to define helper functions, This option allows modules to define helper functions,
constants, etc. constants, etc.

View file

@ -6,12 +6,8 @@ let
cfg = config.xsession.numlock; cfg = config.xsession.numlock;
in in {
options = { xsession.numlock.enable = mkEnableOption "Num Lock"; };
{
options = {
xsession.numlock.enable = mkEnableOption "Num Lock";
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.user.services.numlockx = { systemd.user.services.numlockx = {
@ -27,9 +23,7 @@ in
ExecStart = "${pkgs.numlockx}/bin/numlockx"; ExecStart = "${pkgs.numlockx}/bin/numlockx";
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
}; };
}; };
} }

View file

@ -6,14 +6,12 @@ let
vars = config.pam.sessionVariables; vars = config.pam.sessionVariables;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
pam.sessionVariables = mkOption { pam.sessionVariables = mkOption {
default = {}; default = { };
type = types.attrs; type = types.attrs;
example = { EDITOR = "vim"; }; example = { EDITOR = "vim"; };
description = '' description = ''
@ -27,10 +25,8 @@ in
}; };
}; };
config = mkIf (vars != {}) { config = mkIf (vars != { }) {
home.file.".pam_environment".text = home.file.".pam_environment".text = concatStringsSep "\n"
concatStringsSep "\n" ( (mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') vars) + "\n";
mapAttrsToList (n: v: "${n} OVERRIDE=\"${toString v}\"") vars
) + "\n";
}; };
} }

View file

@ -6,19 +6,13 @@ let
cfg = config.qt; cfg = config.qt;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
imports = [ imports = [
(mkChangedOptionModule (mkChangedOptionModule [ "qt" "useGtkTheme" ] [ "qt" "platformTheme" ]
[ "qt" "useGtkTheme" ]
[ "qt" "platformTheme" ]
(config: (config:
if getAttrFromPath [ "qt" "useGtkTheme" ] config if getAttrFromPath [ "qt" "useGtkTheme" ] config then "gtk" else null))
then "gtk"
else null))
]; ];
options = { options = {
@ -29,10 +23,8 @@ in
type = types.nullOr (types.enum [ "gtk" "gnome" ]); type = types.nullOr (types.enum [ "gtk" "gnome" ]);
default = null; default = null;
example = "gnome"; example = "gnome";
relatedPackages = [ relatedPackages =
"qgnomeplatform" [ "qgnomeplatform" [ "libsForQt5" "qtstyleplugins" ] ];
["libsForQt5" "qtstyleplugins"]
];
description = '' description = ''
Selects the platform theme to use for Qt applications.</para> Selects the platform theme to use for Qt applications.</para>
<para>The options are <para>The options are
@ -59,16 +51,16 @@ in
home.sessionVariables.QT_QPA_PLATFORMTHEME = home.sessionVariables.QT_QPA_PLATFORMTHEME =
if cfg.platformTheme == "gnome" then "gnome" else "gtk2"; if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
home.packages = home.packages = if cfg.platformTheme == "gnome" then
if cfg.platformTheme == "gnome" [ pkgs.qgnomeplatform ]
then [ pkgs.qgnomeplatform ] else
else [ pkgs.libsForQt5.qtstyleplugins ]; [ pkgs.libsForQt5.qtstyleplugins ];
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ]; xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ];
# Enable GTK+ style for Qt4 in either case. # Enable GTK+ style for Qt4 in either case.
# It doesnt support the platform theme packages. # It doesnt support the platform theme packages.
home.activation.useGtkThemeInQt4 = hm.dag.entryAfter ["writeBoundary"] '' home.activation.useGtkThemeInQt4 = hm.dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \ $DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
--set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+ --set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+
''; '';

View file

@ -9,9 +9,7 @@ let
strListOrSingleton = with types; strListOrSingleton = with types;
coercedTo (either (listOf str) str) toList (listOf str); coercedTo (either (listOf str) str) toList (listOf str);
in in {
{
meta.maintainers = with maintainers; [ pacien ]; meta.maintainers = with maintainers; [ pacien ];
options.xdg.mimeApps = { options.xdg.mimeApps = {
@ -80,13 +78,11 @@ in
config.xdg.configFile."mimeapps.list".source; config.xdg.configFile."mimeapps.list".source;
xdg.configFile."mimeapps.list".text = xdg.configFile."mimeapps.list".text =
let let joinValues = mapAttrs (n: concatStringsSep ";");
joinValues = mapAttrs (n: concatStringsSep ";"); in generators.toINI { } {
in "Added Associations" = joinValues cfg.associations.added;
generators.toINI {} { "Removed Associations" = joinValues cfg.associations.removed;
"Added Associations" = joinValues cfg.associations.added; "Default Applications" = joinValues cfg.defaultApplications;
"Removed Associations" = joinValues cfg.associations.removed; };
"Default Applications" = joinValues cfg.defaultApplications;
};
}; };
} }

View file

@ -6,9 +6,7 @@ let
cfg = config.xdg.mime; cfg = config.xdg.mime;
in in {
{
options = { options = {
xdg.mime.enable = mkOption { xdg.mime.enable = mkOption {
type = types.bool; type = types.bool;

View file

@ -6,15 +6,15 @@ let
cfg = config.xdg.userDirs; cfg = config.xdg.userDirs;
in in {
{
meta.maintainers = with maintainers; [ pacien ]; meta.maintainers = with maintainers; [ pacien ];
imports = [ imports = [
(mkRenamedOptionModule (mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [
[ "xdg" "userDirs" "publishShare" ] "xdg"
[ "xdg" "userDirs" "publicShare" ]) "userDirs"
"publicShare"
])
]; ];
options.xdg.userDirs = { options.xdg.userDirs = {
@ -89,18 +89,15 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
xdg.configFile."user-dirs.dirs".text = generators.toKeyValue {} ( xdg.configFile."user-dirs.dirs".text = generators.toKeyValue { } ({
{ XDG_DESKTOP_DIR = cfg.desktop;
XDG_DESKTOP_DIR = cfg.desktop; XDG_DOCUMENTS_DIR = cfg.documents;
XDG_DOCUMENTS_DIR = cfg.documents; XDG_DOWNLOAD_DIR = cfg.download;
XDG_DOWNLOAD_DIR = cfg.download; XDG_MUSIC_DIR = cfg.music;
XDG_MUSIC_DIR = cfg.music; XDG_PICTURES_DIR = cfg.pictures;
XDG_PICTURES_DIR = cfg.pictures; XDG_PUBLICSHARE_DIR = cfg.publicShare;
XDG_PUBLICSHARE_DIR = cfg.publicShare; XDG_TEMPLATES_DIR = cfg.templates;
XDG_TEMPLATES_DIR = cfg.templates; XDG_VIDEOS_DIR = cfg.videos;
XDG_VIDEOS_DIR = cfg.videos; } // cfg.extraConfig);
}
// cfg.extraConfig
);
}; };
} }

View file

@ -6,16 +6,14 @@ let
cfg = config.programs.alacritty; cfg = config.programs.alacritty;
in in {
{
options = { options = {
programs.alacritty = { programs.alacritty = {
enable = mkEnableOption "Alacritty"; enable = mkEnableOption "Alacritty";
settings = mkOption { settings = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
window.dimensions = { window.dimensions = {
@ -45,8 +43,9 @@ in
(mkIf cfg.enable { (mkIf cfg.enable {
home.packages = [ pkgs.alacritty ]; home.packages = [ pkgs.alacritty ];
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != {}) { xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) {
text = replaceStrings ["\\\\"] ["\\"] (builtins.toJSON cfg.settings); text =
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings);
}; };
}) })
]; ];

View file

@ -18,12 +18,10 @@ with lib;
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = { default = {
type = "shellcommand"; type = "shellcommand";
command = "'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'"; command =
regexp = "'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
"'\\[?{" regexp = "'\\[?{" + ''
+ ''"name": "(?P<name>.*)", '' "name": "(?P<name>.*)", "address": "(?P<email>.+)", "name-addr": ".*"''
+ ''"address": "(?P<email>.+)", ''
+ ''"name-addr": ".*"''
+ "}[,\\]]?'"; + "}[,\\]]?'";
shellcommand_external_filtering = "False"; shellcommand_external_filtering = "False";
}; };
@ -36,9 +34,9 @@ with lib;
} }
''; '';
description = '' description = ''
Contact completion configuration as expected per alot. Contact completion configuration as expected per alot.
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
explanation about possible values. explanation about possible values.
''; '';
}; };
@ -52,10 +50,9 @@ with lib;
}; };
config = mkIf config.notmuch.enable { config = mkIf config.notmuch.enable {
alot.sendMailCommand = mkOptionDefault ( alot.sendMailCommand = mkOptionDefault (if config.msmtp.enable then
if config.msmtp.enable "msmtpq --read-envelope-from --read-recipients"
then "msmtpq --read-envelope-from --read-recipients" else
else null null);
);
}; };
} }

View file

@ -17,7 +17,7 @@ with lib;
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
example = { select_query = ""; }; example = { select_query = ""; };
description = '' description = ''
Extra settings to add to this astroid account configuration. Extra settings to add to this astroid account configuration.
@ -26,8 +26,7 @@ with lib;
}; };
config = mkIf config.notmuch.enable { config = mkIf config.notmuch.enable {
astroid.sendMailCommand = mkIf config.msmtp.enable ( astroid.sendMailCommand = mkIf config.msmtp.enable
mkOptionDefault "msmtpq --read-envelope-from --read-recipients" (mkOptionDefault "msmtpq --read-envelope-from --read-recipients");
);
}; };
} }

View file

@ -8,35 +8,32 @@ let
cfg = config.programs.astroid; cfg = config.programs.astroid;
astroidAccounts = astroidAccounts =
filterAttrs filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts;
(n: v: v.astroid.enable)
config.accounts.email.accounts;
boolOpt = b: if b then "true" else "false"; boolOpt = b: if b then "true" else "false";
accountAttr = account: with account; { accountAttr = account:
email = address; with account;
name = realName; {
sendmail = astroid.sendMailCommand; email = address;
additional_sent_tags = ""; name = realName;
default = boolOpt primary; sendmail = astroid.sendMailCommand;
save_drafts_to = "${maildir.absPath}/${folders.drafts}"; additional_sent_tags = "";
save_sent = "true"; default = boolOpt primary;
save_sent_to = "${maildir.absPath}/${folders.sent}"; save_drafts_to = "${maildir.absPath}/${folders.drafts}";
select_query = ""; save_sent = "true";
} save_sent_to = "${maildir.absPath}/${folders.sent}";
// optionalAttrs (signature.showSignature != "none") { select_query = "";
signature_attach = boolOpt (signature.showSignature == "attach"); } // optionalAttrs (signature.showSignature != "none") {
signature_default_on = boolOpt (signature.showSignature != "none"); signature_attach = boolOpt (signature.showSignature == "attach");
signature_file = pkgs.writeText "signature.txt" signature.text; signature_default_on = boolOpt (signature.showSignature != "none");
signature_file_markdown = "false"; signature_file = pkgs.writeText "signature.txt" signature.text;
signature_separate = "true"; # prepends '--\n' to the signature signature_file_markdown = "false";
} signature_separate = "true"; # prepends '--\n' to the signature
// optionalAttrs (gpg != null) { } // optionalAttrs (gpg != null) {
always_gpg_sign = boolOpt gpg.signByDefault; always_gpg_sign = boolOpt gpg.signByDefault;
gpgkey = gpg.key; gpgkey = gpg.key;
} } // astroid.extraConfig;
// astroid.extraConfig;
# See https://github.com/astroidmail/astroid/wiki/Configuration-Reference # See https://github.com/astroidmail/astroid/wiki/Configuration-Reference
configFile = mailAccounts: configFile = mailAccounts:
@ -51,12 +48,9 @@ let
cfg.extraConfig cfg.extraConfig
cfg.externalEditor cfg.externalEditor
]; ];
in in builtins.toJSON astroidConfig;
builtins.toJSON astroidConfig;
in in {
{
options = { options = {
programs.astroid = { programs.astroid = {
enable = mkEnableOption "Astroid"; enable = mkEnableOption "Astroid";
@ -81,7 +75,8 @@ in
"cmd" = cmd; "cmd" = cmd;
}; };
}; };
example = "nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1"; example =
"nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
description = '' description = ''
You can use <code>%1</code>, <code>%2</code>, and You can use <code>%1</code>, <code>%2</code>, and
<code>%3</code> to refer respectively to: <code>%3</code> to refer respectively to:
@ -96,7 +91,7 @@ in
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
example = { poll.interval = 0; }; example = { poll.interval = 0; };
description = '' description = ''
JSON config that will override the default Astroid configuration. JSON config that will override the default Astroid configuration.
@ -106,18 +101,15 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.astroid ]; home.packages = [ pkgs.astroid ];
xdg.configFile."astroid/config".source = xdg.configFile."astroid/config".source = pkgs.runCommand "out.json" {
pkgs.runCommand "out.json" json = configFile astroidAccounts;
{ preferLocalBuild = true;
json = configFile astroidAccounts; allowSubstitutes = false;
preferLocalBuild = true; } ''
allowSubstitutes = false; echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
} '';
''
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
'';
xdg.configFile."astroid/poll.sh" = { xdg.configFile."astroid/poll.sh" = {
executable = true; executable = true;

View file

@ -6,20 +6,21 @@ let
cfg = config.programs.autorandr; cfg = config.programs.autorandr;
matrixOf = n: m: elemType: mkOptionType rec { matrixOf = n: m: elemType:
name = "matrixOf"; mkOptionType rec {
description = "${toString n}×${toString m} matrix of ${elemType.description}s"; name = "matrixOf";
check = xss: description =
let "${toString n}×${toString m} matrix of ${elemType.description}s";
listOfSize = l: xs: isList xs && length xs == l; check = xss:
in let listOfSize = l: xs: isList xs && length xs == l;
listOfSize n xss && all (xs: listOfSize m xs && all elemType.check xs) xss; in listOfSize n xss
merge = mergeOneOption; && all (xs: listOfSize m xs && all elemType.check xs) xss;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*" "*"]); merge = mergeOneOption;
getSubModules = elemType.getSubModules; getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "*" "*" ]);
substSubModules = mod: matrixOf n m (elemType.substSubModules mod); getSubModules = elemType.getSubModules;
functor = (defaultFunctor name) // { wrapped = elemType; }; substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
}; functor = (defaultFunctor name) // { wrapped = elemType; };
};
profileModule = types.submodule { profileModule = types.submodule {
options = { options = {
@ -29,19 +30,19 @@ let
Output name to EDID mapping. Output name to EDID mapping.
Use <code>autorandr --fingerprint</code> to get current setup values. Use <code>autorandr --fingerprint</code> to get current setup values.
''; '';
default = {}; default = { };
}; };
config = mkOption { config = mkOption {
type = types.attrsOf configModule; type = types.attrsOf configModule;
description = "Per output profile configuration."; description = "Per output profile configuration.";
default = {}; default = { };
}; };
hooks = mkOption { hooks = mkOption {
type = profileHooksModule; type = profileHooksModule;
description = "Profile hook scripts."; description = "Profile hook scripts.";
default = {}; default = { };
}; };
}; };
}; };
@ -89,7 +90,7 @@ let
}; };
rotate = mkOption { rotate = mkOption {
type = types.nullOr (types.enum ["normal" "left" "right" "inverted"]); type = types.nullOr (types.enum [ "normal" "left" "right" "inverted" ]);
description = "Output rotate configuration."; description = "Output rotate configuration.";
default = null; default = null;
example = "left"; example = "left";
@ -126,7 +127,7 @@ let
type = types.nullOr (types.submodule { type = types.nullOr (types.submodule {
options = { options = {
method = mkOption { method = mkOption {
type = types.enum ["factor" "pixel" ]; type = types.enum [ "factor" "pixel" ];
description = "Output scaling method."; description = "Output scaling method.";
default = "factor"; default = "factor";
example = "pixel"; example = "pixel";
@ -178,19 +179,21 @@ let
postswitch = mkOption { postswitch = mkOption {
type = types.attrsOf hookType; type = types.attrsOf hookType;
description = "Postswitch hook executed after mode switch."; description = "Postswitch hook executed after mode switch.";
default = {}; default = { };
}; };
preswitch = mkOption { preswitch = mkOption {
type = types.attrsOf hookType; type = types.attrsOf hookType;
description = "Preswitch hook executed before mode switch."; description = "Preswitch hook executed before mode switch.";
default = {}; default = { };
}; };
predetect = mkOption { predetect = mkOption {
type = types.attrsOf hookType; type = types.attrsOf hookType;
description = "Predetect hook executed before autorandr attempts to run xrandr."; description = ''
default = {}; Predetect hook executed before autorandr attempts to run xrandr.
'';
default = { };
}; };
}; };
}; };
@ -211,50 +214,56 @@ let
predetect = mkOption { predetect = mkOption {
type = hookType; type = hookType;
description = "Predetect hook executed before autorandr attempts to run xrandr."; description = ''
Predetect hook executed before autorandr attempts to run xrandr.
'';
default = ""; default = "";
}; };
}; };
}; };
hookToFile = folder: name: hook: hookToFile = folder: name: hook:
nameValuePair nameValuePair "autorandr/${folder}/${name}" {
"autorandr/${folder}/${name}" source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook";
{ source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook"; }; };
profileToFiles = name: profile: with profile; mkMerge ([ profileToFiles = name: profile:
{ with profile;
"autorandr/${name}/setup".text = concatStringsSep "\n" (mapAttrsToList fingerprintToString fingerprint); mkMerge ([
"autorandr/${name}/config".text = concatStringsSep "\n" (mapAttrsToList configToString profile.config); {
} "autorandr/${name}/setup".text = concatStringsSep "\n"
(mkIf (hooks.postswitch != "") (listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ])) (mapAttrsToList fingerprintToString fingerprint);
(mkIf (hooks.preswitch != "") (listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ])) "autorandr/${name}/config".text =
(mkIf (hooks.predetect != "") (listToAttrs [ (hookToFile name "predetect" hooks.predetect) ])) concatStringsSep "\n" (mapAttrsToList configToString profile.config);
]); }
(mkIf (hooks.postswitch != "")
(listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
(mkIf (hooks.preswitch != "")
(listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
(mkIf (hooks.predetect != "")
(listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
]);
fingerprintToString = name: edid: "${name} ${edid}"; fingerprintToString = name: edid: "${name} ${edid}";
configToString = name: config: if config.enable then '' configToString = name: config:
output ${name} if config.enable then ''
${optionalString (config.position != "") "pos ${config.position}"} output ${name}
${optionalString config.primary "primary"} ${optionalString (config.position != "") "pos ${config.position}"}
${optionalString (config.dpi != null) "dpi ${toString config.dpi}"} ${optionalString config.primary "primary"}
${optionalString (config.gamma != "") "gamma ${config.gamma}"} ${optionalString (config.dpi != null) "dpi ${toString config.dpi}"}
${optionalString (config.mode != "") "mode ${config.mode}"} ${optionalString (config.gamma != "") "gamma ${config.gamma}"}
${optionalString (config.rate != "") "rate ${config.rate}"} ${optionalString (config.mode != "") "mode ${config.mode}"}
${optionalString (config.rotate != null) "rotate ${config.rotate}"} ${optionalString (config.rate != "") "rate ${config.rate}"}
${optionalString (config.scale != null) ( ${optionalString (config.rotate != null) "rotate ${config.rotate}"}
(if config.scale.method == "factor" then "scale" else "scale-from") ${optionalString (config.scale != null)
+ " ${toString config.scale.x}x${toString config.scale.y}" ((if config.scale.method == "factor" then "scale" else "scale-from")
)} + " ${toString config.scale.x}x${toString config.scale.y}")}
${optionalString (config.transform != null) ( ${optionalString (config.transform != null) ("transform "
"transform " + concatMapStringsSep "," toString (flatten config.transform) + concatMapStringsSep "," toString (flatten config.transform))}
)} '' else ''
'' else '' output ${name}
output ${name} off
off '';
'';
in in {
{
options = { options = {
programs.autorandr = { programs.autorandr = {
enable = mkEnableOption "Autorandr"; enable = mkEnableOption "Autorandr";
@ -262,39 +271,39 @@ in
hooks = mkOption { hooks = mkOption {
type = globalHooksModule; type = globalHooksModule;
description = "Global hook scripts"; description = "Global hook scripts";
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
postswitch = { postswitch = {
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart"; "notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
"change-background" = readFile ./change-background.sh; "change-background" = readFile ./change-background.sh;
"change-dpi" = ''' "change-dpi" = '''
case "$AUTORANDR_CURRENT_PROFILE" in case "$AUTORANDR_CURRENT_PROFILE" in
default) default)
DPI=120 DPI=120
;; ;;
home) home)
DPI=192 DPI=192
;; ;;
work) work)
DPI=144 DPI=144
;; ;;
*) *)
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE" echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
exit 1 exit 1
esac esac
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
''' '''
}; };
} }
''; '';
}; };
profiles = mkOption { profiles = mkOption {
type = types.attrsOf profileModule; type = types.attrsOf profileModule;
description = "Autorandr profiles specification."; description = "Autorandr profiles specification.";
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
"work" = { "work" = {
@ -323,24 +332,21 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = flatten (mapAttrsToList ( assertions = flatten (mapAttrsToList (profile:
profile: { config, ... }: mapAttrsToList ( { config, ... }:
output: opts: { mapAttrsToList (output: opts: {
assertion = opts.scale == null || opts.transform == null; assertion = opts.scale == null || opts.transform == null;
message = '' message = ''
Cannot use the profile output options 'scale' and 'transform' simultaneously. Cannot use the profile output options 'scale' and 'transform' simultaneously.
Check configuration for: programs.autorandr.profiles.${profile}.config.${output} Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
''; '';
}) }) config) cfg.profiles);
config
)
cfg.profiles);
home.packages = [ pkgs.autorandr ]; home.packages = [ pkgs.autorandr ];
xdg.configFile = mkMerge ([ xdg.configFile = mkMerge ([
(mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch) (mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch) (mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect) (mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
(mkMerge (mapAttrsToList profileToFiles cfg.profiles)) (mkMerge (mapAttrsToList profileToFiles cfg.profiles))
]); ]);
}; };

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.bat; cfg = config.programs.bat;
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.bat = { options.programs.bat = {
@ -16,7 +14,7 @@ in
config = mkOption { config = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = { };
example = { example = {
theme = "TwoDark"; theme = "TwoDark";
pager = "less -FR"; pager = "less -FR";
@ -31,10 +29,9 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.bat ]; home.packages = [ pkgs.bat ];
xdg.configFile."bat/config" = mkIf (cfg.config != {}) { xdg.configFile."bat/config" = mkIf (cfg.config != { }) {
text = concatStringsSep "\n" ( text = concatStringsSep "\n"
mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config (mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config);
);
}; };
}; };
} }

View file

@ -6,19 +6,17 @@ let
cfg = config.programs.beets; cfg = config.programs.beets;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
programs.beets = { programs.beets = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
default = default = if versionAtLeast config.home.stateVersion "19.03" then
if versionAtLeast config.home.stateVersion "19.03" false
then false else
else cfg.settings != {}; cfg.settings != { };
defaultText = "false"; defaultText = "false";
description = '' description = ''
Whether to enable the beets music library manager. This Whether to enable the beets music library manager. This
@ -32,7 +30,8 @@ in
type = types.package; type = types.package;
default = pkgs.beets; default = pkgs.beets;
defaultText = literalExample "pkgs.beets"; defaultText = literalExample "pkgs.beets";
example = literalExample "(pkgs.beets.override { enableCheck = true; })"; example =
literalExample "(pkgs.beets.override { enableCheck = true; })";
description = '' description = ''
The <literal>beets</literal> package to use. The <literal>beets</literal> package to use.
Can be used to specify extensions. Can be used to specify extensions.
@ -41,7 +40,7 @@ in
settings = mkOption { settings = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
description = '' description = ''
Configuration written to Configuration written to
<filename>~/.config/beets/config.yaml</filename> <filename>~/.config/beets/config.yaml</filename>
@ -54,6 +53,6 @@ in
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
xdg.configFile."beets/config.yaml".text = xdg.configFile."beets/config.yaml".text =
builtins.toJSON config.programs.beets.settings; builtins.toJSON config.programs.beets.settings;
}; };
} }

View file

@ -7,29 +7,23 @@ let
cfg = config.programs.broot; cfg = config.programs.broot;
configFile = config: configFile = config:
pkgs.runCommand "conf.toml" pkgs.runCommand "conf.toml" {
{ buildInputs = [ pkgs.remarshal ];
buildInputs = [ pkgs.remarshal ]; preferLocalBuild = true;
preferLocalBuild = true; allowSubstitutes = false;
allowSubstitutes = false; } ''
} remarshal -if json -of toml \
'' < ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \
remarshal -if json -of toml \ > $out
< ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \ '';
> $out
'';
brootConf = { brootConf = {
verbs = verbs =
mapAttrsToList mapAttrsToList (name: value: value // { invocation = name; }) cfg.verbs;
(name: value: value // { invocation = name; })
cfg.verbs;
skin = cfg.skin; skin = cfg.skin;
}; };
in in {
{
meta.maintainers = [ maintainers.aheaume ]; meta.maintainers = [ maintainers.aheaume ];
options.programs.broot = { options.programs.broot = {
@ -63,7 +57,10 @@ in
type = with types; attrsOf (attrsOf (either bool str)); type = with types; attrsOf (attrsOf (either bool str));
default = { default = {
"p" = { execution = ":parent"; }; "p" = { execution = ":parent"; };
"edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; }; "edit" = {
shortcut = "e";
execution = "$EDITOR {file}";
};
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; }; "create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
"view" = { execution = "less {file}"; }; "view" = { execution = "less {file}"; };
}; };
@ -114,7 +111,7 @@ in
skin = mkOption { skin = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
status_normal_fg = "grayscale(18)"; status_normal_fg = "grayscale(18)";
@ -177,38 +174,36 @@ in
# Dummy file to prevent broot from trying to reinstall itself # Dummy file to prevent broot from trying to reinstall itself
xdg.configFile."broot/launcher/installed".text = ""; xdg.configFile."broot/launcher/installed".text = "";
programs.bash.initExtra = programs.bash.initExtra = mkIf cfg.enableBashIntegration (
mkIf cfg.enableBashIntegration ( # Using mkAfter to make it more likely to appear after other
# Using mkAfter to make it more likely to appear after other # manipulations of the prompt.
# manipulations of the prompt. mkAfter ''
mkAfter '' # This script was automatically generated by the broot function
# This script was automatically generated by the broot function # More information can be found in https://github.com/Canop/broot
# More information can be found in https://github.com/Canop/broot # This function starts broot and executes the command
# This function starts broot and executes the command # it produces, if any.
# it produces, if any. # It's needed because some shell commands, like `cd`,
# It's needed because some shell commands, like `cd`, # have no useful effect if executed in a subshell.
# have no useful effect if executed in a subshell. function br {
function br { f=$(mktemp)
f=$(mktemp) (
( set +e
set +e broot --outcmd "$f" "$@"
broot --outcmd "$f" "$@" code=$?
code=$? if [ "$code" != 0 ]; then
if [ "$code" != 0 ]; then rm -f "$f"
rm -f "$f" exit "$code"
exit "$code" fi
fi )
) code=$?
code=$? if [ "$code" != 0 ]; then
if [ "$code" != 0 ]; then return "$code"
return "$code" fi
fi d=$(cat "$f")
d=$(cat "$f") rm -f "$f"
rm -f "$f" eval "$d"
eval "$d" }
} '');
''
);
programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
# This script was automatically generated by the broot function # This script was automatically generated by the broot function

View file

@ -2,13 +2,7 @@
with lib; with lib;
let let browsers = [ "chrome" "chromium" "firefox" "vivaldi" ];
browsers = [
"chrome"
"chromium"
"firefox"
"vivaldi"
];
in { in {
options = { options = {
programs.browserpass = { programs.browserpass = {
@ -24,58 +18,59 @@ in {
}; };
config = mkIf config.programs.browserpass.enable { config = mkIf config.programs.browserpass.enable {
home.file = home.file = foldl' (a: b: a // b) { } (concatMap (x:
foldl' (a: b: a // b) {} with pkgs.stdenv;
(concatMap (x: with pkgs.stdenv; if x == "chrome" then
if x == "chrome" then let
let dir = if isDarwin dir = if isDarwin then
then "Library/Application Support/Google/Chrome/NativeMessagingHosts" "Library/Application Support/Google/Chrome/NativeMessagingHosts"
else ".config/google-chrome/NativeMessagingHosts"; else
in [ ".config/google-chrome/NativeMessagingHosts";
{ in [{
"${dir}/com.github.browserpass.native.json".source = "${dir}/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json"; "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
"${dir}/../policies/managed/com.github.browserpass.native.json".source = "${dir}/../policies/managed/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json"; "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
} }]
] else if x == "chromium" then
else if x == "chromium" then let
let dir = if isDarwin dir = if isDarwin then
then "Library/Application Support/Chromium/NativeMessagingHosts" "Library/Application Support/Chromium/NativeMessagingHosts"
else ".config/chromium/NativeMessagingHosts"; else
in [ ".config/chromium/NativeMessagingHosts";
{ in [
"${dir}/com.github.browserpass.native.json".source = {
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json"; "${dir}/com.github.browserpass.native.json".source =
} "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
{ }
"${dir}/../policies/managed/com.github.browserpass.native.json".source = {
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json"; "${dir}/../policies/managed/com.github.browserpass.native.json".source =
} "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
] }
else if x == "firefox" then ]
let dir = if isDarwin else if x == "firefox" then
then "Library/Application Support/Mozilla/NativeMessagingHosts" let
else ".mozilla/native-messaging-hosts"; dir = if isDarwin then
in [ "Library/Application Support/Mozilla/NativeMessagingHosts"
{ else
"${dir}/com.github.browserpass.native.json".source = ".mozilla/native-messaging-hosts";
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json"; in [{
} "${dir}/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 else if x == "vivaldi" then
then "Library/Application Support/Vivaldi/NativeMessagingHosts" let
else ".config/vivaldi/NativeMessagingHosts"; dir = if isDarwin then
in [ "Library/Application Support/Vivaldi/NativeMessagingHosts"
{ else
"${dir}/com.github.browserpass.native.json".source = ".config/vivaldi/NativeMessagingHosts";
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json"; in [{
"${dir}/../policies/managed/com.github.browserpass.native.json".source = "${dir}/com.github.browserpass.native.json".source =
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json"; "${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
} "${dir}/../policies/managed/com.github.browserpass.native.json".source =
] "${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
else throw "unknown browser ${x}") config.programs.browserpass.browsers }]
); else
throw "unknown browser ${x}") config.programs.browserpass.browsers);
}; };
} }

View file

@ -5,46 +5,44 @@ with lib;
let let
browserModule = defaultPkg: name: visible: browserModule = defaultPkg: name: visible:
let let browser = (builtins.parseDrvName defaultPkg.name).name;
browser = (builtins.parseDrvName defaultPkg.name).name; in {
in enable = mkOption {
{ inherit visible;
enable = mkOption { default = false;
inherit visible; example = true;
default = false; description = "Whether to enable ${name}.";
example = true; type = lib.types.bool;
description = "Whether to enable ${name}.";
type = lib.types.bool;
};
package = mkOption {
inherit visible;
type = types.package;
default = defaultPkg;
defaultText = literalExample "pkgs.${browser}";
description = "The ${name} package to use.";
};
extensions = mkOption {
inherit visible;
type = types.listOf types.str;
default = [];
example = literalExample ''
[
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
]
'';
description = ''
List of ${name} extensions to install.
To find the extension ID, check its URL on the
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
'';
};
}; };
package = mkOption {
inherit visible;
type = types.package;
default = defaultPkg;
defaultText = literalExample "pkgs.${browser}";
description = "The ${name} package to use.";
};
extensions = mkOption {
inherit visible;
type = types.listOf types.str;
default = [ ];
example = literalExample ''
[
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
]
'';
description = ''
List of ${name} extensions to install.
To find the extension ID, check its URL on the
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
'';
};
};
browserConfig = cfg: browserConfig = cfg:
let let
@ -57,31 +55,32 @@ let
google-chrome-dev = "Google/Chrome Dev"; google-chrome-dev = "Google/Chrome Dev";
}; };
configDir = if pkgs.stdenv.isDarwin configDir = if pkgs.stdenv.isDarwin then
then "Library/Application Support/${getAttr browser darwinDirs}" "Library/Application Support/${getAttr browser darwinDirs}"
else "${config.xdg.configHome}/${browser}"; else
"${config.xdg.configHome}/${browser}";
extensionJson = ext: { extensionJson = ext: {
name = "${configDir}/External Extensions/${ext}.json"; name = "${configDir}/External Extensions/${ext}.json";
value.text = builtins.toJSON { value.text = builtins.toJSON {
external_update_url = "https://clients2.google.com/service/update2/crx"; external_update_url =
"https://clients2.google.com/service/update2/crx";
}; };
}; };
in in mkIf cfg.enable {
mkIf cfg.enable { home.packages = [ cfg.package ];
home.packages = [ cfg.package ]; home.file = listToAttrs (map extensionJson cfg.extensions);
home.file = listToAttrs (map extensionJson cfg.extensions); };
};
in in {
{
options.programs = { options.programs = {
chromium = browserModule pkgs.chromium "Chromium" true; chromium = browserModule pkgs.chromium "Chromium" true;
google-chrome = browserModule pkgs.google-chrome "Google Chrome" false; google-chrome = browserModule pkgs.google-chrome "Google Chrome" false;
google-chrome-beta = browserModule pkgs.google-chrome-beta "Google Chrome Beta" false; google-chrome-beta =
google-chrome-dev = browserModule pkgs.google-chrome-dev "Google Chrome Dev" false; browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
google-chrome-dev =
browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
}; };
config = mkMerge [ config = mkMerge [

View file

@ -13,8 +13,11 @@ let
isExecutable = true; isExecutable = true;
inherit (pkgs) perl; inherit (pkgs) perl;
inherit (cfg) dbPath; inherit (cfg) dbPath;
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]); pkgs.perlPackages.DBI
pkgs.perlPackages.DBDSQLite
pkgs.perlPackages.StringShellQuote
]);
}; };
shInit = commandNotFoundHandlerName: '' shInit = commandNotFoundHandlerName: ''
@ -31,14 +34,13 @@ let
} }
''; '';
in in {
{
options.programs.command-not-found = { options.programs.command-not-found = {
enable = mkEnableOption "command-not-found hook for interactive shell"; enable = mkEnableOption "command-not-found hook for interactive shell";
dbPath = mkOption { dbPath = mkOption {
default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ; default =
"/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite";
description = '' description = ''
Absolute path to <filename>programs.sqlite</filename>. By Absolute path to <filename>programs.sqlite</filename>. By
default this file will be provided by your channel default this file will be provided by your channel

View file

@ -6,21 +6,17 @@ let
cfg = config.programs.direnv; cfg = config.programs.direnv;
configFile = config: configFile = config:
pkgs.runCommand "config.toml" pkgs.runCommand "config.toml" {
{ buildInputs = [ pkgs.remarshal ];
buildInputs = [ pkgs.remarshal ]; preferLocalBuild = true;
preferLocalBuild = true; allowSubstitutes = false;
allowSubstitutes = false; } ''
} remarshal -if json -of toml \
'' < ${pkgs.writeText "config.json" (builtins.toJSON config)} \
remarshal -if json -of toml \ > $out
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \ '';
> $out
'';
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options.programs.direnv = { options.programs.direnv = {
@ -28,7 +24,7 @@ in
config = mkOption { config = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
description = '' description = ''
Configuration written to Configuration written to
<filename>~/.config/direnv/config.toml</filename>. <filename>~/.config/direnv/config.toml</filename>.
@ -79,22 +75,18 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.direnv ]; home.packages = [ pkgs.direnv ];
xdg.configFile."direnv/config.toml" = mkIf (cfg.config != {}) { xdg.configFile."direnv/config.toml" =
source = configFile cfg.config; mkIf (cfg.config != { }) { source = configFile cfg.config; };
};
xdg.configFile."direnv/direnvrc" = mkIf (cfg.stdlib != "") { xdg.configFile."direnv/direnvrc" =
text = cfg.stdlib; mkIf (cfg.stdlib != "") { text = cfg.stdlib; };
};
programs.bash.initExtra = programs.bash.initExtra = mkIf cfg.enableBashIntegration (
mkIf cfg.enableBashIntegration ( # Using mkAfter to make it more likely to appear after other
# Using mkAfter to make it more likely to appear after other # manipulations of the prompt.
# manipulations of the prompt. mkAfter ''
mkAfter '' eval "$(${pkgs.direnv}/bin/direnv hook bash)"
eval "$(${pkgs.direnv}/bin/direnv hook bash)" '');
''
);
programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${pkgs.direnv}/bin/direnv hook zsh)" eval "$(${pkgs.direnv}/bin/direnv hook zsh)"

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.eclipse; cfg = config.programs.eclipse;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -27,13 +25,13 @@ in
jvmArgs = mkOption { jvmArgs = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
description = "JVM arguments to use for the Eclipse process."; description = "JVM arguments to use for the Eclipse process.";
}; };
plugins = mkOption { plugins = mkOption {
type = types.listOf types.package; type = types.listOf types.package;
default = []; default = [ ];
description = "Plugins that should be added to Eclipse."; description = "Plugins that should be added to Eclipse.";
}; };
}; };
@ -43,10 +41,8 @@ in
home.packages = [ home.packages = [
(pkgs.eclipses.eclipseWithPlugins { (pkgs.eclipses.eclipseWithPlugins {
eclipse = pkgs.eclipses.eclipse-platform; eclipse = pkgs.eclipses.eclipse-platform;
jvmArgs = jvmArgs = cfg.jvmArgs ++ optional cfg.enableLombok
cfg.jvmArgs "-javaagent:${pkgs.lombok}/share/java/lombok.jar";
++ optional cfg.enableLombok
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
plugins = cfg.plugins; plugins = cfg.plugins;
}) })
]; ];

View file

@ -9,31 +9,35 @@ let
disableBinding = func: key: func; disableBinding = func: key: func;
enableBinding = func: key: "${func} ${toString key}"; enableBinding = func: key: "${func} ${toString key}";
in in {
{
options.programs.feh = { options.programs.feh = {
enable = mkEnableOption "feh - a fast and light image viewer"; enable = mkEnableOption "feh - a fast and light image viewer";
buttons = mkOption { buttons = mkOption {
default = {}; default = { };
type = with types; attrsOf (nullOr (either str int)); type = with types; attrsOf (nullOr (either str int));
example = { zoom_in = 4; zoom_out = "C-4"; }; example = {
zoom_in = 4;
zoom_out = "C-4";
};
description = '' description = ''
Override feh's default mouse button mapping. If you want to disable an Override feh's default mouse button mapping. If you want to disable an
action, set its value to null. action, set its value to null.
See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for
default bindings and available commands. default bindings and available commands.
''; '';
}; };
keybindings = mkOption { keybindings = mkOption {
default = {}; default = { };
type = types.attrsOf (types.nullOr types.str); type = types.attrsOf (types.nullOr types.str);
example = { zoom_in = "plus"; zoom_out = "minus"; }; example = {
zoom_in = "plus";
zoom_out = "minus";
};
description = '' description = ''
Override feh's default keybindings. If you want to disable a keybinding Override feh's default keybindings. If you want to disable a keybinding
set its value to null. set its value to null.
See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for
default bindings and available commands. default bindings and available commands.
''; '';
@ -41,23 +45,26 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [{
{ assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == { });
assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == {}); message =
message = "To disable a keybinding, use `null` instead of an empty string."; "To disable a keybinding, use `null` instead of an empty string.";
} }];
];
home.packages = [ pkgs.feh ]; home.packages = [ pkgs.feh ];
xdg.configFile."feh/buttons".text = '' xdg.configFile."feh/buttons".text = ''
${concatStringsSep "\n" (mapAttrsToList disableBinding (filterAttrs (n: v: v == null) cfg.buttons))} ${concatStringsSep "\n" (mapAttrsToList disableBinding
${concatStringsSep "\n" (mapAttrsToList enableBinding (filterAttrs (n: v: v != null) cfg.buttons))} (filterAttrs (n: v: v == null) cfg.buttons))}
${concatStringsSep "\n" (mapAttrsToList enableBinding
(filterAttrs (n: v: v != null) cfg.buttons))}
''; '';
xdg.configFile."feh/keys".text = '' xdg.configFile."feh/keys".text = ''
${concatStringsSep "\n" (mapAttrsToList disableBinding (filterAttrs (n: v: v == null) cfg.keybindings))} ${concatStringsSep "\n" (mapAttrsToList disableBinding
${concatStringsSep "\n" (mapAttrsToList enableBinding (filterAttrs (n: v: v != null) cfg.keybindings))} (filterAttrs (n: v: v == null) cfg.keybindings))}
${concatStringsSep "\n" (mapAttrsToList enableBinding
(filterAttrs (n: v: v != null) cfg.keybindings))}
''; '';
}; };
} }

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.fzf; cfg = config.programs.fzf;
in in {
{
options.programs.fzf = { options.programs.fzf = {
enable = mkEnableOption "fzf - a command-line fuzzy finder"; enable = mkEnableOption "fzf - a command-line fuzzy finder";
@ -24,7 +22,7 @@ in
defaultOptions = mkOption { defaultOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--height 40%" "--border" ]; example = [ "--height 40%" "--border" ];
description = '' description = ''
Extra command line options given to fzf by default. Extra command line options given to fzf by default.
@ -43,7 +41,7 @@ in
fileWidgetOptions = mkOption { fileWidgetOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--preview 'head {}'" ]; example = [ "--preview 'head {}'" ];
description = '' description = ''
Command line options for the CTRL-T keybinding. Command line options for the CTRL-T keybinding.
@ -53,7 +51,7 @@ in
changeDirWidgetCommand = mkOption { changeDirWidgetCommand = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
example = "fd --type d" ; example = "fd --type d";
description = '' description = ''
The command that gets executed as the source for fzf for the The command that gets executed as the source for fzf for the
ALT-C keybinding. ALT-C keybinding.
@ -62,7 +60,7 @@ in
changeDirWidgetOptions = mkOption { changeDirWidgetOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--preview 'tree -C {} | head -200'" ]; example = [ "--preview 'tree -C {} | head -200'" ];
description = '' description = ''
Command line options for the ALT-C keybinding. Command line options for the ALT-C keybinding.
@ -80,7 +78,7 @@ in
historyWidgetOptions = mkOption { historyWidgetOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--sort" "--exact" ]; example = [ "--sort" "--exact" ];
description = '' description = ''
Command line options for the CTRL-R keybinding. Command line options for the CTRL-R keybinding.
@ -107,19 +105,17 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.fzf ]; home.packages = [ pkgs.fzf ];
home.sessionVariables = home.sessionVariables = mapAttrs (n: v: toString v)
mapAttrs (n: v: toString v) ( (filterAttrs (n: v: v != [ ] && v != null) {
filterAttrs (n: v: v != [] && v != null) { FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand; FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions; FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand; FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions; FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand; FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions; FZF_DEFAULT_COMMAND = cfg.defaultCommand;
FZF_DEFAULT_COMMAND = cfg.defaultCommand; FZF_DEFAULT_OPTS = cfg.defaultOptions;
FZF_DEFAULT_OPTS = cfg.defaultOptions; });
}
);
programs.bash.initExtra = mkIf cfg.enableBashIntegration '' programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then

View file

@ -17,8 +17,8 @@ with lib;
mailboxes = mkOption { mailboxes = mkOption {
type = types.nonEmptyListOf types.str; type = types.nonEmptyListOf types.str;
default = []; default = [ ];
example = ["INBOX" "INBOX.spam"]; example = [ "INBOX" "INBOX.spam" ];
description = '' description = ''
A non-empty list of mailboxes. To download all mail you can A non-empty list of mailboxes. To download all mail you can
use the <literal>ALL</literal> mailbox. use the <literal>ALL</literal> mailbox.

View file

@ -4,27 +4,26 @@ with lib;
let let
accounts = filter (a: a.getmail.enable) accounts =
(attrValues config.accounts.email.accounts); filter (a: a.getmail.enable) (attrValues config.accounts.email.accounts);
renderAccountConfig = account: with account; renderAccountConfig = account:
with account;
let let
passCmd = concatMapStringsSep ", " (x: "'${x}'") passwordCommand; passCmd = concatMapStringsSep ", " (x: "'${x}'") passwordCommand;
renderedMailboxes = concatMapStringsSep ", " (x: "'${x}'") getmail.mailboxes; renderedMailboxes =
retrieverType = if imap.tls.enable concatMapStringsSep ", " (x: "'${x}'") getmail.mailboxes;
then "SimpleIMAPSSLRetriever" retrieverType = if imap.tls.enable then
else "SimpleIMAPRetriever"; "SimpleIMAPSSLRetriever"
destination = if getmail.destinationCommand != null else
then "SimpleIMAPRetriever";
{ destination = if getmail.destinationCommand != null then {
destinationType = "MDA_external"; destinationType = "MDA_external";
destinationPath = getmail.destinationCommand; destinationPath = getmail.destinationCommand;
} } else {
else destinationType = "Maildir";
{ destinationPath = "${maildir.absPath}/";
destinationType = "Maildir"; };
destinationPath = "${maildir.absPath}/";
};
renderGetmailBoolean = v: if v then "true" else "false"; renderGetmailBoolean = v: if v then "true" else "false";
in '' in ''
# Generated by Home-Manager. # Generated by Home-Manager.
@ -46,15 +45,13 @@ let
''; '';
getmailEnabled = length (filter (a: a.getmail.enable) accounts) > 0; getmailEnabled = length (filter (a: a.getmail.enable) accounts) > 0;
# Watch out! This is used by the getmail.service too! # Watch out! This is used by the getmail.service too!
renderConfigFilepath = a: ".getmail/getmail${if a.primary then "rc" else a.name}"; renderConfigFilepath = a:
".getmail/getmail${if a.primary then "rc" else a.name}";
in in {
{
config = mkIf getmailEnabled { config = mkIf getmailEnabled {
home.file = home.file = foldl' (a: b: a // b) { }
foldl' (a: b: a // b) {}
(map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; }) (map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; })
accounts); accounts);
}; };
} }

View file

@ -14,36 +14,31 @@ let
section = head sections; section = head sections;
subsections = tail sections; subsections = tail sections;
subsection = concatStringsSep "." subsections; subsection = concatStringsSep "." subsections;
in in if containsQuote || subsections == [ ] then
if containsQuote || subsections == [] name
then name else
else "${section} \"${subsection}\""; ''${section} "${subsection}"'';
# generation for multiple ini values # generation for multiple ini values
mkKeyValue = k: v: mkKeyValue = k: v:
let let mkKeyValue = generators.mkKeyValueDefault { } "=" k;
mkKeyValue = generators.mkKeyValueDefault {} "=" k; in concatStringsSep "\n" (map mkKeyValue (toList v));
in
concatStringsSep "\n" (map mkKeyValue (toList v));
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI # converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
gitFlattenAttrs = gitFlattenAttrs = let
let recurse = path: value:
recurse = path: value: if isAttrs value then
if isAttrs value then mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
mapAttrsToList (name: value: recurse ([name] ++ path) value) value else if length path > 1 then {
else if length path > 1 then ${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
{ ${concatStringsSep "." (reverseList (tail path))}.${head path} = value; } } else {
else ${head path} = value;
{ ${head path} = value; }; };
in in attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
attrs: foldl recursiveUpdate {} (flatten (recurse [] attrs));
gitToIni = attrs: gitToIni = attrs:
let let toIni = generators.toINI { inherit mkKeyValue mkSectionName; };
toIni = generators.toINI { inherit mkKeyValue mkSectionName; }; in toIni (gitFlattenAttrs attrs);
in
toIni (gitFlattenAttrs attrs);
gitIniType = with types; gitIniType = with types;
let let
@ -51,8 +46,7 @@ let
multipleType = either primitiveType (listOf primitiveType); multipleType = either primitiveType (listOf primitiveType);
sectionType = attrsOf multipleType; sectionType = attrsOf multipleType;
supersectionType = attrsOf (either multipleType sectionType); supersectionType = attrsOf (either multipleType sectionType);
in in attrsOf supersectionType;
attrsOf supersectionType;
signModule = types.submodule { signModule = types.submodule {
options = { options = {
@ -98,21 +92,18 @@ let
contents = mkOption { contents = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
description = '' description = ''
Configuration to include. If empty then a path must be given. Configuration to include. If empty then a path must be given.
''; '';
}; };
}; };
config.path = mkIf (config.contents != {}) ( config.path = mkIf (config.contents != { })
mkDefault (pkgs.writeText "contents" (gitToIni config.contents)) (mkDefault (pkgs.writeText "contents" (gitToIni config.contents)));
);
}); });
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -143,7 +134,7 @@ in
aliases = mkOption { aliases = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = { };
example = { co = "checkout"; }; example = { co = "checkout"; };
description = "Git aliases to define."; description = "Git aliases to define.";
}; };
@ -156,7 +147,7 @@ in
extraConfig = mkOption { extraConfig = mkOption {
type = types.either types.lines gitIniType; type = types.either types.lines gitIniType;
default = {}; default = { };
example = { example = {
core = { whitespace = "trailing-space,space-before-tab"; }; core = { whitespace = "trailing-space,space-before-tab"; };
url."ssh://git@host".insteadOf = "otherhost"; url."ssh://git@host".insteadOf = "otherhost";
@ -174,21 +165,21 @@ in
ignores = mkOption { ignores = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "*~" "*.swp" ]; example = [ "*~" "*.swp" ];
description = "List of paths that should be globally ignored."; description = "List of paths that should be globally ignored.";
}; };
attributes = mkOption { attributes = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "*.pdf diff=pdf" ]; example = [ "*.pdf diff=pdf" ];
description = "List of defining attributes set globally."; description = "List of defining attributes set globally.";
}; };
includes = mkOption { includes = mkOption {
type = types.listOf includeModule; type = types.listOf includeModule;
default = []; default = [ ];
example = literalExample '' example = literalExample ''
[ [
{ path = "~/path/to/config.inc"; } { path = "~/path/to/config.inc"; }
@ -217,109 +208,96 @@ in
}; };
}; };
config = mkIf cfg.enable ( config = mkIf cfg.enable (mkMerge [
mkMerge [ {
{ home.packages = [ cfg.package ];
home.packages = [ cfg.package ];
programs.git.iniContent.user = { programs.git.iniContent.user = {
name = mkIf (cfg.userName != null) cfg.userName; name = mkIf (cfg.userName != null) cfg.userName;
email = mkIf (cfg.userEmail != null) cfg.userEmail; email = mkIf (cfg.userEmail != null) cfg.userEmail;
};
xdg.configFile = {
"git/config".text = gitToIni cfg.iniContent;
"git/ignore" = mkIf (cfg.ignores != [ ]) {
text = concatStringsSep "\n" cfg.ignores + "\n";
}; };
xdg.configFile = { "git/attributes" = mkIf (cfg.attributes != [ ]) {
"git/config".text = gitToIni cfg.iniContent; text = concatStringsSep "\n" cfg.attributes + "\n";
};
};
}
"git/ignore" = mkIf (cfg.ignores != []) { {
text = concatStringsSep "\n" cfg.ignores + "\n"; programs.git.iniContent = let
hasSmtp = name: account: account.smtp != null;
genIdentity = name: account:
with account;
nameValuePair "sendemail.${name}" ({
smtpEncryption = if smtp.tls.enable then "tls" else "";
smtpServer = smtp.host;
smtpUser = userName;
from = address;
} // optionalAttrs (smtp.port != null) {
smtpServerPort = smtp.port;
});
in mapAttrs' genIdentity
(filterAttrs hasSmtp config.accounts.email.accounts);
}
(mkIf (cfg.signing != null) {
programs.git.iniContent = {
user.signingKey = cfg.signing.key;
commit.gpgSign = cfg.signing.signByDefault;
gpg.program = cfg.signing.gpgPath;
};
})
(mkIf (cfg.aliases != { }) { programs.git.iniContent.alias = cfg.aliases; })
(mkIf (lib.isAttrs cfg.extraConfig) {
programs.git.iniContent = cfg.extraConfig;
})
(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 = 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)));
})
"git/attributes" = mkIf (cfg.attributes != []) { (mkIf cfg.lfs.enable {
text = concatStringsSep "\n" cfg.attributes + "\n"; home.packages = [ pkgs.git-lfs ];
};
programs.git.iniContent.filter.lfs =
let skipArg = optional cfg.lfs.skipSmudge "--skip";
in {
clean = "git-lfs clean -- %f";
process =
concatStringsSep " " ([ "git-lfs" "filter-process" ] ++ skipArg);
required = true;
smudge = concatStringsSep " "
([ "git-lfs" "smudge" ] ++ skipArg ++ [ "--" "%f" ]);
}; };
} })
]);
{
programs.git.iniContent =
let
hasSmtp = name: account: account.smtp != null;
genIdentity = name: account: with account;
nameValuePair "sendemail.${name}" ({
smtpEncryption = if smtp.tls.enable then "tls" else "";
smtpServer = smtp.host;
smtpUser = userName;
from = address;
}
// optionalAttrs (smtp.port != null) {
smtpServerPort = smtp.port;
});
in
mapAttrs' genIdentity
(filterAttrs hasSmtp config.accounts.email.accounts);
}
(mkIf (cfg.signing != null) {
programs.git.iniContent = {
user.signingKey = cfg.signing.key;
commit.gpgSign = cfg.signing.signByDefault;
gpg.program = cfg.signing.gpgPath;
};
})
(mkIf (cfg.aliases != {}) {
programs.git.iniContent.alias = cfg.aliases;
})
(mkIf (lib.isAttrs cfg.extraConfig) {
programs.git.iniContent = cfg.extraConfig;
})
(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 =
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 =
let
skipArg = optional cfg.lfs.skipSmudge "--skip";
in
{
clean = "git-lfs clean -- %f";
process = concatStringsSep " " (
[ "git-lfs" "filter-process" ] ++ skipArg
);
required = true;
smudge = concatStringsSep " " (
[ "git-lfs" "smudge" ] ++ skipArg ++ [ "--" "%f" ]
);
};
})
]
);
} }

View file

@ -11,125 +11,118 @@ let
. ${pkgs.gnome3.vte}/etc/profile.d/vte.sh . ${pkgs.gnome3.vte}/etc/profile.d/vte.sh
''; '';
backForeSubModule = types.submodule ( backForeSubModule = types.submodule ({ ... }: {
{ ... }: { options = {
options = { foreground = mkOption {
foreground = mkOption { type = types.str;
type = types.str; description = "The foreground color.";
description = "The foreground color.";
};
background = mkOption {
type = types.str;
description = "The background color.";
};
}; };
}
);
profileColorsSubModule = types.submodule ( background = mkOption {
{ ... }: { type = types.str;
options = { description = "The background color.";
foregroundColor = mkOption {
type = types.str;
description = "The foreground color.";
};
backgroundColor = mkOption {
type = types.str;
description = "The background color.";
};
boldColor = mkOption {
default = null;
type = types.nullOr types.str;
description = "The bold color, null to use same as foreground.";
};
palette = mkOption {
type = types.listOf types.str;
description = "The terminal palette.";
};
cursor = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The color for the terminal cursor.";
};
highlight = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The colors for the terminals highlighted area.";
};
}; };
} };
); });
profileSubModule = types.submodule ( profileColorsSubModule = types.submodule ({ ... }: {
{ name, config, ... }: { options = {
options = { foregroundColor = mkOption {
default = mkOption { type = types.str;
default = false; description = "The foreground color.";
type = types.bool;
description = "Whether this should be the default profile.";
};
visibleName = mkOption {
type = types.str;
description = "The profile name.";
};
colors = mkOption {
default = null;
type = types.nullOr profileColorsSubModule;
description = "The terminal colors, null to use system default.";
};
cursorShape = mkOption {
default = "block";
type = types.enum [ "block" "ibeam" "underline" ];
description = "The cursor shape.";
};
font = mkOption {
default = null;
type = types.nullOr types.str;
description = "The font name, null to use system default.";
};
allowBold = mkOption {
default = null;
type = types.nullOr types.bool;
description = ''
If <literal>true</literal>, allow applications in the
terminal to make text boldface.
'';
};
scrollOnOutput = mkOption {
default = true;
type = types.bool;
description = "Whether to scroll when output is written.";
};
showScrollbar = mkOption {
default = true;
type = types.bool;
description = "Whether the scroll bar should be visible.";
};
scrollbackLines = mkOption {
default = 10000;
type = types.nullOr types.int;
description =
''
The number of scrollback lines to keep, null for infinite.
'';
};
}; };
}
); backgroundColor = mkOption {
type = types.str;
description = "The background color.";
};
boldColor = mkOption {
default = null;
type = types.nullOr types.str;
description = "The bold color, null to use same as foreground.";
};
palette = mkOption {
type = types.listOf types.str;
description = "The terminal palette.";
};
cursor = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The color for the terminal cursor.";
};
highlight = mkOption {
default = null;
type = types.nullOr backForeSubModule;
description = "The colors for the terminals highlighted area.";
};
};
});
profileSubModule = types.submodule ({ name, config, ... }: {
options = {
default = mkOption {
default = false;
type = types.bool;
description = "Whether this should be the default profile.";
};
visibleName = mkOption {
type = types.str;
description = "The profile name.";
};
colors = mkOption {
default = null;
type = types.nullOr profileColorsSubModule;
description = "The terminal colors, null to use system default.";
};
cursorShape = mkOption {
default = "block";
type = types.enum [ "block" "ibeam" "underline" ];
description = "The cursor shape.";
};
font = mkOption {
default = null;
type = types.nullOr types.str;
description = "The font name, null to use system default.";
};
allowBold = mkOption {
default = null;
type = types.nullOr types.bool;
description = ''
If <literal>true</literal>, allow applications in the
terminal to make text boldface.
'';
};
scrollOnOutput = mkOption {
default = true;
type = types.bool;
description = "Whether to scroll when output is written.";
};
showScrollbar = mkOption {
default = true;
type = types.bool;
description = "Whether the scroll bar should be visible.";
};
scrollbackLines = mkOption {
default = 10000;
type = types.nullOr types.int;
description = ''
The number of scrollback lines to keep, null for infinite.
'';
};
};
});
buildProfileSet = pcfg: buildProfileSet = pcfg:
{ {
@ -137,56 +130,41 @@ let
scrollbar-policy = if pcfg.showScrollbar then "always" else "never"; scrollbar-policy = if pcfg.showScrollbar then "always" else "never";
scrollback-lines = pcfg.scrollbackLines; scrollback-lines = pcfg.scrollbackLines;
cursor-shape = pcfg.cursorShape; cursor-shape = pcfg.cursorShape;
} } // (if (pcfg.font == null) then {
// ( use-system-font = true;
if (pcfg.font == null) } else {
then { use-system-font = true; } use-system-font = false;
else { use-system-font = false; font = pcfg.font; } font = pcfg.font;
) // ( }) // (if (pcfg.colors == null) then {
if (pcfg.colors == null) use-theme-colors = true;
then { use-theme-colors = true; } } else
else ( ({
{ use-theme-colors = false;
use-theme-colors = false; foreground-color = pcfg.colors.foregroundColor;
foreground-color = pcfg.colors.foregroundColor; background-color = pcfg.colors.backgroundColor;
background-color = pcfg.colors.backgroundColor; palette = pcfg.colors.palette;
palette = pcfg.colors.palette; } // optionalAttrs (pcfg.allowBold != null) {
} allow-bold = pcfg.allowBold;
// optionalAttrs (pcfg.allowBold != null) { } // (if (pcfg.colors.boldColor == null) then {
allow-bold = pcfg.allowBold; bold-color-same-as-fg = true;
} } else {
// ( bold-color-same-as-fg = false;
if (pcfg.colors.boldColor == null) bold-color = pcfg.colors.boldColor;
then { bold-color-same-as-fg = true; } }) // (if (pcfg.colors.cursor != null) then {
else { cursor-colors-set = true;
bold-color-same-as-fg = false; cursor-foreground-color = pcfg.colors.cursor.foreground;
bold-color = pcfg.colors.boldColor; cursor-background-color = pcfg.colors.cursor.background;
} } else {
) cursor-colors-set = false;
// ( }) // (if (pcfg.colors.highlight != null) then {
if (pcfg.colors.cursor != null) highlight-colors-set = true;
then { highlight-foreground-color = pcfg.colors.highlight.foreground;
cursor-colors-set = true; highlight-background-color = pcfg.colors.highlight.background;
cursor-foreground-color = pcfg.colors.cursor.foreground; } else {
cursor-background-color = pcfg.colors.cursor.background; highlight-colors-set = false;
} })));
else { cursor-colors-set = false; }
)
// (
if (pcfg.colors.highlight != null)
then {
highlight-colors-set = true;
highlight-foreground-color = pcfg.colors.highlight.foreground;
highlight-background-color = pcfg.colors.highlight.background;
}
else { highlight-colors-set = false; }
)
)
);
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -206,7 +184,7 @@ in
}; };
profile = mkOption { profile = mkOption {
default = {}; default = { };
type = types.attrsOf profileSubModule; type = types.attrsOf profileSubModule;
description = "A set of Gnome Terminal profiles."; description = "A set of Gnome Terminal profiles.";
}; };
@ -216,25 +194,21 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.gnome3.gnome_terminal ]; home.packages = [ pkgs.gnome3.gnome_terminal ];
dconf.settings = dconf.settings = let dconfPath = "org/gnome/terminal/legacy";
let in {
dconfPath = "org/gnome/terminal/legacy"; "${dconfPath}" = {
in default-show-menubar = cfg.showMenubar;
{ theme-variant = cfg.themeVariant;
"${dconfPath}" = { schema-version = 3;
default-show-menubar = cfg.showMenubar; };
theme-variant = cfg.themeVariant;
schema-version = 3;
};
"${dconfPath}/profiles:" = { "${dconfPath}/profiles:" = {
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile)); default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
list = attrNames cfg.profile; list = attrNames cfg.profile;
}; };
} } // mapAttrs'
// mapAttrs' (n: v: (n: v: nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v))
nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v) cfg.profile;
) cfg.profile;
programs.bash.initExtra = mkBefore vteInitStr; programs.bash.initExtra = mkBefore vteInitStr;
programs.zsh.initExtra = vteInitStr; programs.zsh.initExtra = vteInitStr;

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.go; cfg = config.programs.go;
in in {
{
meta.maintainers = [ maintainers.rvolosatovs ]; meta.maintainers = [ maintainers.rvolosatovs ];
options = { options = {
@ -24,7 +22,7 @@ in
packages = mkOption { packages = mkOption {
type = with types; attrsOf path; type = with types; attrsOf path;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
"golang.org/x/text" = builtins.fetchGit "https://go.googlesource.com/text"; "golang.org/x/text" = builtins.fetchGit "https://go.googlesource.com/text";
@ -47,18 +45,15 @@ in
extraGoPaths = mkOption { extraGoPaths = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "extraGoPath1" "extraGoPath2" ]; example = [ "extraGoPath1" "extraGoPath2" ];
description = description = let goPathOpt = "programs.go.goPath";
let in ''
goPathOpt = "programs.go.goPath"; Extra <envar>GOPATH</envar>s relative to <envar>HOME</envar> appended
in after
'' <varname><link linkend="opt-${goPathOpt}">${goPathOpt}</link></varname>,
Extra <envar>GOPATH</envar>s relative to <envar>HOME</envar> appended if that option is set.
after '';
<varname><link linkend="opt-${goPathOpt}">${goPathOpt}</link></varname>,
if that option is set.
'';
}; };
goBin = mkOption { goBin = mkOption {
@ -74,24 +69,21 @@ in
{ {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
home.file = home.file = let
let goPath = if cfg.goPath != null then cfg.goPath else "go";
goPath = if cfg.goPath != null then cfg.goPath else "go"; mkSrc = n: v: { "${goPath}/src/${n}".source = v; };
mkSrc = n: v: { "${goPath}/src/${n}".source = v; }; in foldl' (a: b: a // b) { } (mapAttrsToList mkSrc cfg.packages);
in
foldl' (a: b: a // b) {} (mapAttrsToList mkSrc cfg.packages);
} }
(mkIf (cfg.goPath != null) { (mkIf (cfg.goPath != null) {
home.sessionVariables.GOPATH = home.sessionVariables.GOPATH = concatStringsSep ":" (map builtins.toPath
concatStringsSep ":"
(map builtins.toPath
(map (path: "${config.home.homeDirectory}/${path}") (map (path: "${config.home.homeDirectory}/${path}")
([cfg.goPath] ++ cfg.extraGoPaths))); ([ cfg.goPath ] ++ cfg.extraGoPaths)));
}) })
(mkIf (cfg.goBin != null) { (mkIf (cfg.goBin != null) {
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}"; home.sessionVariables.GOBIN =
builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
}) })
]); ]);
} }

View file

@ -8,9 +8,7 @@ let
dag = config.lib.dag; dag = config.lib.dag;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -33,10 +31,7 @@ in
}; };
config = mkIf (cfg.enable && !config.submoduleSupport.enable) { config = mkIf (cfg.enable && !config.submoduleSupport.enable) {
home.packages = [ home.packages =
(pkgs.callPackage ../../home-manager { [ (pkgs.callPackage ../../home-manager { inherit (cfg) path; }) ];
inherit (cfg) path;
})
];
}; };
} }

View file

@ -3,6 +3,7 @@
with lib; with lib;
let let
cfg = config.programs.htop; cfg = config.programs.htop;
list = xs: concatMapStrings (x: "${toString x} ") xs; list = xs: concatMapStrings (x: "${toString x} ") xs;
@ -81,16 +82,15 @@ let
RightCPUs2 = 1; RightCPUs2 = 1;
Blank = 2; Blank = 2;
CPU = 1; CPU = 1;
"CPU(1)"= 1; "CPU(1)" = 1;
"CPU(2)" = 1; "CPU(2)" = 1;
"CPU(3)" = 1; "CPU(3)" = 1;
"CPU(4)" = 1; "CPU(4)" = 1;
}; };
singleMeterType = types.coercedTo singleMeterType = let
(types.enum (attrNames meters)) meterEnum = types.enum (attrNames meters);
(m: { kind = m; mode = meters.${m}; }) meterSubmodule = types.submodule {
(types.submodule {
options = { options = {
kind = mkOption { kind = mkOption {
type = types.enum (attrNames meters); type = types.enum (attrNames meters);
@ -101,10 +101,15 @@ let
mode = mkOption { mode = mkOption {
type = types.enum [ 1 2 3 4 ]; type = types.enum [ 1 2 3 4 ];
example = 2; example = 2;
description = "Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED)."; description =
"Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
}; };
}; };
}); };
in types.coercedTo meterEnum (m: {
kind = m;
mode = meters.${m};
}) meterSubmodule;
meterType = types.submodule { meterType = types.submodule {
options = { options = {
@ -115,7 +120,10 @@ let
"Memory" "Memory"
"LeftCPUs2" "LeftCPUs2"
"RightCPUs2" "RightCPUs2"
{ kind = "CPU"; mode = 3; } {
kind = "CPU";
mode = 3;
}
]; ];
type = types.listOf singleMeterType; type = types.listOf singleMeterType;
}; };
@ -123,7 +131,10 @@ let
description = "Meters shown in the right header."; description = "Meters shown in the right header.";
default = [ "Tasks" "LoadAverage" "Uptime" ]; default = [ "Tasks" "LoadAverage" "Uptime" ];
example = [ example = [
{ kind = "Clock"; mode = 4; } {
kind = "Clock";
mode = 4;
}
"Uptime" "Uptime"
"Tasks" "Tasks"
]; ];
@ -131,15 +142,37 @@ let
}; };
}; };
}; };
in
{ in {
options.programs.htop = { options.programs.htop = {
enable = mkEnableOption "htop"; enable = mkEnableOption "htop";
fields = mkOption { fields = mkOption {
type = types.listOf (types.enum (attrNames fields)); type = types.listOf (types.enum (attrNames fields));
default = [ "PID" "USER" "PRIORITY" "NICE" "M_SIZE" "M_RESIDENT" "M_SHARE" "STATE" "PERCENT_CPU" "PERCENT_MEM" "TIME" "COMM" ]; default = [
example = [ "PID" "USER" "PRIORITY" "PERCENT_CPU" "M_RESIDENT" "PERCENT_MEM" "TIME" "COMM" ]; "PID"
"USER"
"PRIORITY"
"NICE"
"M_SIZE"
"M_RESIDENT"
"M_SHARE"
"STATE"
"PERCENT_CPU"
"PERCENT_MEM"
"TIME"
"COMM"
];
example = [
"PID"
"USER"
"PRIORITY"
"PERCENT_CPU"
"M_RESIDENT"
"PERCENT_MEM"
"TIME"
"COMM"
];
description = "Active fields shown in the table."; description = "Active fields shown in the table.";
}; };
@ -209,7 +242,7 @@ in
default = true; default = true;
description = "Display threads in a different color."; description = "Display threads in a different color.";
}; };
treeView = mkOption { treeView = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -225,7 +258,8 @@ in
detailedCpuTime = mkOption { detailedCpuTime = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = "Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest)."; description =
"Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
}; };
cpuCountFromZero = mkOption { cpuCountFromZero = mkOption {
@ -272,14 +306,23 @@ in
"CPU" "CPU"
"LeftCPUs2" "LeftCPUs2"
"RightCPUs2" "RightCPUs2"
{ kind = "CPU"; mode = 3; } {
kind = "CPU";
mode = 3;
}
]; ];
right = [ right = [
{ kind = "Clock"; mode = 4; } {
kind = "Clock";
mode = 4;
}
"Uptime" "Uptime"
"Tasks" "Tasks"
"LoadAverage" "LoadAverage"
{ kind = "Battery"; mode = 1; } {
kind = "Battery";
mode = 1;
}
]; ];
}; };
type = meterType; type = meterType;

View file

@ -34,9 +34,7 @@ let
# from this package in the activation script. # from this package in the activation script.
infoPkg = pkgs.texinfoInteractive; infoPkg = pkgs.texinfoInteractive;
in in {
{
options = { options = {
programs.info = { programs.info = {
enable = mkEnableOption "GNU Info"; enable = mkEnableOption "GNU Info";
@ -55,19 +53,20 @@ in
home.sessionVariables.INFOPATH = home.sessionVariables.INFOPATH =
"${cfg.homeInfoDirLocation}\${INFOPATH:+:}\${INFOPATH}"; "${cfg.homeInfoDirLocation}\${INFOPATH:+:}\${INFOPATH}";
home.activation.createHomeInfoDir = hm.dag.entryAfter ["installPackages"] '' home.activation.createHomeInfoDir =
oPATH=$PATH hm.dag.entryAfter [ "installPackages" ] ''
export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH" oPATH=$PATH
$DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}" export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH"
$DRY_RUN_CMD rm -f "${cfg.homeInfoDirLocation}/dir" $DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}"
if [[ -d "${homeInfoPath}" ]]; then $DRY_RUN_CMD rm -f "${cfg.homeInfoDirLocation}/dir"
find -L "${homeInfoPath}" \( -name '*.info' -o -name '*.info.gz' \) \ if [[ -d "${homeInfoPath}" ]]; then
-exec $DRY_RUN_CMD ${infoPkg}/bin/install-info '{}' \ find -L "${homeInfoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
"${cfg.homeInfoDirLocation}/dir" \; -exec $DRY_RUN_CMD ${infoPkg}/bin/install-info '{}' \
fi "${cfg.homeInfoDirLocation}/dir" \;
export PATH="$oPATH" fi
unset oPATH export PATH="$oPATH"
''; unset oPATH
'';
home.packages = [ infoPkg ]; home.packages = [ infoPkg ];

View file

@ -15,19 +15,17 @@ let
colorsType = types.submodule { colorsType = types.submodule {
options = { options = {
null = colorType; null = colorType;
false = colorType; false = colorType;
true = colorType; true = colorType;
numbers = colorType; numbers = colorType;
strings = colorType; strings = colorType;
arrays = colorType; arrays = colorType;
objects = colorType; objects = colorType;
}; };
}; };
in in {
{
options = { options = {
programs.jq = { programs.jq = {
enable = mkEnableOption "the jq command-line JSON processor"; enable = mkEnableOption "the jq command-line JSON processor";
@ -52,12 +50,12 @@ in
''; '';
default = { default = {
null = "1;30"; null = "1;30";
false = "0;39"; false = "0;39";
true = "0;39"; true = "0;39";
numbers = "0;39"; numbers = "0;39";
strings = "0;32"; strings = "0;32";
arrays = "1;39"; arrays = "1;39";
objects = "1;39"; objects = "1;39";
}; };
@ -69,8 +67,10 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.jq ]; home.packages = [ pkgs.jq ];
home.sessionVariables = let c = cfg.colors; in { home.sessionVariables = let c = cfg.colors;
JQ_COLORS = "${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}"; in {
JQ_COLORS =
"${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}";
}; };
}; };
} }

View file

@ -10,16 +10,44 @@ let
options = { options = {
name = mkOption { name = mkOption {
type = types.enum [ type = types.enum [
"NormalBegin" "NormalIdle" "NormalEnd" "NormalKey" "NormalBegin"
"InsertBegin" "InsertIdle" "InsertEnd" "InsertKey" "NormalIdle"
"InsertChar" "InsertDelete" "InsertMove" "WinCreate" "NormalEnd"
"WinClose" "WinResize" "WinDisplay" "WinSetOption" "NormalKey"
"BufSetOption" "BufNewFile" "BufOpenFile" "BufCreate" "InsertBegin"
"BufWritePre" "BufWritePost" "BufReload" "BufClose" "InsertIdle"
"BufOpenFifo" "BufReadFifo" "BufCloseFifo" "RuntimeError" "InsertEnd"
"ModeChange" "PromptIdle" "GlobalSetOption" "KakBegin" "InsertKey"
"KakEnd" "FocusIn" "FocusOut" "RawKey" "InsertChar"
"InsertCompletionShow" "InsertCompletionHide" "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" "InsertCompletionSelect"
]; ];
example = "SetOption"; example = "SetOption";
@ -159,7 +187,8 @@ let
}; };
autoInfo = mkOption { autoInfo = mkOption {
type = types.nullOr (types.listOf (types.enum [ "command" "onkey" "normal" ])); type = types.nullOr
(types.listOf (types.enum [ "command" "onkey" "normal" ]));
default = null; default = null;
example = [ "command" "normal" ]; example = [ "command" "normal" ];
description = '' description = ''
@ -169,7 +198,7 @@ let
}; };
autoComplete = mkOption { autoComplete = mkOption {
type = types.nullOr(types.listOf (types.enum [ "insert" "prompt" ])); type = types.nullOr (types.listOf (types.enum [ "insert" "prompt" ]));
default = null; default = null;
description = '' description = ''
Modes in which to display possible completions. Modes in which to display possible completions.
@ -450,7 +479,7 @@ let
keyMappings = mkOption { keyMappings = mkOption {
type = types.listOf keyMapping; type = types.listOf keyMapping;
default = []; default = [ ];
description = '' description = ''
User-defined key mappings. For documentation, see User-defined key mappings. For documentation, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc"/>. <link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc"/>.
@ -459,7 +488,7 @@ let
hooks = mkOption { hooks = mkOption {
type = types.listOf hook; type = types.listOf hook;
default = []; default = [ ];
description = '' description = ''
Global hooks. For documentation, see Global hooks. For documentation, see
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc"/>. <link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc"/>.
@ -468,92 +497,103 @@ let
}; };
}; };
configFile = configFile = let
let wrapOptions = with cfg.config.wrapLines;
wrapOptions = with cfg.config.wrapLines; concatStrings [ concatStrings [
"${optionalString word " -word"}" "${optionalString word " -word"}"
"${optionalString indent " -indent"}" "${optionalString indent " -indent"}"
"${optionalString (marker != null) " -marker ${marker}"}" "${optionalString (marker != null) " -marker ${marker}"}"
"${optionalString (maxWidth != null) " -width ${toString maxWidth}"}" "${optionalString (maxWidth != null) " -width ${toString maxWidth}"}"
]; ];
numberLinesOptions = with cfg.config.numberLines; concatStrings [ numberLinesOptions = with cfg.config.numberLines;
concatStrings [
"${optionalString relative " -relative "}" "${optionalString relative " -relative "}"
"${optionalString highlightCursor " -hlcursor"}" "${optionalString highlightCursor " -hlcursor"}"
"${optionalString (separator != null) " -separator ${separator}"}" "${optionalString (separator != null) " -separator ${separator}"}"
]; ];
uiOptions = with cfg.config.ui; concatStringsSep " " [ uiOptions = with cfg.config.ui;
concatStringsSep " " [
"ncurses_set_title=${if setTitle then "true" else "false"}" "ncurses_set_title=${if setTitle then "true" else "false"}"
"ncurses_status_on_top=${if (statusLine == "top") then "true" else "false"}" "ncurses_status_on_top=${
if (statusLine == "top") then "true" else "false"
}"
"ncurses_assistant=${assistant}" "ncurses_assistant=${assistant}"
"ncurses_enable_mouse=${if enableMouse then "true" else "false"}" "ncurses_enable_mouse=${if enableMouse then "true" else "false"}"
"ncurses_change_colors=${if changeColors then "true" else "false"}" "ncurses_change_colors=${if changeColors then "true" else "false"}"
"${optionalString (wheelDownButton != null) "${optionalString (wheelDownButton != null)
"ncurses_wheel_down_button=${wheelDownButton}"}" "ncurses_wheel_down_button=${wheelDownButton}"}"
"${optionalString (wheelUpButton != null) "${optionalString (wheelUpButton != null)
"ncurses_wheel_up_button=${wheelUpButton}"}" "ncurses_wheel_up_button=${wheelUpButton}"}"
"${optionalString (shiftFunctionKeys != null) "${optionalString (shiftFunctionKeys != null)
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}" "ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
"ncurses_builtin_key_parser=${if useBuiltinKeyParser then "true" else "false"}" "ncurses_builtin_key_parser=${
if useBuiltinKeyParser then "true" else "false"
}"
]; ];
keyMappingString = km: concatStringsSep " " [ keyMappingString = km:
concatStringsSep " " [
"map global" "map global"
"${km.mode} ${km.key} '${km.effect}'" "${km.mode} ${km.key} '${km.effect}'"
"${optionalString (km.docstring != null) "-docstring '${km.docstring}'"}" "${optionalString (km.docstring != null)
"-docstring '${km.docstring}'"}"
]; ];
hookString = h: concatStringsSep " " [ hookString = h:
"hook" "${optionalString (h.group != null) "-group ${group}"}" concatStringsSep " " [
"${optionalString (h.once) "-once"}" "global" "hook"
"${h.name}" "${optionalString (h.option != null) h.option}" "${optionalString (h.group != null) "-group ${group}"}"
"${optionalString (h.once) "-once"}"
"global"
"${h.name}"
"${optionalString (h.option != null) h.option}"
"%{ ${h.commands} }" "%{ ${h.commands} }"
]; ];
cfgStr = with cfg.config; concatStringsSep "\n" ( cfgStr = with cfg.config;
[ "# Generated by home-manager" ] concatStringsSep "\n" ([ "# Generated by home-manager" ]
++ optional (colorScheme != null) "colorscheme ${colorScheme}" ++ optional (colorScheme != null) "colorscheme ${colorScheme}"
++ optional (tabStop != null) "set-option global tabstop ${toString tabStop}" ++ optional (tabStop != null)
++ optional (indentWidth != null) "set-option global indentwidth ${toString indentWidth}" "set-option global tabstop ${toString tabStop}"
++ optional (indentWidth != null)
"set-option global indentwidth ${toString indentWidth}"
++ optional (!incrementalSearch) "set-option global incsearch false" ++ optional (!incrementalSearch) "set-option global incsearch false"
++ optional (alignWithTabs) "set-option global aligntab true" ++ optional (alignWithTabs) "set-option global aligntab true"
++ optional (autoInfo != null) "set-option global autoinfo ${concatStringsSep "|" autoInfo}" ++ optional (autoInfo != null)
++ optional (autoComplete != null) "set-option global autocomplete ${concatStringsSep "|" autoComplete}" "set-option global autoinfo ${concatStringsSep "|" autoInfo}"
++ optional (autoReload != null) "set-option global/ autoreload ${autoReload}" ++ optional (autoComplete != null)
++ optional (wrapLines != null && wrapLines.enable) "add-highlighter global/ wrap${wrapOptions}" "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) ++ optional (numberLines != null && numberLines.enable)
"add-highlighter global/ number-lines${numberLinesOptions}" "add-highlighter global/ number-lines${numberLinesOptions}"
++ optional showMatching "add-highlighter global/ show-matching" ++ optional showMatching "add-highlighter global/ show-matching"
++ optional (scrollOff != null) ++ optional (scrollOff != null)
"set-option global scrolloff ${toString scrollOff.lines},${toString scrollOff.columns}" "set-option global scrolloff ${toString scrollOff.lines},${
toString scrollOff.columns
}"
++ [ "# UI options" ] ++ [ "# UI options" ]
++ optional (ui != null) "set-option global ui_options ${uiOptions}" ++ optional (ui != null) "set-option global ui_options ${uiOptions}"
++ [ "# Key mappings" ] ++ [ "# Key mappings" ] ++ map keyMappingString keyMappings
++ map keyMappingString keyMappings
++ [ "# Hooks" ] ++ [ "# Hooks" ] ++ map hookString hooks);
++ map hookString hooks in pkgs.writeText "kakrc"
); (optionalString (cfg.config != null) cfgStr + "\n" + cfg.extraConfig);
in
pkgs.writeText "kakrc" (
optionalString (cfg.config != null) cfgStr
+ "\n"
+ cfg.extraConfig
);
in in {
{
options = { options = {
programs.kakoune = { programs.kakoune = {
enable = mkEnableOption "the kakoune text editor"; enable = mkEnableOption "the kakoune text editor";
config = mkOption { config = mkOption {
type = types.nullOr configModule; type = types.nullOr configModule;
default = {}; default = { };
description = "kakoune configuration options."; description = "kakoune configuration options.";
}; };

View file

@ -6,15 +6,16 @@ let
cfg = config.programs.keychain; cfg = config.programs.keychain;
flags = cfg.extraFlags flags = cfg.extraFlags ++ optional (cfg.agents != [ ])
++ optional (cfg.agents != []) "--agents ${concatStringsSep "," cfg.agents}" "--agents ${concatStringsSep "," cfg.agents}"
++ optional (cfg.inheritType != null) "--inherit ${cfg.inheritType}"; ++ optional (cfg.inheritType != null) "--inherit ${cfg.inheritType}";
shellCommand = "${cfg.package}/bin/keychain --eval ${concatStringsSep " " flags} ${concatStringsSep " " cfg.keys}"; shellCommand =
"${cfg.package}/bin/keychain --eval ${concatStringsSep " " flags} ${
concatStringsSep " " cfg.keys
}";
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.keychain = { options.programs.keychain = {
@ -39,14 +40,15 @@ in
agents = mkOption { agents = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
description = '' description = ''
Agents to add. Agents to add.
''; '';
}; };
inheritType = mkOption { inheritType = mkOption {
type = types.nullOr (types.enum ["local" "any" "local-once" "any-once"]); type =
types.nullOr (types.enum [ "local" "any" "local-once" "any-once" ]);
default = null; default = null;
description = '' description = ''
Inherit type to attempt from agent variables from the environment. Inherit type to attempt from agent variables from the environment.

View file

@ -11,12 +11,10 @@ let
ll = "ls -l"; ll = "ls -l";
la = "ls -a"; la = "ls -a";
lt = "ls --tree"; lt = "ls --tree";
lla ="ls -la"; lla = "ls -la";
}; };
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.lsd = { options.programs.lsd = {

View file

@ -9,16 +9,13 @@ let
formatLine = o: n: v: formatLine = o: n: v:
let let
formatValue = v: formatValue = v:
if isBool v then (if v then "True" else "False") if isBool v then (if v then "True" else "False") else toString v;
else toString v; in if isAttrs v then
in concatStringsSep "\n" (mapAttrsToList (formatLine "${o}${n}.") v)
if isAttrs v else
then concatStringsSep "\n" (mapAttrsToList (formatLine "${o}${n}.") v) (if v == "" then "" else "${o}${n}: ${formatValue v}");
else (if v == "" then "" else "${o}${n}: ${formatValue v}");
in in {
{
meta.maintainers = [ maintainers.rprospero ]; meta.maintainers = [ maintainers.rprospero ];
options.programs.matplotlib = { options.programs.matplotlib = {
@ -31,7 +28,7 @@ in
Add terms to the <filename>matplotlibrc</filename> file to Add terms to the <filename>matplotlibrc</filename> file to
control the default matplotlib behavior. control the default matplotlib behavior.
''; '';
example = literalExample '' example = literalExample ''
{ {
backend = "Qt5Agg"; backend = "Qt5Agg";
axes = { axes = {
@ -55,10 +52,8 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
xdg.configFile."matplotlib/matplotlibrc".text = xdg.configFile."matplotlib/matplotlibrc".text = concatStringsSep "\n" ([ ]
concatStringsSep "\n" ([] ++ mapAttrsToList (formatLine "") cfg.config
++ mapAttrsToList (formatLine "") cfg.config ++ optional (cfg.extraConfig != "") cfg.extraConfig) + "\n";
++ optional (cfg.extraConfig != "") cfg.extraConfig
) + "\n";
}; };
} }

View file

@ -6,9 +6,7 @@ let
extraConfigType = with lib.types; attrsOf (either (either str int) bool); extraConfigType = with lib.types; attrsOf (either (either str int) bool);
in in {
{
options.mbsync = { options.mbsync = {
enable = mkEnableOption "synchronization using mbsync"; enable = mkEnableOption "synchronization using mbsync";
@ -62,7 +60,7 @@ in
extraConfig.channel = mkOption { extraConfig.channel = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
MaxMessages = 10000; MaxMessages = 10000;
@ -76,7 +74,7 @@ in
extraConfig.local = mkOption { extraConfig.local = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
description = '' description = ''
Local store extra configuration. Local store extra configuration.
''; '';
@ -84,7 +82,7 @@ in
extraConfig.remote = mkOption { extraConfig.remote = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
description = '' description = ''
Remote store extra configuration. Remote store extra configuration.
''; '';
@ -92,7 +90,7 @@ in
extraConfig.account = mkOption { extraConfig.account = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
PipelineDepth = 10; PipelineDepth = 10;

View file

@ -10,14 +10,15 @@ let
mbsyncAccounts = mbsyncAccounts =
filter (a: a.mbsync.enable) (attrValues config.accounts.email.accounts); filter (a: a.mbsync.enable) (attrValues config.accounts.email.accounts);
genTlsConfig = tls: { genTlsConfig = tls:
SSLType = {
if !tls.enable then "None" SSLType = if !tls.enable then
else if tls.useStartTls then "STARTTLS" "None"
else "IMAPS"; else if tls.useStartTls then
} "STARTTLS"
// else
optionalAttrs (tls.enable && tls.certificatesFile != null) { "IMAPS";
} // optionalAttrs (tls.enable && tls.certificatesFile != null) {
CertificateFile = toString tls.certificatesFile; CertificateFile = toString tls.certificatesFile;
}; };
@ -30,79 +31,61 @@ let
genSection = header: entries: genSection = header: entries:
let let
escapeValue = escape [ "\"" ]; escapeValue = escape [ ''"'' ];
hasSpace = v: builtins.match ".* .*" v != null; hasSpace = v: builtins.match ".* .*" v != null;
genValue = n: v: genValue = n: v:
if isList v if isList v then
then concatMapStringsSep " " (genValue n) v concatMapStringsSep " " (genValue n) v
else if isBool v then (if v then "yes" else "no") else if isBool v then
else if isInt v then toString v (if v then "yes" else "no")
else if isString v && hasSpace v then "\"${escapeValue v}\"" else if isInt v then
else if isString v then v toString v
else if isString v && hasSpace v then
''"${escapeValue v}"''
else if isString v then
v
else else
let prettyV = lib.generators.toPretty {} v; let prettyV = lib.generators.toPretty { } v;
in throw "mbsync: unexpected value for option ${n}: '${prettyV}'"; in throw "mbsync: unexpected value for option ${n}: '${prettyV}'";
in in ''
'' ${header}
${header} ${concatStringsSep "\n"
${concatStringsSep "\n" (mapAttrsToList (n: v: "${n} ${genValue n v}") entries)}
(mapAttrsToList (n: v: "${n} ${genValue n v}") entries)} '';
'';
genAccountConfig = account: with account; genAccountConfig = account:
genSection "IMAPAccount ${name}" ( with account;
{ genSection "IMAPAccount ${name}" ({
Host = imap.host; Host = imap.host;
User = userName; User = userName;
PassCmd = toString passwordCommand; PassCmd = toString passwordCommand;
} } // genTlsConfig imap.tls
// genTlsConfig imap.tls // optionalAttrs (imap.port != null) { Port = toString imap.port; }
// optionalAttrs (imap.port != null) { Port = toString imap.port; } // mbsync.extraConfig.account) + "\n"
// mbsync.extraConfig.account + genSection "IMAPStore ${name}-remote"
) ({ Account = name; } // mbsync.extraConfig.remote) + "\n"
+ "\n" + genSection "MaildirStore ${name}-local" ({
+ genSection "IMAPStore ${name}-remote" ( Path = "${maildir.absPath}/";
{ Inbox = "${maildir.absPath}/${folders.inbox}";
Account = name; SubFolders = "Verbatim";
} } // optionalAttrs (mbsync.flatten != null) { Flatten = mbsync.flatten; }
// mbsync.extraConfig.remote // mbsync.extraConfig.local) + "\n" + genSection "Channel ${name}" ({
) Master = ":${name}-remote:";
+ "\n" Slave = ":${name}-local:";
+ genSection "MaildirStore ${name}-local" ( Patterns = mbsync.patterns;
{ Create = masterSlaveMapping.${mbsync.create};
Path = "${maildir.absPath}/"; Remove = masterSlaveMapping.${mbsync.remove};
Inbox = "${maildir.absPath}/${folders.inbox}"; Expunge = masterSlaveMapping.${mbsync.expunge};
SubFolders = "Verbatim"; SyncState = "*";
} } // mbsync.extraConfig.channel) + "\n";
// optionalAttrs (mbsync.flatten != null) { Flatten = mbsync.flatten; }
// mbsync.extraConfig.local
)
+ "\n"
+ genSection "Channel ${name}" (
{
Master = ":${name}-remote:";
Slave = ":${name}-local:";
Patterns = mbsync.patterns;
Create = masterSlaveMapping.${mbsync.create};
Remove = masterSlaveMapping.${mbsync.remove};
Expunge = masterSlaveMapping.${mbsync.expunge};
SyncState = "*";
}
// mbsync.extraConfig.channel
)
+ "\n";
genGroupConfig = name: channels: genGroupConfig = name: channels:
let let
genGroupChannel = n: boxes: "Channel ${n}:${concatStringsSep "," boxes}"; genGroupChannel = n: boxes: "Channel ${n}:${concatStringsSep "," boxes}";
in in concatStringsSep "\n"
concatStringsSep "\n" ( ([ "Group ${name}" ] ++ mapAttrsToList genGroupChannel channels);
[ "Group ${name}" ] ++ mapAttrsToList genGroupChannel channels
);
in in {
{
options = { options = {
programs.mbsync = { programs.mbsync = {
enable = mkEnableOption "mbsync IMAP4 and Maildir mailbox synchronizer"; enable = mkEnableOption "mbsync IMAP4 and Maildir mailbox synchronizer";
@ -117,7 +100,7 @@ in
groups = mkOption { groups = mkOption {
type = types.attrsOf (types.attrsOf (types.listOf types.str)); type = types.attrsOf (types.attrsOf (types.listOf types.str));
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
inboxes = { inboxes = {
@ -142,41 +125,34 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = assertions = let
let checkAccounts = pred: msg:
checkAccounts = pred: msg: let badAccounts = filter pred mbsyncAccounts;
let in {
badAccounts = filter pred mbsyncAccounts; assertion = badAccounts == [ ];
in { message = "mbsync: ${msg} for accounts: "
assertion = badAccounts == []; + concatMapStringsSep ", " (a: a.name) badAccounts;
message = "mbsync: ${msg} for accounts: " };
+ concatMapStringsSep ", " (a: a.name) badAccounts; in [
}; (checkAccounts (a: a.maildir == null) "Missing maildir configuration")
in (checkAccounts (a: a.imap == null) "Missing IMAP configuration")
[ (checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
(checkAccounts (a: a.maildir == null) "Missing maildir configuration") (checkAccounts (a: a.userName == null) "Missing username")
(checkAccounts (a: a.imap == null) "Missing IMAP configuration") ];
(checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
(checkAccounts (a: a.userName == null) "Missing username")
];
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ]; programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
home.file.".mbsyncrc".text = home.file.".mbsyncrc".text = let
let accountsConfig = map genAccountConfig mbsyncAccounts;
accountsConfig = map genAccountConfig mbsyncAccounts; groupsConfig = mapAttrsToList genGroupConfig cfg.groups;
groupsConfig = mapAttrsToList genGroupConfig cfg.groups; in concatStringsSep "\n" ([''
in # Generated by Home Manager.
concatStringsSep "\n" ( ''] ++ optional (cfg.extraConfig != "") cfg.extraConfig ++ accountsConfig
[ "# Generated by Home Manager.\n" ] ++ groupsConfig) + "\n";
++ optional (cfg.extraConfig != "") cfg.extraConfig
++ accountsConfig
++ groupsConfig
) + "\n";
home.activation = mkIf (mbsyncAccounts != []) { home.activation = mkIf (mbsyncAccounts != [ ]) {
createMaildir = createMaildir =
hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] '' hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${ $DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.mercurial; cfg = config.programs.mercurial;
in in {
{
options = { options = {
programs.mercurial = { programs.mercurial = {
@ -33,13 +31,13 @@ in
aliases = mkOption { aliases = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
description = "Mercurial aliases to define."; description = "Mercurial aliases to define.";
}; };
extraConfig = mkOption { extraConfig = mkOption {
type = types.either types.attrs types.lines; type = types.either types.attrs types.lines;
default = {}; default = { };
description = "Additional configuration to add."; description = "Additional configuration to add.";
}; };
@ -50,53 +48,53 @@ in
ignores = mkOption { ignores = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "*~" "*.swp" ]; example = [ "*~" "*.swp" ];
description = "List of globs for files to be globally ignored."; description = "List of globs for files to be globally ignored.";
}; };
ignoresRegexp = mkOption { ignoresRegexp = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "^.*~$" "^.*\\.swp$" ]; example = [ "^.*~$" "^.*\\.swp$" ];
description = description =
"List of regular expressions for files to be globally ignored."; "List of regular expressions for files to be globally ignored.";
}; };
}; };
}; };
config = mkIf cfg.enable ( config = mkIf cfg.enable (mkMerge [
mkMerge [ {
{ home.packages = [ cfg.package ];
home.packages = [ cfg.package ];
programs.mercurial.iniContent.ui = { programs.mercurial.iniContent.ui = {
username = cfg.userName + " <" + cfg.userEmail + ">"; username = cfg.userName + " <" + cfg.userEmail + ">";
}; };
xdg.configFile."hg/hgrc".text = generators.toINI {} cfg.iniContent; xdg.configFile."hg/hgrc".text = generators.toINI { } cfg.iniContent;
} }
(mkIf (cfg.ignores != [] || cfg.ignoresRegexp != []) { (mkIf (cfg.ignores != [ ] || cfg.ignoresRegexp != [ ]) {
programs.mercurial.iniContent.ui.ignore = programs.mercurial.iniContent.ui.ignore =
"${config.xdg.configHome}/hg/hgignore_global"; "${config.xdg.configHome}/hg/hgignore_global";
xdg.configFile."hg/hgignore_global".text = xdg.configFile."hg/hgignore_global".text = ''
"syntax: glob\n" + concatStringsSep "\n" cfg.ignores + "\n" + syntax: glob
"syntax: regexp\n" + concatStringsSep "\n" cfg.ignoresRegexp + "\n"; '' + concatStringsSep "\n" cfg.ignores + "\n" + ''
}) syntax: regexp
'' + concatStringsSep "\n" cfg.ignoresRegexp + "\n";
})
(mkIf (cfg.aliases != {}) { (mkIf (cfg.aliases != { }) {
programs.mercurial.iniContent.alias = cfg.aliases; programs.mercurial.iniContent.alias = cfg.aliases;
}) })
(mkIf (lib.isAttrs cfg.extraConfig) { (mkIf (lib.isAttrs cfg.extraConfig) {
programs.mercurial.iniContent = cfg.extraConfig; programs.mercurial.iniContent = cfg.extraConfig;
}) })
(mkIf (lib.isString cfg.extraConfig) { (mkIf (lib.isString cfg.extraConfig) {
xdg.configFile."hg/hgrc".text = cfg.extraConfig; xdg.configFile."hg/hgrc".text = cfg.extraConfig;
}) })
] ]);
);
} }

View file

@ -23,31 +23,21 @@ let
}.${typeOf option}; }.${typeOf option};
renderOptions = options: renderOptions = options:
concatStringsSep "\n" concatStringsSep "\n" (mapAttrsToList (name: value:
(mapAttrsToList let
(name: value: rendered = renderOption value;
let length = toString (stringLength rendered);
rendered = renderOption value; in "${name}=%${length}%${rendered}") options);
length = toString (stringLength rendered);
in
"${name}=%${length}%${rendered}")
options);
renderProfiles = profiles: renderProfiles = profiles:
concatStringsSep "\n" concatStringsSep "\n" (mapAttrsToList (name: value: ''
(mapAttrsToList [${name}]
(name: value: '' ${renderOptions value}
[${name}] '') profiles);
${renderOptions value}
'')
profiles);
renderBindings = bindings: renderBindings = bindings:
concatStringsSep "\n" concatStringsSep "\n"
(mapAttrsToList (mapAttrsToList (name: value: "${name} ${value}") bindings);
(name: value:
"${name} ${value}")
bindings);
in { in {
options = { options = {
@ -56,7 +46,7 @@ in {
scripts = mkOption { scripts = mkOption {
type = with types; listOf (either package str); type = with types; listOf (either package str);
default = []; default = [ ];
example = literalExample "[ pkgs.mpvScripts.mpris ]"; example = literalExample "[ pkgs.mpvScripts.mpris ]";
description = '' description = ''
List of scripts to use with mpv. List of scripts to use with mpv.
@ -74,7 +64,7 @@ in {
for the full list of options. for the full list of options.
''; '';
type = mpvOptions; type = mpvOptions;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
profile = "gpu-hq"; profile = "gpu-hq";
@ -92,7 +82,7 @@ in {
<option>programs.mpv.config</option> for more information. <option>programs.mpv.config</option> for more information.
''; '';
type = mpvProfiles; type = mpvProfiles;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
fast = { fast = {
@ -117,7 +107,7 @@ in {
for the full list of options. for the full list of options.
''; '';
type = mpvBindings; type = mpvBindings;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
WHEEL_UP = "seek 10"; WHEEL_UP = "seek 10";
@ -131,19 +121,20 @@ in {
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
{ {
home.packages = [( home.packages = [
if cfg.scripts == [] (if cfg.scripts == [ ] then
then pkgs.mpv pkgs.mpv
else pkgs.mpv-with-scripts.override { scripts = cfg.scripts; } else
)]; pkgs.mpv-with-scripts.override { scripts = cfg.scripts; })
];
} }
(mkIf (cfg.config != {} || cfg.profiles != {}) { (mkIf (cfg.config != { } || cfg.profiles != { }) {
xdg.configFile."mpv/mpv.conf".text = '' xdg.configFile."mpv/mpv.conf".text = ''
${optionalString (cfg.config != {}) (renderOptions cfg.config)} ${optionalString (cfg.config != { }) (renderOptions cfg.config)}
${optionalString (cfg.profiles != {}) (renderProfiles cfg.profiles)} ${optionalString (cfg.profiles != { }) (renderProfiles cfg.profiles)}
''; '';
}) })
(mkIf (cfg.bindings != {}) { (mkIf (cfg.bindings != { }) {
xdg.configFile."mpv/input.conf".text = renderBindings cfg.bindings; xdg.configFile."mpv/input.conf".text = renderBindings cfg.bindings;
}) })
]); ]);

View file

@ -23,7 +23,8 @@ with lib;
}; };
tls.fingerprint = mkOption { tls.fingerprint = mkOption {
type = types.nullOr (types.strMatching "([[:alnum:]]{2}\:)+[[:alnum:]]{2}"); type =
types.nullOr (types.strMatching "([[:alnum:]]{2}:)+[[:alnum:]]{2}");
default = null; default = null;
example = "my:SH:a2:56:ha:sh"; example = "my:SH:a2:56:ha:sh";
description = '' description = ''

View file

@ -6,38 +6,32 @@ let
cfg = config.programs.msmtp; cfg = config.programs.msmtp;
msmtpAccounts = filter (a: a.msmtp.enable) msmtpAccounts =
(attrValues config.accounts.email.accounts); filter (a: a.msmtp.enable) (attrValues config.accounts.email.accounts);
onOff = p: if p then "on" else "off"; onOff = p: if p then "on" else "off";
accountStr = account: with account; accountStr = account:
concatStringsSep "\n" ( with account;
[ "account ${name}" ] concatStringsSep "\n" ([ "account ${name}" ]
++ mapAttrsToList (n: v: n + " " + v) ( ++ mapAttrsToList (n: v: n + " " + v) ({
{ host = smtp.host;
host = smtp.host; from = address;
from = address; auth = "on";
auth = "on"; user = userName;
user = userName; tls = onOff smtp.tls.enable;
tls = onOff smtp.tls.enable; tls_starttls = onOff smtp.tls.useStartTls;
tls_starttls = onOff smtp.tls.useStartTls; tls_trust_file = smtp.tls.certificatesFile;
tls_trust_file = smtp.tls.certificatesFile; } // optionalAttrs (msmtp.tls.fingerprint != null) {
} tls_fingerprint = msmtp.tls.fingerprint;
// optionalAttrs (msmtp.tls.fingerprint != null) { } // optionalAttrs (smtp.port != null) { port = toString smtp.port; }
tls_fingerprint = msmtp.tls.fingerprint;
}
// optionalAttrs (smtp.port != null) {
port = toString smtp.port;
}
// optionalAttrs (passwordCommand != null) { // optionalAttrs (passwordCommand != null) {
# msmtp requires the password to finish with a newline. # msmtp requires the password to finish with a newline.
passwordeval = ''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"''; passwordeval =
} ''${pkgs.bash}/bin/bash -c "${toString passwordCommand}; echo"'';
// msmtp.extraConfig } // msmtp.extraConfig) ++ optional primary ''
)
++ optional primary "\naccount default : ${name}" account default : ${name}'');
);
configFile = mailAccounts: '' configFile = mailAccounts: ''
# Generated by Home Manager. # Generated by Home Manager.
@ -47,9 +41,7 @@ let
${concatStringsSep "\n\n" (map accountStr mailAccounts)} ${concatStringsSep "\n\n" (map accountStr mailAccounts)}
''; '';
in in {
{
options = { options = {
programs.msmtp = { programs.msmtp = {
@ -71,7 +63,7 @@ in
xdg.configFile."msmtp/config".text = configFile msmtpAccounts; xdg.configFile."msmtp/config".text = configFile msmtpAccounts;
home.sessionVariables = { home.sessionVariables = {
MSMTP_QUEUE = "${config.xdg.dataHome}/msmtp/queue"; MSMTP_QUEUE = "${config.xdg.dataHome}/msmtp/queue";
MSMTP_LOG = "${config.xdg.dataHome}/msmtp/queue.log"; MSMTP_LOG = "${config.xdg.dataHome}/msmtp/queue.log";
}; };

View file

@ -26,10 +26,9 @@ with lib;
}; };
config = mkIf config.neomutt.enable { config = mkIf config.neomutt.enable {
neomutt.sendMailCommand = mkOptionDefault ( neomutt.sendMailCommand = mkOptionDefault (if config.msmtp.enable then
if config.msmtp.enable "msmtpq --read-envelope-from --read-recipients"
then "msmtpq --read-envelope-from --read-recipients" else
else null null);
);
}; };
} }

View file

@ -6,8 +6,8 @@ let
cfg = config.programs.neomutt; cfg = config.programs.neomutt;
neomuttAccounts = filter (a: a.neomutt.enable) neomuttAccounts =
(attrValues config.accounts.email.accounts); filter (a: a.neomutt.enable) (attrValues config.accounts.email.accounts);
sidebarModule = types.submodule { sidebarModule = types.submodule {
options = { options = {
@ -76,13 +76,12 @@ let
yesno = x: if x then "yes" else "no"; yesno = x: if x then "yes" else "no";
setOption = n: v: if v == null then "unset ${n}" else "set ${n}=${v}"; setOption = n: v: if v == null then "unset ${n}" else "set ${n}=${v}";
escape = replaceStrings ["%"] ["%25"]; escape = replaceStrings [ "%" ] [ "%25" ];
accountFilename = account: accountFilename = account: config.xdg.configHome + "/neomutt/" + account.name;
config.xdg.configHome + "/neomutt/" + account.name;
genCommonFolderHooks = account: with account; genCommonFolderHooks = account:
{ with account; {
from = "'${address}'"; from = "'${address}'";
realname = "'${realName}'"; realname = "'${realName}'";
spoolfile = "'+${folders.inbox}'"; spoolfile = "'+${folders.inbox}'";
@ -91,13 +90,13 @@ let
trash = "'+${folders.trash}'"; trash = "'+${folders.trash}'";
}; };
mtaSection = account: with account; mtaSection = account:
let with account;
passCmd = concatStringsSep " " passwordCommand; let passCmd = concatStringsSep " " passwordCommand;
in in if neomutt.sendMailCommand != null then {
if neomutt.sendMailCommand != null then { sendmail = "'${neomutt.sendMailCommand}'";
sendmail = "'${neomutt.sendMailCommand}'"; } else
} else let let
smtpProto = if smtp.tls.enable then "smtps" else "smtp"; smtpProto = if smtp.tls.enable then "smtps" else "smtp";
smtpBaseUrl = "${smtpProto}://${escape userName}@${smtp.host}"; smtpBaseUrl = "${smtpProto}://${escape userName}@${smtp.host}";
in { in {
@ -105,35 +104,32 @@ let
smtp_pass = "'`${passCmd}`'"; smtp_pass = "'`${passCmd}`'";
}; };
genMaildirAccountConfig = account: with account; genMaildirAccountConfig = account:
with account;
let let
folderHook = folderHook = mapAttrsToList setOption (genCommonFolderHooks account // {
mapAttrsToList setOption ( folder = "'${account.maildir.absPath}'";
genCommonFolderHooks account }) ++ optional (neomutt.extraConfig != "") neomutt.extraConfig;
// { folder = "'${account.maildir.absPath}'"; } in ''
) ${concatStringsSep "\n" folderHook}
++ optional (neomutt.extraConfig != "") neomutt.extraConfig; '';
in
''
${concatStringsSep "\n" folderHook}
'';
registerAccount = account: with account; registerAccount = account:
'' with account; ''
# register account ${name} # register account ${name}
mailboxes "${account.maildir.absPath}/${folders.inbox}" mailboxes "${account.maildir.absPath}/${folders.inbox}"
folder-hook ${account.maildir.absPath}/ " \ folder-hook ${account.maildir.absPath}/ " \
source ${accountFilename account} " source ${accountFilename account} "
''; '';
mraSection = account: with account; mraSection = account:
if account.maildir != null with account;
then genMaildirAccountConfig account if account.maildir != null then
else throw "Only maildir is supported at the moment"; genMaildirAccountConfig account
else
optionsStr = attrs: throw "Only maildir is supported at the moment";
concatStringsSep "\n" (mapAttrsToList setOption attrs);
optionsStr = attrs: concatStringsSep "\n" (mapAttrsToList setOption attrs);
sidebarSection = '' sidebarSection = ''
# Sidebar # Sidebar
@ -143,81 +139,74 @@ let
set sidebar_format = '${cfg.sidebar.format}' set sidebar_format = '${cfg.sidebar.format}'
''; '';
bindSection = bindSection = concatMapStringsSep "\n"
concatMapStringsSep (bind: ''bind ${bind.map} ${bind.key} "${bind.action}"'') cfg.binds;
"\n"
(bind: "bind ${bind.map} ${bind.key} \"${bind.action}\"")
cfg.binds;
macroSection = macroSection = concatMapStringsSep "\n"
concatMapStringsSep (bind: ''macro ${bind.map} ${bind.key} "${bind.action}"'') cfg.macros;
"\n"
(bind: "macro ${bind.map} ${bind.key} \"${bind.action}\"")
cfg.macros;
mailCheckSection = '' mailCheckSection = ''
set mail_check_stats set mail_check_stats
set mail_check_stats_interval = ${toString cfg.checkStatsInterval} set mail_check_stats_interval = ${toString cfg.checkStatsInterval}
''; '';
notmuchSection = account: with account; '' notmuchSection = account:
# notmuch section with account; ''
set nm_default_uri = "notmuch://${config.accounts.email.maildirBasePath}" # notmuch section
virtual-mailboxes "My INBOX" "notmuch://?query=tag:inbox" set nm_default_uri = "notmuch://${config.accounts.email.maildirBasePath}"
''; virtual-mailboxes "My INBOX" "notmuch://?query=tag:inbox"
'';
accountStr = account: with account; '' accountStr = account:
# Generated by Home Manager. with account;
set ssl_force_tls = yes ''
set certificate_file=${config.accounts.email.certificatesFile} # Generated by Home Manager.
set ssl_force_tls = yes
set certificate_file=${config.accounts.email.certificatesFile}
# GPG section # GPG section
set crypt_use_gpgme = yes set crypt_use_gpgme = yes
set crypt_autosign = ${yesno (gpg.signByDefault or false)} set crypt_autosign = ${yesno (gpg.signByDefault or false)}
set pgp_use_gpg_agent = yes set pgp_use_gpg_agent = yes
set mbox_type = ${if maildir != null then "Maildir" else "mbox"} set mbox_type = ${if maildir != null then "Maildir" else "mbox"}
set sort = "${cfg.sort}" set sort = "${cfg.sort}"
# MTA section # MTA section
${optionsStr (mtaSection account)} ${optionsStr (mtaSection account)}
${optionalString (cfg.checkStatsInterval != null) mailCheckSection} ${optionalString (cfg.checkStatsInterval != null) mailCheckSection}
${optionalString cfg.sidebar.enable sidebarSection} ${optionalString cfg.sidebar.enable sidebarSection}
# MRA section # MRA section
${mraSection account} ${mraSection account}
# Extra configuration # Extra configuration
${account.neomutt.extraConfig} ${account.neomutt.extraConfig}
'' '' + optionalString (account.signature.showSignature != "none") ''
+ optionalString (account.signature.showSignature != "none") '' set signature = ${pkgs.writeText "signature.txt" account.signature.text}
set signature = ${pkgs.writeText "signature.txt" account.signature.text} '' + optionalString account.notmuch.enable (notmuchSection account);
''
+ optionalString account.notmuch.enable (notmuchSection account);
in in {
{
options = { options = {
programs.neomutt = { programs.neomutt = {
enable = mkEnableOption "the NeoMutt mail client"; enable = mkEnableOption "the NeoMutt mail client";
sidebar = mkOption { sidebar = mkOption {
type = sidebarModule; type = sidebarModule;
default = {}; default = { };
description = "Options related to the sidebar."; description = "Options related to the sidebar.";
}; };
binds = mkOption { binds = mkOption {
type = types.listOf bindModule; type = types.listOf bindModule;
default = []; default = [ ];
description = "List of keybindings."; description = "List of keybindings.";
}; };
macros = mkOption { macros = mkOption {
type = types.listOf bindModule; type = types.listOf bindModule;
default = []; default = [ ];
description = "List of macros."; description = "List of macros.";
}; };
@ -259,7 +248,7 @@ in
settings = mkOption { settings = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = { };
description = "Extra configuration appended to the end."; description = "Extra configuration appended to the end.";
}; };
@ -277,43 +266,37 @@ in
rcFile = account: { rcFile = account: {
"${accountFilename account}".text = accountStr account; "${accountFilename account}".text = accountStr account;
}; };
in in foldl' (a: b: a // b) { } (map rcFile neomuttAccounts);
foldl' (a: b: a // b) {} (map rcFile neomuttAccounts);
xdg.configFile."neomutt/neomuttrc" = mkIf (neomuttAccounts != []) { xdg.configFile."neomutt/neomuttrc" = mkIf (neomuttAccounts != [ ]) {
text = text = let primary = filter (a: a.primary) neomuttAccounts;
let in ''
primary = filter (a: a.primary) neomuttAccounts; # Generated by Home Manager.
in set header_cache = "${config.xdg.cacheHome}/neomutt/headers/"
'' set message_cachedir = "${config.xdg.cacheHome}/neomutt/messages/"
# Generated by Home Manager. set editor = "${cfg.editor}"
set header_cache = "${config.xdg.cacheHome}/neomutt/headers/" set implicit_autoview = yes
set message_cachedir = "${config.xdg.cacheHome}/neomutt/messages/"
set editor = "${cfg.editor}"
set implicit_autoview = yes
alternative_order text/enriched text/plain text alternative_order text/enriched text/plain text
set delete = yes set delete = yes
# Binds # Binds
${bindSection} ${bindSection}
# Macros # Macros
${macroSection} ${macroSection}
${optionalString cfg.vimKeys "source ${pkgs.neomutt}/share/doc/neomutt/vim-keys/vim-keys.rc"} ${optionalString cfg.vimKeys
"source ${pkgs.neomutt}/share/doc/neomutt/vim-keys/vim-keys.rc"}
# Extra configuration # Extra configuration
${optionsStr cfg.settings} ${optionsStr cfg.settings}
${cfg.extraConfig} ${cfg.extraConfig}
'' '' + concatMapStringsSep "\n" registerAccount neomuttAccounts +
+ # source primary account
concatMapStringsSep "\n" registerAccount neomuttAccounts "source ${accountFilename (builtins.head primary)}";
+
# source primary account
"source ${accountFilename (builtins.head primary)}";
}; };
}; };
} }

View file

@ -4,11 +4,9 @@ with lib;
let let
cfg = config.programs.newsboat; cfg = config.programs.newsboat;
wrapQuote = x: "\"${x}\""; wrapQuote = x: ''"${x}"'';
in in {
{
options = { options = {
programs.newsboat = { programs.newsboat = {
enable = mkEnableOption "the Newsboat feed reader"; enable = mkEnableOption "the Newsboat feed reader";
@ -24,8 +22,8 @@ in
tags = mkOption { tags = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = ["foo" "bar"]; example = [ "foo" "bar" ];
description = "Feed tags."; description = "Feed tags.";
}; };
@ -37,8 +35,11 @@ in
}; };
}; };
}); });
default = []; default = [ ];
example = [{url = "http://example.com"; tags = ["foo" "bar"];}]; example = [{
url = "http://example.com";
tags = [ "foo" "bar" ];
}];
description = "List of news feeds."; description = "List of news feeds.";
}; };
@ -57,7 +58,9 @@ in
autoReload = mkOption { autoReload = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = "Whether to enable automatic reloading while newsboat is running."; description = ''
Whether to enable automatic reloading while newsboat is running.
'';
}; };
reloadTime = mkOption { reloadTime = mkOption {
@ -74,43 +77,40 @@ in
queries = mkOption { queries = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = { };
example = { example = { "foo" = ''rssurl =~ "example.com"''; };
"foo" = "rssurl =~ \"example.com\"";
};
description = "A list of queries to use."; description = "A list of queries to use.";
}; };
extraConfig = mkOption { extraConfig = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
description = "Extra configuration values that will be appended to the end."; description = ''
Extra configuration values that will be appended to the end.
'';
}; };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.newsboat ]; home.packages = [ pkgs.newsboat ];
home.file.".newsboat/urls".text = home.file.".newsboat/urls".text = let
let mkUrlEntry = u:
mkUrlEntry = u: concatStringsSep " " ( concatStringsSep " " ([ u.url ] ++ map wrapQuote u.tags
[u.url] ++ optional (u.title != null) (wrapQuote "~${u.title}"));
++ map wrapQuote u.tags urls = map mkUrlEntry cfg.urls;
++ optional (u.title != null) (wrapQuote "~${u.title}")
);
urls = map mkUrlEntry cfg.urls;
mkQueryEntry = n: v: "\"query:${n}:${escape ["\""] v}\""; mkQueryEntry = n: v: ''"query:${n}:${escape [ ''"'' ] v}"'';
queries = mapAttrsToList mkQueryEntry cfg.queries; queries = mapAttrsToList mkQueryEntry cfg.queries;
in in concatStringsSep "\n" (urls ++ queries) + "\n";
concatStringsSep "\n" (urls ++ queries) + "\n";
home.file.".newsboat/config".text = '' home.file.".newsboat/config".text = ''
max-items ${toString cfg.maxItems} max-items ${toString cfg.maxItems}
browser ${cfg.browser} browser ${cfg.browser}
reload-threads ${toString cfg.reloadThreads} reload-threads ${toString cfg.reloadThreads}
auto-reload ${if cfg.autoReload then "yes" else "no"} auto-reload ${if cfg.autoReload then "yes" else "no"}
${optionalString (cfg.reloadTime != null) (toString "reload-time ${toString cfg.reloadTime}")} ${optionalString (cfg.reloadTime != null)
(toString "reload-time ${toString cfg.reloadTime}")}
prepopulate-query-feeds yes prepopulate-query-feeds yes
${cfg.extraConfig} ${cfg.extraConfig}

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ...}: { config, lib, pkgs, ... }:
with lib; with lib;
@ -6,9 +6,7 @@ let
cfg = config.programs.noti; cfg = config.programs.noti;
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.noti = { options.programs.noti = {
@ -16,7 +14,7 @@ in
settings = mkOption { settings = mkOption {
type = types.attrsOf (types.attrsOf types.str); type = types.attrsOf (types.attrsOf types.str);
default = {}; default = { };
description = '' description = ''
Configuration written to Configuration written to
<filename>~/.config/noti/noti.yaml</filename>. <filename>~/.config/noti/noti.yaml</filename>.
@ -45,9 +43,8 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.noti ]; home.packages = [ pkgs.noti ];
xdg.configFile."noti/noti.yaml" = mkIf (cfg.settings != {}) { xdg.configFile."noti/noti.yaml" =
text = generators.toYAML {} cfg.settings; mkIf (cfg.settings != { }) { text = generators.toYAML { } cfg.settings; };
};
}; };
} }

View file

@ -1,7 +1,5 @@
{ lib, ... }: { lib, ... }:
{ {
options.notmuch = { options.notmuch = { enable = lib.mkEnableOption "notmuch indexing"; };
enable = lib.mkEnableOption "notmuch indexing";
};
} }

View file

@ -9,53 +9,42 @@ let
mkIniKeyValue = key: value: mkIniKeyValue = key: value:
let let
tweakVal = v: tweakVal = v:
if isString v then v if isString v then
else if isList v then concatMapStringsSep ";" tweakVal v v
else if isBool v then (if v then "true" else "false") else if isList v then
else toString v; concatMapStringsSep ";" tweakVal v
in else if isBool v then
"${key}=${tweakVal value}"; (if v then "true" else "false")
else
toString v;
in "${key}=${tweakVal value}";
notmuchIni = notmuchIni = recursiveUpdate {
recursiveUpdate database = { path = config.accounts.email.maildirBasePath; };
{
database = {
path = config.accounts.email.maildirBasePath;
};
maildir = { maildir = { synchronize_flags = cfg.maildir.synchronizeFlags; };
synchronize_flags = cfg.maildir.synchronizeFlags;
};
new = { new = {
ignore = cfg.new.ignore; ignore = cfg.new.ignore;
tags = cfg.new.tags; tags = cfg.new.tags;
}; };
user = user = let
let accounts = filter (a: a.notmuch.enable)
accounts = (attrValues config.accounts.email.accounts);
filter (a: a.notmuch.enable) primary = filter (a: a.primary) accounts;
(attrValues config.accounts.email.accounts); secondaries = filter (a: !a.primary) accounts;
primary = filter (a: a.primary) accounts; in {
secondaries = filter (a: !a.primary) accounts; name = catAttrs "realName" primary;
in { primary_email = catAttrs "address" primary;
name = catAttrs "realName" primary; other_email = catAttrs "aliases" primary ++ catAttrs "address" secondaries
primary_email = catAttrs "address" primary; ++ catAttrs "aliases" secondaries;
other_email = catAttrs "aliases" primary };
++ catAttrs "address" secondaries
++ catAttrs "aliases" secondaries;
};
search = { search = { exclude_tags = cfg.search.excludeTags; };
exclude_tags = cfg.search.excludeTags; } cfg.extraConfig;
};
}
cfg.extraConfig;
in in {
{
options = { options = {
programs.notmuch = { programs.notmuch = {
enable = mkEnableOption "Notmuch mail indexer"; enable = mkEnableOption "Notmuch mail indexer";
@ -65,7 +54,7 @@ in
options = { options = {
ignore = mkOption { ignore = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
description = '' description = ''
A list to specify files and directories that will not be A list to specify files and directories that will not be
searched for messages by <command>notmuch new</command>. searched for messages by <command>notmuch new</command>.
@ -83,7 +72,7 @@ in
}; };
}; };
}; };
default = {}; default = { };
description = '' description = ''
Options related to email processing performed by Options related to email processing performed by
<command>notmuch new</command>. <command>notmuch new</command>.
@ -92,7 +81,7 @@ in
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrsOf (types.attrsOf types.str); type = types.attrsOf (types.attrsOf types.str);
default = {}; default = { };
description = '' description = ''
Options that should be appended to the notmuch configuration file. Options that should be appended to the notmuch configuration file.
''; '';
@ -159,11 +148,11 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
{ {
assertion = notmuchIni.user.name != []; assertion = notmuchIni.user.name != [ ];
message = "notmuch: Must have a user name set."; message = "notmuch: Must have a user name set.";
} }
{ {
assertion = notmuchIni.user.primary_email != []; assertion = notmuchIni.user.primary_email != [ ];
message = "notmuch: Must have a user primary email address set."; message = "notmuch: Must have a user primary email address set.";
} }
]; ];
@ -176,33 +165,27 @@ in
}; };
xdg.configFile."notmuch/notmuchrc".text = xdg.configFile."notmuch/notmuchrc".text =
let let toIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
toIni = generators.toINI { mkKeyValue = mkIniKeyValue; }; in ''
in # Generated by Home Manager.
"# Generated by Home Manager.\n\n"
+ toIni notmuchIni;
home.file = '' + toIni notmuchIni;
let
hook = name: cmds:
{
"${notmuchIni.database.path}/.notmuch/hooks/${name}".source =
pkgs.writeShellScript name ''
export PATH="${pkgs.notmuch}/bin''${PATH:+:}$PATH"
export NOTMUCH_CONFIG="${config.xdg.configHome}/notmuch/notmuchrc"
export NMBGIT="${config.xdg.dataHome}/notmuch/nmbug"
${cmds} home.file = let
''; hook = name: cmds: {
}; "${notmuchIni.database.path}/.notmuch/hooks/${name}".source =
in pkgs.writeShellScript name ''
optionalAttrs (cfg.hooks.preNew != "") export PATH="${pkgs.notmuch}/bin''${PATH:+:}$PATH"
(hook "pre-new" cfg.hooks.preNew) export NOTMUCH_CONFIG="${config.xdg.configHome}/notmuch/notmuchrc"
// export NMBGIT="${config.xdg.dataHome}/notmuch/nmbug"
optionalAttrs (cfg.hooks.postNew != "")
(hook "post-new" cfg.hooks.postNew) ${cmds}
// '';
optionalAttrs (cfg.hooks.postInsert != "") };
(hook "post-insert" cfg.hooks.postInsert); in optionalAttrs (cfg.hooks.preNew != "") (hook "pre-new" cfg.hooks.preNew)
// optionalAttrs (cfg.hooks.postNew != "")
(hook "post-new" cfg.hooks.postNew)
// optionalAttrs (cfg.hooks.postInsert != "")
(hook "post-insert" cfg.hooks.postInsert);
}; };
} }

View file

@ -11,23 +11,18 @@ let
let let
pluginDirs = map (pkg: "${pkg}/share/obs/obs-plugins") packages; pluginDirs = map (pkg: "${pkg}/share/obs/obs-plugins") packages;
plugins = concatMapStringsSep " " (p: "${p}/*") pluginDirs; plugins = concatMapStringsSep " " (p: "${p}/*") pluginDirs;
in in pkgs.runCommand "obs-studio-plugins" {
pkgs.runCommand "obs-studio-plugins" preferLocalBuild = true;
{ allowSubstitutes = false;
preferLocalBuild = true; } ''
allowSubstitutes = false; mkdir $out
} [[ '${plugins}' ]] || exit 0
'' for plugin in ${plugins}; do
mkdir $out ln -s "$plugin" $out/
[[ '${plugins}' ]] || exit 0 done
for plugin in ${plugins}; do '';
ln -s "$plugin" $out/
done
'';
in in {
{
meta.maintainers = [ maintainers.adisbladis ]; meta.maintainers = [ maintainers.adisbladis ];
options = { options = {
@ -35,7 +30,7 @@ in
enable = mkEnableOption "obs-studio"; enable = mkEnableOption "obs-studio";
plugins = mkOption { plugins = mkOption {
default = []; default = [ ];
example = literalExample "[ pkgs.obs-linuxbrowser ]"; example = literalExample "[ pkgs.obs-linuxbrowser ]";
description = "Optional OBS plugins."; description = "Optional OBS plugins.";
type = types.listOf types.package; type = types.listOf types.package;
@ -46,8 +41,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ package ]; home.packages = [ package ];
xdg.configFile."obs-studio/plugins" = mkIf (cfg.plugins != []) { xdg.configFile."obs-studio/plugins" =
source = mkPluginEnv cfg.plugins; mkIf (cfg.plugins != [ ]) { source = mkPluginEnv cfg.plugins; };
};
}; };
} }

View file

@ -6,18 +6,14 @@ let
extraConfigType = with types; attrsOf (either (either str int) bool); extraConfigType = with types; attrsOf (either (either str int) bool);
in in {
{
options.offlineimap = { options.offlineimap = {
enable = mkEnableOption "OfflineIMAP"; enable = mkEnableOption "OfflineIMAP";
extraConfig.account = mkOption { extraConfig.account = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = { example = { autorefresh = 20; };
autorefresh = 20;
};
description = '' description = ''
Extra configuration options to add to the account section. Extra configuration options to add to the account section.
''; '';
@ -25,10 +21,8 @@ in
extraConfig.local = mkOption { extraConfig.local = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = { example = { sync_deletes = true; };
sync_deletes = true;
};
description = '' description = ''
Extra configuration options to add to the local account Extra configuration options to add to the local account
section. section.
@ -37,7 +31,7 @@ in
extraConfig.remote = mkOption { extraConfig.remote = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = { example = {
maxconnections = 2; maxconnections = 2;
expunge = false; expunge = false;

View file

@ -12,11 +12,11 @@ let
toIni = generators.toINI { toIni = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
value' = value' = if isBool value then
if isBool value then (if value then "yes" else "no") (if value then "yes" else "no")
else toString value; else
in toString value;
"${key} = ${value'}"; in "${key} = ${value'}";
}; };
# Generates a script to fetch only a specific account. # Generates a script to fetch only a specific account.
@ -29,90 +29,65 @@ let
# Something like # Something like
# #
# $ email <account name> <program name> <program args> # $ email <account name> <program name> <program args>
genOfflineImapScript = account: with account; genOfflineImapScript = account:
with account;
pkgs.writeShellScriptBin "offlineimap-${name}" '' pkgs.writeShellScriptBin "offlineimap-${name}" ''
exec ${pkgs.offlineimap}/bin/offlineimap -a${account.name} "$@" exec ${pkgs.offlineimap}/bin/offlineimap -a${account.name} "$@"
''; '';
accountStr = account: with account; accountStr = account:
with account;
let let
postSyncHook = optionalAttrs (offlineimap.postSyncHookCommand != "") { postSyncHook = optionalAttrs (offlineimap.postSyncHookCommand != "") {
postsynchook = postsynchook = pkgs.writeShellScriptBin "postsynchook"
pkgs.writeShellScriptBin offlineimap.postSyncHookCommand + "/bin/postsynchook";
"postsynchook"
offlineimap.postSyncHookCommand
+ "/bin/postsynchook";
}; };
localType = localType =
if account.flavor == "gmail.com" if account.flavor == "gmail.com" then "GmailMaildir" else "Maildir";
then "GmailMaildir"
else "Maildir";
remoteType = remoteType = if account.flavor == "gmail.com" then "Gmail" else "IMAP";
if account.flavor == "gmail.com"
then "Gmail"
else "IMAP";
remoteHost = optionalAttrs (imap.host != null) { remoteHost =
remotehost = imap.host; optionalAttrs (imap.host != null) { remotehost = imap.host; };
remotePort =
optionalAttrs ((imap.port or null) != null) { remoteport = imap.port; };
ssl = if imap.tls.enable then {
ssl = true;
sslcacertfile = imap.tls.certificatesFile;
starttls = imap.tls.useStartTls;
} else {
ssl = false;
}; };
remotePort = optionalAttrs ((imap.port or null) != null) {
remoteport = imap.port;
};
ssl =
if imap.tls.enable
then
{
ssl = true;
sslcacertfile = imap.tls.certificatesFile;
starttls = imap.tls.useStartTls;
}
else
{
ssl = false;
};
remotePassEval = remotePassEval =
let let arglist = concatMapStringsSep "," (x: "'${x}'") passwordCommand;
arglist = concatMapStringsSep "," (x: "'${x}'") passwordCommand; in optionalAttrs (passwordCommand != null) {
in remotepasseval = ''get_pass("${name}", [${arglist}])'';
optionalAttrs (passwordCommand != null) { };
remotepasseval = ''get_pass("${name}", [${arglist}])''; in toIni {
}; "Account ${name}" = {
in localrepository = "${name}-local";
toIni { remoterepository = "${name}-remote";
"Account ${name}" = { } // postSyncHook // offlineimap.extraConfig.account;
localrepository = "${name}-local";
remoterepository = "${name}-remote";
}
// postSyncHook
// offlineimap.extraConfig.account;
"Repository ${name}-local" = { "Repository ${name}-local" = {
type = localType; type = localType;
localfolders = maildir.absPath; localfolders = maildir.absPath;
} } // offlineimap.extraConfig.local;
// offlineimap.extraConfig.local;
"Repository ${name}-remote" = { "Repository ${name}-remote" = {
type = remoteType; type = remoteType;
remoteuser = userName; remoteuser = userName;
} } // remoteHost // remotePort // remotePassEval // ssl
// remoteHost
// remotePort
// remotePassEval
// ssl
// offlineimap.extraConfig.remote; // offlineimap.extraConfig.remote;
}; };
extraConfigType = with types; attrsOf (either (either str int) bool); extraConfigType = with types; attrsOf (either (either str int) bool);
in in {
{
options = { options = {
programs.offlineimap = { programs.offlineimap = {
enable = mkEnableOption "OfflineIMAP"; enable = mkEnableOption "OfflineIMAP";
@ -133,7 +108,7 @@ in
extraConfig.general = mkOption { extraConfig.general = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = { example = {
maxage = 30; maxage = 30;
ui = "blinkenlights"; ui = "blinkenlights";
@ -146,10 +121,8 @@ in
extraConfig.default = mkOption { extraConfig.default = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = { example = { gmailtrashfolder = "[Gmail]/Papierkorb"; };
gmailtrashfolder = "[Gmail]/Papierkorb";
};
description = '' description = ''
Extra configuration options added to the Extra configuration options added to the
<option>DEFAULT</option> section. <option>DEFAULT</option> section.
@ -158,7 +131,7 @@ in
extraConfig.mbnames = mkOption { extraConfig.mbnames = mkOption {
type = extraConfigType; type = extraConfigType;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
filename = "~/.config/mutt/mailboxes"; filename = "~/.config/mutt/mailboxes";
@ -181,27 +154,20 @@ in
xdg.configFile."offlineimap/get_settings.py".text = cfg.pythonFile; xdg.configFile."offlineimap/get_settings.py".text = cfg.pythonFile;
xdg.configFile."offlineimap/config".text = xdg.configFile."offlineimap/config".text = ''
'' # Generated by Home Manager.
# Generated by Home Manager. # See https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf
# See https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf # for an exhaustive list of options.
# for an exhaustive list of options. '' + toIni ({
'' general = {
+ toIni ({ accounts = concatMapStringsSep "," (a: a.name) accounts;
general = { pythonfile = "${config.xdg.configHome}/offlineimap/get_settings.py";
accounts = concatMapStringsSep "," (a: a.name) accounts; metadata = "${config.xdg.dataHome}/offlineimap";
pythonfile = "${config.xdg.configHome}/offlineimap/get_settings.py"; } // cfg.extraConfig.general;
metadata = "${config.xdg.dataHome}/offlineimap"; } // optionalAttrs (cfg.extraConfig.mbnames != { }) {
} mbnames = { enabled = true; } // cfg.extraConfig.mbnames;
// cfg.extraConfig.general; } // optionalAttrs (cfg.extraConfig.default != { }) {
} DEFAULT = cfg.extraConfig.default;
// optionalAttrs (cfg.extraConfig.mbnames != {}) { }) + "\n" + concatStringsSep "\n" (map accountStr accounts);
mbnames = { enabled = true; } // cfg.extraConfig.mbnames;
}
// optionalAttrs (cfg.extraConfig.default != {}) {
DEFAULT = cfg.extraConfig.default;
})
+ "\n"
+ concatStringsSep "\n" (map accountStr accounts);
}; };
} }

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.opam; cfg = config.programs.opam;
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.opam = { options.programs.opam = {

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.password-store; cfg = config.programs.password-store;
in in {
{
meta.maintainers = with maintainers; [ pacien ]; meta.maintainers = with maintainers; [ pacien ];
options.programs.password-store = { options.programs.password-store = {

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.pazi; cfg = config.programs.pazi;
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.pazi = { options.programs.pazi = {

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.pidgin; cfg = config.programs.pidgin;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -23,7 +21,7 @@ in
}; };
plugins = mkOption { plugins = mkOption {
default = []; default = [ ];
example = literalExample "[ pkgs.pidgin-otr pkgs.pidgin-osd ]"; example = literalExample "[ pkgs.pidgin-otr pkgs.pidgin-osd ]";
description = "Plugins that should be available to Pidgin."; description = "Plugins that should be available to Pidgin.";
}; };

View file

@ -9,32 +9,34 @@ let
mkSetVariableStr = n: v: mkSetVariableStr = n: v:
let let
mkValueStr = v: mkValueStr = v:
if v == true then "on" if v == true then
else if v == false then "off" "on"
else if isInt v then toString v else if v == false then
else if isString v then v "off"
else abort ("values ${toPretty v} is of unsupported type"); else if isInt v then
in toString v
"set ${n} ${mkValueStr 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}"; mkBindingStr = k: v: ''"${k}": ${v}'';
in in {
{
options.programs.readline = { options.programs.readline = {
enable = mkEnableOption "readline"; enable = mkEnableOption "readline";
bindings = mkOption { bindings = mkOption {
default = {}; default = { };
type = types.attrsOf types.str; type = types.attrsOf types.str;
example = { "\C-h" = "backward-kill-word"; }; example = { "\\C-h" = "backward-kill-word"; };
description = "Readline bindings."; description = "Readline bindings.";
}; };
variables = mkOption { variables = mkOption {
type = with types; attrsOf (either str (either int bool)); type = with types; attrsOf (either str (either int bool));
default = {}; default = { };
example = { expand-tilde = true; }; example = { expand-tilde = true; };
description = '' description = ''
Readline customization variable assignments. Readline customization variable assignments.
@ -58,19 +60,16 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.file.".inputrc".text = home.file.".inputrc".text = let
let configStr = concatStringsSep "\n"
configStr = concatStringsSep "\n" ( (optional cfg.includeSystemConfig "$include /etc/inputrc"
optional cfg.includeSystemConfig "$include /etc/inputrc"
++ mapAttrsToList mkSetVariableStr cfg.variables ++ mapAttrsToList mkSetVariableStr cfg.variables
++ mapAttrsToList mkBindingStr cfg.bindings ++ mapAttrsToList mkBindingStr cfg.bindings);
); in ''
in # Generated by Home Manager.
''
# Generated by Home Manager.
${configStr} ${configStr}
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
}; };
} }

View file

@ -7,10 +7,11 @@ let
cfg = config.programs.rofi; cfg = config.programs.rofi;
colorOption = description: mkOption { colorOption = description:
type = types.str; mkOption {
description = description; type = types.str;
}; description = description;
};
rowColorSubmodule = types.submodule { rowColorSubmodule = types.submodule {
options = { options = {
@ -71,72 +72,64 @@ let
}; };
valueToString = value: valueToString = value:
if isBool value if isBool value then (if value then "true" else "else") else toString value;
then (if value then "true" else "else")
else toString value;
windowColorsToString = window: concatStringsSep ", " (with window; [ windowColorsToString = window:
background concatStringsSep ", " (with window; [ background border separator ]);
border
separator
]);
rowsColorsToString = rows: '' rowsColorsToString = rows: ''
${optionalString ${optionalString (rows.normal != null)
(rows.normal != null) (setOption "color-normal" (rowColorsToString rows.normal))}
(setOption "color-normal" (rowColorsToString rows.normal))} ${optionalString (rows.active != null)
${optionalString (setOption "color-active" (rowColorsToString rows.active))}
(rows.active != null) ${optionalString (rows.urgent != null)
(setOption "color-active" (rowColorsToString rows.active))} (setOption "color-urgent" (rowColorsToString rows.urgent))}
${optionalString
(rows.urgent != null)
(setOption "color-urgent" (rowColorsToString rows.urgent))}
''; '';
rowColorsToString = row: concatStringsSep ", " (with row; [ rowColorsToString = row:
background concatStringsSep ", " (with row; [
foreground background
backgroundAlt foreground
highlight.background backgroundAlt
highlight.foreground highlight.background
]); highlight.foreground
]);
setOption = name: value: setOption = name: value:
optionalString (value != null) "rofi.${name}: ${valueToString value}"; optionalString (value != null) "rofi.${name}: ${valueToString value}";
setColorScheme = colors: optionalString (colors != null) '' setColorScheme = colors:
${optionalString optionalString (colors != null) ''
(colors.window != null) ${optionalString (colors.window != null) setOption "color-window"
setOption "color-window" (windowColorsToString colors.window)} (windowColorsToString colors.window)}
${optionalString ${optionalString (colors.rows != null) (rowsColorsToString colors.rows)}
(colors.rows != null) '';
(rowsColorsToString colors.rows)}
'';
locationsMap = { locationsMap = {
center = 0; center = 0;
top-left = 1; top-left = 1;
top = 2; top = 2;
top-right = 3; top-right = 3;
right = 4; right = 4;
bottom-right = 5; bottom-right = 5;
bottom = 6; bottom = 6;
bottom-left = 7; bottom-left = 7;
left = 8; left = 8;
}; };
themeName = themeName = if (cfg.theme == null) then
if (cfg.theme == null) then null null
else if (lib.isString cfg.theme) then cfg.theme else if (lib.isString cfg.theme) then
else lib.removeSuffix ".rasi" (baseNameOf cfg.theme); cfg.theme
else
lib.removeSuffix ".rasi" (baseNameOf cfg.theme);
themePath = if (lib.isString cfg.theme) then null else cfg.theme; themePath = if (lib.isString cfg.theme) then null else cfg.theme;
in in {
{
options.programs.rofi = { options.programs.rofi = {
enable = mkEnableOption "Rofi: A window switcher, application launcher and dmenu replacement"; enable = mkEnableOption
"Rofi: A window switcher, application launcher and dmenu replacement";
width = mkOption { width = mkOption {
default = null; default = null;
@ -295,14 +288,12 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [{
{ assertion = cfg.theme == null || cfg.colors == null;
assertion = cfg.theme == null || cfg.colors == null; message = ''
message = '' Cannot use the rofi options 'theme' and 'colors' simultaneously.
Cannot use the rofi options 'theme' and 'colors' simultaneously. '';
''; }];
}
];
home.packages = [ pkgs.rofi ]; home.packages = [ pkgs.rofi ];
@ -314,11 +305,8 @@ in
${setOption "eh" cfg.rowHeight} ${setOption "eh" cfg.rowHeight}
${setOption "padding" cfg.padding} ${setOption "padding" cfg.padding}
${setOption "separator-style" cfg.separator} ${setOption "separator-style" cfg.separator}
${setOption "hide-scrollbar" ( ${setOption "hide-scrollbar"
if (cfg.scrollbar != null) (if (cfg.scrollbar != null) then (!cfg.scrollbar) else cfg.scrollbar)}
then (! cfg.scrollbar)
else cfg.scrollbar
)}
${setOption "terminal" cfg.terminal} ${setOption "terminal" cfg.terminal}
${setOption "cycle" cfg.cycle} ${setOption "cycle" cfg.cycle}
${setOption "fullscreen" cfg.fullscreen} ${setOption "fullscreen" cfg.fullscreen}
@ -333,7 +321,7 @@ in
''; '';
xdg.dataFile = mkIf (themePath != null) { xdg.dataFile = mkIf (themePath != null) {
"rofi/themes/${themeName}.rasi".source = themePath; "rofi/themes/${themeName}.rasi".source = themePath;
}; };
}; };
} }

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.rtorrent; cfg = config.programs.rtorrent;
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.rtorrent = { options.programs.rtorrent = {
@ -30,8 +28,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.rtorrent ]; home.packages = [ pkgs.rtorrent ];
xdg.configFile."rtorrent/rtorrent.rc" = mkIf (cfg.settings != "") { xdg.configFile."rtorrent/rtorrent.rc" =
text = cfg.settings; mkIf (cfg.settings != "") { text = cfg.settings; };
};
}; };
} }

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.skim; cfg = config.programs.skim;
in in {
{
options.programs.skim = { options.programs.skim = {
enable = mkEnableOption "skim - a command-line fuzzy finder"; enable = mkEnableOption "skim - a command-line fuzzy finder";
@ -24,7 +22,7 @@ in
defaultOptions = mkOption { defaultOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--height 40%" "--prompt " ]; example = [ "--height 40%" "--prompt " ];
description = '' description = ''
Extra command line options given to skim by default. Extra command line options given to skim by default.
@ -43,7 +41,7 @@ in
fileWidgetOptions = mkOption { fileWidgetOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--preview 'head {}'" ]; example = [ "--preview 'head {}'" ];
description = '' description = ''
Command line options for the CTRL-T keybinding. Command line options for the CTRL-T keybinding.
@ -53,7 +51,7 @@ in
changeDirWidgetCommand = mkOption { changeDirWidgetCommand = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
example = "fd --type d" ; example = "fd --type d";
description = '' description = ''
The command that gets executed as the source for skim for the The command that gets executed as the source for skim for the
ALT-C keybinding. ALT-C keybinding.
@ -62,7 +60,7 @@ in
changeDirWidgetOptions = mkOption { changeDirWidgetOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--preview 'tree -C {} | head -200'" ]; example = [ "--preview 'tree -C {} | head -200'" ];
description = '' description = ''
Command line options for the ALT-C keybinding. Command line options for the ALT-C keybinding.
@ -71,7 +69,7 @@ in
historyWidgetOptions = mkOption { historyWidgetOptions = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "--tac" "--exact" ]; example = [ "--tac" "--exact" ];
description = '' description = ''
Command line options for the CTRL-R keybinding. Command line options for the CTRL-R keybinding.
@ -98,18 +96,16 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.skim ]; home.packages = [ pkgs.skim ];
home.sessionVariables = home.sessionVariables = mapAttrs (n: v: toString v)
mapAttrs (n: v: toString v) ( (filterAttrs (n: v: v != [ ] && v != null) {
filterAttrs (n: v: v != [] && v != null) { SKIM_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
SKIM_ALT_C_COMMAND = cfg.changeDirWidgetCommand; SKIM_ALT_C_OPTS = cfg.changeDirWidgetOptions;
SKIM_ALT_C_OPTS = cfg.changeDirWidgetOptions; SKIM_CTRL_R_OPTS = cfg.historyWidgetOptions;
SKIM_CTRL_R_OPTS = cfg.historyWidgetOptions; SKIM_CTRL_T_COMMAND = cfg.fileWidgetCommand;
SKIM_CTRL_T_COMMAND = cfg.fileWidgetCommand; SKIM_CTRL_T_OPTS = cfg.fileWidgetOptions;
SKIM_CTRL_T_OPTS = cfg.fileWidgetOptions; SKIM_DEFAULT_COMMAND = cfg.defaultCommand;
SKIM_DEFAULT_COMMAND = cfg.defaultCommand; SKIM_DEFAULT_OPTIONS = cfg.defaultOptions;
SKIM_DEFAULT_OPTIONS = cfg.defaultOptions; });
}
);
programs.bash.initExtra = mkIf cfg.enableBashIntegration '' programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then

View file

@ -7,20 +7,17 @@ let
cfg = config.programs.starship; cfg = config.programs.starship;
configFile = config: configFile = config:
pkgs.runCommand "config.toml" pkgs.runCommand "config.toml" {
{ buildInputs = [ pkgs.remarshal ];
buildInputs = [ pkgs.remarshal ]; preferLocalBuild = true;
preferLocalBuild = true; allowSubstitutes = false;
allowSubstitutes = false; } ''
} remarshal -if json -of toml \
'' < ${pkgs.writeText "config.json" (builtins.toJSON config)} \
remarshal -if json -of toml \ > $out
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \ '';
> $out
'';
in
{ in {
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.starship = { options.programs.starship = {
@ -35,7 +32,7 @@ in
settings = mkOption { settings = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
description = '' description = ''
Configuration written to Configuration written to
<filename>~/.config/starship.toml</filename>. <filename>~/.config/starship.toml</filename>.
@ -73,9 +70,8 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
xdg.configFile."starship.toml" = mkIf (cfg.settings != {}) { xdg.configFile."starship.toml" =
source = configFile cfg.settings; mkIf (cfg.settings != { }) { source = configFile cfg.settings; };
};
programs.bash.initExtra = mkIf cfg.enableBashIntegration '' programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
if [[ -z $INSIDE_EMACS ]]; then if [[ -z $INSIDE_EMACS ]]; then

View file

@ -9,38 +9,39 @@ let
themePath = theme: "${pkgs.taskwarrior}/share/doc/task/rc/${theme}.theme"; themePath = theme: "${pkgs.taskwarrior}/share/doc/task/rc/${theme}.theme";
includeTheme = location: includeTheme = location:
if location == null then "" if location == null then
else if isString location then "include ${themePath location}" ""
else "include ${location}"; else if isString location then
"include ${themePath location}"
else
"include ${location}";
formatValue = value: formatValue = value:
if isBool value then if value then "true" else "false" if isBool value then
else if isList value then concatMapStringsSep "," formatValue value if value then "true" else "false"
else toString value; else if isList value then
concatMapStringsSep "," formatValue value
else
toString value;
formatLine = key: value: formatLine = key: value: "${key}=${formatValue value}";
"${key}=${formatValue value}";
formatSet = key: values: formatSet = key: values:
(concatStringsSep "\n" (concatStringsSep "\n"
(mapAttrsToList (mapAttrsToList (subKey: subValue: formatPair "${key}.${subKey}" subValue)
(subKey: subValue: formatPair "${key}.${subKey}" subValue)
values)); values));
formatPair = key: value: formatPair = key: value:
if isAttrs value then formatSet key value if isAttrs value then formatSet key value else formatLine key value;
else formatLine key value;
in in {
{
options = { options = {
programs.taskwarrior = { programs.taskwarrior = {
enable = mkEnableOption "Task Warrior"; enable = mkEnableOption "Task Warrior";
config = mkOption { config = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
confirmation = false; confirmation = false;
@ -103,8 +104,7 @@ in
data.location=${cfg.dataLocation} data.location=${cfg.dataLocation}
${includeTheme cfg.colorTheme} ${includeTheme cfg.colorTheme}
${concatStringsSep "\n" ( ${concatStringsSep "\n" (mapAttrsToList formatPair cfg.config)}
mapAttrsToList formatPair cfg.config)}
${cfg.extraConfig} ${cfg.extraConfig}
''; '';

View file

@ -13,9 +13,7 @@ let
fi fi
''; '';
in in {
{
options = { options = {
programs.termite = { programs.termite = {
enable = mkEnableOption "Termite VTE-based terminal"; enable = mkEnableOption "Termite VTE-based terminal";
@ -61,7 +59,9 @@ in
mouseAutohide = mkOption { mouseAutohide = mkOption {
default = null; default = null;
type = types.nullOr types.bool; type = types.nullOr types.bool;
description = "Automatically hide the mouse pointer when you start typing."; description = ''
Automatically hide the mouse pointer when you start typing.
'';
}; };
scrollOnOutput = mkOption { scrollOnOutput = mkOption {
@ -73,7 +73,9 @@ in
scrollOnKeystroke = mkOption { scrollOnKeystroke = mkOption {
default = null; default = null;
type = types.nullOr types.bool; type = types.nullOr types.bool;
description = "Scroll to the bottom automatically when a key is pressed."; description = ''
Scroll to the bottom automatically when a key is pressed.
'';
}; };
searchWrap = mkOption { searchWrap = mkOption {
@ -106,14 +108,16 @@ in
default = null; default = null;
example = "terminal"; example = "terminal";
type = types.nullOr types.str; type = types.nullOr types.str;
description = "The name of the icon to be used for the terminal process."; description =
"The name of the icon to be used for the terminal process.";
}; };
scrollbackLines = mkOption { scrollbackLines = mkOption {
default = null; default = null;
example = 10000; example = 10000;
type = types.nullOr types.int; type = types.nullOr types.int;
description = "Set the number of lines to limit the terminal's scrollback."; description =
"Set the number of lines to limit the terminal's scrollback.";
}; };
browser = mkOption { browser = mkOption {
@ -149,7 +153,8 @@ in
filterUnmatchedUrls = mkOption { filterUnmatchedUrls = mkOption {
default = null; default = null;
type = types.nullOr types.bool; type = types.nullOr types.bool;
description = "Whether to hide url hints not matching input in url hints mode."; description =
"Whether to hide url hints not matching input in url hints mode.";
}; };
modifyOtherKeys = mkOption { modifyOtherKeys = mkOption {
@ -290,7 +295,8 @@ in
default = ""; default = "";
example = "fullscreen = true"; example = "fullscreen = true";
type = types.lines; type = types.lines;
description = "Extra options that should be added to [options] section."; description =
"Extra options that should be added to [options] section.";
}; };
colorsExtra = mkOption { colorsExtra = mkOption {
@ -301,78 +307,81 @@ in
color2 = #60b48a color2 = #60b48a
''; '';
type = types.lines; type = types.lines;
description = "Extra colors options that should be added to [colors] section."; description =
"Extra colors options that should be added to [colors] section.";
}; };
hintsExtra = mkOption { hintsExtra = mkOption {
default = ""; default = "";
example = "border = #3f3f3f"; example = "border = #3f3f3f";
type = types.lines; type = types.lines;
description = "Extra hints options that should be added to [hints] section."; description =
"Extra hints options that should be added to [hints] section.";
}; };
}; };
}; };
config = ( config = (let
let boolToString = v: if v then "true" else "false";
boolToString = v: if v then "true" else "false"; optionalBoolean = name: val:
optionalBoolean = name: val: lib.optionalString (val != null) "${name} = ${boolToString val}"; lib.optionalString (val != null) "${name} = ${boolToString val}";
optionalInteger = name: val: lib.optionalString (val != null) "${name} = ${toString val}"; optionalInteger = name: val:
optionalString = name: val: lib.optionalString (val != null) "${name} = ${val}"; lib.optionalString (val != null) "${name} = ${toString val}";
in mkIf cfg.enable { optionalString = name: val:
home.packages = [ pkgs.termite ]; lib.optionalString (val != null) "${name} = ${val}";
xdg.configFile."termite/config".text = '' in mkIf cfg.enable {
[options] home.packages = [ pkgs.termite ];
${optionalBoolean "allow_bold" cfg.allowBold} xdg.configFile."termite/config".text = ''
${optionalBoolean "audible_bell" cfg.audibleBell} [options]
${optionalString "browser" cfg.browser} ${optionalBoolean "allow_bold" cfg.allowBold}
${optionalBoolean "clickable_url" cfg.clickableUrl} ${optionalBoolean "audible_bell" cfg.audibleBell}
${optionalString "cursor_blink" cfg.cursorBlink} ${optionalString "browser" cfg.browser}
${optionalString "cursor_shape" cfg.cursorShape} ${optionalBoolean "clickable_url" cfg.clickableUrl}
${optionalBoolean "dynamic_title" cfg.dynamicTitle} ${optionalString "cursor_blink" cfg.cursorBlink}
${optionalBoolean "filter_unmatched_urls" cfg.filterUnmatchedUrls} ${optionalString "cursor_shape" cfg.cursorShape}
${optionalString "font" cfg.font} ${optionalBoolean "dynamic_title" cfg.dynamicTitle}
${optionalBoolean "fullscreen" cfg.fullscreen} ${optionalBoolean "filter_unmatched_urls" cfg.filterUnmatchedUrls}
${optionalString "geometry" cfg.geometry} ${optionalString "font" cfg.font}
${optionalString "icon_name" cfg.iconName} ${optionalBoolean "fullscreen" cfg.fullscreen}
${optionalBoolean "modify_other_keys" cfg.modifyOtherKeys} ${optionalString "geometry" cfg.geometry}
${optionalBoolean "mouse_autohide" cfg.mouseAutohide} ${optionalString "icon_name" cfg.iconName}
${optionalBoolean "scroll_on_keystroke" cfg.scrollOnKeystroke} ${optionalBoolean "modify_other_keys" cfg.modifyOtherKeys}
${optionalBoolean "scroll_on_output" cfg.scrollOnOutput} ${optionalBoolean "mouse_autohide" cfg.mouseAutohide}
${optionalInteger "scrollback_lines" cfg.scrollbackLines} ${optionalBoolean "scroll_on_keystroke" cfg.scrollOnKeystroke}
${optionalString "scrollbar" cfg.scrollbar} ${optionalBoolean "scroll_on_output" cfg.scrollOnOutput}
${optionalBoolean "search_wrap" cfg.searchWrap} ${optionalInteger "scrollback_lines" cfg.scrollbackLines}
${optionalBoolean "size_hints" cfg.sizeHints} ${optionalString "scrollbar" cfg.scrollbar}
${optionalBoolean "urgent_on_bell" cfg.urgentOnBell} ${optionalBoolean "search_wrap" cfg.searchWrap}
${optionalBoolean "size_hints" cfg.sizeHints}
${optionalBoolean "urgent_on_bell" cfg.urgentOnBell}
${cfg.optionsExtra} ${cfg.optionsExtra}
[colors] [colors]
${optionalString "background" cfg.backgroundColor} ${optionalString "background" cfg.backgroundColor}
${optionalString "cursor" cfg.cursorColor} ${optionalString "cursor" cfg.cursorColor}
${optionalString "cursor_foreground" cfg.cursorForegroundColor} ${optionalString "cursor_foreground" cfg.cursorForegroundColor}
${optionalString "foreground" cfg.foregroundColor} ${optionalString "foreground" cfg.foregroundColor}
${optionalString "foregroundBold" cfg.foregroundBoldColor} ${optionalString "foregroundBold" cfg.foregroundBoldColor}
${optionalString "highlight" cfg.highlightColor} ${optionalString "highlight" cfg.highlightColor}
${cfg.colorsExtra} ${cfg.colorsExtra}
[hints] [hints]
${optionalString "active_background" cfg.hintsActiveBackgroundColor} ${optionalString "active_background" cfg.hintsActiveBackgroundColor}
${optionalString "active_foreground" cfg.hintsActiveForegroundColor} ${optionalString "active_foreground" cfg.hintsActiveForegroundColor}
${optionalString "background" cfg.hintsBackgroundColor} ${optionalString "background" cfg.hintsBackgroundColor}
${optionalString "border" cfg.hintsBorderColor} ${optionalString "border" cfg.hintsBorderColor}
${optionalInteger "border_width" cfg.hintsBorderWidth} ${optionalInteger "border_width" cfg.hintsBorderWidth}
${optionalString "font" cfg.hintsFont} ${optionalString "font" cfg.hintsFont}
${optionalString "foreground" cfg.hintsForegroundColor} ${optionalString "foreground" cfg.hintsForegroundColor}
${optionalInteger "padding" cfg.hintsPadding} ${optionalInteger "padding" cfg.hintsPadding}
${optionalInteger "roundness" cfg.hintsRoundness} ${optionalInteger "roundness" cfg.hintsRoundness}
${cfg.hintsExtra} ${cfg.hintsExtra}
''; '';
programs.bash.initExtra = vteInitStr; programs.bash.initExtra = vteInitStr;
programs.zsh.initExtra = vteInitStr; programs.zsh.initExtra = vteInitStr;
} });
);
} }

View file

@ -8,9 +8,7 @@ let
texlivePkgs = cfg.extraPackages pkgs.texlive; texlivePkgs = cfg.extraPackages pkgs.texlive;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -35,13 +33,11 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [{
{ assertion = texlivePkgs != { };
assertion = texlivePkgs != {}; message = "Must provide at least one extra package in"
message = "Must provide at least one extra package in" + " 'programs.texlive.extraPackages'.";
+ " 'programs.texlive.extraPackages'."; }];
}
];
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];

View file

@ -6,9 +6,7 @@ let
cfg = config.programs.urxvt; cfg = config.programs.urxvt;
in in {
{
options.programs.urxvt = { options.programs.urxvt = {
enable = mkEnableOption "rxvt-unicode terminal emulator"; enable = mkEnableOption "rxvt-unicode terminal emulator";
@ -21,14 +19,14 @@ in
fonts = mkOption { fonts = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
description = "List of fonts to be used."; description = "List of fonts to be used.";
example = [ "xft:Droid Sans Mono Nerd Font:size=9" ]; example = [ "xft:Droid Sans Mono Nerd Font:size=9" ];
}; };
keybindings = mkOption { keybindings = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
default = {}; default = { };
description = "Mapping of keybindings to actions"; description = "Mapping of keybindings to actions";
example = literalExample '' example = literalExample ''
{ {
@ -41,7 +39,8 @@ in
iso14755 = mkOption { iso14755 = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
description = "ISO14755 support for viewing and entering unicode characters."; description =
"ISO14755 support for viewing and entering unicode characters.";
}; };
scroll = { scroll = {
@ -75,11 +74,12 @@ in
floating = mkOption { floating = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
description = "Whether to display an rxvt scrollbar without a trough."; description =
"Whether to display an rxvt scrollbar without a trough.";
}; };
}; };
}; };
default = {}; default = { };
description = "Scrollbar settings."; description = "Scrollbar settings.";
}; };
@ -92,7 +92,8 @@ in
keepPosition = mkOption { keepPosition = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
description = "Whether to keep a scroll position when TTY receives new lines."; description =
"Whether to keep a scroll position when TTY receives new lines.";
}; };
scrollOnKeystroke = mkOption { scrollOnKeystroke = mkOption {
@ -117,11 +118,12 @@ in
shading = mkOption { shading = mkOption {
type = types.ints.between 0 200; type = types.ints.between 0 200;
default = 100; default = 100;
description = "Darken (0 .. 99) or lighten (101 .. 200) the transparent background."; description =
"Darken (0 .. 99) or lighten (101 .. 200) the transparent background.";
}; };
extraConfig = mkOption { extraConfig = mkOption {
default = {}; default = { };
type = types.attrs; type = types.attrs;
description = "Additional configuration to add."; description = "Additional configuration to add.";
example = { "shading" = 15; }; example = { "shading" = 15; };
@ -145,12 +147,10 @@ in
"URxvt.transparent" = cfg.transparent; "URxvt.transparent" = cfg.transparent;
"URxvt.shading" = cfg.shading; "URxvt.shading" = cfg.shading;
"URxvt.iso14755" = cfg.iso14755; "URxvt.iso14755" = cfg.iso14755;
} // flip mapAttrs' cfg.keybindings (kb: action: } // flip mapAttrs' cfg.keybindings
nameValuePair "URxvt.keysym.${kb}" action (kb: action: nameValuePair "URxvt.keysym.${kb}" action)
) // optionalAttrs (cfg.fonts != []) { // optionalAttrs (cfg.fonts != [ ]) {
"URxvt.font" = concatStringsSep "," cfg.fonts; "URxvt.font" = concatStringsSep "," cfg.fonts;
} // flip mapAttrs' cfg.extraConfig (k: v: } // flip mapAttrs' cfg.extraConfig (k: v: nameValuePair "URxvt.${k}" v);
nameValuePair "URxvt.${k}" v
);
}; };
} }

View file

@ -31,43 +31,36 @@ let
}; };
vimSettingsType = types.submodule { vimSettingsType = types.submodule {
options = options = let
let opt = name: type:
opt = name: type: mkOption { mkOption {
type = types.nullOr type; type = types.nullOr type;
default = null; default = null;
visible = false; visible = false;
}; };
in in mapAttrs opt knownSettings;
mapAttrs opt knownSettings;
}; };
setExpr = name: value: setExpr = name: value:
let let
v = v = if isBool value then
if isBool value then (if value then "" else "no") + name (if value then "" else "no") + name
else else
"${name}=${ "${name}=${
if isList value if isList value then concatStringsSep "," value else toString value
then concatStringsSep "," value }";
else toString value in optionalString (value != null) ("set " + v);
}";
in
optionalString (value != null) ("set " + v);
plugins = plugins = let
let vpkgs = pkgs.vimPlugins;
vpkgs = pkgs.vimPlugins; getPkg = p:
getPkg = p: if isDerivation p then
if isDerivation p [ p ]
then [ p ] else
else optional (isString p && hasAttr p vpkgs) vpkgs.${p}; optional (isString p && hasAttr p vpkgs) vpkgs.${p};
in in concatMap getPkg cfg.plugins;
concatMap getPkg cfg.plugins;
in in {
{
options = { options = {
programs.vim = { programs.vim = {
enable = mkEnableOption "Vim"; enable = mkEnableOption "Vim";
@ -75,7 +68,7 @@ in
plugins = mkOption { plugins = mkOption {
type = with types; listOf (either str package); type = with types; listOf (either str package);
default = defaultPlugins; default = defaultPlugins;
example = literalExample ''[ pkgs.vimPlugins.YankRing ]''; example = literalExample "[ pkgs.vimPlugins.YankRing ]";
description = '' description = ''
List of vim plugins to install. To get a list of supported plugins run: List of vim plugins to install. To get a list of supported plugins run:
<command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A vimPlugins</command>. <command>nix-env -f '&lt;nixpkgs&gt;' -qaP -A vimPlugins</command>.
@ -88,7 +81,7 @@ in
settings = mkOption { settings = mkOption {
type = vimSettingsType; type = vimSettingsType;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
expandtab = true; expandtab = true;
@ -102,14 +95,12 @@ in
options. options.
<informaltable frame="none"><tgroup cols="1"><tbody> <informaltable frame="none"><tgroup cols="1"><tbody>
${concatStringsSep "\n" ( ${concatStringsSep "\n" (mapAttrsToList (n: v: ''
mapAttrsToList (n: v: '' <row>
<row> <entry><varname>${n}</varname></entry>
<entry><varname>${n}</varname></entry> <entry>${v.description}</entry>
<entry>${v.description}</entry> </row>
</row> '') knownSettings)}
'') knownSettings
)}
</tbody></tgroup></informaltable> </tbody></tgroup></informaltable>
See the Vim documentation for detailed descriptions of these See the Vim documentation for detailed descriptions of these
@ -136,56 +127,45 @@ in
}; };
}; };
config = ( config = (let
let customRC = ''
customRC = '' ${concatStringsSep "\n" (filter (v: v != "") (mapAttrsToList setExpr
${concatStringsSep "\n" ( (builtins.intersectAttrs knownSettings cfg.settings)))}
filter (v: v != "") (
mapAttrsToList setExpr (
builtins.intersectAttrs knownSettings cfg.settings)))}
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
vim = pkgs.vim_configurable.customize { vim = pkgs.vim_configurable.customize {
name = "vim"; name = "vim";
vimrcConfig = { vimrcConfig = {
inherit customRC; inherit customRC;
packages.home-manager.start = plugins; packages.home-manager.start = plugins;
};
}; };
in };
mkIf cfg.enable { in mkIf cfg.enable {
assertions = assertions = let
let packagesNotFound =
packagesNotFound = filter (p: isString p && (!hasAttr p pkgs.vimPlugins)) cfg.plugins; filter (p: isString p && (!hasAttr p pkgs.vimPlugins)) cfg.plugins;
in in [{
[ assertion = packagesNotFound == [ ];
{ message = "Following VIM plugin not found in pkgs.vimPlugins: ${
assertion = packagesNotFound == []; concatMapStringsSep ", " (p: ''"${p}"'') packagesNotFound
message = "Following VIM plugin not found in pkgs.vimPlugins: ${ }";
concatMapStringsSep ", " (p: ''"${p}"'') packagesNotFound }];
}";
}
];
warnings = warnings = let stringPlugins = filter isString cfg.plugins;
let in optional (stringPlugins != [ ]) ''
stringPlugins = filter isString cfg.plugins; Specifying VIM plugins using strings is deprecated, found ${
in concatMapStringsSep ", " (p: ''"${p}"'') stringPlugins
optional (stringPlugins != []) '' } as strings.
Specifying VIM plugins using strings is deprecated, found ${ '';
concatMapStringsSep ", " (p: ''"${p}"'') stringPlugins
} as strings.
'';
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
programs.vim = { programs.vim = {
package = vim; package = vim;
plugins = defaultPlugins; plugins = defaultPlugins;
}; };
} });
);
} }

View file

@ -7,8 +7,8 @@ let
cfg = config.programs.vscode.haskell; cfg = config.programs.vscode.haskell;
defaultHieNixExe = hie-nix.hies + "/bin/hie-wrapper"; defaultHieNixExe = hie-nix.hies + "/bin/hie-wrapper";
defaultHieNixExeText = literalExample defaultHieNixExeText =
"\"\${pkgs.hie-nix.hies}/bin/hie-wrapper\""; literalExample ''"''${pkgs.hie-nix.hies}/bin/hie-wrapper"'';
hie-nix = pkgs.hie-nix or (abort '' hie-nix = pkgs.hie-nix or (abort ''
vscode.haskell: pkgs.hie-nix missing. Please add an overlay such as: vscode.haskell: pkgs.hie-nix missing. Please add an overlay such as:
@ -21,9 +21,7 @@ let
] ]
''; '';
in in {
{
options.programs.vscode.haskell = { options.programs.vscode.haskell = {
enable = mkEnableOption "Haskell integration for Visual Studio Code"; enable = mkEnableOption "Haskell integration for Visual Studio Code";
@ -57,10 +55,8 @@ in
}; };
programs.vscode.extensions = programs.vscode.extensions =
[ [ pkgs.vscode-extensions.justusadam.language-haskell ]
pkgs.vscode-extensions.justusadam.language-haskell
]
++ lib.optional cfg.hie.enable ++ lib.optional cfg.hie.enable
pkgs.vscode-extensions.alanz.vscode-hie-server; pkgs.vscode-extensions.alanz.vscode-hie-server;
}; };
} }

View file

@ -7,16 +7,14 @@ let
cfg = config.programs.z-lua; cfg = config.programs.z-lua;
aliases = { aliases = {
zz = "z -c"; # restrict matches to subdirs of $PWD zz = "z -c"; # restrict matches to subdirs of $PWD
zi = "z -i"; # cd with interactive selection zi = "z -i"; # cd with interactive selection
zf = "z -I"; # use fzf to select in multiple matches zf = "z -I"; # use fzf to select in multiple matches
zb = "z -b"; # quickly cd to the parent directory zb = "z -b"; # quickly cd to the parent directory
zh = "z -I -t ."; # fzf zh = "z -I -t ."; # fzf
}; };
in in {
{
meta.maintainers = [ maintainers.marsam ]; meta.maintainers = [ maintainers.marsam ];
options.programs.z-lua = { options.programs.z-lua = {
@ -24,7 +22,7 @@ in
options = mkOption { options = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "enhanced" "once" "fzf" ]; example = [ "enhanced" "once" "fzf" ];
description = '' description = ''
List of options to pass to z.lua. List of options to pass to z.lua.
@ -68,15 +66,21 @@ in
home.packages = [ pkgs.z-lua ]; home.packages = [ pkgs.z-lua ];
programs.bash.initExtra = mkIf cfg.enableBashIntegration '' programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
eval "$(${pkgs.z-lua}/bin/z --init bash ${concatStringsSep " " cfg.options})" eval "$(${pkgs.z-lua}/bin/z --init bash ${
concatStringsSep " " cfg.options
})"
''; '';
programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
eval "$(${pkgs.z-lua}/bin/z --init zsh ${concatStringsSep " " cfg.options})" eval "$(${pkgs.z-lua}/bin/z --init zsh ${
concatStringsSep " " cfg.options
})"
''; '';
programs.fish.shellInit = mkIf cfg.enableFishIntegration '' programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
source (${pkgs.z-lua}/bin/z --init fish ${concatStringsSep " " cfg.options} | psub) source (${pkgs.z-lua}/bin/z --init fish ${
concatStringsSep " " cfg.options
} | psub)
''; '';
programs.bash.shellAliases = mkIf cfg.enableAliases aliases; programs.bash.shellAliases = mkIf cfg.enableAliases aliases;

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ...}: { config, lib, pkgs, ... }:
with lib; with lib;
@ -9,14 +9,10 @@ let
formatLine = n: v: formatLine = n: v:
let let
formatValue = v: formatValue = v:
if isBool v then (if v then "true" else "false") if isBool v then (if v then "true" else "false") else toString v;
else toString v; in ''set ${n} "${formatValue v}"'';
in
"set ${n}\t\"${formatValue v}\"";
in in {
{
meta.maintainers = [ maintainers.rprospero ]; meta.maintainers = [ maintainers.rprospero ];
options.programs.zathura = { options.programs.zathura = {
@ -25,7 +21,7 @@ in
focused on keyboard interaction''; focused on keyboard interaction'';
options = mkOption { options = mkOption {
default = {}; default = { };
type = with types; attrsOf (either str (either bool int)); type = with types; attrsOf (either str (either bool int));
description = '' description = ''
Add <option>:set</option> command options to zathura and make Add <option>:set</option> command options to zathura and make
@ -36,7 +32,10 @@ in
</citerefentry> </citerefentry>
for the full list of options. for the full list of options.
''; '';
example = { default-bg = "#000000"; default-fg = "#FFFFFF"; }; example = {
default-bg = "#000000";
default-fg = "#FFFFFF";
};
}; };
extraConfig = mkOption { extraConfig = mkOption {
@ -52,10 +51,8 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.zathura ]; home.packages = [ pkgs.zathura ];
xdg.configFile."zathura/zathurarc".text = xdg.configFile."zathura/zathurarc".text = concatStringsSep "\n" ([ ]
concatStringsSep "\n" ([] ++ optional (cfg.extraConfig != "") cfg.extraConfig
++ optional (cfg.extraConfig != "") cfg.extraConfig ++ mapAttrsToList formatLine cfg.options) + "\n";
++ mapAttrsToList formatLine cfg.options
) + "\n";
}; };
} }

View file

@ -22,19 +22,15 @@ with lib;
config = mkIf config.services.blueman-applet.enable { config = mkIf config.services.blueman-applet.enable {
systemd.user.services.blueman-applet = { systemd.user.services.blueman-applet = {
Unit = { Unit = {
Description = "Blueman applet"; Description = "Blueman applet";
After = [ "graphical-session-pre.target" ]; After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = { ExecStart = "${pkgs.blueman}/bin/blueman-applet"; };
ExecStart = "${pkgs.blueman}/bin/blueman-applet";
};
}; };
}; };
} }

View file

@ -9,37 +9,24 @@ let
package = pkgs.cbatticon; package = pkgs.cbatticon;
makeCommand = commandName: commandArg: makeCommand = commandName: commandArg:
optional (commandArg != null) ( optional (commandArg != null)
let (let cmd = pkgs.writeShellScript commandName commandArg;
cmd = pkgs.writeShellScript commandName commandArg; in "--${commandName} ${cmd}");
in
"--${commandName} ${cmd}"
);
commandLine = concatStringsSep " " ( commandLine = concatStringsSep " " ([ "${package}/bin/cbatticon" ]
[ "${package}/bin/cbatticon" ]
++ makeCommand "command-critical-level" cfg.commandCriticalLevel ++ makeCommand "command-critical-level" cfg.commandCriticalLevel
++ makeCommand "command-left-click" cfg.commandLeftClick ++ makeCommand "command-left-click" cfg.commandLeftClick
++ optional ++ optional (cfg.iconType != null) "--icon-type ${cfg.iconType}"
(cfg.iconType != null) ++ optional (cfg.lowLevelPercent != null)
"--icon-type ${cfg.iconType}" "--low-level ${toString cfg.lowLevelPercent}"
++ optional ++ optional (cfg.criticalLevelPercent != null)
(cfg.lowLevelPercent != null) "--critical-level ${toString cfg.criticalLevelPercent}"
"--low-level ${toString cfg.lowLevelPercent}" ++ optional (cfg.updateIntervalSeconds != null)
++ optional "--update-interval ${toString cfg.updateIntervalSeconds}"
(cfg.criticalLevelPercent != null) ++ optional (cfg.hideNotification != null && cfg.hideNotification)
"--critical-level ${toString cfg.criticalLevelPercent}" "--hide-notification");
++ optional
(cfg.updateIntervalSeconds != null)
"--update-interval ${toString cfg.updateIntervalSeconds}"
++ optional
(cfg.hideNotification != null && cfg.hideNotification)
"--hide-notification"
);
in in {
{
meta.maintainers = [ maintainers.pmiddend ]; meta.maintainers = [ maintainers.pmiddend ];
options = { options = {
@ -66,7 +53,8 @@ in
}; };
iconType = mkOption { iconType = mkOption {
type = types.nullOr (types.enum [ "standard" "notification" "symbolic" ]); type =
types.nullOr (types.enum [ "standard" "notification" "symbolic" ]);
default = null; default = null;
example = "symbolic"; example = "symbolic";
description = "Icon type to display in the system tray."; description = "Icon type to display in the system tray.";
@ -119,9 +107,7 @@ in
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
ExecStart = commandLine; ExecStart = commandLine;

View file

@ -7,44 +7,41 @@ let
cfg = config.services.compton; cfg = config.services.compton;
configFile = pkgs.writeText "compton.conf" configFile = pkgs.writeText "compton.conf" (optionalString cfg.fade ''
(optionalString cfg.fade '' # fading
# fading fading = true;
fading = true; fade-delta = ${toString cfg.fadeDelta};
fade-delta = ${toString cfg.fadeDelta}; fade-in-step = ${elemAt cfg.fadeSteps 0};
fade-in-step = ${elemAt cfg.fadeSteps 0}; fade-out-step = ${elemAt cfg.fadeSteps 1};
fade-out-step = ${elemAt cfg.fadeSteps 1}; fade-exclude = ${toJSON cfg.fadeExclude};
fade-exclude = ${toJSON cfg.fadeExclude}; '' + optionalString cfg.shadow ''
'' +
optionalString cfg.shadow ''
# shadows # shadows
shadow = true; shadow = true;
shadow-offset-x = ${toString (elemAt cfg.shadowOffsets 0)}; shadow-offset-x = ${toString (elemAt cfg.shadowOffsets 0)};
shadow-offset-y = ${toString (elemAt cfg.shadowOffsets 1)}; shadow-offset-y = ${toString (elemAt cfg.shadowOffsets 1)};
shadow-opacity = ${cfg.shadowOpacity}; shadow-opacity = ${cfg.shadowOpacity};
shadow-exclude = ${toJSON cfg.shadowExclude}; shadow-exclude = ${toJSON cfg.shadowExclude};
no-dock-shadow = ${toJSON cfg.noDockShadow}; no-dock-shadow = ${toJSON cfg.noDockShadow};
no-dnd-shadow = ${toJSON cfg.noDNDShadow}; no-dnd-shadow = ${toJSON cfg.noDNDShadow};
'' + '' + optionalString cfg.blur ''
optionalString cfg.blur ''
# blur # blur
blur-background = true; blur-background = true;
blur-background-exclude = ${toJSON cfg.blurExclude}; blur-background-exclude = ${toJSON cfg.blurExclude};
'' + '' '' + ''
# opacity # opacity
active-opacity = ${cfg.activeOpacity}; active-opacity = ${cfg.activeOpacity};
inactive-opacity = ${cfg.inactiveOpacity}; inactive-opacity = ${cfg.inactiveOpacity};
menu-opacity = ${cfg.menuOpacity}; menu-opacity = ${cfg.menuOpacity};
opacity-rule = ${toJSON cfg.opacityRule}; opacity-rule = ${toJSON cfg.opacityRule};
# other options # other options
backend = ${toJSON cfg.backend}; backend = ${toJSON cfg.backend};
vsync = ${toJSON cfg.vSync}; vsync = ${toJSON cfg.vSync};
refresh-rate = ${toString cfg.refreshRate}; refresh-rate = ${toString cfg.refreshRate};
'' + cfg.extraOptions); '' + cfg.extraOptions);
in { in {
@ -61,11 +58,8 @@ in {
blurExclude = mkOption { blurExclude = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ example = [ "class_g = 'slop'" "class_i = 'polybar'" ];
"class_g = 'slop'"
"class_i = 'polybar'"
];
description = '' description = ''
List of windows to exclude background blur. List of windows to exclude background blur.
See the See the
@ -105,12 +99,8 @@ in {
fadeExclude = mkOption { fadeExclude = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ example = [ "window_type *= 'menu'" "name ~= 'Firefox$'" "focused = 1" ];
"window_type *= 'menu'"
"name ~= 'Firefox$'"
"focused = 1"
];
description = '' description = ''
List of conditions of windows that should not be faded. List of conditions of windows that should not be faded.
See the See the
@ -150,12 +140,8 @@ in {
shadowExclude = mkOption { shadowExclude = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ example = [ "window_type *= 'menu'" "name ~= 'Firefox$'" "focused = 1" ];
"window_type *= 'menu'"
"name ~= 'Firefox$'"
"focused = 1"
];
description = '' description = ''
List of conditions of windows that should have no shadow. List of conditions of windows that should have no shadow.
See the See the
@ -212,11 +198,8 @@ in {
opacityRule = mkOption { opacityRule = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ example = [ "87:class_i ?= 'scratchpad'" "91:class_i ?= 'xterm'" ];
"87:class_i ?= 'scratchpad'"
"91:class_i ?= 'xterm'"
];
description = '' description = ''
List of opacity rules. List of opacity rules.
See the See the
@ -256,7 +239,7 @@ in {
default = 0; default = 0;
example = 60; example = 60;
description = '' description = ''
Screen refresh rate (0 = automatically detect). Screen refresh rate (0 = automatically detect).
''; '';
}; };
@ -293,16 +276,13 @@ in {
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
ExecStart = "${cfg.package}/bin/compton --config ${configFile}"; ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
Restart = "always"; Restart = "always";
RestartSec = 3; RestartSec = 3;
} } // optionalAttrs (cfg.backend == "glx") {
// optionalAttrs (cfg.backend == "glx") {
# Temporarily fixes corrupt colours with Mesa 18. # Temporarily fixes corrupt colours with Mesa 18.
Environment = [ "allow_rgb10_configs=false" ]; Environment = [ "allow_rgb10_configs=false" ];
}; };

View file

@ -6,17 +6,19 @@ let
cfg = config.services.dunst; cfg = config.services.dunst;
eitherStrBoolIntList = with types; either str (either bool (either int (listOf str))); eitherStrBoolIntList = with types;
either str (either bool (either int (listOf str)));
toDunstIni = generators.toINI { toDunstIni = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
value' = value' = if isBool value then
if isBool value then (if value then "yes" else "no") (if value then "yes" else "no")
else if isString value then "\"${value}\"" else if isString value then
else toString value; ''"${value}"''
in else
"${key}=${value'}"; toString value;
in "${key}=${value'}";
}; };
themeType = types.submodule { themeType = types.submodule {
@ -48,9 +50,7 @@ let
size = "32x32"; size = "32x32";
}; };
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -65,7 +65,7 @@ in
settings = mkOption { settings = mkOption {
type = with types; attrsOf (attrsOf eitherStrBoolIntList); type = with types; attrsOf (attrsOf eitherStrBoolIntList);
default = {}; default = { };
description = "Configuration written to ~/.config/dunstrc"; description = "Configuration written to ~/.config/dunstrc";
example = literalExample '' example = literalExample ''
{ {
@ -87,86 +87,73 @@ in
}; };
}; };
config = mkIf cfg.enable ( config = mkIf cfg.enable (mkMerge [
mkMerge [ {
{ xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source =
xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source = "${pkgs.dunst}/share/dbus-1/services/org.knopwob.dunst.service";
"${pkgs.dunst}/share/dbus-1/services/org.knopwob.dunst.service";
services.dunst.settings.global.icon_path = services.dunst.settings.global.icon_path = let
let useCustomTheme = cfg.iconTheme.package != hicolorTheme.package
useCustomTheme = || cfg.iconTheme.name != hicolorTheme.name || cfg.iconTheme.size
cfg.iconTheme.package != hicolorTheme.package != hicolorTheme.size;
|| cfg.iconTheme.name != hicolorTheme.name
|| cfg.iconTheme.size != hicolorTheme.size;
basePaths = [ basePaths = [
"/run/current-system/sw" "/run/current-system/sw"
config.home.profileDirectory config.home.profileDirectory
cfg.iconTheme.package cfg.iconTheme.package
] ++ optional useCustomTheme hicolorTheme.package; ] ++ optional useCustomTheme hicolorTheme.package;
themes = themes = [ cfg.iconTheme ] ++ optional useCustomTheme
[ (hicolorTheme // { size = cfg.iconTheme.size; });
cfg.iconTheme
] ++ optional useCustomTheme (
hicolorTheme // { size = cfg.iconTheme.size; }
);
categories = [ categories = [
"actions" "actions"
"animations" "animations"
"apps" "apps"
"categories" "categories"
"devices" "devices"
"emblems" "emblems"
"emotes" "emotes"
"filesystem" "filesystem"
"intl" "intl"
"mimetypes" "mimetypes"
"places" "places"
"status" "status"
"stock" "stock"
]; ];
in in concatStringsSep ":" (concatMap (theme:
concatStringsSep ":" ( concatMap (basePath:
concatMap (theme: map (category:
concatMap (basePath: "${basePath}/share/icons/${theme.name}/${theme.size}/${category}")
map (category: categories) basePaths) themes);
"${basePath}/share/icons/${theme.name}/${theme.size}/${category}"
) categories
) basePaths
) themes
);
systemd.user.services.dunst = { systemd.user.services.dunst = {
Unit = { Unit = {
Description = "Dunst notification daemon"; Description = "Dunst notification daemon";
After = [ "graphical-session-pre.target" ]; After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "dbus";
BusName = "org.freedesktop.Notifications";
ExecStart = "${pkgs.dunst}/bin/dunst";
};
}; };
}
(mkIf (cfg.settings != {}) { Service = {
xdg.configFile."dunst/dunstrc" = { Type = "dbus";
text = toDunstIni cfg.settings; BusName = "org.freedesktop.Notifications";
onChange = '' ExecStart = "${pkgs.dunst}/bin/dunst";
pkillVerbose=""
if [[ -v VERBOSE ]]; then
pkillVerbose="-e"
fi
$DRY_RUN_CMD ${pkgs.procps}/bin/pkill -u $USER $pkillVerbose dunst || true
unset pkillVerbose
'';
}; };
}) };
] }
);
(mkIf (cfg.settings != { }) {
xdg.configFile."dunst/dunstrc" = {
text = toDunstIni cfg.settings;
onChange = ''
pkillVerbose=""
if [[ -v VERBOSE ]]; then
pkillVerbose="-e"
fi
$DRY_RUN_CMD ${pkgs.procps}/bin/pkill -u $USER $pkillVerbose dunst || true
unset pkillVerbose
'';
};
})
]);
} }

View file

@ -10,9 +10,8 @@ let
configText = builtins.toJSON ({ inherit (cfg) order; } // cfg.extraConfig); configText = builtins.toJSON ({ inherit (cfg) order; } // cfg.extraConfig);
configFile = pkgs.writeText "dwm-status.json" configText; configFile = pkgs.writeText "dwm-status.json" configText;
in
{ in {
options = { options = {
services.dwm-status = { services.dwm-status = {
enable = mkEnableOption "dwm-status user service"; enable = mkEnableOption "dwm-status user service";
@ -32,7 +31,7 @@ in
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrs; type = types.attrs;
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
separator = "#"; separator = "#";
@ -58,13 +57,9 @@ in
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = { ExecStart = "${cfg.package}/bin/dwm-status ${configFile}"; };
ExecStart = "${cfg.package}/bin/dwm-status ${configFile}";
};
}; };
}; };
} }

View file

@ -8,26 +8,21 @@ let
emacsCfg = config.programs.emacs; emacsCfg = config.programs.emacs;
emacsBinPath = "${emacsCfg.finalPackage}/bin"; emacsBinPath = "${emacsCfg.finalPackage}/bin";
in in {
options.services.emacs = { enable = mkEnableOption "the Emacs daemon"; };
{
options.services.emacs = {
enable = mkEnableOption "the Emacs daemon";
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [{
{ assertion = emacsCfg.enable;
assertion = emacsCfg.enable; message = "The Emacs service module requires"
message = "The Emacs service module requires" + " 'programs.emacs.enable = true'.";
+ " 'programs.emacs.enable = true'."; }];
}
];
systemd.user.services.emacs = { systemd.user.services.emacs = {
Unit = { Unit = {
Description = "Emacs: the extensible, self-documenting text editor"; Description = "Emacs: the extensible, self-documenting text editor";
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/"; Documentation =
"info:emacs man:emacs(1) https://gnu.org/software/emacs/";
# Avoid killing the Emacs session, which may be full of # Avoid killing the Emacs session, which may be full of
# unsaved buffers. # unsaved buffers.
@ -35,14 +30,13 @@ in
}; };
Service = { Service = {
ExecStart = "${pkgs.runtimeShell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'"; ExecStart =
"${pkgs.runtimeShell} -l -c 'exec ${emacsBinPath}/emacs --fg-daemon'";
ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs)'"; ExecStop = "${emacsBinPath}/emacsclient --eval '(kill-emacs)'";
Restart = "on-failure"; Restart = "on-failure";
}; };
Install = { Install = { WantedBy = [ "default.target" ]; };
WantedBy = [ "default.target" ];
};
}; };
}; };
} }

View file

@ -7,16 +7,10 @@ let
cfg = config.services.flameshot; cfg = config.services.flameshot;
package = pkgs.flameshot; package = pkgs.flameshot;
in in {
{
meta.maintainers = [ maintainers.hamhut1066 ]; meta.maintainers = [ maintainers.hamhut1066 ];
options = { options = { services.flameshot = { enable = mkEnableOption "Flameshot"; }; };
services.flameshot = {
enable = mkEnableOption "Flameshot";
};
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ package ]; home.packages = [ package ];
@ -33,9 +27,7 @@ in
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
Environment = "PATH=${config.home.profileDirectory}/bin"; Environment = "PATH=${config.home.profileDirectory}/bin";

View file

@ -6,17 +6,19 @@ let
cfg = config.services.getmail; cfg = config.services.getmail;
accounts = filter (a: a.getmail.enable) accounts =
(attrValues config.accounts.email.accounts); filter (a: a.getmail.enable) (attrValues config.accounts.email.accounts);
# Note: The getmail service does not expect a path, but just the filename! # Note: The getmail service does not expect a path, but just the filename!
renderConfigFilepath = a: if a.primary then "getmailrc" else "getmail${a.name}"; renderConfigFilepath = a:
configFiles = concatMapStringsSep " " (a: " --rcfile ${renderConfigFilepath a}") accounts; if a.primary then "getmailrc" else "getmail${a.name}";
in configFiles =
{ concatMapStringsSep " " (a: " --rcfile ${renderConfigFilepath a}") accounts;
in {
options = { options = {
services.getmail = { services.getmail = {
enable = mkEnableOption "the getmail systemd service to automatically retrieve mail"; enable = mkEnableOption
"the getmail systemd service to automatically retrieve mail";
frequency = mkOption { frequency = mkOption {
type = types.str; type = types.str;
@ -36,25 +38,17 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.user.services.getmail = { systemd.user.services.getmail = {
Unit = { Unit = { Description = "getmail email fetcher"; };
Description = "getmail email fetcher"; Service = { ExecStart = "${pkgs.getmail}/bin/getmail ${configFiles}"; };
};
Service = {
ExecStart = "${pkgs.getmail}/bin/getmail ${configFiles}";
};
}; };
systemd.user.timers.getmail = { systemd.user.timers.getmail = {
Unit = { Unit = { Description = "getmail email fetcher"; };
Description = "getmail email fetcher";
};
Timer = { Timer = {
OnCalendar = "${cfg.frequency}"; OnCalendar = "${cfg.frequency}";
Unit = "getmail.service"; Unit = "getmail.service";
}; };
Install = { Install = { WantedBy = [ "timers.target" ]; };
WantedBy = [ "timers.target" ];
};
}; };
}; };

View file

@ -6,9 +6,7 @@ let
cfg = config.services.gnome-keyring; cfg = config.services.gnome-keyring;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -16,8 +14,8 @@ in
enable = mkEnableOption "GNOME Keyring"; enable = mkEnableOption "GNOME Keyring";
components = mkOption { components = mkOption {
type = types.listOf (types.enum ["pkcs11" "secrets" "ssh"]); type = types.listOf (types.enum [ "pkcs11" "secrets" "ssh" ]);
default = []; default = [ ];
description = '' description = ''
The GNOME keyring components to start. If empty then the The GNOME keyring components to start. If empty then the
default set of components will be started. default set of components will be started.
@ -34,22 +32,15 @@ in
}; };
Service = { Service = {
ExecStart = ExecStart = let
let args = concatStringsSep " " ([ "--start" "--foreground" ]
args = concatStringsSep " " ( ++ optional (cfg.components != [ ])
[ "--start" "--foreground" ] ("--components=" + concatStringsSep "," cfg.components));
++ optional (cfg.components != []) ( in "${pkgs.gnome3.gnome_keyring}/bin/gnome-keyring-daemon ${args}";
"--components=" + concatStringsSep "," cfg.components
)
);
in
"${pkgs.gnome3.gnome_keyring}/bin/gnome-keyring-daemon ${args}";
Restart = "on-abort"; Restart = "on-abort";
}; };
Install = { Install = { WantedBy = [ "graphical-session-pre.target" ]; };
WantedBy = [ "graphical-session-pre.target" ];
};
}; };
}; };
} }

View file

@ -6,12 +6,10 @@ let
cfg = config.services.grobi; cfg = config.services.grobi;
eitherStrBoolIntList = eitherStrBoolIntList = with types;
with types; either str (either bool (either int (listOf str))); either str (either bool (either int (listOf str)));
in in {
{
meta.maintainers = [ maintainers.mbrgm ]; meta.maintainers = [ maintainers.mbrgm ];
options = { options = {
@ -20,7 +18,7 @@ in
executeAfter = mkOption { executeAfter = mkOption {
type = with types; listOf str; type = with types; listOf str;
default = []; default = [ ];
example = [ "setxkbmap dvorak" ]; example = [ "setxkbmap dvorak" ];
description = '' description = ''
Commands to be run after an output configuration was Commands to be run after an output configuration was
@ -32,7 +30,7 @@ in
rules = mkOption { rules = mkOption {
type = with types; listOf (attrsOf eitherStrBoolIntList); type = with types; listOf (attrsOf eitherStrBoolIntList);
default = []; default = [ ];
example = literalExample '' example = literalExample ''
[ [
{ {
@ -88,9 +86,7 @@ in
Environment = "PATH=${pkgs.xorg.xrandr}/bin:${pkgs.bash}/bin"; Environment = "PATH=${pkgs.xorg.xrandr}/bin:${pkgs.bash}/bin";
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
}; };
xdg.configFile."grobi.conf".text = builtins.toJSON { xdg.configFile."grobi.conf".text = builtins.toJSON {

View file

@ -6,23 +6,16 @@ let
cfg = config.services.hound; cfg = config.services.hound;
configFile = pkgs.writeText "hound-config.json" ( configFile = pkgs.writeText "hound-config.json" (builtins.toJSON {
builtins.toJSON { max-concurrent-indexers = cfg.maxConcurrentIndexers;
max-concurrent-indexers = cfg.maxConcurrentIndexers; dbpath = cfg.databasePath;
dbpath = cfg.databasePath; repos = cfg.repositories;
repos = cfg.repositories; health-check-url = "/healthz";
health-check-url = "/healthz"; });
}
);
houndOptions = [ houndOptions = [ "--addr ${cfg.listenAddress}" "--conf ${configFile}" ];
"--addr ${cfg.listenAddress}"
"--conf ${configFile}"
];
in in {
{
meta.maintainers = [ maintainers.adisbladis ]; meta.maintainers = [ maintainers.adisbladis ];
options.services.hound = { options.services.hound = {
@ -37,7 +30,7 @@ in
databasePath = mkOption { databasePath = mkOption {
type = types.path; type = types.path;
default = "${config.xdg.dataHome}/hound"; default = "${config.xdg.dataHome}/hound";
defaultText = "\$XDG_DATA_HOME/hound"; defaultText = "$XDG_DATA_HOME/hound";
description = "The Hound database path."; description = "The Hound database path.";
}; };
@ -49,7 +42,7 @@ in
repositories = mkOption { repositories = mkOption {
type = types.attrsOf (types.uniq types.attrs); type = types.attrsOf (types.uniq types.attrs);
default = {}; default = { };
example = literalExample '' example = literalExample ''
{ {
SomeGitRepo = { SomeGitRepo = {
@ -67,17 +60,14 @@ in
home.packages = [ pkgs.hound ]; home.packages = [ pkgs.hound ];
systemd.user.services.hound = { systemd.user.services.hound = {
Unit = { Unit = { Description = "Hound source code search engine"; };
Description = "Hound source code search engine";
};
Install = { Install = { WantedBy = [ "default.target" ]; };
WantedBy = [ "default.target" ];
};
Service = { Service = {
Environment = "PATH=${makeBinPath [ pkgs.mercurial pkgs.git ]}"; Environment = "PATH=${makeBinPath [ pkgs.mercurial pkgs.git ]}";
ExecStart = "${pkgs.hound}/bin/houndd ${concatStringsSep " " houndOptions}"; ExecStart =
"${pkgs.hound}/bin/houndd ${concatStringsSep " " houndOptions}";
}; };
}; };
}; };

View file

@ -16,13 +16,16 @@ with lib;
onNotifyPost = mkOption { onNotifyPost = mkOption {
type = with types; either str (attrsOf str); type = with types; either str (attrsOf str);
default = ""; default = "";
example = { mail = "\${pkgs.notmuch}/bin/notmuch new && \${pkgs.libnotify}/bin/notify-send 'New mail arrived'"; }; example = {
mail =
"\${pkgs.notmuch}/bin/notmuch new && \${pkgs.libnotify}/bin/notify-send 'New mail arrived'";
};
description = "Shell commands to run after onNotify event."; description = "Shell commands to run after onNotify event.";
}; };
boxes = mkOption { boxes = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
example = [ "Inbox" "[Gmail]/MyLabel" ]; example = [ "Inbox" "[Gmail]/MyLabel" ];
description = "IMAP folders to watch."; description = "IMAP folders to watch.";
}; };

View file

@ -6,102 +6,85 @@ let
cfg = config.services.imapnotify; cfg = config.services.imapnotify;
safeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""]; safeName = lib.replaceChars [ "@" ":" "\\" "[" "]" ] [ "-" "-" "-" "" "" ];
imapnotifyAccounts = imapnotifyAccounts =
filter (a: a.imapnotify.enable) filter (a: a.imapnotify.enable) (attrValues config.accounts.email.accounts);
(attrValues config.accounts.email.accounts);
genAccountUnit = account: genAccountUnit = account:
let let name = safeName account.name;
name = safeName account.name; in {
in name = "imapnotify-${name}";
{ value = {
name = "imapnotify-${name}"; Unit = { Description = "imapnotify for ${name}"; };
value = {
Unit = {
Description = "imapnotify for ${name}";
};
Service = { Service = {
ExecStart = "${pkgs.imapnotify}/bin/imapnotify -c ${genAccountConfig account}"; ExecStart =
} // optionalAttrs account.notmuch.enable { "${pkgs.imapnotify}/bin/imapnotify -c ${genAccountConfig account}";
Environment = "NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc"; } // optionalAttrs account.notmuch.enable {
}; Environment =
"NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc";
Install = {
WantedBy = [ "default.target" ];
};
}; };
Install = { WantedBy = [ "default.target" ]; };
}; };
};
genAccountConfig = account: genAccountConfig = account:
pkgs.writeText "imapnotify-${safeName account.name}-config.js" ( pkgs.writeText "imapnotify-${safeName account.name}-config.js" (let
let port = if account.imap.port != null then
port = account.imap.port
if account.imap.port != null then account.imap.port else if account.imap.tls.enable then
else if account.imap.tls.enable then 993 993
else 143; else
143;
toJSON = builtins.toJSON; toJSON = builtins.toJSON;
in in ''
'' var child_process = require('child_process');
var child_process = require('child_process');
function getStdout(cmd) { function getStdout(cmd) {
var stdout = child_process.execSync(cmd); var stdout = child_process.execSync(cmd);
return stdout.toString().trim(); return stdout.toString().trim();
} }
exports.host = ${toJSON account.imap.host} exports.host = ${toJSON account.imap.host}
exports.port = ${toJSON port}; exports.port = ${toJSON port};
exports.tls = ${toJSON account.imap.tls.enable}; exports.tls = ${toJSON account.imap.tls.enable};
exports.username = ${toJSON account.userName}; exports.username = ${toJSON account.userName};
exports.password = getStdout("${toString account.passwordCommand}"); exports.password = getStdout("${toString account.passwordCommand}");
exports.onNotify = ${toJSON account.imapnotify.onNotify}; exports.onNotify = ${toJSON account.imapnotify.onNotify};
exports.onNotifyPost = ${toJSON account.imapnotify.onNotifyPost}; exports.onNotifyPost = ${toJSON account.imapnotify.onNotifyPost};
exports.boxes = ${toJSON account.imapnotify.boxes}; exports.boxes = ${toJSON account.imapnotify.boxes};
'' '');
);
in in {
{
meta.maintainers = [ maintainers.nickhu ]; meta.maintainers = [ maintainers.nickhu ];
options = { options = {
services.imapnotify = { services.imapnotify = { enable = mkEnableOption "imapnotify"; };
enable = mkEnableOption "imapnotify";
};
accounts.email.accounts = mkOption { accounts.email.accounts = mkOption {
type = with types; attrsOf (submodule ( type = with types; attrsOf (submodule (import ./imapnotify-accounts.nix));
import ./imapnotify-accounts.nix
));
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = assertions = let
let checkAccounts = pred: msg:
checkAccounts = pred: msg: let badAccounts = filter pred imapnotifyAccounts;
let in {
badAccounts = filter pred imapnotifyAccounts; assertion = badAccounts == [ ];
in message = "imapnotify: Missing ${msg} for accounts: "
{ + concatMapStringsSep ", " (a: a.name) badAccounts;
assertion = badAccounts == []; };
message = "imapnotify: Missing ${msg} for accounts: " in [
+ concatMapStringsSep ", " (a: a.name) badAccounts; (checkAccounts (a: a.maildir == null) "maildir configuration")
}; (checkAccounts (a: a.imap == null) "IMAP configuration")
in (checkAccounts (a: a.passwordCommand == null) "password command")
[ (checkAccounts (a: a.userName == null) "username")
(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 = systemd.user.services = listToAttrs (map genAccountUnit imapnotifyAccounts);
listToAttrs (map genAccountUnit imapnotifyAccounts);
}; };
} }

View file

@ -7,9 +7,7 @@ let
cfg = config.services.kdeconnect; cfg = config.services.kdeconnect;
package = pkgs.kdeconnect; package = pkgs.kdeconnect;
in in {
{
meta.maintainers = [ maintainers.adisbladis ]; meta.maintainers = [ maintainers.adisbladis ];
options = { options = {
@ -31,14 +29,13 @@ in
systemd.user.services.kdeconnect = { systemd.user.services.kdeconnect = {
Unit = { Unit = {
Description = "Adds communication between your desktop and your smartphone"; Description =
"Adds communication between your desktop and your smartphone";
After = [ "graphical-session-pre.target" ]; After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
Environment = "PATH=${config.home.profileDirectory}/bin"; Environment = "PATH=${config.home.profileDirectory}/bin";
@ -52,16 +49,16 @@ in
systemd.user.services.kdeconnect-indicator = { systemd.user.services.kdeconnect-indicator = {
Unit = { Unit = {
Description = "kdeconnect-indicator"; Description = "kdeconnect-indicator";
After = [ "graphical-session-pre.target" After = [
"polybar.service" "graphical-session-pre.target"
"taffybar.service" "polybar.service"
"stalonetray.service" ]; "taffybar.service"
"stalonetray.service"
];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
Environment = "PATH=${config.home.profileDirectory}/bin"; Environment = "PATH=${config.home.profileDirectory}/bin";

View file

@ -13,19 +13,15 @@ with lib;
config = mkIf config.services.keepassx.enable { config = mkIf config.services.keepassx.enable {
systemd.user.services.keepassx = { systemd.user.services.keepassx = {
Unit = { Unit = {
Description = "KeePassX password manager"; Description = "KeePassX password manager";
After = [ "graphical-session-pre.target" ]; After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = { ExecStart = "${pkgs.keepassx}/bin/keepassx -min -lock"; };
ExecStart = "${pkgs.keepassx}/bin/keepassx -min -lock";
};
}; };
}; };
} }

View file

@ -6,14 +6,10 @@ let
cfg = config.services.lorri; cfg = config.services.lorri;
in in {
{
meta.maintainers = [ maintainers.gerschtli ]; meta.maintainers = [ maintainers.gerschtli ];
options = { options = { services.lorri.enable = mkEnableOption "lorri build daemon"; };
services.lorri.enable = mkEnableOption "lorri build daemon";
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.lorri ]; home.packages = [ pkgs.lorri ];
@ -33,25 +29,22 @@ in
ProtectSystem = "strict"; ProtectSystem = "strict";
ProtectHome = "read-only"; ProtectHome = "read-only";
Restart = "on-failure"; Restart = "on-failure";
Environment = Environment = let
let path = with pkgs; makeSearchPath "bin" [ nix gitMinimal gnutar gzip ]; path = with pkgs;
in "PATH=${path}"; makeSearchPath "bin" [ nix gitMinimal gnutar gzip ];
in "PATH=${path}";
}; };
}; };
sockets.lorri = { sockets.lorri = {
Unit = { Unit = { Description = "Socket for lorri build daemon"; };
Description = "Socket for lorri build daemon";
};
Socket = { Socket = {
ListenStream = "%t/lorri/daemon.socket"; ListenStream = "%t/lorri/daemon.socket";
RuntimeDirectory = "lorri"; RuntimeDirectory = "lorri";
}; };
Install = { Install = { WantedBy = [ "sockets.target" ]; };
WantedBy = [ "sockets.target" ];
};
}; };
}; };
}; };

View file

@ -6,14 +6,10 @@ let
cfg = config.services.mbsync; cfg = config.services.mbsync;
mbsyncOptions = mbsyncOptions = [ "--all" ] ++ optional (cfg.verbose) "--verbose"
[ "--all" ++ optional (cfg.configFile != null) "--config ${cfg.configFile}";
] ++ optional (cfg.verbose) "--verbose"
++ optional (cfg.configFile != null) "--config ${cfg.configFile}";
in in {
{
meta.maintainers = [ maintainers.pjones ]; meta.maintainers = [ maintainers.pjones ];
options.services.mbsync = { options.services.mbsync = {
@ -81,30 +77,28 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.user.services.mbsync = { systemd.user.services.mbsync = {
Unit = { Unit = { Description = "mbsync mailbox synchronization"; };
Description = "mbsync mailbox synchronization";
};
Service = { Service = {
Type = "oneshot"; Type = "oneshot";
ExecStart = "${cfg.package}/bin/mbsync ${concatStringsSep " " mbsyncOptions}"; ExecStart =
} // (optionalAttrs (cfg.postExec != null) { ExecStartPost = cfg.postExec; }) "${cfg.package}/bin/mbsync ${concatStringsSep " " mbsyncOptions}";
// (optionalAttrs (cfg.preExec != null) { ExecStartPre = cfg.preExec; }); } // (optionalAttrs (cfg.postExec != null) {
ExecStartPost = cfg.postExec;
}) // (optionalAttrs (cfg.preExec != null) {
ExecStartPre = cfg.preExec;
});
}; };
systemd.user.timers.mbsync = { systemd.user.timers.mbsync = {
Unit = { Unit = { Description = "mbsync mailbox synchronization"; };
Description = "mbsync mailbox synchronization";
};
Timer = { Timer = {
OnCalendar = cfg.frequency; OnCalendar = cfg.frequency;
Unit = "mbsync.service"; Unit = "mbsync.service";
}; };
Install = { Install = { WantedBy = [ "timers.target" ]; };
WantedBy = [ "timers.target" ];
};
}; };
}; };
} }

View file

@ -9,11 +9,11 @@ let
toIni = generators.toINI { toIni = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
value' = value' = if isBool value then
if isBool value then (if value then "True" else "False") (if value then "True" else "False")
else toString value; else
in toString value;
"${key} = ${value'}"; in "${key} = ${value'}";
}; };
mpdris2Conf = { mpdris2Conf = {
@ -29,9 +29,7 @@ let
}; };
}; };
in in {
{
meta.maintainers = [ maintainers.pjones ]; meta.maintainers = [ maintainers.pjones ];
options.services.mpdris2 = { options.services.mpdris2 = {
@ -76,19 +74,15 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [{
{ assertion = config.services.mpd.enable;
assertion = config.services.mpd.enable; message = "The mpdris2 module requires 'services.mpd.enable = true'.";
message = "The mpdris2 module requires 'services.mpd.enable = true'."; }];
}
];
xdg.configFile."mpDris2/mpDris2.conf".text = toIni mpdris2Conf; xdg.configFile."mpDris2/mpDris2.conf".text = toIni mpdris2Conf;
systemd.user.services.mpdris2 = { systemd.user.services.mpdris2 = {
Install = { Install = { WantedBy = [ "default.target" ]; };
WantedBy = [ "default.target" ];
};
Unit = { Unit = {
Description = "MPRIS 2 support for MPD"; Description = "MPRIS 2 support for MPD";

View file

@ -150,23 +150,21 @@ in {
}; };
config = let config = let
mapRemotes = gen: with attrsets; mapAttrs' mapRemotes = gen:
with attrsets;
mapAttrs'
(name: remoteCfg: nameValuePair "muchsync-${name}" (gen name remoteCfg)) (name: remoteCfg: nameValuePair "muchsync-${name}" (gen name remoteCfg))
cfg.remotes; cfg.remotes;
in mkIf (cfg.remotes != { }) { in mkIf (cfg.remotes != { }) {
assertions = [ assertions = [{
{ assertion = config.programs.notmuch.enable;
assertion = config.programs.notmuch.enable; message = ''
message = '' The muchsync module requires 'programs.notmuch.enable = true'.
The muchsync module requires 'programs.notmuch.enable = true'. '';
''; }];
}
];
systemd.user.services = mapRemotes (name: remoteCfg: { systemd.user.services = mapRemotes (name: remoteCfg: {
Unit = { Unit = { Description = "muchsync sync service (${name})"; };
Description = "muchsync sync service (${name})";
};
Service = { Service = {
CPUSchedulingPolicy = "idle"; CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle"; IOSchedulingClass = "idle";
@ -175,8 +173,7 @@ in {
''"NOTMUCH_CONFIG=${config.home.sessionVariables.NOTMUCH_CONFIG}"'' ''"NOTMUCH_CONFIG=${config.home.sessionVariables.NOTMUCH_CONFIG}"''
''"NMBGIT=${config.home.sessionVariables.NMBGIT}"'' ''"NMBGIT=${config.home.sessionVariables.NMBGIT}"''
]; ];
ExecStart = concatStringsSep " " ( ExecStart = concatStringsSep " " ([ "${pkgs.muchsync}/bin/muchsync" ]
[ "${pkgs.muchsync}/bin/muchsync" ]
++ [ "-s ${escapeShellArg remoteCfg.sshCommand}" ] ++ [ "-s ${escapeShellArg remoteCfg.sshCommand}" ]
++ optional (!remoteCfg.upload) "--noup" ++ optional (!remoteCfg.upload) "--noup"
@ -187,25 +184,20 @@ in {
# remote configuration # remote configuration
++ [ (escapeShellArg remoteCfg.remote.host) ] ++ [ (escapeShellArg remoteCfg.remote.host) ]
++ optional (remoteCfg.remote.muchsyncPath != "") ++ optional (remoteCfg.remote.muchsyncPath != "")
"-r ${escapeShellArg remoteCfg.remote.muchsyncPath}" "-r ${escapeShellArg remoteCfg.remote.muchsyncPath}"
++ optional remoteCfg.remote.checkForModifiedFiles "-F" ++ optional remoteCfg.remote.checkForModifiedFiles "-F"
++ optional (!remoteCfg.remote.importNew) "--nonew" ++ optional (!remoteCfg.remote.importNew) "--nonew");
);
}; };
}); });
systemd.user.timers = mapRemotes (name: remoteCfg: { systemd.user.timers = mapRemotes (name: remoteCfg: {
Unit = { Unit = { Description = "muchsync periodic sync (${name})"; };
Description = "muchsync periodic sync (${name})";
};
Timer = { Timer = {
Unit = "muchsync-${name}.service"; Unit = "muchsync-${name}.service";
OnCalendar = remoteCfg.frequency; OnCalendar = remoteCfg.frequency;
Persistent = true; Persistent = true;
}; };
Install = { Install = { WantedBy = [ "timers.target" ]; };
WantedBy = [ "timers.target" ];
};
}); });
}; };
} }

View file

@ -6,9 +6,7 @@ let
cfg = config.services.network-manager-applet; cfg = config.services.network-manager-applet;
in in {
{
meta.maintainers = [ maintainers.rycee ]; meta.maintainers = [ maintainers.rycee ];
options = { options = {
@ -25,17 +23,13 @@ in
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
ExecStart = toString ( ExecStart = toString
[ ([ "${pkgs.networkmanagerapplet}/bin/nm-applet" "--sm-disable" ]
"${pkgs.networkmanagerapplet}/bin/nm-applet" ++ optional config.xsession.preferStatusNotifierItems
"--sm-disable" "--indicator");
] ++ optional config.xsession.preferStatusNotifierItems "--indicator"
);
}; };
}; };
}; };

View file

@ -4,9 +4,7 @@ with lib;
{ {
options = { options = {
services.nextcloud-client = { services.nextcloud-client = { enable = mkEnableOption "Nextcloud Client"; };
enable = mkEnableOption "Nextcloud Client";
};
}; };
config = mkIf config.services.nextcloud-client.enable { config = mkIf config.services.nextcloud-client.enable {
@ -22,9 +20,7 @@ with lib;
ExecStart = "${pkgs.nextcloud-client}/bin/nextcloud"; ExecStart = "${pkgs.nextcloud-client}/bin/nextcloud";
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
}; };
}; };
} }

View file

@ -4,9 +4,7 @@ with lib;
{ {
options = { options = {
services.owncloud-client = { services.owncloud-client = { enable = mkEnableOption "Owncloud Client"; };
enable = mkEnableOption "Owncloud Client";
};
}; };
config = mkIf config.services.owncloud-client.enable { config = mkIf config.services.owncloud-client.enable {
@ -22,9 +20,7 @@ with lib;
ExecStart = "${pkgs.owncloud-client}/bin/owncloud"; ExecStart = "${pkgs.owncloud-client}/bin/owncloud";
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
}; };
}; };
} }

View file

@ -7,15 +7,11 @@ let
cfg = config.services.parcellite; cfg = config.services.parcellite;
package = pkgs.parcellite; package = pkgs.parcellite;
in in {
{
meta.maintainers = [ maintainers.gleber ]; meta.maintainers = [ maintainers.gleber ];
options = { options = {
services.parcellite = { services.parcellite = { enable = mkEnableOption "Parcellite"; };
enable = mkEnableOption "Parcellite";
};
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
@ -28,9 +24,7 @@ in
PartOf = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ];
}; };
Install = { Install = { WantedBy = [ "graphical-session.target" ]; };
WantedBy = [ "graphical-session.target" ];
};
Service = { Service = {
ExecStart = "${package}/bin/parcellite"; ExecStart = "${package}/bin/parcellite";

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