mirror of
https://github.com/nix-community/home-manager.git
synced 2025-12-05 16:41:04 +01:00
treewide: reformat nixfmt-rfc-style
Reformat repository using new nixfmt-rfc-style.
This commit is contained in:
parent
5df48c4255
commit
cba2f9ce95
1051 changed files with 37028 additions and 26594 deletions
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.abook;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.abook;
|
||||
in
|
||||
{
|
||||
options.programs.abook = {
|
||||
enable = lib.mkEnableOption "Abook";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,29 @@
|
|||
{ config, lib, confSections, confSection, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
confSections,
|
||||
confSection,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
||||
mapAttrNames = f: attr:
|
||||
lib.listToAttrs (lib.attrValues (lib.mapAttrs (k: v: {
|
||||
name = f k;
|
||||
value = v;
|
||||
}) attr));
|
||||
mapAttrNames =
|
||||
f: attr:
|
||||
lib.listToAttrs (
|
||||
lib.attrValues (
|
||||
lib.mapAttrs (k: v: {
|
||||
name = f k;
|
||||
value = v;
|
||||
}) attr
|
||||
)
|
||||
);
|
||||
|
||||
addAccountName = name: k: "${k}:account=${name}";
|
||||
|
||||
oauth2Params = mkOption {
|
||||
type = with types;
|
||||
type =
|
||||
with types;
|
||||
nullOr (submodule {
|
||||
options = {
|
||||
token_endpoint = mkOption {
|
||||
|
|
@ -37,7 +49,9 @@ let
|
|||
};
|
||||
});
|
||||
default = null;
|
||||
example = { token_endpoint = "<token_endpoint>"; };
|
||||
example = {
|
||||
token_endpoint = "<token_endpoint>";
|
||||
};
|
||||
description = ''
|
||||
Sets the oauth2 params if authentication mechanism oauthbearer or
|
||||
xoauth2 is used.
|
||||
|
|
@ -45,157 +59,188 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
type = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options.aerc = {
|
||||
enable = lib.mkEnableOption "aerc";
|
||||
extraAccounts = mkOption {
|
||||
type = confSection;
|
||||
default = { };
|
||||
example =
|
||||
literalExpression ''{ source = "maildir://~/Maildir/example"; }'';
|
||||
description = ''
|
||||
Extra config added to the configuration section for this account in
|
||||
{file}`$HOME/.config/aerc/accounts.conf`.
|
||||
See {manpage}`aerc-accounts(5)`.
|
||||
'';
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options.aerc = {
|
||||
enable = lib.mkEnableOption "aerc";
|
||||
extraAccounts = mkOption {
|
||||
type = confSection;
|
||||
default = { };
|
||||
example = literalExpression ''{ source = "maildir://~/Maildir/example"; }'';
|
||||
description = ''
|
||||
Extra config added to the configuration section for this account in
|
||||
{file}`$HOME/.config/aerc/accounts.conf`.
|
||||
See {manpage}`aerc-accounts(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
extraBinds = mkOption {
|
||||
type = confSections;
|
||||
default = { };
|
||||
example = literalExpression ''{ messages = { d = ":move ''${folder.trash}<Enter>"; }; }'';
|
||||
description = ''
|
||||
Extra bindings specific to this account, added to
|
||||
{file}`$HOME/.config/aerc/binds.conf`.
|
||||
See {manpage}`aerc-binds(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = confSections;
|
||||
default = { };
|
||||
example = literalExpression "{ ui = { sidebar-width = 25; }; }";
|
||||
description = ''
|
||||
Config specific to this account, added to {file}`$HOME/.config/aerc/aerc.conf`.
|
||||
Aerc only supports per-account UI configuration.
|
||||
For other sections of {file}`$HOME/.config/aerc/aerc.conf`,
|
||||
use `programs.aerc.extraConfig`.
|
||||
See {manpage}`aerc-config(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
imapAuth = mkOption {
|
||||
type =
|
||||
with types;
|
||||
nullOr (enum [
|
||||
"oauthbearer"
|
||||
"xoauth2"
|
||||
]);
|
||||
default = null;
|
||||
example = "auth";
|
||||
description = ''
|
||||
Sets the authentication mechanism if imap is used as the incoming
|
||||
method.
|
||||
See {manpage}`aerc-imap(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
imapOauth2Params = oauth2Params;
|
||||
|
||||
smtpAuth = mkOption {
|
||||
type =
|
||||
with types;
|
||||
nullOr (enum [
|
||||
"none"
|
||||
"plain"
|
||||
"login"
|
||||
"oauthbearer"
|
||||
"xoauth2"
|
||||
]);
|
||||
default = "plain";
|
||||
example = "auth";
|
||||
description = ''
|
||||
Sets the authentication mechanism if smtp is used as the outgoing
|
||||
method.
|
||||
See {manpage}`aerc-smtp(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
smtpOauth2Params = oauth2Params;
|
||||
};
|
||||
|
||||
extraBinds = mkOption {
|
||||
type = confSections;
|
||||
default = { };
|
||||
example = literalExpression
|
||||
''{ messages = { d = ":move ''${folder.trash}<Enter>"; }; }'';
|
||||
description = ''
|
||||
Extra bindings specific to this account, added to
|
||||
{file}`$HOME/.config/aerc/binds.conf`.
|
||||
See {manpage}`aerc-binds(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = confSections;
|
||||
default = { };
|
||||
example = literalExpression "{ ui = { sidebar-width = 25; }; }";
|
||||
description = ''
|
||||
Config specific to this account, added to {file}`$HOME/.config/aerc/aerc.conf`.
|
||||
Aerc only supports per-account UI configuration.
|
||||
For other sections of {file}`$HOME/.config/aerc/aerc.conf`,
|
||||
use `programs.aerc.extraConfig`.
|
||||
See {manpage}`aerc-config(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
imapAuth = mkOption {
|
||||
type = with types; nullOr (enum [ "oauthbearer" "xoauth2" ]);
|
||||
default = null;
|
||||
example = "auth";
|
||||
description = ''
|
||||
Sets the authentication mechanism if imap is used as the incoming
|
||||
method.
|
||||
See {manpage}`aerc-imap(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
imapOauth2Params = oauth2Params;
|
||||
|
||||
smtpAuth = mkOption {
|
||||
type = with types;
|
||||
nullOr (enum [ "none" "plain" "login" "oauthbearer" "xoauth2" ]);
|
||||
default = "plain";
|
||||
example = "auth";
|
||||
description = ''
|
||||
Sets the authentication mechanism if smtp is used as the outgoing
|
||||
method.
|
||||
See {manpage}`aerc-smtp(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
smtpOauth2Params = oauth2Params;
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
mkAccount = name: account:
|
||||
mkAccount =
|
||||
name: account:
|
||||
let
|
||||
nullOrMap = f: v: if v == null then v else f v;
|
||||
|
||||
optPort = port: if port != null then ":${toString port}" else "";
|
||||
|
||||
optAttr = k: v:
|
||||
if v != null && v != [ ] && v != "" then { ${k} = v; } else { };
|
||||
optAttr = k: v: if v != null && v != [ ] && v != "" then { ${k} = v; } else { };
|
||||
|
||||
optPwCmd = k: p:
|
||||
optAttr "${k}-cred-cmd" (nullOrMap (lib.concatStringsSep " ") p);
|
||||
optPwCmd = k: p: optAttr "${k}-cred-cmd" (nullOrMap (lib.concatStringsSep " ") p);
|
||||
|
||||
useOauth = auth: builtins.elem auth [ "oauthbearer" "xoauth2" ];
|
||||
useOauth =
|
||||
auth:
|
||||
builtins.elem auth [
|
||||
"oauthbearer"
|
||||
"xoauth2"
|
||||
];
|
||||
|
||||
oauthParams = { auth, params }:
|
||||
oauthParams =
|
||||
{ auth, params }:
|
||||
if useOauth auth && params != null && params != { } then
|
||||
"?" + builtins.concatStringsSep "&"
|
||||
(lib.attrsets.mapAttrsToList (k: v: k + "=" + lib.strings.escapeURL v)
|
||||
(lib.attrsets.filterAttrs (k: v: v != null) params))
|
||||
"?"
|
||||
+ builtins.concatStringsSep "&" (
|
||||
lib.attrsets.mapAttrsToList (k: v: k + "=" + lib.strings.escapeURL v) (
|
||||
lib.attrsets.filterAttrs (k: v: v != null) params
|
||||
)
|
||||
)
|
||||
else
|
||||
"";
|
||||
|
||||
mkConfig = {
|
||||
maildir = cfg: {
|
||||
source =
|
||||
"maildir://${config.accounts.email.maildirBasePath}/${cfg.maildir.path}";
|
||||
source = "maildir://${config.accounts.email.maildirBasePath}/${cfg.maildir.path}";
|
||||
};
|
||||
|
||||
maildirpp = cfg: {
|
||||
source =
|
||||
"maildirpp://${config.accounts.email.maildirBasePath}/${cfg.maildir.path}/Inbox";
|
||||
source = "maildirpp://${config.accounts.email.maildirBasePath}/${cfg.maildir.path}/Inbox";
|
||||
};
|
||||
|
||||
imap = { userName, imap, passwordCommand, aerc, ... }@cfg:
|
||||
imap =
|
||||
{
|
||||
userName,
|
||||
imap,
|
||||
passwordCommand,
|
||||
aerc,
|
||||
...
|
||||
}@cfg:
|
||||
let
|
||||
loginMethod' =
|
||||
if cfg.aerc.imapAuth != null then "+${cfg.aerc.imapAuth}" else "";
|
||||
loginMethod' = if cfg.aerc.imapAuth != null then "+${cfg.aerc.imapAuth}" else "";
|
||||
|
||||
oauthParams' = oauthParams {
|
||||
auth = cfg.aerc.imapAuth;
|
||||
params = cfg.aerc.imapOauth2Params;
|
||||
};
|
||||
|
||||
protocol = if imap.tls.enable then
|
||||
if imap.tls.useStartTls then "imap" else "imaps${loginMethod'}"
|
||||
else
|
||||
"imap+insecure";
|
||||
protocol =
|
||||
if imap.tls.enable then
|
||||
if imap.tls.useStartTls then "imap" else "imaps${loginMethod'}"
|
||||
else
|
||||
"imap+insecure";
|
||||
|
||||
port' = optPort imap.port;
|
||||
|
||||
in {
|
||||
source =
|
||||
"${protocol}://${userName}@${imap.host}${port'}${oauthParams'}";
|
||||
} // optPwCmd "source" passwordCommand;
|
||||
in
|
||||
{
|
||||
source = "${protocol}://${userName}@${imap.host}${port'}${oauthParams'}";
|
||||
}
|
||||
// optPwCmd "source" passwordCommand;
|
||||
|
||||
smtp = { userName, smtp, passwordCommand, ... }@cfg:
|
||||
smtp =
|
||||
{
|
||||
userName,
|
||||
smtp,
|
||||
passwordCommand,
|
||||
...
|
||||
}@cfg:
|
||||
let
|
||||
loginMethod' =
|
||||
if cfg.aerc.smtpAuth != null then "+${cfg.aerc.smtpAuth}" else "";
|
||||
loginMethod' = if cfg.aerc.smtpAuth != null then "+${cfg.aerc.smtpAuth}" else "";
|
||||
|
||||
oauthParams' = oauthParams {
|
||||
auth = cfg.aerc.smtpAuth;
|
||||
params = cfg.aerc.smtpOauth2Params;
|
||||
};
|
||||
|
||||
protocol = if smtp.tls.enable then
|
||||
if smtp.tls.useStartTls then
|
||||
"smtp${loginMethod'}"
|
||||
protocol =
|
||||
if smtp.tls.enable then
|
||||
if smtp.tls.useStartTls then "smtp${loginMethod'}" else "smtps${loginMethod'}"
|
||||
else
|
||||
"smtps${loginMethod'}"
|
||||
else
|
||||
"smtp+insecure${loginMethod'}";
|
||||
"smtp+insecure${loginMethod'}";
|
||||
|
||||
port' = optPort smtp.port;
|
||||
|
||||
in {
|
||||
outgoing =
|
||||
"${protocol}://${userName}@${smtp.host}${port'}${oauthParams'}";
|
||||
} // optPwCmd "outgoing" passwordCommand;
|
||||
in
|
||||
{
|
||||
outgoing = "${protocol}://${userName}@${smtp.host}${port'}${oauthParams'}";
|
||||
}
|
||||
// optPwCmd "outgoing" passwordCommand;
|
||||
|
||||
msmtp = cfg: {
|
||||
outgoing = "msmtpq --read-envelope-from --read-recipients";
|
||||
|
|
@ -203,17 +248,21 @@ in {
|
|||
|
||||
};
|
||||
|
||||
basicCfg = account:
|
||||
basicCfg =
|
||||
account:
|
||||
{
|
||||
from = "${account.realName} <${account.address}>";
|
||||
} // (optAttr "copy-to" account.folders.sent)
|
||||
}
|
||||
// (optAttr "copy-to" account.folders.sent)
|
||||
// (optAttr "default" account.folders.inbox)
|
||||
// (optAttr "postpone" account.folders.drafts)
|
||||
// (optAttr "aliases" account.aliases);
|
||||
|
||||
sourceCfg = account:
|
||||
if account.mbsync.enable && account.mbsync.flatten == null
|
||||
&& account.mbsync.subFolders == "Maildir++" then
|
||||
sourceCfg =
|
||||
account:
|
||||
if
|
||||
account.mbsync.enable && account.mbsync.flatten == null && account.mbsync.subFolders == "Maildir++"
|
||||
then
|
||||
mkConfig.maildirpp account
|
||||
else if account.mbsync.enable || account.offlineimap.enable then
|
||||
mkConfig.maildir account
|
||||
|
|
@ -222,7 +271,8 @@ in {
|
|||
else
|
||||
{ };
|
||||
|
||||
outgoingCfg = account:
|
||||
outgoingCfg =
|
||||
account:
|
||||
if account.msmtp.enable then
|
||||
mkConfig.msmtp account
|
||||
else if account.smtp != null then
|
||||
|
|
@ -230,19 +280,22 @@ in {
|
|||
else
|
||||
{ };
|
||||
|
||||
gpgCfg = account:
|
||||
gpgCfg =
|
||||
account:
|
||||
lib.optionalAttrs (account.gpg != null) {
|
||||
pgp-key-id = account.gpg.key;
|
||||
pgp-auto-sign = account.gpg.signByDefault;
|
||||
pgp-opportunistic-encrypt = account.gpg.encryptByDefault;
|
||||
};
|
||||
|
||||
in (basicCfg account) // (sourceCfg account) // (outgoingCfg account)
|
||||
// (gpgCfg account) // account.aerc.extraAccounts;
|
||||
in
|
||||
(basicCfg account)
|
||||
// (sourceCfg account)
|
||||
// (outgoingCfg account)
|
||||
// (gpgCfg account)
|
||||
// account.aerc.extraAccounts;
|
||||
|
||||
mkAccountConfig = name: account:
|
||||
mapAttrNames (addAccountName name) account.aerc.extraConfig;
|
||||
mkAccountConfig = name: account: mapAttrNames (addAccountName name) account.aerc.extraConfig;
|
||||
|
||||
mkAccountBinds = name: account:
|
||||
mapAttrNames (addAccountName name) account.aerc.extraBinds;
|
||||
mkAccountBinds = name: account: mapAttrNames (addAccountName name) account.aerc.extraBinds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,34 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
attrsets generators literalExpression mapAttrs mkIf mkOption types;
|
||||
attrsets
|
||||
generators
|
||||
literalExpression
|
||||
mapAttrs
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.aerc;
|
||||
|
||||
primitive = with types;
|
||||
((type: either type (listOf type)) (nullOr (oneOf [ str int bool float ])))
|
||||
primitive =
|
||||
with types;
|
||||
((type: either type (listOf type)) (
|
||||
nullOr (oneOf [
|
||||
str
|
||||
int
|
||||
bool
|
||||
float
|
||||
])
|
||||
))
|
||||
// {
|
||||
description =
|
||||
"values (null, bool, int, string, or float) or a list of values, that will be joined with a comma";
|
||||
description = "values (null, bool, int, string, or float) or a list of values, that will be joined with a comma";
|
||||
};
|
||||
|
||||
confSection = types.attrsOf primitive;
|
||||
|
|
@ -19,18 +38,25 @@ let
|
|||
sectionsOrLines = types.either types.lines confSections;
|
||||
|
||||
accounts = import ./aerc-accounts.nix {
|
||||
inherit config pkgs lib confSection confSections;
|
||||
inherit
|
||||
config
|
||||
pkgs
|
||||
lib
|
||||
confSection
|
||||
confSections
|
||||
;
|
||||
};
|
||||
|
||||
aerc-accounts =
|
||||
attrsets.filterAttrs (_: v: v.aerc.enable) config.accounts.email.accounts;
|
||||
aerc-accounts = attrsets.filterAttrs (_: v: v.aerc.enable) config.accounts.email.accounts;
|
||||
|
||||
configDir = if (pkgs.stdenv.isDarwin && !config.xdg.enable) then
|
||||
"Library/Preferences/aerc"
|
||||
else
|
||||
"${config.xdg.configHome}/aerc";
|
||||
configDir =
|
||||
if (pkgs.stdenv.isDarwin && !config.xdg.enable) then
|
||||
"Library/Preferences/aerc"
|
||||
else
|
||||
"${config.xdg.configHome}/aerc";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ lukasngl ];
|
||||
|
||||
options.accounts.email.accounts = accounts.type;
|
||||
|
|
@ -44,8 +70,7 @@ in {
|
|||
extraAccounts = mkOption {
|
||||
type = sectionsOrLines;
|
||||
default = { };
|
||||
example = literalExpression
|
||||
''{ Work = { source = "maildir://~/Maildir/work"; }; }'';
|
||||
example = literalExpression ''{ Work = { source = "maildir://~/Maildir/work"; }; }'';
|
||||
description = ''
|
||||
Extra lines added to {file}`$HOME/.config/aerc/accounts.conf`.
|
||||
|
||||
|
|
@ -103,127 +128,151 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
joinCfg = cfgs: lib.concatStringsSep "\n" (lib.filter (v: v != "") cfgs);
|
||||
config =
|
||||
let
|
||||
joinCfg = cfgs: lib.concatStringsSep "\n" (lib.filter (v: v != "") cfgs);
|
||||
|
||||
toINI = conf: # quirk: global section is prepended w/o section heading
|
||||
let
|
||||
global = conf.global or { };
|
||||
local = removeAttrs conf [ "global" ];
|
||||
mkValueString = v:
|
||||
if lib.isList v then # join with comma
|
||||
lib.concatStringsSep ","
|
||||
(map (generators.mkValueStringDefault { }) v)
|
||||
else
|
||||
generators.mkValueStringDefault { } v;
|
||||
mkKeyValue =
|
||||
generators.mkKeyValueDefault { inherit mkValueString; } " = ";
|
||||
in joinCfg [
|
||||
(generators.toKeyValue { inherit mkKeyValue; } global)
|
||||
(generators.toINI { inherit mkKeyValue; } local)
|
||||
toINI =
|
||||
conf: # quirk: global section is prepended w/o section heading
|
||||
let
|
||||
global = conf.global or { };
|
||||
local = removeAttrs conf [ "global" ];
|
||||
mkValueString =
|
||||
v:
|
||||
if lib.isList v then # join with comma
|
||||
lib.concatStringsSep "," (map (generators.mkValueStringDefault { }) v)
|
||||
else
|
||||
generators.mkValueStringDefault { } v;
|
||||
mkKeyValue = generators.mkKeyValueDefault { inherit mkValueString; } " = ";
|
||||
in
|
||||
joinCfg [
|
||||
(generators.toKeyValue { inherit mkKeyValue; } global)
|
||||
(generators.toINI { inherit mkKeyValue; } local)
|
||||
];
|
||||
|
||||
mkINI = conf: if lib.isString conf then conf else toINI conf;
|
||||
|
||||
mkStyleset = attrsets.mapAttrs' (
|
||||
k: v:
|
||||
let
|
||||
value = if lib.isString v then v else toINI { global = v; };
|
||||
in
|
||||
{
|
||||
name = "${configDir}/stylesets/${k}";
|
||||
value.text = joinCfg [
|
||||
header
|
||||
value
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
mkTemplates = attrsets.mapAttrs' (
|
||||
k: v: {
|
||||
name = "${configDir}/templates/${k}";
|
||||
value.text = v;
|
||||
}
|
||||
);
|
||||
|
||||
primaryAccount = attrsets.filterAttrs (_: v: v.primary) aerc-accounts;
|
||||
otherAccounts = attrsets.filterAttrs (_: v: !v.primary) aerc-accounts;
|
||||
|
||||
primaryAccountAccounts = mapAttrs accounts.mkAccount primaryAccount;
|
||||
|
||||
accountsExtraAccounts = mapAttrs accounts.mkAccount otherAccounts;
|
||||
|
||||
accountsExtraConfig = mapAttrs accounts.mkAccountConfig aerc-accounts;
|
||||
|
||||
accountsExtraBinds = mapAttrs accounts.mkAccountBinds aerc-accounts;
|
||||
|
||||
joinContextual = contextual: joinCfg (map mkINI (lib.attrValues contextual));
|
||||
|
||||
isRecursivelyEmpty =
|
||||
x:
|
||||
if lib.isAttrs x then lib.all (x: x == { } || isRecursivelyEmpty x) (lib.attrValues x) else false;
|
||||
|
||||
genAccountsConf = (
|
||||
(cfg.extraAccounts != "" && cfg.extraAccounts != { })
|
||||
|| !(isRecursivelyEmpty accountsExtraAccounts)
|
||||
|| !(isRecursivelyEmpty primaryAccountAccounts)
|
||||
);
|
||||
|
||||
genAercConf = (
|
||||
(cfg.extraConfig != "" && cfg.extraConfig != { }) || !(isRecursivelyEmpty accountsExtraConfig)
|
||||
);
|
||||
|
||||
genBindsConf = (
|
||||
(cfg.extraBinds != "" && cfg.extraBinds != { }) || !(isRecursivelyEmpty accountsExtraBinds)
|
||||
);
|
||||
|
||||
header = ''
|
||||
# Generated by Home Manager.
|
||||
'';
|
||||
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
warnings =
|
||||
if genAccountsConf && (cfg.extraConfig.general.unsafe-accounts-conf or false) == false then
|
||||
[
|
||||
''
|
||||
aerc: `programs.aerc.enable` is set, but `...extraConfig.general.unsafe-accounts-conf` is set to false or unset.
|
||||
This will prevent aerc from starting; see `unsafe-accounts-conf` in the man page aerc-config(5):
|
||||
> By default, the file permissions of accounts.conf must be restrictive and only allow reading by the file owner (0600).
|
||||
> Set this option to true to ignore this permission check. Use this with care as it may expose your credentials.
|
||||
These permissions are not possible with home-manager, since the generated file is in the nix-store (permissions 0444).
|
||||
Therefore, please set `programs.aerc.extraConfig.general.unsafe-accounts-conf = true`.
|
||||
This option is safe; if `passwordCommand` is properly set, no credentials will be written to the nix store.
|
||||
''
|
||||
]
|
||||
else
|
||||
[ ];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
extraConfigSections = (
|
||||
lib.unique (lib.flatten (lib.mapAttrsToList (_: v: lib.attrNames v.aerc.extraConfig) aerc-accounts))
|
||||
);
|
||||
in
|
||||
extraConfigSections == [ ] || extraConfigSections == [ "ui" ];
|
||||
message = ''
|
||||
Only the ui section of $XDG_CONFIG_HOME/aerc.conf supports contextual (per-account) configuration.
|
||||
Please configure it with accounts.email.accounts._.aerc.extraConfig.ui and move any other
|
||||
configuration to programs.aerc.extraConfig.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
mkINI = conf: if lib.isString conf then conf else toINI conf;
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
mkStyleset = attrsets.mapAttrs' (k: v:
|
||||
let value = if lib.isString v then v else toINI { global = v; };
|
||||
in {
|
||||
name = "${configDir}/stylesets/${k}";
|
||||
value.text = joinCfg [ header value ];
|
||||
});
|
||||
home.file =
|
||||
{
|
||||
"${configDir}/accounts.conf" = mkIf genAccountsConf {
|
||||
text = joinCfg [
|
||||
header
|
||||
(mkINI cfg.extraAccounts)
|
||||
(mkINI primaryAccountAccounts)
|
||||
(mkINI accountsExtraAccounts)
|
||||
];
|
||||
};
|
||||
|
||||
mkTemplates = attrsets.mapAttrs' (k: v: {
|
||||
name = "${configDir}/templates/${k}";
|
||||
value.text = v;
|
||||
});
|
||||
"${configDir}/aerc.conf" = mkIf genAercConf {
|
||||
text = joinCfg [
|
||||
header
|
||||
(mkINI cfg.extraConfig)
|
||||
(joinContextual accountsExtraConfig)
|
||||
];
|
||||
};
|
||||
|
||||
primaryAccount = attrsets.filterAttrs (_: v: v.primary) aerc-accounts;
|
||||
otherAccounts = attrsets.filterAttrs (_: v: !v.primary) aerc-accounts;
|
||||
|
||||
primaryAccountAccounts = mapAttrs accounts.mkAccount primaryAccount;
|
||||
|
||||
accountsExtraAccounts = mapAttrs accounts.mkAccount otherAccounts;
|
||||
|
||||
accountsExtraConfig = mapAttrs accounts.mkAccountConfig aerc-accounts;
|
||||
|
||||
accountsExtraBinds = mapAttrs accounts.mkAccountBinds aerc-accounts;
|
||||
|
||||
joinContextual = contextual:
|
||||
joinCfg (map mkINI (lib.attrValues contextual));
|
||||
|
||||
isRecursivelyEmpty = x:
|
||||
if lib.isAttrs x then
|
||||
lib.all (x: x == { } || isRecursivelyEmpty x) (lib.attrValues x)
|
||||
else
|
||||
false;
|
||||
|
||||
genAccountsConf = ((cfg.extraAccounts != "" && cfg.extraAccounts != { })
|
||||
|| !(isRecursivelyEmpty accountsExtraAccounts)
|
||||
|| !(isRecursivelyEmpty primaryAccountAccounts));
|
||||
|
||||
genAercConf = ((cfg.extraConfig != "" && cfg.extraConfig != { })
|
||||
|| !(isRecursivelyEmpty accountsExtraConfig));
|
||||
|
||||
genBindsConf = ((cfg.extraBinds != "" && cfg.extraBinds != { })
|
||||
|| !(isRecursivelyEmpty accountsExtraBinds));
|
||||
|
||||
header = ''
|
||||
# Generated by Home Manager.
|
||||
'';
|
||||
|
||||
in mkIf cfg.enable {
|
||||
warnings = if genAccountsConf
|
||||
&& (cfg.extraConfig.general.unsafe-accounts-conf or false) == false then [''
|
||||
aerc: `programs.aerc.enable` is set, but `...extraConfig.general.unsafe-accounts-conf` is set to false or unset.
|
||||
This will prevent aerc from starting; see `unsafe-accounts-conf` in the man page aerc-config(5):
|
||||
> By default, the file permissions of accounts.conf must be restrictive and only allow reading by the file owner (0600).
|
||||
> Set this option to true to ignore this permission check. Use this with care as it may expose your credentials.
|
||||
These permissions are not possible with home-manager, since the generated file is in the nix-store (permissions 0444).
|
||||
Therefore, please set `programs.aerc.extraConfig.general.unsafe-accounts-conf = true`.
|
||||
This option is safe; if `passwordCommand` is properly set, no credentials will be written to the nix store.
|
||||
''] else
|
||||
[ ];
|
||||
|
||||
assertions = [{
|
||||
assertion = let
|
||||
extraConfigSections = (lib.unique (lib.flatten
|
||||
(lib.mapAttrsToList (_: v: lib.attrNames v.aerc.extraConfig)
|
||||
aerc-accounts)));
|
||||
in extraConfigSections == [ ] || extraConfigSections == [ "ui" ];
|
||||
message = ''
|
||||
Only the ui section of $XDG_CONFIG_HOME/aerc.conf supports contextual (per-account) configuration.
|
||||
Please configure it with accounts.email.accounts._.aerc.extraConfig.ui and move any other
|
||||
configuration to programs.aerc.extraConfig.
|
||||
'';
|
||||
}];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file = {
|
||||
"${configDir}/accounts.conf" = mkIf genAccountsConf {
|
||||
text = joinCfg [
|
||||
header
|
||||
(mkINI cfg.extraAccounts)
|
||||
(mkINI primaryAccountAccounts)
|
||||
(mkINI accountsExtraAccounts)
|
||||
];
|
||||
};
|
||||
|
||||
"${configDir}/aerc.conf" = mkIf genAercConf {
|
||||
text = joinCfg [
|
||||
header
|
||||
(mkINI cfg.extraConfig)
|
||||
(joinContextual accountsExtraConfig)
|
||||
];
|
||||
};
|
||||
|
||||
"${configDir}/binds.conf" = mkIf genBindsConf {
|
||||
text = joinCfg [
|
||||
header
|
||||
(mkINI cfg.extraBinds)
|
||||
(joinContextual accountsExtraBinds)
|
||||
];
|
||||
};
|
||||
} // (mkStyleset cfg.stylesets) // (mkTemplates cfg.templates);
|
||||
};
|
||||
"${configDir}/binds.conf" = mkIf genBindsConf {
|
||||
text = joinCfg [
|
||||
header
|
||||
(mkINI cfg.extraBinds)
|
||||
(joinContextual accountsExtraBinds)
|
||||
];
|
||||
};
|
||||
}
|
||||
// (mkStyleset cfg.stylesets)
|
||||
// (mkTemplates cfg.templates);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
cfg = config.programs.aerospace;
|
||||
|
|
@ -6,22 +11,29 @@ let
|
|||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
# filterAttrsRecursive supporting lists, as well.
|
||||
filterListAndAttrsRecursive = pred: set:
|
||||
lib.listToAttrs (lib.concatMap (name:
|
||||
let v = set.${name};
|
||||
in if pred v then
|
||||
[
|
||||
(lib.nameValuePair name (if lib.isAttrs v then
|
||||
filterListAndAttrsRecursive pred v
|
||||
else if lib.isList v then
|
||||
(map (i:
|
||||
if lib.isAttrs i then filterListAndAttrsRecursive pred i else i)
|
||||
(lib.filter pred v))
|
||||
else
|
||||
v))
|
||||
]
|
||||
else
|
||||
[ ]) (lib.attrNames set));
|
||||
filterListAndAttrsRecursive =
|
||||
pred: set:
|
||||
lib.listToAttrs (
|
||||
lib.concatMap (
|
||||
name:
|
||||
let
|
||||
v = set.${name};
|
||||
in
|
||||
if pred v then
|
||||
[
|
||||
(lib.nameValuePair name (
|
||||
if lib.isAttrs v then
|
||||
filterListAndAttrsRecursive pred v
|
||||
else if lib.isList v then
|
||||
(map (i: if lib.isAttrs i then filterListAndAttrsRecursive pred i else i) (lib.filter pred v))
|
||||
else
|
||||
v
|
||||
))
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
) (lib.attrNames set)
|
||||
);
|
||||
filterNulls = filterListAndAttrsRecursive (v: v != null);
|
||||
|
||||
# Turns
|
||||
|
|
@ -30,16 +42,22 @@ let
|
|||
# {"if.foo" = "xxx"; "if.bar" = "yyy"}
|
||||
# so that the correct TOML is generated for the
|
||||
# on-window-detected table.
|
||||
flattenConditions = attrs:
|
||||
let conditions = attrs."if" or { };
|
||||
in builtins.removeAttrs attrs [ "if" ]
|
||||
// lib.concatMapAttrs (n: v: { "if.${n}" = v; }) conditions;
|
||||
flattenConditions =
|
||||
attrs:
|
||||
let
|
||||
conditions = attrs."if" or { };
|
||||
in
|
||||
builtins.removeAttrs attrs [ "if" ] // lib.concatMapAttrs (n: v: { "if.${n}" = v; }) conditions;
|
||||
|
||||
flattenOnWindowDetected = cfg:
|
||||
let owd = cfg.on-window-detected or [ ];
|
||||
in cfg // { on-window-detected = map flattenConditions owd; };
|
||||
flattenOnWindowDetected =
|
||||
cfg:
|
||||
let
|
||||
owd = cfg.on-window-detected or [ ];
|
||||
in
|
||||
cfg // { on-window-detected = map flattenConditions owd; };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ damidoug ];
|
||||
|
||||
options.programs.aerospace = {
|
||||
|
|
@ -76,102 +94,122 @@ in {
|
|||
enable-normalization-flatten-containers = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description =
|
||||
''Containers that have only one child are "flattened".'';
|
||||
description = ''Containers that have only one child are "flattened".'';
|
||||
};
|
||||
enable-normalization-opposite-orientation-for-nested-containers = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Containers that nest into each other must have opposite orientations.";
|
||||
};
|
||||
enable-normalization-opposite-orientation-for-nested-containers =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description =
|
||||
"Containers that nest into each other must have opposite orientations.";
|
||||
};
|
||||
accordion-padding = mkOption {
|
||||
type = types.int;
|
||||
default = 30;
|
||||
description = "Padding between windows in an accordion container.";
|
||||
};
|
||||
default-root-container-layout = mkOption {
|
||||
type = types.enum [ "tiles" "accordion" ];
|
||||
type = types.enum [
|
||||
"tiles"
|
||||
"accordion"
|
||||
];
|
||||
default = "tiles";
|
||||
description = "Default layout for the root container.";
|
||||
};
|
||||
default-root-container-orientation = mkOption {
|
||||
type = types.enum [ "horizontal" "vertical" "auto" ];
|
||||
type = types.enum [
|
||||
"horizontal"
|
||||
"vertical"
|
||||
"auto"
|
||||
];
|
||||
default = "auto";
|
||||
description = "Default orientation for the root container.";
|
||||
};
|
||||
on-window-detected = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
"if" = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
app-id = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "The application ID to match (optional).";
|
||||
};
|
||||
workspace = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "The workspace name to match (optional).";
|
||||
};
|
||||
window-title-regex-substring = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description =
|
||||
"Substring to match in the window title (optional).";
|
||||
};
|
||||
app-name-regex-substring = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description =
|
||||
"Regex substring to match the app name (optional).";
|
||||
};
|
||||
during-aerospace-startup = mkOption {
|
||||
type = with types; nullOr bool;
|
||||
default = null;
|
||||
description =
|
||||
"Whether to match during aerospace startup (optional).";
|
||||
type = types.listOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
"if" = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
app-id = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "The application ID to match (optional).";
|
||||
};
|
||||
workspace = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "The workspace name to match (optional).";
|
||||
};
|
||||
window-title-regex-substring = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "Substring to match in the window title (optional).";
|
||||
};
|
||||
app-name-regex-substring = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = "Regex substring to match the app name (optional).";
|
||||
};
|
||||
during-aerospace-startup = mkOption {
|
||||
type = with types; nullOr bool;
|
||||
default = null;
|
||||
description = "Whether to match during aerospace startup (optional).";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Conditions for detecting a window.";
|
||||
};
|
||||
check-further-callbacks = mkOption {
|
||||
type = with types; nullOr bool;
|
||||
default = null;
|
||||
description = "Whether to check further callbacks after this rule (optional).";
|
||||
};
|
||||
run = mkOption {
|
||||
type =
|
||||
with types;
|
||||
oneOf [
|
||||
str
|
||||
(listOf str)
|
||||
];
|
||||
example = [
|
||||
"move-node-to-workspace m"
|
||||
"resize-node"
|
||||
];
|
||||
description = "Commands to execute when the conditions match (required).";
|
||||
};
|
||||
default = { };
|
||||
description = "Conditions for detecting a window.";
|
||||
};
|
||||
check-further-callbacks = mkOption {
|
||||
type = with types; nullOr bool;
|
||||
default = null;
|
||||
description =
|
||||
"Whether to check further callbacks after this rule (optional).";
|
||||
};
|
||||
run = mkOption {
|
||||
type = with types; oneOf [ str (listOf str) ];
|
||||
example = [ "move-node-to-workspace m" "resize-node" ];
|
||||
description =
|
||||
"Commands to execute when the conditions match (required).";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
example = [{
|
||||
"if" = {
|
||||
app-id = "Another.Cool.App";
|
||||
workspace = "cool-workspace";
|
||||
window-title-regex-substring = "Title";
|
||||
app-name-regex-substring = "CoolApp";
|
||||
during-aerospace-startup = false;
|
||||
};
|
||||
check-further-callbacks = false;
|
||||
run = [ "move-node-to-workspace m" "resize-node" ];
|
||||
}];
|
||||
description =
|
||||
"Commands to run every time a new window is detected with optional conditions.";
|
||||
example = [
|
||||
{
|
||||
"if" = {
|
||||
app-id = "Another.Cool.App";
|
||||
workspace = "cool-workspace";
|
||||
window-title-regex-substring = "Title";
|
||||
app-name-regex-substring = "CoolApp";
|
||||
during-aerospace-startup = false;
|
||||
};
|
||||
check-further-callbacks = false;
|
||||
run = [
|
||||
"move-node-to-workspace m"
|
||||
"resize-node"
|
||||
];
|
||||
}
|
||||
];
|
||||
description = "Commands to run every time a new window is detected with optional conditions.";
|
||||
};
|
||||
workspace-to-monitor-force-assignment = mkOption {
|
||||
type = with types;
|
||||
nullOr (attrsOf (oneOf [ int str (listOf str) ]));
|
||||
type =
|
||||
with types;
|
||||
nullOr (
|
||||
attrsOf (oneOf [
|
||||
int
|
||||
str
|
||||
(listOf str)
|
||||
])
|
||||
);
|
||||
default = null;
|
||||
description = ''
|
||||
Map workspaces to specific monitors.
|
||||
|
|
@ -182,17 +220,18 @@ in {
|
|||
"2" = "main"; # Main monitor.
|
||||
"3" = "secondary"; # Secondary monitor (non-main).
|
||||
"4" = "built-in"; # Built-in display.
|
||||
"5" =
|
||||
"^built-in retina display$"; # Regex for the built-in retina display.
|
||||
"6" = [ "secondary" "dell" ]; # Match first pattern in the list.
|
||||
"5" = "^built-in retina display$"; # Regex for the built-in retina display.
|
||||
"6" = [
|
||||
"secondary"
|
||||
"dell"
|
||||
]; # Match first pattern in the list.
|
||||
};
|
||||
};
|
||||
on-focus-changed = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
example = [ "move-mouse monitor-lazy-center" ];
|
||||
description =
|
||||
"Commands to run every time focused window or workspace changes.";
|
||||
description = "Commands to run every time focused window or workspace changes.";
|
||||
};
|
||||
on-focused-monitor-changed = mkOption {
|
||||
type = with types; listOf str;
|
||||
|
|
@ -210,7 +249,10 @@ in {
|
|||
description = "Commands to run every time workspace changes.";
|
||||
};
|
||||
key-mapping.preset = mkOption {
|
||||
type = types.enum [ "qwerty" "dvorak" ];
|
||||
type = types.enum [
|
||||
"qwerty"
|
||||
"dvorak"
|
||||
];
|
||||
default = "qwerty";
|
||||
description = "Keymapping preset.";
|
||||
};
|
||||
|
|
@ -243,15 +285,14 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.aerospace" pkgs
|
||||
lib.platforms.darwin)
|
||||
(lib.hm.assertions.assertPlatform "programs.aerospace" pkgs lib.platforms.darwin)
|
||||
];
|
||||
|
||||
home = {
|
||||
packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
file.".config/aerospace/aerospace.toml".source =
|
||||
tomlFormat.generate "aerospace"
|
||||
(filterNulls (flattenOnWindowDetected cfg.userSettings));
|
||||
file.".config/aerospace/aerospace.toml".source = tomlFormat.generate "aerospace" (
|
||||
filterNulls (flattenOnWindowDetected cfg.userSettings)
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.afew;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.afew;
|
||||
in
|
||||
{
|
||||
options.programs.afew = {
|
||||
enable = lib.mkEnableOption "the afew initial tagging script for Notmuch";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.alacritty;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.alacritty = {
|
||||
enable = lib.mkEnableOption "Alacritty";
|
||||
|
|
@ -56,40 +62,45 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [{
|
||||
# If using the theme option, ensure that theme exists in the
|
||||
# alacritty-theme package.
|
||||
assertion = let
|
||||
available = lib.pipe "${pkgs.alacritty-theme}/share/alacritty-theme" [
|
||||
builtins.readDir
|
||||
(lib.filterAttrs
|
||||
(name: type: type == "regular" && lib.hasSuffix ".toml" name))
|
||||
lib.attrNames
|
||||
(lib.map (lib.removeSuffix ".toml"))
|
||||
];
|
||||
in cfg.theme == null || (builtins.elem cfg.theme available);
|
||||
message = "The alacritty theme '${cfg.theme}' does not exist.";
|
||||
}];
|
||||
assertions = [
|
||||
{
|
||||
# If using the theme option, ensure that theme exists in the
|
||||
# alacritty-theme package.
|
||||
assertion =
|
||||
let
|
||||
available = lib.pipe "${pkgs.alacritty-theme}/share/alacritty-theme" [
|
||||
builtins.readDir
|
||||
(lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".toml" name))
|
||||
lib.attrNames
|
||||
(lib.map (lib.removeSuffix ".toml"))
|
||||
];
|
||||
in
|
||||
cfg.theme == null || (builtins.elem cfg.theme available);
|
||||
message = "The alacritty theme '${cfg.theme}' does not exist.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.alacritty.settings = let
|
||||
theme = "${pkgs.alacritty-theme}/share/alacritty-theme/${cfg.theme}.toml";
|
||||
in lib.mkIf (cfg.theme != null) {
|
||||
general.import =
|
||||
lib.mkIf (lib.versionAtLeast cfg.package.version "0.14") [ theme ];
|
||||
import = lib.mkIf (lib.versionOlder cfg.package.version "0.14") [ theme ];
|
||||
};
|
||||
programs.alacritty.settings =
|
||||
let
|
||||
theme = "${pkgs.alacritty-theme}/share/alacritty-theme/${cfg.theme}.toml";
|
||||
in
|
||||
lib.mkIf (cfg.theme != null) {
|
||||
general.import = lib.mkIf (lib.versionAtLeast cfg.package.version "0.14") [ theme ];
|
||||
import = lib.mkIf (lib.versionOlder cfg.package.version "0.14") [ theme ];
|
||||
};
|
||||
|
||||
xdg.configFile."alacritty/alacritty.toml" = lib.mkIf (cfg.settings != { }) {
|
||||
source = (tomlFormat.generate "alacritty.toml" cfg.settings).overrideAttrs
|
||||
(finalAttrs: prevAttrs: {
|
||||
source = (tomlFormat.generate "alacritty.toml" cfg.settings).overrideAttrs (
|
||||
finalAttrs: prevAttrs: {
|
||||
buildCommand = lib.concatStringsSep "\n" [
|
||||
prevAttrs.buildCommand
|
||||
# TODO: why is this needed? Is there a better way to retain escape sequences?
|
||||
"substituteInPlace $out --replace-quiet '\\\\' '\\'"
|
||||
];
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
pkgs:
|
||||
{ config, lib, ... }:
|
||||
let inherit (lib) mkOption types;
|
||||
in {
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
options.alot = {
|
||||
sendMailCommand = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
|
|
@ -16,11 +18,9 @@ in {
|
|||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
type = "shellcommand";
|
||||
command =
|
||||
"'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
|
||||
regexp = "'\\[?{" + ''
|
||||
"name": "(?P<name>.*)", "address": "(?P<email>.+)", "name-addr": ".*"''
|
||||
+ "}[,\\]]?'";
|
||||
command = "'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
|
||||
regexp =
|
||||
"'\\[?{" + ''"name": "(?P<name>.*)", "address": "(?P<email>.+)", "name-addr": ".*"'' + "}[,\\]]?'";
|
||||
shellcommand_external_filtering = "False";
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
|
|
@ -48,9 +48,8 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf config.notmuch.enable {
|
||||
alot.sendMailCommand = lib.mkOptionDefault (if config.msmtp.enable then
|
||||
"msmtpq --read-envelope-from --read-recipients"
|
||||
else
|
||||
null);
|
||||
alot.sendMailCommand = lib.mkOptionDefault (
|
||||
if config.msmtp.enable then "msmtpq --read-envelope-from --read-recipients" else null
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,35 @@
|
|||
# alot config loader is sensitive to leading space !
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
concatStringsSep mapAttrsToList mkOption optionalAttrs optionalString types;
|
||||
concatStringsSep
|
||||
mapAttrsToList
|
||||
mkOption
|
||||
optionalAttrs
|
||||
optionalString
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.alot;
|
||||
|
||||
enabledAccounts = lib.filter (a: a.notmuch.enable)
|
||||
(lib.attrValues config.accounts.email.accounts);
|
||||
enabledAccounts = lib.filter (a: a.notmuch.enable) (lib.attrValues config.accounts.email.accounts);
|
||||
|
||||
# sorted: primary first
|
||||
alotAccounts = lib.sort (a: b: !(a.primary -> b.primary)) enabledAccounts;
|
||||
|
||||
boolStr = v: if v then "True" else "False";
|
||||
|
||||
mkKeyValue = key: value:
|
||||
let value' = if lib.isBool value then boolStr value else toString value;
|
||||
in "${key} = ${value'}";
|
||||
mkKeyValue =
|
||||
key: value:
|
||||
let
|
||||
value' = if lib.isBool value then boolStr value else toString value;
|
||||
in
|
||||
"${key} = ${value'}";
|
||||
|
||||
mk2ndLevelSectionName = name: "[" + name + "]";
|
||||
|
||||
|
|
@ -59,67 +72,95 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
accountStr = account:
|
||||
accountStr =
|
||||
account:
|
||||
let
|
||||
inherit (account)
|
||||
alot maildir name address realName folders aliases gpg signature;
|
||||
in concatStringsSep "\n" ([ "[[${name}]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) ({
|
||||
address = address;
|
||||
realname = realName;
|
||||
sendmail_command =
|
||||
optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
|
||||
} // optionalAttrs (folders.sent != null) {
|
||||
sent_box = "maildir" + "://" + maildir.absPath + "/" + folders.sent;
|
||||
} // optionalAttrs (folders.drafts != null) {
|
||||
draft_box = "maildir" + "://" + maildir.absPath + "/" + folders.drafts;
|
||||
} // optionalAttrs (aliases != [ ]) {
|
||||
aliases = concatStringsSep "," aliases;
|
||||
} // optionalAttrs (gpg != null) {
|
||||
gpg_key = gpg.key;
|
||||
encrypt_by_default = if gpg.encryptByDefault then "all" else "none";
|
||||
sign_by_default = boolStr gpg.signByDefault;
|
||||
} // optionalAttrs (signature.showSignature != "none") {
|
||||
signature = pkgs.writeText "signature.txt" signature.text;
|
||||
signature_as_attachment = boolStr (signature.showSignature == "attach");
|
||||
}) ++ [ alot.extraConfig ] ++ [ "[[[abook]]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion);
|
||||
alot
|
||||
maildir
|
||||
name
|
||||
address
|
||||
realName
|
||||
folders
|
||||
aliases
|
||||
gpg
|
||||
signature
|
||||
;
|
||||
in
|
||||
concatStringsSep "\n" (
|
||||
[ "[[${name}]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) (
|
||||
{
|
||||
address = address;
|
||||
realname = realName;
|
||||
sendmail_command = optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
|
||||
}
|
||||
// optionalAttrs (folders.sent != null) {
|
||||
sent_box = "maildir" + "://" + maildir.absPath + "/" + folders.sent;
|
||||
}
|
||||
// optionalAttrs (folders.drafts != null) {
|
||||
draft_box = "maildir" + "://" + maildir.absPath + "/" + folders.drafts;
|
||||
}
|
||||
// optionalAttrs (aliases != [ ]) {
|
||||
aliases = concatStringsSep "," aliases;
|
||||
}
|
||||
// optionalAttrs (gpg != null) {
|
||||
gpg_key = gpg.key;
|
||||
encrypt_by_default = if gpg.encryptByDefault then "all" else "none";
|
||||
sign_by_default = boolStr gpg.signByDefault;
|
||||
}
|
||||
// optionalAttrs (signature.showSignature != "none") {
|
||||
signature = pkgs.writeText "signature.txt" signature.text;
|
||||
signature_as_attachment = boolStr (signature.showSignature == "attach");
|
||||
}
|
||||
)
|
||||
++ [ alot.extraConfig ]
|
||||
++ [ "[[[abook]]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion
|
||||
);
|
||||
|
||||
configFile = let
|
||||
bindingsToStr = attrSet:
|
||||
concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${v}") attrSet);
|
||||
in ''
|
||||
# Generated by Home Manager.
|
||||
# See http://alot.readthedocs.io/en/latest/configuration/config_options.html
|
||||
configFile =
|
||||
let
|
||||
bindingsToStr = attrSet: concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${v}") attrSet);
|
||||
in
|
||||
''
|
||||
# Generated by Home Manager.
|
||||
# See http://alot.readthedocs.io/en/latest/configuration/config_options.html
|
||||
|
||||
${lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings}
|
||||
${cfg.extraConfig}
|
||||
[tags]
|
||||
'' + (let
|
||||
submoduleToAttrs = m:
|
||||
lib.filterAttrs (name: v: name != "_module" && v != null) m;
|
||||
in lib.generators.toINI { mkSectionName = mk2ndLevelSectionName; }
|
||||
(lib.mapAttrs (name: x: submoduleToAttrs x) cfg.tags)) + ''
|
||||
[bindings]
|
||||
${bindingsToStr cfg.bindings.global}
|
||||
${lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings}
|
||||
${cfg.extraConfig}
|
||||
[tags]
|
||||
''
|
||||
+ (
|
||||
let
|
||||
submoduleToAttrs = m: lib.filterAttrs (name: v: name != "_module" && v != null) m;
|
||||
in
|
||||
lib.generators.toINI { mkSectionName = mk2ndLevelSectionName; } (
|
||||
lib.mapAttrs (name: x: submoduleToAttrs x) cfg.tags
|
||||
)
|
||||
)
|
||||
+ ''
|
||||
[bindings]
|
||||
${bindingsToStr cfg.bindings.global}
|
||||
|
||||
[[bufferlist]]
|
||||
${bindingsToStr cfg.bindings.bufferlist}
|
||||
[[search]]
|
||||
${bindingsToStr cfg.bindings.search}
|
||||
[[envelope]]
|
||||
${bindingsToStr cfg.bindings.envelope}
|
||||
[[taglist]]
|
||||
${bindingsToStr cfg.bindings.taglist}
|
||||
[[thread]]
|
||||
${bindingsToStr cfg.bindings.thread}
|
||||
[[bufferlist]]
|
||||
${bindingsToStr cfg.bindings.bufferlist}
|
||||
[[search]]
|
||||
${bindingsToStr cfg.bindings.search}
|
||||
[[envelope]]
|
||||
${bindingsToStr cfg.bindings.envelope}
|
||||
[[taglist]]
|
||||
${bindingsToStr cfg.bindings.taglist}
|
||||
[[thread]]
|
||||
${bindingsToStr cfg.bindings.thread}
|
||||
|
||||
[accounts]
|
||||
[accounts]
|
||||
|
||||
${lib.concatStringsSep "\n\n" (map accountStr alotAccounts)}
|
||||
'';
|
||||
${lib.concatStringsSep "\n\n" (map accountStr alotAccounts)}
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.alot = {
|
||||
enable = mkOption {
|
||||
|
|
@ -196,9 +237,12 @@ in {
|
|||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types;
|
||||
let primitive = either (either (either str int) bool) float;
|
||||
in attrsOf primitive;
|
||||
type =
|
||||
with types;
|
||||
let
|
||||
primitive = either (either (either str int) bool) float;
|
||||
in
|
||||
attrsOf primitive;
|
||||
default = {
|
||||
initial_command = "search tag:inbox AND NOT tag:killed";
|
||||
auto_remove_unread = true;
|
||||
|
|
@ -237,9 +281,11 @@ in {
|
|||
xdg.configFile."alot/config".text = configFile;
|
||||
|
||||
xdg.configFile."alot/hooks.py" = lib.mkIf (cfg.hooks != "") {
|
||||
text = ''
|
||||
# Generated by Home Manager.
|
||||
'' + cfg.hooks;
|
||||
text =
|
||||
''
|
||||
# Generated by Home Manager.
|
||||
''
|
||||
+ cfg.hooks;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,25 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.zsh.antidote;
|
||||
|
||||
zPluginStr = (pluginNames:
|
||||
lib.optionalString (pluginNames != [ ]) "${lib.concatStrings (map (name: ''
|
||||
${name}
|
||||
'') pluginNames)}");
|
||||
zPluginStr = (
|
||||
pluginNames:
|
||||
lib.optionalString (pluginNames != [ ])
|
||||
"${lib.concatStrings (
|
||||
map (name: ''
|
||||
${name}
|
||||
'') pluginNames
|
||||
)}"
|
||||
);
|
||||
|
||||
parseHashId = path:
|
||||
lib.elemAt (builtins.match "${builtins.storeDir}/([a-zA-Z0-9]+)-.*" path) 0;
|
||||
in {
|
||||
parseHashId = path: lib.elemAt (builtins.match "${builtins.storeDir}/([a-zA-Z0-9]+)-.*" path) 0;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.hitsmaxft ];
|
||||
|
||||
options.programs.zsh.antidote = {
|
||||
|
|
@ -30,25 +40,26 @@ in {
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.zsh.initContent = let
|
||||
configFiles = pkgs.runCommand "hm_antidote-files" { } ''
|
||||
echo "${zPluginStr cfg.plugins}" > $out
|
||||
'';
|
||||
hashId = parseHashId "${configFiles}";
|
||||
in (lib.mkOrder 550 ''
|
||||
## home-manager/antidote begin :
|
||||
source ${cfg.package}/share/antidote/antidote.zsh
|
||||
${lib.optionalString cfg.useFriendlyNames
|
||||
"zstyle ':antidote:bundle' use-friendly-names 'yes'"}
|
||||
programs.zsh.initContent =
|
||||
let
|
||||
configFiles = pkgs.runCommand "hm_antidote-files" { } ''
|
||||
echo "${zPluginStr cfg.plugins}" > $out
|
||||
'';
|
||||
hashId = parseHashId "${configFiles}";
|
||||
in
|
||||
(lib.mkOrder 550 ''
|
||||
## home-manager/antidote begin :
|
||||
source ${cfg.package}/share/antidote/antidote.zsh
|
||||
${lib.optionalString cfg.useFriendlyNames "zstyle ':antidote:bundle' use-friendly-names 'yes'"}
|
||||
|
||||
bundlefile=${configFiles}
|
||||
zstyle ':antidote:bundle' file $bundlefile
|
||||
staticfile=/tmp/tmp_hm_zsh_plugins.zsh-${hashId}
|
||||
zstyle ':antidote:static' file $staticfile
|
||||
bundlefile=${configFiles}
|
||||
zstyle ':antidote:bundle' file $bundlefile
|
||||
staticfile=/tmp/tmp_hm_zsh_plugins.zsh-${hashId}
|
||||
zstyle ':antidote:static' file $staticfile
|
||||
|
||||
antidote load $bundlefile $staticfile
|
||||
antidote load $bundlefile $staticfile
|
||||
|
||||
## home-manager/antidote end
|
||||
'');
|
||||
## home-manager/antidote end
|
||||
'');
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.aria2;
|
||||
|
||||
formatLine = n: v:
|
||||
formatLine =
|
||||
n: v:
|
||||
let
|
||||
formatValue = v:
|
||||
if builtins.isBool v then
|
||||
(if v then "true" else "false")
|
||||
else
|
||||
toString v;
|
||||
in "${n}=${formatValue v}";
|
||||
in {
|
||||
formatValue = v: if builtins.isBool v then (if v then "true" else "false") else toString v;
|
||||
in
|
||||
"${n}=${formatValue v}";
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.justinlovinger ];
|
||||
|
||||
options.programs.aria2 = {
|
||||
|
|
@ -19,7 +23,14 @@ in {
|
|||
package = lib.mkPackageOption pkgs "aria2" { nullable = true; };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ bool float int str ]);
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
float
|
||||
int
|
||||
str
|
||||
]);
|
||||
default = { };
|
||||
description = ''
|
||||
Options to add to {file}`aria2.conf` file.
|
||||
|
|
@ -50,8 +61,10 @@ in {
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."aria2/aria2.conf".text = lib.concatStringsSep "\n" ([ ]
|
||||
xdg.configFile."aria2/aria2.conf".text = lib.concatStringsSep "\n" (
|
||||
[ ]
|
||||
++ lib.mapAttrsToList formatLine cfg.settings
|
||||
++ lib.optional (cfg.extraConfig != "") cfg.extraConfig);
|
||||
++ lib.optional (cfg.extraConfig != "") cfg.extraConfig
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{ config, lib, ... }: {
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
options.astroid = {
|
||||
enable = lib.mkEnableOption "Astroid";
|
||||
|
||||
|
|
@ -14,7 +15,9 @@
|
|||
extraConfig = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.anything;
|
||||
default = { };
|
||||
example = { select_query = ""; };
|
||||
example = {
|
||||
select_query = "";
|
||||
};
|
||||
description = ''
|
||||
Extra settings to add to this astroid account configuration.
|
||||
'';
|
||||
|
|
@ -22,7 +25,8 @@
|
|||
};
|
||||
|
||||
config = lib.mkIf config.notmuch.enable {
|
||||
astroid.sendMailCommand = lib.mkIf config.msmtp.enable
|
||||
(lib.mkOptionDefault "msmtpq --read-envelope-from --read-recipients");
|
||||
astroid.sendMailCommand = lib.mkIf config.msmtp.enable (
|
||||
lib.mkOptionDefault "msmtpq --read-envelope-from --read-recipients"
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
||||
|
|
@ -6,12 +11,12 @@ let
|
|||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
astroidAccounts =
|
||||
lib.filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts;
|
||||
astroidAccounts = lib.filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts;
|
||||
|
||||
boolOpt = b: if b then "true" else "false";
|
||||
|
||||
accountAttr = account:
|
||||
accountAttr =
|
||||
account:
|
||||
with account;
|
||||
{
|
||||
email = address;
|
||||
|
|
@ -23,33 +28,38 @@ let
|
|||
save_sent = "true";
|
||||
save_sent_to = "${maildir.absPath}/${folders.sent}/cur/";
|
||||
select_query = "";
|
||||
} // lib.optionalAttrs (signature.showSignature != "none") {
|
||||
}
|
||||
// lib.optionalAttrs (signature.showSignature != "none") {
|
||||
signature_attach = boolOpt (signature.showSignature == "attach");
|
||||
signature_default_on = boolOpt (signature.showSignature != "none");
|
||||
signature_file = pkgs.writeText "signature.txt" signature.text;
|
||||
signature_file_markdown = "false";
|
||||
signature_separate = "true"; # prepends '--\n' to the signature
|
||||
} // lib.optionalAttrs (gpg != null) {
|
||||
}
|
||||
// lib.optionalAttrs (gpg != null) {
|
||||
always_gpg_sign = boolOpt gpg.signByDefault;
|
||||
gpgkey = gpg.key;
|
||||
} // astroid.extraConfig;
|
||||
}
|
||||
// astroid.extraConfig;
|
||||
|
||||
# See https://github.com/astroidmail/astroid/wiki/Configuration-Reference
|
||||
finalConfig = let
|
||||
template = lib.importJSON ./astroid-config-template.json;
|
||||
astroidConfig = lib.foldl' lib.recursiveUpdate template [
|
||||
{
|
||||
astroid.notmuch_config =
|
||||
"${config.xdg.configHome}/notmuch/default/config";
|
||||
accounts = lib.mapAttrs (n: accountAttr) astroidAccounts;
|
||||
crypto.gpg.path = "${pkgs.gnupg}/bin/gpg";
|
||||
}
|
||||
cfg.extraConfig
|
||||
cfg.externalEditor
|
||||
];
|
||||
in astroidConfig;
|
||||
finalConfig =
|
||||
let
|
||||
template = lib.importJSON ./astroid-config-template.json;
|
||||
astroidConfig = lib.foldl' lib.recursiveUpdate template [
|
||||
{
|
||||
astroid.notmuch_config = "${config.xdg.configHome}/notmuch/default/config";
|
||||
accounts = lib.mapAttrs (n: accountAttr) astroidAccounts;
|
||||
crypto.gpg.path = "${pkgs.gnupg}/bin/gpg";
|
||||
}
|
||||
cfg.extraConfig
|
||||
cfg.externalEditor
|
||||
];
|
||||
in
|
||||
astroidConfig;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.astroid = {
|
||||
enable = lib.mkEnableOption "Astroid";
|
||||
|
|
@ -69,15 +79,15 @@ in {
|
|||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
# Converts it into JSON that can be merged into the configuration.
|
||||
apply = cmd:
|
||||
apply =
|
||||
cmd:
|
||||
lib.optionalAttrs (cmd != null) {
|
||||
editor = {
|
||||
"external_editor" = "true";
|
||||
"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 = ''
|
||||
You can use the following variables:
|
||||
|
||||
|
|
@ -117,8 +127,7 @@ in {
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."astroid/config".source =
|
||||
jsonFormat.generate "astroid-config" finalConfig;
|
||||
xdg.configFile."astroid/config".source = jsonFormat.generate "astroid-config" finalConfig;
|
||||
|
||||
xdg.configFile."astroid/poll.sh" = lib.mkIf (cfg.pollScript != "") {
|
||||
executable = true;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.atuin;
|
||||
daemonCfg = cfg.daemon;
|
||||
|
|
@ -7,8 +12,12 @@ let
|
|||
|
||||
inherit (lib) mkIf mkOption types;
|
||||
inherit (pkgs.stdenv) isLinux isDarwin;
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ hawkw water-sucks ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
hawkw
|
||||
water-sucks
|
||||
];
|
||||
|
||||
options.programs.atuin = {
|
||||
enable = lib.mkEnableOption "atuin";
|
||||
|
|
@ -17,18 +26,15 @@ in {
|
|||
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption {
|
||||
inherit config;
|
||||
extraDescription =
|
||||
"If enabled, this will bind `ctrl-r` to open the Atuin history.";
|
||||
extraDescription = "If enabled, this will bind `ctrl-r` to open the Atuin history.";
|
||||
};
|
||||
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption {
|
||||
inherit config;
|
||||
extraDescription =
|
||||
"If enabled, this will bind the up-arrow key to open the Atuin history.";
|
||||
extraDescription = "If enabled, this will bind the up-arrow key to open the Atuin history.";
|
||||
};
|
||||
|
||||
enableNushellIntegration =
|
||||
lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption {
|
||||
inherit config;
|
||||
|
|
@ -41,21 +47,30 @@ in {
|
|||
flags = mkOption {
|
||||
default = [ ];
|
||||
type = types.listOf types.str;
|
||||
example = [ "--disable-up-arrow" "--disable-ctrl-r" ];
|
||||
example = [
|
||||
"--disable-up-arrow"
|
||||
"--disable-ctrl-r"
|
||||
];
|
||||
description = ''
|
||||
Flags to append to the shell hook.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types;
|
||||
type =
|
||||
with types;
|
||||
let
|
||||
prim = oneOf [ bool int str ];
|
||||
prim = oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
];
|
||||
primOrPrimAttrs = either prim (attrsOf prim);
|
||||
entry = either prim (listOf primOrPrimAttrs);
|
||||
entryOrAttrsOf = t: either entry (attrsOf t);
|
||||
entries = entryOrAttrsOf (entryOrAttrsOf entry);
|
||||
in attrsOf entries // { description = "Atuin configuration"; };
|
||||
in
|
||||
attrsOf entries // { description = "Atuin configuration"; };
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
|
|
@ -79,8 +94,15 @@ in {
|
|||
|
||||
logLevel = mkOption {
|
||||
default = null;
|
||||
type =
|
||||
types.nullOr (types.enum [ "trace" "debug" "info" "warn" "error" ]);
|
||||
type = types.nullOr (
|
||||
types.enum [
|
||||
"trace"
|
||||
"debug"
|
||||
"info"
|
||||
"warn"
|
||||
"error"
|
||||
]
|
||||
);
|
||||
description = ''
|
||||
Verbosity of Atuin daemon logging.
|
||||
'';
|
||||
|
|
@ -88,126 +110,145 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let flagsStr = lib.escapeShellArgs cfg.flags;
|
||||
in mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
# Always add the configured `atuin` package.
|
||||
home.packages = [ cfg.package ];
|
||||
config =
|
||||
let
|
||||
flagsStr = lib.escapeShellArgs cfg.flags;
|
||||
in
|
||||
mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
# Always add the configured `atuin` package.
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
# If there are user-provided settings, generate the config file.
|
||||
xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "atuin-config" cfg.settings;
|
||||
};
|
||||
# If there are user-provided settings, generate the config file.
|
||||
xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) {
|
||||
source = tomlFormat.generate "atuin-config" cfg.settings;
|
||||
};
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
|
||||
eval "$(${lib.getExe cfg.package} init bash ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
|
||||
eval "$(${lib.getExe cfg.package} init bash ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init fish ${flagsStr} | source
|
||||
'';
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init fish ${flagsStr} | source
|
||||
'';
|
||||
|
||||
programs.nushell = mkIf cfg.enableNushellIntegration {
|
||||
extraConfig = ''
|
||||
source ${
|
||||
pkgs.runCommand "atuin-nushell-config.nu" {
|
||||
nativeBuildInputs = [ pkgs.writableTmpDirAsHomeHook ];
|
||||
} ''
|
||||
${lib.getExe cfg.package} init nu ${flagsStr} >> "$out"
|
||||
''
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf daemonCfg.enable (lib.mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = lib.versionAtLeast cfg.package.version "18.2.0";
|
||||
message = ''
|
||||
The Atuin daemon requires at least version 18.2.0 or later.
|
||||
programs.nushell = mkIf cfg.enableNushellIntegration {
|
||||
extraConfig = ''
|
||||
source ${
|
||||
pkgs.runCommand "atuin-nushell-config.nu"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.writableTmpDirAsHomeHook ];
|
||||
}
|
||||
''
|
||||
${lib.getExe cfg.package} init nu ${flagsStr} >> "$out"
|
||||
''
|
||||
}
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = isLinux || isDarwin;
|
||||
message =
|
||||
"The Atuin daemon can only be configured on either Linux or macOS.";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
programs.atuin.settings = { daemon = { enabled = true; }; };
|
||||
}
|
||||
(mkIf isLinux {
|
||||
programs.atuin.settings = { daemon = { systemd_socket = true; }; };
|
||||
(mkIf daemonCfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = lib.versionAtLeast cfg.package.version "18.2.0";
|
||||
message = ''
|
||||
The Atuin daemon requires at least version 18.2.0 or later.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = isLinux || isDarwin;
|
||||
message = "The Atuin daemon can only be configured on either Linux or macOS.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.user.services.atuin-daemon = {
|
||||
Unit = {
|
||||
Description = "Atuin daemon";
|
||||
Requires = [ "atuin-daemon.socket" ];
|
||||
};
|
||||
Install = {
|
||||
Also = [ "atuin-daemon.socket" ];
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe cfg.package} daemon";
|
||||
Environment = lib.optionals (daemonCfg.logLevel != null)
|
||||
[ "ATUIN_LOG=${daemonCfg.logLevel}" ];
|
||||
Restart = "on-failure";
|
||||
RestartSteps = 3;
|
||||
RestartMaxDelaySec = 6;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.sockets.atuin-daemon = let
|
||||
socket_dir = if lib.versionAtLeast cfg.package.version "18.4.0" then
|
||||
"%t"
|
||||
else
|
||||
"%D/atuin";
|
||||
in {
|
||||
Unit = { Description = "Atuin daemon socket"; };
|
||||
Install = { WantedBy = [ "sockets.target" ]; };
|
||||
Socket = {
|
||||
ListenStream = "${socket_dir}/atuin.sock";
|
||||
SocketMode = "0600";
|
||||
RemoveOnStop = true;
|
||||
};
|
||||
};
|
||||
})
|
||||
(mkIf isDarwin {
|
||||
programs.atuin.settings = {
|
||||
daemon = {
|
||||
socket_path =
|
||||
lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock";
|
||||
};
|
||||
};
|
||||
|
||||
launchd.agents.atuin-daemon = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ "${lib.getExe cfg.package}" "daemon" ];
|
||||
EnvironmentVariables =
|
||||
lib.optionalAttrs (daemonCfg.logLevel != null) {
|
||||
ATUIN_LOG = daemonCfg.logLevel;
|
||||
programs.atuin.settings = {
|
||||
daemon = {
|
||||
enabled = true;
|
||||
};
|
||||
};
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Background";
|
||||
};
|
||||
};
|
||||
})
|
||||
]))
|
||||
]);
|
||||
}
|
||||
(mkIf isLinux {
|
||||
programs.atuin.settings = {
|
||||
daemon = {
|
||||
systemd_socket = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services.atuin-daemon = {
|
||||
Unit = {
|
||||
Description = "Atuin daemon";
|
||||
Requires = [ "atuin-daemon.socket" ];
|
||||
};
|
||||
Install = {
|
||||
Also = [ "atuin-daemon.socket" ];
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe cfg.package} daemon";
|
||||
Environment = lib.optionals (daemonCfg.logLevel != null) [ "ATUIN_LOG=${daemonCfg.logLevel}" ];
|
||||
Restart = "on-failure";
|
||||
RestartSteps = 3;
|
||||
RestartMaxDelaySec = 6;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.sockets.atuin-daemon =
|
||||
let
|
||||
socket_dir = if lib.versionAtLeast cfg.package.version "18.4.0" then "%t" else "%D/atuin";
|
||||
in
|
||||
{
|
||||
Unit = {
|
||||
Description = "Atuin daemon socket";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "sockets.target" ];
|
||||
};
|
||||
Socket = {
|
||||
ListenStream = "${socket_dir}/atuin.sock";
|
||||
SocketMode = "0600";
|
||||
RemoveOnStop = true;
|
||||
};
|
||||
};
|
||||
})
|
||||
(mkIf isDarwin {
|
||||
programs.atuin.settings = {
|
||||
daemon = {
|
||||
socket_path = lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock";
|
||||
};
|
||||
};
|
||||
|
||||
launchd.agents.atuin-daemon = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [
|
||||
"${lib.getExe cfg.package}"
|
||||
"daemon"
|
||||
];
|
||||
EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) {
|
||||
ATUIN_LOG = daemonCfg.logLevel;
|
||||
};
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Background";
|
||||
};
|
||||
};
|
||||
})
|
||||
]
|
||||
))
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.autojump;
|
||||
|
||||
inherit (lib) mkIf;
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.evanjs ];
|
||||
|
||||
options.programs.autojump = {
|
||||
|
|
@ -11,22 +17,21 @@ in {
|
|||
|
||||
package = lib.mkPackageOption pkgs "autojump" { };
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (lib.mkBefore ''
|
||||
. ${cfg.package}/share/autojump/autojump.bash
|
||||
'');
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
||||
lib.mkBefore ''
|
||||
. ${cfg.package}/share/autojump/autojump.bash
|
||||
''
|
||||
);
|
||||
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
. ${cfg.package}/share/autojump/autojump.zsh
|
||||
|
|
|
|||
|
|
@ -1,25 +1,49 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
literalExpression listToAttrs mapAttrs' mapAttrsToList mkIf mkOption
|
||||
optional types;
|
||||
literalExpression
|
||||
listToAttrs
|
||||
mapAttrs'
|
||||
mapAttrsToList
|
||||
mkIf
|
||||
mkOption
|
||||
optional
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.autorandr;
|
||||
|
||||
matrixOf = n: m: elemType:
|
||||
matrixOf =
|
||||
n: m: elemType:
|
||||
lib.mkOptionType rec {
|
||||
name = "matrixOf";
|
||||
description =
|
||||
"${toString n}×${toString m} matrix of ${elemType.description}s";
|
||||
check = xss:
|
||||
let listOfSize = l: xs: lib.isList xs && lib.length xs == l;
|
||||
in listOfSize n xss
|
||||
&& lib.all (xs: listOfSize m xs && lib.all elemType.check xs) xss;
|
||||
description = "${toString n}×${toString m} matrix of ${elemType.description}s";
|
||||
check =
|
||||
xss:
|
||||
let
|
||||
listOfSize = l: xs: lib.isList xs && lib.length xs == l;
|
||||
in
|
||||
listOfSize n xss && lib.all (xs: listOfSize m xs && lib.all elemType.check xs) xss;
|
||||
merge = lib.mergeOneOption;
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "*" "*" ]);
|
||||
getSubOptions =
|
||||
prefix:
|
||||
elemType.getSubOptions (
|
||||
prefix
|
||||
++ [
|
||||
"*"
|
||||
"*"
|
||||
]
|
||||
);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
|
||||
functor = (lib.defaultFunctor name) // { wrapped = elemType; };
|
||||
functor = (lib.defaultFunctor name) // {
|
||||
wrapped = elemType;
|
||||
};
|
||||
};
|
||||
|
||||
profileModule = types.submodule {
|
||||
|
|
@ -97,7 +121,14 @@ let
|
|||
};
|
||||
|
||||
rotate = mkOption {
|
||||
type = types.nullOr (types.enum [ "normal" "left" "right" "inverted" ]);
|
||||
type = types.nullOr (
|
||||
types.enum [
|
||||
"normal"
|
||||
"left"
|
||||
"right"
|
||||
"inverted"
|
||||
]
|
||||
);
|
||||
description = "Output rotate configuration.";
|
||||
default = null;
|
||||
example = "left";
|
||||
|
|
@ -128,26 +159,31 @@ let
|
|||
};
|
||||
|
||||
scale = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
method = mkOption {
|
||||
type = types.enum [ "factor" "pixel" ];
|
||||
description = "Output scaling method.";
|
||||
default = "factor";
|
||||
example = "pixel";
|
||||
};
|
||||
type = types.nullOr (
|
||||
types.submodule {
|
||||
options = {
|
||||
method = mkOption {
|
||||
type = types.enum [
|
||||
"factor"
|
||||
"pixel"
|
||||
];
|
||||
description = "Output scaling method.";
|
||||
default = "factor";
|
||||
example = "pixel";
|
||||
};
|
||||
|
||||
x = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Horizontal scaling factor/pixels.";
|
||||
};
|
||||
x = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Horizontal scaling factor/pixels.";
|
||||
};
|
||||
|
||||
y = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Vertical scaling factor/pixels.";
|
||||
y = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Vertical scaling factor/pixels.";
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
description = ''
|
||||
Output scale configuration.
|
||||
|
||||
|
|
@ -172,7 +208,12 @@ let
|
|||
};
|
||||
|
||||
filter = mkOption {
|
||||
type = types.nullOr (types.enum [ "bilinear" "nearest" ]);
|
||||
type = types.nullOr (
|
||||
types.enum [
|
||||
"bilinear"
|
||||
"nearest"
|
||||
]
|
||||
);
|
||||
description = "Interpolation method to be used for scaling the output.";
|
||||
default = null;
|
||||
example = "nearest";
|
||||
|
|
@ -242,30 +283,35 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
hookToFile = folder: name: hook:
|
||||
hookToFile =
|
||||
folder: name: hook:
|
||||
lib.nameValuePair "autorandr/${folder}/${name}" {
|
||||
source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook";
|
||||
};
|
||||
profileToFiles = name: profile:
|
||||
let inherit (profile) hooks;
|
||||
in lib.mkMerge [
|
||||
profileToFiles =
|
||||
name: profile:
|
||||
let
|
||||
inherit (profile) hooks;
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
"autorandr/${name}/setup".text = lib.concatStringsSep "\n"
|
||||
(mapAttrsToList fingerprintToString profile.fingerprint);
|
||||
"autorandr/${name}/config".text = lib.concatStringsSep "\n"
|
||||
(mapAttrsToList configToString profile.config);
|
||||
"autorandr/${name}/setup".text = lib.concatStringsSep "\n" (
|
||||
mapAttrsToList fingerprintToString profile.fingerprint
|
||||
);
|
||||
"autorandr/${name}/config".text = lib.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) ]))
|
||||
(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}";
|
||||
configToString = name: config:
|
||||
configToString =
|
||||
name: config:
|
||||
if config.enable then
|
||||
lib.concatStringsSep "\n" ([ "output ${name}" ]
|
||||
lib.concatStringsSep "\n" (
|
||||
[ "output ${name}" ]
|
||||
++ optional (config.position != "") "pos ${config.position}"
|
||||
++ optional (config.crtc != null) "crtc ${toString config.crtc}"
|
||||
++ optional config.primary "primary"
|
||||
|
|
@ -275,18 +321,23 @@ let
|
|||
++ optional (config.rate != "") "rate ${config.rate}"
|
||||
++ optional (config.rotate != null) "rotate ${config.rotate}"
|
||||
++ optional (config.filter != null) "filter ${config.filter}"
|
||||
++ optional (config.transform != null) ("transform "
|
||||
+ lib.concatMapStringsSep "," toString (lib.flatten config.transform))
|
||||
++ optional (config.scale != null)
|
||||
((if config.scale.method == "factor" then "scale" else "scale-from")
|
||||
+ " ${toString config.scale.x}x${toString config.scale.y}")
|
||||
++ optional (config.extraConfig != "") config.extraConfig)
|
||||
else ''
|
||||
output ${name}
|
||||
off
|
||||
'';
|
||||
++ optional (config.transform != null) (
|
||||
"transform " + lib.concatMapStringsSep "," toString (lib.flatten config.transform)
|
||||
)
|
||||
++ optional (config.scale != null) (
|
||||
(if config.scale.method == "factor" then "scale" else "scale-from")
|
||||
+ " ${toString config.scale.x}x${toString config.scale.y}"
|
||||
)
|
||||
++ optional (config.extraConfig != "") config.extraConfig
|
||||
)
|
||||
else
|
||||
''
|
||||
output ${name}
|
||||
off
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.autorandr = {
|
||||
enable = lib.mkEnableOption "Autorandr";
|
||||
|
|
@ -358,15 +409,19 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = lib.flatten (mapAttrsToList (profile:
|
||||
{ config, ... }:
|
||||
mapAttrsToList (output: opts: {
|
||||
assertion = opts.scale == null || opts.transform == null;
|
||||
message = ''
|
||||
Cannot use the profile output options 'scale' and 'transform' simultaneously.
|
||||
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
|
||||
'';
|
||||
}) config) cfg.profiles);
|
||||
assertions = lib.flatten (
|
||||
mapAttrsToList (
|
||||
profile:
|
||||
{ config, ... }:
|
||||
mapAttrsToList (output: opts: {
|
||||
assertion = opts.scale == null || opts.transform == null;
|
||||
message = ''
|
||||
Cannot use the profile output options 'scale' and 'transform' simultaneously.
|
||||
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
|
||||
'';
|
||||
}) config
|
||||
) cfg.profiles
|
||||
);
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.programs.awscli;
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.anthonyroussel ];
|
||||
|
||||
options.programs.awscli = {
|
||||
|
|
@ -55,16 +61,12 @@ in {
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file."${config.home.homeDirectory}/.aws/config" =
|
||||
lib.mkIf (cfg.settings != { }) {
|
||||
source =
|
||||
iniFormat.generate "aws-config-${config.home.username}" cfg.settings;
|
||||
};
|
||||
home.file."${config.home.homeDirectory}/.aws/config" = lib.mkIf (cfg.settings != { }) {
|
||||
source = iniFormat.generate "aws-config-${config.home.username}" cfg.settings;
|
||||
};
|
||||
|
||||
home.file."${config.home.homeDirectory}/.aws/credentials" =
|
||||
lib.mkIf (cfg.credentials != { }) {
|
||||
source = iniFormat.generate "aws-credentials-${config.home.username}"
|
||||
cfg.credentials;
|
||||
};
|
||||
home.file."${config.home.homeDirectory}/.aws/credentials" = lib.mkIf (cfg.credentials != { }) {
|
||||
source = iniFormat.generate "aws-credentials-${config.home.username}" cfg.credentials;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
cfg = config.programs.bacon;
|
||||
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
|
||||
configDir = if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/org.dystroy.bacon"
|
||||
else
|
||||
"${config.xdg.configHome}/bacon";
|
||||
configDir =
|
||||
if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/org.dystroy.bacon"
|
||||
else
|
||||
"${config.xdg.configHome}/bacon";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.shimunn ];
|
||||
|
||||
options.programs.bacon = {
|
||||
|
|
@ -23,7 +30,13 @@ in {
|
|||
default = { };
|
||||
example = {
|
||||
jobs.default = {
|
||||
command = [ "cargo" "build" "--all-features" "--color" "always" ];
|
||||
command = [
|
||||
"cargo"
|
||||
"build"
|
||||
"--all-features"
|
||||
"--color"
|
||||
"always"
|
||||
];
|
||||
need_stdout = true;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,21 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption optionalAttrs types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
optionalAttrs
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.bash;
|
||||
|
||||
writeBashScript = name: text:
|
||||
writeBashScript =
|
||||
name: text:
|
||||
pkgs.writeTextFile {
|
||||
inherit name text;
|
||||
checkPhase = ''
|
||||
|
|
@ -12,15 +23,19 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "programs" "bash" "enableAutojump" ] [
|
||||
"programs"
|
||||
"autojump"
|
||||
"enable"
|
||||
])
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "programs" "bash" "enableAutojump" ]
|
||||
[
|
||||
"programs"
|
||||
"autojump"
|
||||
"enable"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
|
|
@ -70,8 +85,14 @@ in {
|
|||
};
|
||||
|
||||
historyControl = mkOption {
|
||||
type = types.listOf
|
||||
(types.enum [ "erasedups" "ignoredups" "ignorespace" "ignoreboth" ]);
|
||||
type = types.listOf (
|
||||
types.enum [
|
||||
"erasedups"
|
||||
"ignoredups"
|
||||
"ignorespace"
|
||||
"ignoreboth"
|
||||
]
|
||||
);
|
||||
default = [ ];
|
||||
description = "Controlling how commands are saved on the history list.";
|
||||
};
|
||||
|
|
@ -79,9 +100,12 @@ in {
|
|||
historyIgnore = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "ls" "cd" "exit" ];
|
||||
description =
|
||||
"List of commands that should not be saved to the history list.";
|
||||
example = [
|
||||
"ls"
|
||||
"cd"
|
||||
"exit"
|
||||
];
|
||||
description = "List of commands that should not be saved to the history list.";
|
||||
};
|
||||
|
||||
shellOptions = mkOption {
|
||||
|
|
@ -101,7 +125,10 @@ in {
|
|||
# Warn if closing shell with running jobs.
|
||||
"checkjobs"
|
||||
];
|
||||
example = [ "extglob" "-cdspell" ];
|
||||
example = [
|
||||
"extglob"
|
||||
"-cdspell"
|
||||
];
|
||||
description = ''
|
||||
Shell options to set. Prefix an option with
|
||||
"`-`" to unset.
|
||||
|
|
@ -111,7 +138,9 @@ in {
|
|||
sessionVariables = mkOption {
|
||||
default = { };
|
||||
type = types.attrs;
|
||||
example = { MAILCHECK = 30; };
|
||||
example = {
|
||||
MAILCHECK = 30;
|
||||
};
|
||||
description = ''
|
||||
Environment variables that will be set for the Bash session.
|
||||
'';
|
||||
|
|
@ -170,77 +199,90 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
aliasesStr = lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList (k: v: "alias ${k}=${lib.escapeShellArg v}")
|
||||
cfg.shellAliases);
|
||||
config =
|
||||
let
|
||||
aliasesStr = lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (k: v: "alias ${k}=${lib.escapeShellArg v}") cfg.shellAliases
|
||||
);
|
||||
|
||||
shoptsStr = let switch = v: if lib.hasPrefix "-" v then "-u" else "-s";
|
||||
in lib.concatStringsSep "\n"
|
||||
(map (v: "shopt ${switch v} ${lib.removePrefix "-" v}") cfg.shellOptions);
|
||||
shoptsStr =
|
||||
let
|
||||
switch = v: if lib.hasPrefix "-" v then "-u" else "-s";
|
||||
in
|
||||
lib.concatStringsSep "\n" (map (v: "shopt ${switch v} ${lib.removePrefix "-" v}") cfg.shellOptions);
|
||||
|
||||
sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
|
||||
sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
|
||||
|
||||
historyControlStr = (lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList (n: v: "${n}=${v}")
|
||||
(optionalAttrs (cfg.historyFileSize != null) {
|
||||
HISTFILESIZE = toString cfg.historyFileSize;
|
||||
} // optionalAttrs (cfg.historySize != null) {
|
||||
HISTSIZE = toString cfg.historySize;
|
||||
} // optionalAttrs (cfg.historyFile != null) {
|
||||
HISTFILE = ''"${cfg.historyFile}"'';
|
||||
} // optionalAttrs (cfg.historyControl != [ ]) {
|
||||
HISTCONTROL = lib.concatStringsSep ":" cfg.historyControl;
|
||||
} // optionalAttrs (cfg.historyIgnore != [ ]) {
|
||||
HISTIGNORE =
|
||||
lib.escapeShellArg (lib.concatStringsSep ":" cfg.historyIgnore);
|
||||
}) ++ lib.optional (cfg.historyFile != null)
|
||||
''mkdir -p "$(dirname "$HISTFILE")"''));
|
||||
in mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
historyControlStr = (
|
||||
lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (n: v: "${n}=${v}") (
|
||||
optionalAttrs (cfg.historyFileSize != null) {
|
||||
HISTFILESIZE = toString cfg.historyFileSize;
|
||||
}
|
||||
// optionalAttrs (cfg.historySize != null) {
|
||||
HISTSIZE = toString cfg.historySize;
|
||||
}
|
||||
// optionalAttrs (cfg.historyFile != null) {
|
||||
HISTFILE = ''"${cfg.historyFile}"'';
|
||||
}
|
||||
// optionalAttrs (cfg.historyControl != [ ]) {
|
||||
HISTCONTROL = lib.concatStringsSep ":" cfg.historyControl;
|
||||
}
|
||||
// optionalAttrs (cfg.historyIgnore != [ ]) {
|
||||
HISTIGNORE = lib.escapeShellArg (lib.concatStringsSep ":" cfg.historyIgnore);
|
||||
}
|
||||
)
|
||||
++ lib.optional (cfg.historyFile != null) ''mkdir -p "$(dirname "$HISTFILE")"''
|
||||
)
|
||||
);
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file.".bash_profile".source = writeBashScript "bash_profile" ''
|
||||
# include .profile if it exists
|
||||
[[ -f ~/.profile ]] && . ~/.profile
|
||||
home.file.".bash_profile".source = writeBashScript "bash_profile" ''
|
||||
# include .profile if it exists
|
||||
[[ -f ~/.profile ]] && . ~/.profile
|
||||
|
||||
# include .bashrc if it exists
|
||||
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
||||
'';
|
||||
# include .bashrc if it exists
|
||||
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
||||
'';
|
||||
|
||||
# If completion is enabled then make sure it is sourced very early. This
|
||||
# is to avoid problems if any other initialization code attempts to set up
|
||||
# completion.
|
||||
programs.bash.initExtra = mkIf cfg.enableCompletion (lib.mkOrder 100 ''
|
||||
if [[ ! -v BASH_COMPLETION_VERSINFO ]]; then
|
||||
. "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"
|
||||
fi
|
||||
'');
|
||||
# If completion is enabled then make sure it is sourced very early. This
|
||||
# is to avoid problems if any other initialization code attempts to set up
|
||||
# completion.
|
||||
programs.bash.initExtra = mkIf cfg.enableCompletion (
|
||||
lib.mkOrder 100 ''
|
||||
if [[ ! -v BASH_COMPLETION_VERSINFO ]]; then
|
||||
. "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"
|
||||
fi
|
||||
''
|
||||
);
|
||||
|
||||
home.file.".profile".source = writeBashScript "profile" ''
|
||||
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
|
||||
home.file.".profile".source = writeBashScript "profile" ''
|
||||
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
|
||||
|
||||
${sessionVarsStr}
|
||||
${sessionVarsStr}
|
||||
|
||||
${cfg.profileExtra}
|
||||
'';
|
||||
${cfg.profileExtra}
|
||||
'';
|
||||
|
||||
home.file.".bashrc".source = writeBashScript "bashrc" ''
|
||||
${cfg.bashrcExtra}
|
||||
home.file.".bashrc".source = writeBashScript "bashrc" ''
|
||||
${cfg.bashrcExtra}
|
||||
|
||||
# Commands that should be applied only for interactive shells.
|
||||
[[ $- == *i* ]] || return
|
||||
# Commands that should be applied only for interactive shells.
|
||||
[[ $- == *i* ]] || return
|
||||
|
||||
${historyControlStr}
|
||||
${historyControlStr}
|
||||
|
||||
${shoptsStr}
|
||||
${shoptsStr}
|
||||
|
||||
${aliasesStr}
|
||||
${aliasesStr}
|
||||
|
||||
${cfg.initExtra}
|
||||
'';
|
||||
${cfg.initExtra}
|
||||
'';
|
||||
|
||||
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
|
||||
source = writeBashScript "bash_logout" cfg.logoutExtra;
|
||||
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
|
||||
source = writeBashScript "bash_logout" cfg.logoutExtra;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.bashmount;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.bashmount;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.AndersonTorres ];
|
||||
|
||||
options.programs.bashmount = {
|
||||
|
|
@ -24,7 +31,6 @@ in {
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."bashmount/config" =
|
||||
lib.mkIf (cfg.extraConfig != "") { text = cfg.extraConfig; };
|
||||
xdg.configFile."bashmount/config" = lib.mkIf (cfg.extraConfig != "") { text = cfg.extraConfig; };
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,22 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkEnableOption mkOption mkIf types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkEnableOption
|
||||
mkOption
|
||||
mkIf
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.bat;
|
||||
|
||||
toConfigFile = attrs:
|
||||
toConfigFile =
|
||||
attrs:
|
||||
let
|
||||
inherit (builtins) isBool attrNames;
|
||||
nonBoolFlags = lib.filterAttrs (_: v: !(isBool v)) attrs;
|
||||
|
|
@ -17,20 +29,31 @@ let
|
|||
switches = lib.concatMapStrings (k: ''
|
||||
--${k}
|
||||
'') (attrNames enabledBoolFlags);
|
||||
in keyValuePairs + switches;
|
||||
in {
|
||||
in
|
||||
keyValuePairs + switches;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ khaneliman ];
|
||||
|
||||
options.programs.bat = {
|
||||
enable = mkEnableOption "bat, a cat clone with wings";
|
||||
|
||||
config = mkOption {
|
||||
type = with types; attrsOf (oneOf [ str (listOf str) bool ]);
|
||||
type =
|
||||
with types;
|
||||
attrsOf (oneOf [
|
||||
str
|
||||
(listOf str)
|
||||
bool
|
||||
]);
|
||||
default = { };
|
||||
example = {
|
||||
theme = "TwoDark";
|
||||
pager = "less -FR";
|
||||
map-syntax = [ "*.jenkinsfile:Groovy" "*.props:Java Properties" ];
|
||||
map-syntax = [
|
||||
"*.jenkinsfile:Groovy"
|
||||
"*.props:Java Properties"
|
||||
];
|
||||
};
|
||||
description = ''
|
||||
Bat configuration.
|
||||
|
|
@ -40,8 +63,7 @@ in {
|
|||
extraPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
example = literalExpression
|
||||
"with pkgs.bat-extras; [ batdiff batman batgrep batwatch ];";
|
||||
example = literalExpression "with pkgs.bat-extras; [ batdiff batman batgrep batwatch ];";
|
||||
description = ''
|
||||
Additional bat packages to install.
|
||||
'';
|
||||
|
|
@ -50,21 +72,24 @@ in {
|
|||
package = lib.mkPackageOption pkgs "bat" { };
|
||||
|
||||
themes = mkOption {
|
||||
type = types.attrsOf (types.either types.lines (types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the theme folder.";
|
||||
};
|
||||
type = types.attrsOf (
|
||||
types.either types.lines (
|
||||
types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the theme folder.";
|
||||
};
|
||||
|
||||
file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description =
|
||||
"Subpath of the theme file within the source, if needed.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Subpath of the theme file within the source, if needed.";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
|
|
@ -85,20 +110,23 @@ in {
|
|||
};
|
||||
|
||||
syntaxes = mkOption {
|
||||
type = types.attrsOf (types.either types.lines (types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the syntax folder.";
|
||||
};
|
||||
file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description =
|
||||
"Subpath of the syntax file within the source, if needed.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
type = types.attrsOf (
|
||||
types.either types.lines (
|
||||
types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the syntax folder.";
|
||||
};
|
||||
file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Subpath of the syntax file within the source, if needed.";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
|
|
@ -119,54 +147,75 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (lib.mkMerge [
|
||||
(mkIf (lib.any lib.isString (lib.attrValues cfg.themes)) {
|
||||
warnings = [''
|
||||
Using programs.bat.themes as a string option is deprecated and will be
|
||||
removed in the future. Please change to using it as an attribute set
|
||||
instead.
|
||||
''];
|
||||
})
|
||||
(mkIf (lib.any lib.isString (lib.attrValues cfg.syntaxes)) {
|
||||
warnings = [''
|
||||
Using programs.bat.syntaxes as a string option is deprecated and will be
|
||||
removed in the future. Please change to using it as an attribute set
|
||||
instead.
|
||||
''];
|
||||
})
|
||||
{
|
||||
home.packages = [ cfg.package ] ++ cfg.extraPackages;
|
||||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
(mkIf (lib.any lib.isString (lib.attrValues cfg.themes)) {
|
||||
warnings = [
|
||||
''
|
||||
Using programs.bat.themes as a string option is deprecated and will be
|
||||
removed in the future. Please change to using it as an attribute set
|
||||
instead.
|
||||
''
|
||||
];
|
||||
})
|
||||
(mkIf (lib.any lib.isString (lib.attrValues cfg.syntaxes)) {
|
||||
warnings = [
|
||||
''
|
||||
Using programs.bat.syntaxes as a string option is deprecated and will be
|
||||
removed in the future. Please change to using it as an attribute set
|
||||
instead.
|
||||
''
|
||||
];
|
||||
})
|
||||
{
|
||||
home.packages = [ cfg.package ] ++ cfg.extraPackages;
|
||||
|
||||
xdg.configFile = lib.mkMerge ([{
|
||||
"bat/config" =
|
||||
mkIf (cfg.config != { }) { text = toConfigFile cfg.config; };
|
||||
}] ++ (lib.flip lib.mapAttrsToList cfg.themes (name: val: {
|
||||
"bat/themes/${name}.tmTheme" = if lib.isString val then {
|
||||
text = val;
|
||||
} else {
|
||||
source =
|
||||
if isNull val.file then "${val.src}" else "${val.src}/${val.file}";
|
||||
};
|
||||
})) ++ (lib.flip lib.mapAttrsToList cfg.syntaxes (name: val: {
|
||||
"bat/syntaxes/${name}.sublime-syntax" = if lib.isString val then {
|
||||
text = val;
|
||||
} else {
|
||||
source =
|
||||
if isNull val.file then "${val.src}" else "${val.src}/${val.file}";
|
||||
};
|
||||
})));
|
||||
xdg.configFile = lib.mkMerge (
|
||||
[
|
||||
{
|
||||
"bat/config" = mkIf (cfg.config != { }) { text = toConfigFile cfg.config; };
|
||||
}
|
||||
]
|
||||
++ (lib.flip lib.mapAttrsToList cfg.themes (
|
||||
name: val: {
|
||||
"bat/themes/${name}.tmTheme" =
|
||||
if lib.isString val then
|
||||
{
|
||||
text = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
source = if isNull val.file then "${val.src}" else "${val.src}/${val.file}";
|
||||
};
|
||||
}
|
||||
))
|
||||
++ (lib.flip lib.mapAttrsToList cfg.syntaxes (
|
||||
name: val: {
|
||||
"bat/syntaxes/${name}.sublime-syntax" =
|
||||
if lib.isString val then
|
||||
{
|
||||
text = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
source = if isNull val.file then "${val.src}" else "${val.src}/${val.file}";
|
||||
};
|
||||
}
|
||||
))
|
||||
);
|
||||
|
||||
# NOTE: run `bat cache --build` in an empty directory to work
|
||||
# around failure when ~/cache exists
|
||||
# https://github.com/sharkdp/bat/issues/1726
|
||||
home.activation.batCache = lib.hm.dag.entryAfter [ "linkGeneration" ] ''
|
||||
(
|
||||
export XDG_CACHE_HOME=${lib.escapeShellArg config.xdg.cacheHome}
|
||||
verboseEcho "Rebuilding bat theme cache"
|
||||
cd "${pkgs.emptyDirectory}"
|
||||
run ${lib.getExe cfg.package} cache --build
|
||||
)
|
||||
'';
|
||||
}
|
||||
]);
|
||||
# NOTE: run `bat cache --build` in an empty directory to work
|
||||
# around failure when ~/cache exists
|
||||
# https://github.com/sharkdp/bat/issues/1726
|
||||
home.activation.batCache = lib.hm.dag.entryAfter [ "linkGeneration" ] ''
|
||||
(
|
||||
export XDG_CACHE_HOME=${lib.escapeShellArg config.xdg.cacheHome}
|
||||
verboseEcho "Rebuilding bat theme cache"
|
||||
cd "${pkgs.emptyDirectory}"
|
||||
run ${lib.getExe cfg.package} cache --build
|
||||
)
|
||||
'';
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,34 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.beets;
|
||||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ rycee Scrumplex ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
rycee
|
||||
Scrumplex
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.beets = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = if lib.versionAtLeast config.home.stateVersion "19.03" then
|
||||
false
|
||||
else
|
||||
cfg.settings != { };
|
||||
default =
|
||||
if lib.versionAtLeast config.home.stateVersion "19.03" then false else cfg.settings != { };
|
||||
defaultText = "false";
|
||||
description = ''
|
||||
Whether to enable the beets music library manager. This
|
||||
|
|
@ -27,8 +39,7 @@ in {
|
|||
};
|
||||
|
||||
package = lib.mkPackageOption pkgs "beets" {
|
||||
example =
|
||||
"(pkgs.beets.override { pluginOverrides = { beatport.enable = false; }; })";
|
||||
example = "(pkgs.beets.override { pluginOverrides = { beatport.enable = false; }; })";
|
||||
extraDescription = ''
|
||||
Can be used to specify extensions.
|
||||
'';
|
||||
|
|
@ -70,8 +81,7 @@ in {
|
|||
(mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."beets/config.yaml".source =
|
||||
yamlFormat.generate "beets-config" cfg.settings;
|
||||
xdg.configFile."beets/config.yaml".source = yamlFormat.generate "beets-config" cfg.settings;
|
||||
})
|
||||
|
||||
(mkIf (cfg.mpdIntegration.enableStats || cfg.mpdIntegration.enableUpdate) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.bemenu;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.bemenu;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.programs.bemenu = {
|
||||
|
|
@ -9,7 +16,13 @@ in {
|
|||
package = lib.mkPackageOption pkgs "bemenu" { nullable = true; };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ str number bool ]);
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (oneOf [
|
||||
str
|
||||
number
|
||||
bool
|
||||
]);
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
|
|
@ -29,15 +42,13 @@ in {
|
|||
width-factor = 0.3;
|
||||
}
|
||||
'';
|
||||
description =
|
||||
"Configuration options for bemenu. See {manpage}`bemenu(1)`.";
|
||||
description = "Configuration options for bemenu. See {manpage}`bemenu(1)`.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.bemenu" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.bemenu" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
||||
|
|
@ -6,24 +11,33 @@ let
|
|||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
mkNullableOption = args:
|
||||
lib.mkOption (args // {
|
||||
type = lib.types.nullOr args.type;
|
||||
default = null;
|
||||
});
|
||||
mkNullableOption =
|
||||
args:
|
||||
lib.mkOption (
|
||||
args
|
||||
// {
|
||||
type = lib.types.nullOr args.type;
|
||||
default = null;
|
||||
}
|
||||
);
|
||||
|
||||
cleanRepositories = repos:
|
||||
map (repo:
|
||||
if builtins.isString repo then {
|
||||
path = repo;
|
||||
} else
|
||||
removeNullValues repo) repos;
|
||||
cleanRepositories =
|
||||
repos:
|
||||
map (
|
||||
repo:
|
||||
if builtins.isString repo then
|
||||
{
|
||||
path = repo;
|
||||
}
|
||||
else
|
||||
removeNullValues repo
|
||||
) repos;
|
||||
|
||||
mkRetentionOption = frequency:
|
||||
mkRetentionOption =
|
||||
frequency:
|
||||
mkNullableOption {
|
||||
type = types.int;
|
||||
description =
|
||||
"Number of ${frequency} archives to keep. Use -1 for no limit.";
|
||||
description = "Number of ${frequency} archives to keep. Use -1 for no limit.";
|
||||
example = 3;
|
||||
};
|
||||
|
||||
|
|
@ -56,7 +70,12 @@ let
|
|||
consistencyCheckModule = types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.enum [ "repository" "archives" "data" "extract" ];
|
||||
type = types.enum [
|
||||
"repository"
|
||||
"archives"
|
||||
"data"
|
||||
"extract"
|
||||
];
|
||||
description = "Name of consistency check to run.";
|
||||
example = "repository";
|
||||
};
|
||||
|
|
@ -69,146 +88,151 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
configModule = types.submodule ({ config, ... }: {
|
||||
config.location.extraConfig.exclude_from =
|
||||
lib.mkIf config.location.excludeHomeManagerSymlinks
|
||||
(lib.mkAfter [ (toString hmExcludeFile) ]);
|
||||
options = {
|
||||
location = {
|
||||
sourceDirectories = mkNullableOption {
|
||||
type = types.listOf types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Directories to backup.
|
||||
configModule = types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
config.location.extraConfig.exclude_from = lib.mkIf config.location.excludeHomeManagerSymlinks (
|
||||
lib.mkAfter [ (toString hmExcludeFile) ]
|
||||
);
|
||||
options = {
|
||||
location = {
|
||||
sourceDirectories = mkNullableOption {
|
||||
type = types.listOf types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Directories to backup.
|
||||
|
||||
Mutually exclusive with [](#opt-programs.borgmatic.backups._name_.location.patterns).
|
||||
'';
|
||||
example = literalExpression "[config.home.homeDirectory]";
|
||||
Mutually exclusive with [](#opt-programs.borgmatic.backups._name_.location.patterns).
|
||||
'';
|
||||
example = literalExpression "[config.home.homeDirectory]";
|
||||
};
|
||||
|
||||
patterns = mkNullableOption {
|
||||
type = types.listOf types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Patterns to include/exclude.
|
||||
|
||||
See the output of `borg help patterns` for the syntax. Pattern paths
|
||||
are relative to `/` even when a different recursion root is set.
|
||||
|
||||
Mutually exclusive with [](#opt-programs.borgmatic.backups._name_.location.sourceDirectories).
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
"R /home/user"
|
||||
"- home/user/.cache"
|
||||
"- home/user/Downloads"
|
||||
"+ home/user/Videos/Important Video"
|
||||
"- home/user/Videos"
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
repositories = mkOption {
|
||||
type = types.listOf (types.either types.str repositoryOption);
|
||||
apply = cleanRepositories;
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
"path" = "ssh://myuser@myrepo.myserver.com/./repo";
|
||||
"label" = "server";
|
||||
}
|
||||
{
|
||||
"path" = "/var/lib/backups/local.borg";
|
||||
"label" = "local";
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of local or remote repositories with paths and optional labels.
|
||||
'';
|
||||
};
|
||||
|
||||
excludeHomeManagerSymlinks = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to exclude Home Manager generated symbolic links from
|
||||
the backups. This facilitates restoring the whole home
|
||||
directory when the Nix store doesn't contain the latest
|
||||
Home Manager generation.
|
||||
'';
|
||||
default = false;
|
||||
example = true;
|
||||
};
|
||||
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
patterns = mkNullableOption {
|
||||
type = types.listOf types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Patterns to include/exclude.
|
||||
|
||||
See the output of `borg help patterns` for the syntax. Pattern paths
|
||||
are relative to `/` even when a different recursion root is set.
|
||||
|
||||
Mutually exclusive with [](#opt-programs.borgmatic.backups._name_.location.sourceDirectories).
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
"R /home/user"
|
||||
"- home/user/.cache"
|
||||
"- home/user/Downloads"
|
||||
"+ home/user/Videos/Important Video"
|
||||
"- home/user/Videos"
|
||||
]
|
||||
'';
|
||||
storage = {
|
||||
encryptionPasscommand = mkNullableOption {
|
||||
type = types.str;
|
||||
description = "Command writing the passphrase to standard output.";
|
||||
example = literalExpression ''"''${pkgs.password-store}/bin/pass borg-repo"'';
|
||||
};
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
repositories = mkOption {
|
||||
type = types.listOf (types.either types.str repositoryOption);
|
||||
apply = cleanRepositories;
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
"path" = "ssh://myuser@myrepo.myserver.com/./repo";
|
||||
"label" = "server";
|
||||
}
|
||||
{
|
||||
"path" = "/var/lib/backups/local.borg";
|
||||
"label" = "local";
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of local or remote repositories with paths and optional labels.
|
||||
'';
|
||||
retention = {
|
||||
keepWithin = mkNullableOption {
|
||||
type = types.strMatching "[[:digit:]]+[Hdwmy]";
|
||||
description = "Keep all archives within this time interval.";
|
||||
example = "2d";
|
||||
};
|
||||
|
||||
keepSecondly = mkRetentionOption "secondly";
|
||||
keepMinutely = mkRetentionOption "minutely";
|
||||
keepHourly = mkRetentionOption "hourly";
|
||||
keepDaily = mkRetentionOption "daily";
|
||||
keepWeekly = mkRetentionOption "weekly";
|
||||
keepMonthly = mkRetentionOption "monthly";
|
||||
keepYearly = mkRetentionOption "yearly";
|
||||
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
excludeHomeManagerSymlinks = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to exclude Home Manager generated symbolic links from
|
||||
the backups. This facilitates restoring the whole home
|
||||
directory when the Nix store doesn't contain the latest
|
||||
Home Manager generation.
|
||||
'';
|
||||
default = false;
|
||||
example = true;
|
||||
consistency = {
|
||||
checks = mkOption {
|
||||
type = types.listOf consistencyCheckModule;
|
||||
default = [ ];
|
||||
description = "Consistency checks to run";
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
name = "repository";
|
||||
frequency = "2 weeks";
|
||||
}
|
||||
{
|
||||
name = "archives";
|
||||
frequency = "4 weeks";
|
||||
}
|
||||
{
|
||||
name = "data";
|
||||
frequency = "6 weeks";
|
||||
}
|
||||
{
|
||||
name = "extract";
|
||||
frequency = "6 weeks";
|
||||
}
|
||||
];
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
extraConfig = extraConfigOption;
|
||||
output = {
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
hooks = {
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
storage = {
|
||||
encryptionPasscommand = mkNullableOption {
|
||||
type = types.str;
|
||||
description = "Command writing the passphrase to standard output.";
|
||||
example =
|
||||
literalExpression ''"''${pkgs.password-store}/bin/pass borg-repo"'';
|
||||
};
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
retention = {
|
||||
keepWithin = mkNullableOption {
|
||||
type = types.strMatching "[[:digit:]]+[Hdwmy]";
|
||||
description = "Keep all archives within this time interval.";
|
||||
example = "2d";
|
||||
};
|
||||
|
||||
keepSecondly = mkRetentionOption "secondly";
|
||||
keepMinutely = mkRetentionOption "minutely";
|
||||
keepHourly = mkRetentionOption "hourly";
|
||||
keepDaily = mkRetentionOption "daily";
|
||||
keepWeekly = mkRetentionOption "weekly";
|
||||
keepMonthly = mkRetentionOption "monthly";
|
||||
keepYearly = mkRetentionOption "yearly";
|
||||
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
consistency = {
|
||||
checks = mkOption {
|
||||
type = types.listOf consistencyCheckModule;
|
||||
default = [ ];
|
||||
description = "Consistency checks to run";
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
name = "repository";
|
||||
frequency = "2 weeks";
|
||||
}
|
||||
{
|
||||
name = "archives";
|
||||
frequency = "4 weeks";
|
||||
}
|
||||
{
|
||||
name = "data";
|
||||
frequency = "6 weeks";
|
||||
}
|
||||
{
|
||||
name = "extract";
|
||||
frequency = "6 weeks";
|
||||
}
|
||||
];
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = extraConfigOption;
|
||||
};
|
||||
|
||||
output = { extraConfig = extraConfigOption; };
|
||||
|
||||
hooks = { extraConfig = extraConfigOption; };
|
||||
};
|
||||
});
|
||||
|
||||
removeNullValues = attrSet:
|
||||
lib.filterAttrs (key: value: value != null) attrSet;
|
||||
removeNullValues = attrSet: lib.filterAttrs (key: value: value != null) attrSet;
|
||||
|
||||
hmFiles = builtins.attrValues config.home.file;
|
||||
hmSymlinks = (lib.filter (file: !file.recursive) hmFiles);
|
||||
|
|
@ -218,25 +242,35 @@ let
|
|||
hmExcludePatterns = lib.concatMapStrings hmExcludePattern hmSymlinks;
|
||||
hmExcludeFile = pkgs.writeText "hm-symlinks.txt" hmExcludePatterns;
|
||||
|
||||
writeConfig = config:
|
||||
lib.generators.toYAML { } (removeNullValues ({
|
||||
source_directories = config.location.sourceDirectories;
|
||||
patterns = config.location.patterns;
|
||||
repositories = config.location.repositories;
|
||||
encryption_passcommand = config.storage.encryptionPasscommand;
|
||||
keep_within = config.retention.keepWithin;
|
||||
keep_secondly = config.retention.keepSecondly;
|
||||
keep_minutely = config.retention.keepMinutely;
|
||||
keep_hourly = config.retention.keepHourly;
|
||||
keep_daily = config.retention.keepDaily;
|
||||
keep_weekly = config.retention.keepWeekly;
|
||||
keep_monthly = config.retention.keepMonthly;
|
||||
keep_yearly = config.retention.keepYearly;
|
||||
checks = config.consistency.checks;
|
||||
} // config.location.extraConfig // config.storage.extraConfig
|
||||
// config.retention.extraConfig // config.consistency.extraConfig
|
||||
// config.output.extraConfig // config.hooks.extraConfig));
|
||||
in {
|
||||
writeConfig =
|
||||
config:
|
||||
lib.generators.toYAML { } (
|
||||
removeNullValues (
|
||||
{
|
||||
source_directories = config.location.sourceDirectories;
|
||||
patterns = config.location.patterns;
|
||||
repositories = config.location.repositories;
|
||||
encryption_passcommand = config.storage.encryptionPasscommand;
|
||||
keep_within = config.retention.keepWithin;
|
||||
keep_secondly = config.retention.keepSecondly;
|
||||
keep_minutely = config.retention.keepMinutely;
|
||||
keep_hourly = config.retention.keepHourly;
|
||||
keep_daily = config.retention.keepDaily;
|
||||
keep_weekly = config.retention.keepWeekly;
|
||||
keep_monthly = config.retention.keepMonthly;
|
||||
keep_yearly = config.retention.keepYearly;
|
||||
checks = config.consistency.checks;
|
||||
}
|
||||
// config.location.extraConfig
|
||||
// config.storage.extraConfig
|
||||
// config.retention.extraConfig
|
||||
// config.consistency.extraConfig
|
||||
// config.output.extraConfig
|
||||
// config.hooks.extraConfig
|
||||
)
|
||||
);
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.DamienCassou ];
|
||||
|
||||
options = {
|
||||
|
|
@ -272,25 +306,28 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = (lib.mapAttrsToList (backup: opts: {
|
||||
assertion = opts.location.sourceDirectories == null
|
||||
|| opts.location.patterns == null;
|
||||
message = ''
|
||||
Borgmatic backup configuration "${backup}" cannot specify both 'location.sourceDirectories' and 'location.patterns'.
|
||||
'';
|
||||
}) cfg.backups) ++ (lib.mapAttrsToList (backup: opts: {
|
||||
assertion = !(opts.location.sourceDirectories == null
|
||||
&& opts.location.patterns == null);
|
||||
message = ''
|
||||
Borgmatic backup configuration "${backup}" must specify one of 'location.sourceDirectories' or 'location.patterns'.
|
||||
'';
|
||||
}) cfg.backups);
|
||||
assertions =
|
||||
(lib.mapAttrsToList (backup: opts: {
|
||||
assertion = opts.location.sourceDirectories == null || opts.location.patterns == null;
|
||||
message = ''
|
||||
Borgmatic backup configuration "${backup}" cannot specify both 'location.sourceDirectories' and 'location.patterns'.
|
||||
'';
|
||||
}) cfg.backups)
|
||||
++ (lib.mapAttrsToList (backup: opts: {
|
||||
assertion = !(opts.location.sourceDirectories == null && opts.location.patterns == null);
|
||||
message = ''
|
||||
Borgmatic backup configuration "${backup}" must specify one of 'location.sourceDirectories' or 'location.patterns'.
|
||||
'';
|
||||
}) cfg.backups);
|
||||
|
||||
xdg.configFile = with lib.attrsets;
|
||||
mapAttrs' (configName: config:
|
||||
xdg.configFile =
|
||||
with lib.attrsets;
|
||||
mapAttrs' (
|
||||
configName: config:
|
||||
nameValuePair ("borgmatic.d/" + configName + ".yaml") {
|
||||
text = writeConfig config;
|
||||
}) cfg.backups;
|
||||
}
|
||||
) cfg.backups;
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
cfg = config.programs.bottom;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.bottom = {
|
||||
enable = lib.mkEnableOption ''
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
||||
|
|
@ -37,7 +42,10 @@ let
|
|||
};
|
||||
|
||||
mode = mkOption {
|
||||
type = types.enum [ "file" "directory" ];
|
||||
type = types.enum [
|
||||
"file"
|
||||
"directory"
|
||||
];
|
||||
default = "directory";
|
||||
description = ''
|
||||
Does the current path redirect a file or a directory?
|
||||
|
|
@ -81,7 +89,8 @@ let
|
|||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.programs.boxxy = {
|
||||
enable = lib.mkEnableOption "boxxy: Boxes in badly behaving applications";
|
||||
|
||||
|
|
@ -96,13 +105,11 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.boxxy" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.boxxy" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.file = lib.mkIf (cfg.rules != [ ]) {
|
||||
"${configPath}".source =
|
||||
settingsFormat.generate "boxxy-config.yaml" { rules = cfg.rules; };
|
||||
"${configPath}".source = settingsFormat.generate "boxxy-config.yaml" { rules = cfg.rules; };
|
||||
};
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
|
@ -110,4 +117,3 @@ in {
|
|||
|
||||
meta.maintainers = with lib.hm.maintainers; [ nikp123 ];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption mkRenamedOptionModule types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
mkRenamedOptionModule
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.broot;
|
||||
|
||||
|
|
@ -13,7 +24,15 @@ let
|
|||
modal = lib.mkEnableOption "modal (vim) mode";
|
||||
|
||||
verbs = mkOption {
|
||||
type = with types; listOf (attrsOf (oneOf [ bool str (listOf str) ]));
|
||||
type =
|
||||
with types;
|
||||
listOf (
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
str
|
||||
(listOf str)
|
||||
])
|
||||
);
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[
|
||||
|
|
@ -116,53 +135,64 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
shellInit = shell:
|
||||
shellInit =
|
||||
shell:
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
lib.mkAfter ''
|
||||
source ${
|
||||
pkgs.runCommand "br.${shell}" { nativeBuildInputs = [ cfg.package ]; }
|
||||
"broot --print-shell-function ${shell} > $out"
|
||||
pkgs.runCommand "br.${shell}" {
|
||||
nativeBuildInputs = [ cfg.package ];
|
||||
} "broot --print-shell-function ${shell} > $out"
|
||||
}
|
||||
'';
|
||||
in {
|
||||
meta.maintainers = [ lib.hm.maintainers.aheaume lib.maintainers.dermetfan ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.hm.maintainers.aheaume
|
||||
lib.maintainers.dermetfan
|
||||
];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "programs" "broot" "modal" ] [
|
||||
"programs"
|
||||
"broot"
|
||||
"settings"
|
||||
"modal"
|
||||
])
|
||||
(mkRenamedOptionModule [ "programs" "broot" "verbs" ] [
|
||||
"programs"
|
||||
"broot"
|
||||
"settings"
|
||||
"verbs"
|
||||
])
|
||||
(mkRenamedOptionModule [ "programs" "broot" "skin" ] [
|
||||
"programs"
|
||||
"broot"
|
||||
"settings"
|
||||
"skin"
|
||||
])
|
||||
(mkRenamedOptionModule
|
||||
[ "programs" "broot" "modal" ]
|
||||
[
|
||||
"programs"
|
||||
"broot"
|
||||
"settings"
|
||||
"modal"
|
||||
]
|
||||
)
|
||||
(mkRenamedOptionModule
|
||||
[ "programs" "broot" "verbs" ]
|
||||
[
|
||||
"programs"
|
||||
"broot"
|
||||
"settings"
|
||||
"verbs"
|
||||
]
|
||||
)
|
||||
(mkRenamedOptionModule
|
||||
[ "programs" "broot" "skin" ]
|
||||
[
|
||||
"programs"
|
||||
"broot"
|
||||
"settings"
|
||||
"skin"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options.programs.broot = {
|
||||
enable = lib.mkEnableOption "Broot, a better way to navigate directories";
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableNushellIntegration =
|
||||
lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
package = lib.mkPackageOption pkgs "broot" { };
|
||||
|
||||
|
|
@ -190,9 +220,7 @@ in {
|
|||
postBuild = ''
|
||||
rm $out/conf.hjson
|
||||
${lib.getExe pkgs.jq} --slurp add > $out/conf.hjson \
|
||||
<(${
|
||||
lib.getExe pkgs.hjson-go
|
||||
} -c ${cfg.package.src}/resources/default-conf/conf.hjson) \
|
||||
<(${lib.getExe pkgs.hjson-go} -c ${cfg.package.src}/resources/default-conf/conf.hjson) \
|
||||
${jsonFormat.generate "broot-config.json" cfg.settings}
|
||||
'';
|
||||
};
|
||||
|
|
@ -205,8 +233,7 @@ in {
|
|||
|
||||
fish.shellInit = mkIf cfg.enableFishIntegration (shellInit "fish");
|
||||
|
||||
nushell.extraConfig =
|
||||
mkIf cfg.enableNushellIntegration (shellInit "nushell");
|
||||
nushell.extraConfig = mkIf cfg.enableNushellIntegration (shellInit "nushell");
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,21 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.browserpass;
|
||||
browsers = [ "brave" "chrome" "chromium" "firefox" "librewolf" "vivaldi" ];
|
||||
in {
|
||||
browsers = [
|
||||
"brave"
|
||||
"chrome"
|
||||
"chromium"
|
||||
"firefox"
|
||||
"librewolf"
|
||||
"vivaldi"
|
||||
];
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.browserpass = {
|
||||
enable = lib.mkEnableOption "the browserpass extension host application";
|
||||
|
|
@ -17,82 +30,108 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.file = lib.foldl' (a: b: a // b) { } (lib.concatMap (x:
|
||||
with pkgs.stdenv;
|
||||
if x == "brave" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts"
|
||||
else
|
||||
".config/BraveSoftware/Brave-Browser/NativeMessagingHosts";
|
||||
in [{
|
||||
# Policies are read from `/etc/brave/policies` only
|
||||
# https://github.com/brave/brave-browser/issues/19052
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
}]
|
||||
else if x == "chrome" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Google/Chrome/NativeMessagingHosts"
|
||||
else
|
||||
".config/google-chrome/NativeMessagingHosts";
|
||||
in [{
|
||||
"${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";
|
||||
}]
|
||||
else if x == "chromium" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Chromium/NativeMessagingHosts"
|
||||
else
|
||||
".config/chromium/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
"${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";
|
||||
}
|
||||
]
|
||||
else if x == "firefox" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
|
||||
}]
|
||||
else if x == "librewolf" then
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/LibreWolf/NativeMessagingHosts"
|
||||
else
|
||||
".librewolf/native-messaging-hosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
|
||||
}]
|
||||
home.file = lib.foldl' (a: b: a // b) { } (
|
||||
lib.concatMap (
|
||||
x:
|
||||
with pkgs.stdenv;
|
||||
if x == "brave" then
|
||||
let
|
||||
dir =
|
||||
if isDarwin then
|
||||
"Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts"
|
||||
else
|
||||
".config/BraveSoftware/Brave-Browser/NativeMessagingHosts";
|
||||
in
|
||||
[
|
||||
{
|
||||
# Policies are read from `/etc/brave/policies` only
|
||||
# https://github.com/brave/brave-browser/issues/19052
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
]
|
||||
else if x == "chrome" then
|
||||
let
|
||||
dir =
|
||||
if isDarwin then
|
||||
"Library/Application Support/Google/Chrome/NativeMessagingHosts"
|
||||
else
|
||||
".config/google-chrome/NativeMessagingHosts";
|
||||
in
|
||||
[
|
||||
{
|
||||
"${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";
|
||||
}
|
||||
]
|
||||
else if x == "chromium" then
|
||||
let
|
||||
dir =
|
||||
if isDarwin then
|
||||
"Library/Application Support/Chromium/NativeMessagingHosts"
|
||||
else
|
||||
".config/chromium/NativeMessagingHosts";
|
||||
in
|
||||
[
|
||||
{
|
||||
"${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";
|
||||
}
|
||||
]
|
||||
else if x == "firefox" then
|
||||
let
|
||||
dir =
|
||||
if isDarwin then
|
||||
"Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
in
|
||||
[
|
||||
{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
|
||||
}
|
||||
]
|
||||
else if x == "librewolf" then
|
||||
let
|
||||
dir =
|
||||
if isDarwin then
|
||||
"Library/Application Support/LibreWolf/NativeMessagingHosts"
|
||||
else
|
||||
".librewolf/native-messaging-hosts";
|
||||
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 then
|
||||
"Library/Application Support/Vivaldi/NativeMessagingHosts"
|
||||
else
|
||||
".config/vivaldi/NativeMessagingHosts";
|
||||
in [{
|
||||
"${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";
|
||||
}]
|
||||
else
|
||||
throw "unknown browser ${x}") cfg.browsers);
|
||||
else if x == "vivaldi" then
|
||||
let
|
||||
dir =
|
||||
if isDarwin then
|
||||
"Library/Application Support/Vivaldi/NativeMessagingHosts"
|
||||
else
|
||||
".config/vivaldi/NativeMessagingHosts";
|
||||
in
|
||||
[
|
||||
{
|
||||
"${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";
|
||||
}
|
||||
]
|
||||
else
|
||||
throw "unknown browser ${x}"
|
||||
) cfg.browsers
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,38 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.btop;
|
||||
|
||||
finalConfig = let
|
||||
toKeyValue = lib.generators.toKeyValue {
|
||||
mkKeyValue = lib.generators.mkKeyValueDefault {
|
||||
mkValueString = v:
|
||||
with builtins;
|
||||
if isBool v then
|
||||
(if v then "True" else "False")
|
||||
else if isString v then
|
||||
''"${v}"''
|
||||
else
|
||||
toString v;
|
||||
} " = ";
|
||||
};
|
||||
in ''
|
||||
${toKeyValue cfg.settings}
|
||||
${lib.optionalString (cfg.extraConfig != "") cfg.extraConfig}
|
||||
'';
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ GaetanLepage khaneliman ];
|
||||
finalConfig =
|
||||
let
|
||||
toKeyValue = lib.generators.toKeyValue {
|
||||
mkKeyValue = lib.generators.mkKeyValueDefault {
|
||||
mkValueString =
|
||||
v:
|
||||
with builtins;
|
||||
if isBool v then
|
||||
(if v then "True" else "False")
|
||||
else if isString v then
|
||||
''"${v}"''
|
||||
else
|
||||
toString v;
|
||||
} " = ";
|
||||
};
|
||||
in
|
||||
''
|
||||
${toKeyValue cfg.settings}
|
||||
${lib.optionalString (cfg.extraConfig != "") cfg.extraConfig}
|
||||
'';
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
GaetanLepage
|
||||
khaneliman
|
||||
];
|
||||
|
||||
options.programs.btop = {
|
||||
enable = lib.mkEnableOption "btop";
|
||||
|
|
@ -28,7 +40,14 @@ in {
|
|||
package = lib.mkPackageOption pkgs "btop" { nullable = true; };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ bool float int str ]);
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
float
|
||||
int
|
||||
str
|
||||
]);
|
||||
default = { };
|
||||
example = {
|
||||
color_theme = "Default";
|
||||
|
|
@ -105,18 +124,24 @@ in {
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile = let
|
||||
mkThemeConfig = name: theme: {
|
||||
name = "btop/themes/${name}.theme";
|
||||
value = {
|
||||
source = (if builtins.isPath theme || lib.isStorePath theme then
|
||||
theme
|
||||
else
|
||||
pkgs.writeText "btop-theme.theme" theme);
|
||||
xdg.configFile =
|
||||
let
|
||||
mkThemeConfig = name: theme: {
|
||||
name = "btop/themes/${name}.theme";
|
||||
value = {
|
||||
source = (
|
||||
if builtins.isPath theme || lib.isStorePath theme then
|
||||
theme
|
||||
else
|
||||
pkgs.writeText "btop-theme.theme" theme
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
"btop/btop.conf" = lib.mkIf (cfg.settings != { }) { text = finalConfig; };
|
||||
} // lib.mapAttrs' mkThemeConfig cfg.themes;
|
||||
in
|
||||
{
|
||||
|
||||
"btop/btop.conf" = lib.mkIf (cfg.settings != { }) { text = finalConfig; };
|
||||
}
|
||||
// lib.mapAttrs' mkThemeConfig cfg.themes;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.programs.bun;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.jack5079 ];
|
||||
|
||||
options.programs.bun = {
|
||||
|
|
@ -55,13 +61,12 @@ in {
|
|||
};
|
||||
|
||||
# https://bun.sh/docs/install/lockfile#how-do-i-git-diff-bun-s-lockfile
|
||||
programs.git.attributes =
|
||||
lib.mkIf (cfg.enableGitIntegration && (cfg.package != null))
|
||||
[ "*.lockb binary diff=lockb" ];
|
||||
programs.git.extraConfig.diff.lockb =
|
||||
lib.mkIf (cfg.enableGitIntegration && (cfg.package != null)) {
|
||||
textconv = lib.getExe cfg.package;
|
||||
binary = true;
|
||||
};
|
||||
programs.git.attributes = lib.mkIf (cfg.enableGitIntegration && (cfg.package != null)) [
|
||||
"*.lockb binary diff=lockb"
|
||||
];
|
||||
programs.git.extraConfig.diff.lockb = lib.mkIf (cfg.enableGitIntegration && (cfg.package != null)) {
|
||||
textconv = lib.getExe cfg.package;
|
||||
binary = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,32 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.programs.carapace;
|
||||
bin = lib.getExe cfg.package;
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ weathercold bobvanderlinden ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
weathercold
|
||||
bobvanderlinden
|
||||
];
|
||||
|
||||
options.programs.carapace = {
|
||||
enable = lib.mkEnableOption
|
||||
"carapace, a multi-shell multi-command argument completer";
|
||||
enable = lib.mkEnableOption "carapace, a multi-shell multi-command argument completer";
|
||||
|
||||
package = lib.mkPackageOption pkgs "carapace" { };
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableNushellIntegration =
|
||||
lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
|
@ -52,41 +56,52 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
xdg.configFile = lib.mkIf (config.programs.fish.enable
|
||||
&& cfg.enableFishIntegration
|
||||
&& lib.versionOlder config.programs.fish.package.version "4.0.0") (
|
||||
# Convert the entries from `carapace --list` to empty
|
||||
# xdg.configFile."fish/completions/NAME.fish" entries.
|
||||
#
|
||||
# This is to disable fish builtin completion for each of the
|
||||
# carapace-supported completions.
|
||||
#
|
||||
# This is necessary for carapace to properly work with fish version < 4.0b1.
|
||||
#
|
||||
# It is in line with the instructions from
|
||||
# carapace-bin:
|
||||
#
|
||||
# carapace --list | awk '{print $1}' | xargs -I{} touch ~/.config/fish/completions/{}.fish
|
||||
#
|
||||
# See https://carapace-sh.github.io/carapace-bin/setup.html#fish
|
||||
let
|
||||
carapaceListFile = pkgs.runCommandLocal "carapace-list" {
|
||||
buildInputs = [ cfg.package ];
|
||||
} ''
|
||||
${bin} --list > $out
|
||||
'';
|
||||
in lib.pipe carapaceListFile [
|
||||
lib.fileContents
|
||||
(lib.splitString "\n")
|
||||
(map (builtins.match "^([a-z0-9-]+) .*"))
|
||||
(builtins.filter
|
||||
(match: match != null && (builtins.length match) > 0))
|
||||
(map (match: builtins.head match))
|
||||
(map (name: {
|
||||
name = "fish/completions/${name}.fish";
|
||||
value = { text = ""; };
|
||||
}))
|
||||
builtins.listToAttrs
|
||||
]);
|
||||
xdg.configFile =
|
||||
lib.mkIf
|
||||
(
|
||||
config.programs.fish.enable
|
||||
&& cfg.enableFishIntegration
|
||||
&& lib.versionOlder config.programs.fish.package.version "4.0.0"
|
||||
)
|
||||
(
|
||||
# Convert the entries from `carapace --list` to empty
|
||||
# xdg.configFile."fish/completions/NAME.fish" entries.
|
||||
#
|
||||
# This is to disable fish builtin completion for each of the
|
||||
# carapace-supported completions.
|
||||
#
|
||||
# This is necessary for carapace to properly work with fish version < 4.0b1.
|
||||
#
|
||||
# It is in line with the instructions from
|
||||
# carapace-bin:
|
||||
#
|
||||
# carapace --list | awk '{print $1}' | xargs -I{} touch ~/.config/fish/completions/{}.fish
|
||||
#
|
||||
# See https://carapace-sh.github.io/carapace-bin/setup.html#fish
|
||||
let
|
||||
carapaceListFile =
|
||||
pkgs.runCommandLocal "carapace-list"
|
||||
{
|
||||
buildInputs = [ cfg.package ];
|
||||
}
|
||||
''
|
||||
${bin} --list > $out
|
||||
'';
|
||||
in
|
||||
lib.pipe carapaceListFile [
|
||||
lib.fileContents
|
||||
(lib.splitString "\n")
|
||||
(map (builtins.match "^([a-z0-9-]+) .*"))
|
||||
(builtins.filter (match: match != null && (builtins.length match) > 0))
|
||||
(map (match: builtins.head match))
|
||||
(map (name: {
|
||||
name = "fish/completions/${name}.fish";
|
||||
value = {
|
||||
text = "";
|
||||
};
|
||||
}))
|
||||
builtins.listToAttrs
|
||||
]
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.cava;
|
||||
|
||||
iniFmt = pkgs.formats.ini { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.bddvlpr ];
|
||||
|
||||
options.programs.cava = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption;
|
||||
|
||||
|
|
@ -8,7 +13,8 @@ let
|
|||
|
||||
jsonFmt = pkgs.formats.json { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.bricked ];
|
||||
|
||||
options.programs.cavalier = {
|
||||
|
|
@ -75,8 +81,7 @@ in {
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.cavalier" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.cavalier" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
||||
|
|
@ -11,11 +16,13 @@ let
|
|||
"vivaldi"
|
||||
];
|
||||
|
||||
browserModule = defaultPkg: name: visible:
|
||||
browserModule =
|
||||
defaultPkg: name: visible:
|
||||
let
|
||||
browser = (builtins.parseDrvName defaultPkg.name).name;
|
||||
isProprietaryChrome = lib.hasPrefix "Google Chrome" name;
|
||||
in {
|
||||
in
|
||||
{
|
||||
enable = mkOption {
|
||||
inherit visible;
|
||||
type = types.bool;
|
||||
|
|
@ -36,7 +43,10 @@ let
|
|||
inherit visible;
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--enable-logging=stderr" "--ignore-gpu-blocklist" ];
|
||||
example = [
|
||||
"--enable-logging=stderr"
|
||||
"--ignore-gpu-blocklist"
|
||||
];
|
||||
description = ''
|
||||
List of command-line arguments to be passed to ${name}.
|
||||
|
||||
|
|
@ -47,12 +57,14 @@ let
|
|||
[Chromium codesearch](https://source.chromium.org/search?q=file:switches.cc&ss=chromium%2Fchromium%2Fsrc).
|
||||
'';
|
||||
};
|
||||
} // lib.optionalAttrs (!isProprietaryChrome) {
|
||||
}
|
||||
// lib.optionalAttrs (!isProprietaryChrome) {
|
||||
# Extensions do not work with Google Chrome
|
||||
# see https://github.com/nix-community/home-manager/issues/1383
|
||||
extensions = mkOption {
|
||||
inherit visible;
|
||||
type = with types;
|
||||
type =
|
||||
with types;
|
||||
let
|
||||
extensionType = submodule {
|
||||
options = {
|
||||
|
|
@ -93,7 +105,8 @@ let
|
|||
};
|
||||
};
|
||||
};
|
||||
in listOf (coercedTo str (v: { id = v; }) extensionType);
|
||||
in
|
||||
listOf (coercedTo str (v: { id = v; }) extensionType);
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[
|
||||
|
|
@ -149,7 +162,8 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
browserConfig = cfg:
|
||||
browserConfig =
|
||||
cfg:
|
||||
let
|
||||
|
||||
drvName = (builtins.parseDrvName cfg.package.name).name;
|
||||
|
|
@ -164,23 +178,33 @@ let
|
|||
brave = "BraveSoftware/Brave-Browser";
|
||||
};
|
||||
|
||||
linuxDirs = { brave = "BraveSoftware/Brave-Browser"; };
|
||||
linuxDirs = {
|
||||
brave = "BraveSoftware/Brave-Browser";
|
||||
};
|
||||
|
||||
configDir = if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/" + (darwinDirs."${browser}" or browser)
|
||||
else
|
||||
"${config.xdg.configHome}/" + (linuxDirs."${browser}" or browser);
|
||||
configDir =
|
||||
if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/" + (darwinDirs."${browser}" or browser)
|
||||
else
|
||||
"${config.xdg.configHome}/" + (linuxDirs."${browser}" or browser);
|
||||
|
||||
extensionJson = ext:
|
||||
extensionJson =
|
||||
ext:
|
||||
assert ext.crxPath != null -> ext.version != null;
|
||||
with builtins; {
|
||||
with builtins;
|
||||
{
|
||||
name = "${configDir}/External Extensions/${ext.id}.json";
|
||||
value.text = toJSON (if ext.crxPath != null then {
|
||||
external_crx = ext.crxPath;
|
||||
external_version = ext.version;
|
||||
} else {
|
||||
external_update_url = ext.updateUrl;
|
||||
});
|
||||
value.text = toJSON (
|
||||
if ext.crxPath != null then
|
||||
{
|
||||
external_crx = ext.crxPath;
|
||||
external_version = ext.version;
|
||||
}
|
||||
else
|
||||
{
|
||||
external_update_url = ext.updateUrl;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
dictionary = pkg: {
|
||||
|
|
@ -193,48 +217,61 @@ let
|
|||
paths = cfg.nativeMessagingHosts;
|
||||
};
|
||||
|
||||
package = if cfg.commandLineArgs != [ ] then
|
||||
cfg.package.override {
|
||||
commandLineArgs = lib.concatStringsSep " " cfg.commandLineArgs;
|
||||
}
|
||||
else
|
||||
cfg.package;
|
||||
package =
|
||||
if cfg.commandLineArgs != [ ] then
|
||||
cfg.package.override {
|
||||
commandLineArgs = lib.concatStringsSep " " cfg.commandLineArgs;
|
||||
}
|
||||
else
|
||||
cfg.package;
|
||||
|
||||
in lib.mkIf cfg.enable {
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
home.packages = [ package ];
|
||||
home.file = lib.optionalAttrs (!isProprietaryChrome) (lib.listToAttrs
|
||||
((map extensionJson cfg.extensions)
|
||||
++ (map dictionary cfg.dictionaries)) // {
|
||||
"${configDir}/NativeMessagingHosts" =
|
||||
lib.mkIf (cfg.nativeMessagingHosts != [ ]) {
|
||||
source =
|
||||
"${nativeMessagingHostsJoined}/etc/chromium/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
});
|
||||
home.file = lib.optionalAttrs (!isProprietaryChrome) (
|
||||
lib.listToAttrs ((map extensionJson cfg.extensions) ++ (map dictionary cfg.dictionaries))
|
||||
// {
|
||||
"${configDir}/NativeMessagingHosts" = lib.mkIf (cfg.nativeMessagingHosts != [ ]) {
|
||||
source = "${nativeMessagingHostsJoined}/etc/chromium/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
# Extensions do not work with the proprietary Google Chrome version
|
||||
# see https://github.com/nix-community/home-manager/issues/1383
|
||||
imports = map (lib.flip lib.mkRemovedOptionModule
|
||||
"The `extensions` option does not work on Google Chrome anymore.") [
|
||||
[ "programs" "google-chrome" "extensions" ]
|
||||
[ "programs" "google-chrome-beta" "extensions" ]
|
||||
[ "programs" "google-chrome-dev" "extensions" ]
|
||||
];
|
||||
imports =
|
||||
map
|
||||
(lib.flip lib.mkRemovedOptionModule "The `extensions` option does not work on Google Chrome anymore.")
|
||||
[
|
||||
[
|
||||
"programs"
|
||||
"google-chrome"
|
||||
"extensions"
|
||||
]
|
||||
[
|
||||
"programs"
|
||||
"google-chrome-beta"
|
||||
"extensions"
|
||||
]
|
||||
[
|
||||
"programs"
|
||||
"google-chrome-dev"
|
||||
"extensions"
|
||||
]
|
||||
];
|
||||
|
||||
options.programs = {
|
||||
chromium = browserModule pkgs.chromium "Chromium" true;
|
||||
google-chrome = browserModule pkgs.google-chrome "Google Chrome" false;
|
||||
google-chrome-beta =
|
||||
browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
|
||||
google-chrome-dev =
|
||||
browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
|
||||
google-chrome-beta = browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
|
||||
google-chrome-dev = browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
|
||||
brave = browserModule pkgs.brave "Brave Browser" false;
|
||||
vivaldi = browserModule pkgs.vivaldi "Vivaldi Browser" false;
|
||||
};
|
||||
|
||||
config = lib.mkMerge
|
||||
(map (browser: browserConfig config.programs.${browser}) supportedBrowsers);
|
||||
config = lib.mkMerge (map (browser: browserConfig config.programs.${browser}) supportedBrowsers);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.cmus;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.cmus;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.joygnu ];
|
||||
|
||||
options.programs.cmus = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
# Adapted from Nixpkgs.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.command-not-found;
|
||||
commandNotFound = pkgs.substituteAll {
|
||||
|
|
@ -9,7 +14,10 @@ let
|
|||
src = ./command-not-found.pl;
|
||||
isExecutable = true;
|
||||
inherit (cfg) dbPath;
|
||||
perl = pkgs.perl.withPackages (p: [ p.DBDSQLite p.StringShellQuote ]);
|
||||
perl = pkgs.perl.withPackages (p: [
|
||||
p.DBDSQLite
|
||||
p.StringShellQuote
|
||||
]);
|
||||
};
|
||||
|
||||
shInit = commandNotFoundHandlerName: ''
|
||||
|
|
@ -26,13 +34,13 @@ let
|
|||
}
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.programs.command-not-found = {
|
||||
enable = lib.mkEnableOption "command-not-found hook for interactive shell";
|
||||
|
||||
dbPath = lib.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 = ''
|
||||
Absolute path to {file}`programs.sqlite`. By
|
||||
default this file will be provided by your channel
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.programs.comodoro;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ soywod ];
|
||||
|
||||
options.programs.comodoro = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.darcs;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.darcs;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ chris-martin ];
|
||||
|
||||
options = {
|
||||
|
|
@ -23,24 +30,28 @@ in {
|
|||
boring = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "^.idea$" ".iml$" "^.stack-work$" ];
|
||||
example = [
|
||||
"^.idea$"
|
||||
".iml$"
|
||||
"^.stack-work$"
|
||||
];
|
||||
description = "File patterns to ignore";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{ home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; }
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{ home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; }
|
||||
|
||||
(lib.mkIf (cfg.author != [ ]) {
|
||||
home.file.".darcs/author".text =
|
||||
lib.concatMapStrings (x: x + "\n") cfg.author;
|
||||
})
|
||||
(lib.mkIf (cfg.author != [ ]) {
|
||||
home.file.".darcs/author".text = lib.concatMapStrings (x: x + "\n") cfg.author;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.boring != [ ]) {
|
||||
home.file.".darcs/boring".text =
|
||||
lib.concatMapStrings (x: x + "\n") cfg.boring;
|
||||
})
|
||||
(lib.mkIf (cfg.boring != [ ]) {
|
||||
home.file.".darcs/boring".text = lib.concatMapStrings (x: x + "\n") cfg.boring;
|
||||
})
|
||||
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,21 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkDefault mkIf mkOption types;
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
cfg = config.programs.dircolors;
|
||||
|
||||
formatLine = n: v: "${n} ${toString v}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.justinlovinger ];
|
||||
|
||||
options.programs.dircolors = {
|
||||
|
|
@ -19,14 +30,11 @@ in {
|
|||
|
||||
package = lib.mkPackageOption pkgs "dircolors" { default = "coreutils"; };
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
|
|
@ -54,169 +62,175 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
dircolorsPath = if config.home.preferXdgDirectories then
|
||||
"${config.xdg.configHome}/dir_colors"
|
||||
else
|
||||
"~/.dir_colors";
|
||||
config =
|
||||
let
|
||||
dircolorsPath =
|
||||
if config.home.preferXdgDirectories then "${config.xdg.configHome}/dir_colors" else "~/.dir_colors";
|
||||
|
||||
dircolorsConfig = lib.concatStringsSep "\n" ([ ]
|
||||
++ lib.mapAttrsToList formatLine cfg.settings ++ [ "" ]
|
||||
++ lib.optional (cfg.extraConfig != "") cfg.extraConfig);
|
||||
in mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
# Add default settings from `dircolors --print-database`.
|
||||
programs.dircolors.settings = {
|
||||
RESET = mkDefault "0";
|
||||
DIR = mkDefault "01;34";
|
||||
LINK = mkDefault "01;36";
|
||||
MULTIHARDLINK = mkDefault "00";
|
||||
FIFO = mkDefault "40;33";
|
||||
SOCK = mkDefault "01;35";
|
||||
DOOR = mkDefault "01;35";
|
||||
BLK = mkDefault "40;33;01";
|
||||
CHR = mkDefault "40;33;01";
|
||||
ORPHAN = mkDefault "40;31;01";
|
||||
MISSING = mkDefault "00";
|
||||
SETUID = mkDefault "37;41";
|
||||
SETGID = mkDefault "30;43";
|
||||
CAPABILITY = mkDefault "30;41";
|
||||
STICKY_OTHER_WRITABLE = mkDefault "30;42";
|
||||
OTHER_WRITABLE = mkDefault "34;42";
|
||||
STICKY = mkDefault "37;44";
|
||||
EXEC = mkDefault "01;32";
|
||||
".tar" = mkDefault "01;31";
|
||||
".tgz" = mkDefault "01;31";
|
||||
".arc" = mkDefault "01;31";
|
||||
".arj" = mkDefault "01;31";
|
||||
".taz" = mkDefault "01;31";
|
||||
".lha" = mkDefault "01;31";
|
||||
".lz4" = mkDefault "01;31";
|
||||
".lzh" = mkDefault "01;31";
|
||||
".lzma" = mkDefault "01;31";
|
||||
".tlz" = mkDefault "01;31";
|
||||
".txz" = mkDefault "01;31";
|
||||
".tzo" = mkDefault "01;31";
|
||||
".t7z" = mkDefault "01;31";
|
||||
".zip" = mkDefault "01;31";
|
||||
".z" = mkDefault "01;31";
|
||||
".dz" = mkDefault "01;31";
|
||||
".gz" = mkDefault "01;31";
|
||||
".lrz" = mkDefault "01;31";
|
||||
".lz" = mkDefault "01;31";
|
||||
".lzo" = mkDefault "01;31";
|
||||
".xz" = mkDefault "01;31";
|
||||
".zst" = mkDefault "01;31";
|
||||
".tzst" = mkDefault "01;31";
|
||||
".bz2" = mkDefault "01;31";
|
||||
".bz" = mkDefault "01;31";
|
||||
".tbz" = mkDefault "01;31";
|
||||
".tbz2" = mkDefault "01;31";
|
||||
".tz" = mkDefault "01;31";
|
||||
".deb" = mkDefault "01;31";
|
||||
".rpm" = mkDefault "01;31";
|
||||
".jar" = mkDefault "01;31";
|
||||
".war" = mkDefault "01;31";
|
||||
".ear" = mkDefault "01;31";
|
||||
".sar" = mkDefault "01;31";
|
||||
".rar" = mkDefault "01;31";
|
||||
".alz" = mkDefault "01;31";
|
||||
".ace" = mkDefault "01;31";
|
||||
".zoo" = mkDefault "01;31";
|
||||
".cpio" = mkDefault "01;31";
|
||||
".7z" = mkDefault "01;31";
|
||||
".rz" = mkDefault "01;31";
|
||||
".cab" = mkDefault "01;31";
|
||||
".wim" = mkDefault "01;31";
|
||||
".swm" = mkDefault "01;31";
|
||||
".dwm" = mkDefault "01;31";
|
||||
".esd" = mkDefault "01;31";
|
||||
".jpg" = mkDefault "01;35";
|
||||
".jpeg" = mkDefault "01;35";
|
||||
".mjpg" = mkDefault "01;35";
|
||||
".mjpeg" = mkDefault "01;35";
|
||||
".gif" = mkDefault "01;35";
|
||||
".bmp" = mkDefault "01;35";
|
||||
".pbm" = mkDefault "01;35";
|
||||
".pgm" = mkDefault "01;35";
|
||||
".ppm" = mkDefault "01;35";
|
||||
".tga" = mkDefault "01;35";
|
||||
".xbm" = mkDefault "01;35";
|
||||
".xpm" = mkDefault "01;35";
|
||||
".tif" = mkDefault "01;35";
|
||||
".tiff" = mkDefault "01;35";
|
||||
".png" = mkDefault "01;35";
|
||||
".svg" = mkDefault "01;35";
|
||||
".svgz" = mkDefault "01;35";
|
||||
".mng" = mkDefault "01;35";
|
||||
".pcx" = mkDefault "01;35";
|
||||
".mov" = mkDefault "01;35";
|
||||
".mpg" = mkDefault "01;35";
|
||||
".mpeg" = mkDefault "01;35";
|
||||
".m2v" = mkDefault "01;35";
|
||||
".mkv" = mkDefault "01;35";
|
||||
".webm" = mkDefault "01;35";
|
||||
".ogm" = mkDefault "01;35";
|
||||
".mp4" = mkDefault "01;35";
|
||||
".m4v" = mkDefault "01;35";
|
||||
".mp4v" = mkDefault "01;35";
|
||||
".vob" = mkDefault "01;35";
|
||||
".qt" = mkDefault "01;35";
|
||||
".nuv" = mkDefault "01;35";
|
||||
".wmv" = mkDefault "01;35";
|
||||
".asf" = mkDefault "01;35";
|
||||
".rm" = mkDefault "01;35";
|
||||
".rmvb" = mkDefault "01;35";
|
||||
".flc" = mkDefault "01;35";
|
||||
".avi" = mkDefault "01;35";
|
||||
".fli" = mkDefault "01;35";
|
||||
".flv" = mkDefault "01;35";
|
||||
".gl" = mkDefault "01;35";
|
||||
".dl" = mkDefault "01;35";
|
||||
".xcf" = mkDefault "01;35";
|
||||
".xwd" = mkDefault "01;35";
|
||||
".yuv" = mkDefault "01;35";
|
||||
".cgm" = mkDefault "01;35";
|
||||
".emf" = mkDefault "01;35";
|
||||
".ogv" = mkDefault "01;35";
|
||||
".ogx" = mkDefault "01;35";
|
||||
".aac" = mkDefault "00;36";
|
||||
".au" = mkDefault "00;36";
|
||||
".flac" = mkDefault "00;36";
|
||||
".m4a" = mkDefault "00;36";
|
||||
".mid" = mkDefault "00;36";
|
||||
".midi" = mkDefault "00;36";
|
||||
".mka" = mkDefault "00;36";
|
||||
".mp3" = mkDefault "00;36";
|
||||
".mpc" = mkDefault "00;36";
|
||||
".ogg" = mkDefault "00;36";
|
||||
".ra" = mkDefault "00;36";
|
||||
".wav" = mkDefault "00;36";
|
||||
".oga" = mkDefault "00;36";
|
||||
".opus" = mkDefault "00;36";
|
||||
".spx" = mkDefault "00;36";
|
||||
".xspf" = mkDefault "00;36";
|
||||
};
|
||||
dircolorsConfig = lib.concatStringsSep "\n" (
|
||||
[ ]
|
||||
++ lib.mapAttrsToList formatLine cfg.settings
|
||||
++ [ "" ]
|
||||
++ lib.optional (cfg.extraConfig != "") cfg.extraConfig
|
||||
);
|
||||
in
|
||||
mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
# Add default settings from `dircolors --print-database`.
|
||||
programs.dircolors.settings = {
|
||||
RESET = mkDefault "0";
|
||||
DIR = mkDefault "01;34";
|
||||
LINK = mkDefault "01;36";
|
||||
MULTIHARDLINK = mkDefault "00";
|
||||
FIFO = mkDefault "40;33";
|
||||
SOCK = mkDefault "01;35";
|
||||
DOOR = mkDefault "01;35";
|
||||
BLK = mkDefault "40;33;01";
|
||||
CHR = mkDefault "40;33;01";
|
||||
ORPHAN = mkDefault "40;31;01";
|
||||
MISSING = mkDefault "00";
|
||||
SETUID = mkDefault "37;41";
|
||||
SETGID = mkDefault "30;43";
|
||||
CAPABILITY = mkDefault "30;41";
|
||||
STICKY_OTHER_WRITABLE = mkDefault "30;42";
|
||||
OTHER_WRITABLE = mkDefault "34;42";
|
||||
STICKY = mkDefault "37;44";
|
||||
EXEC = mkDefault "01;32";
|
||||
".tar" = mkDefault "01;31";
|
||||
".tgz" = mkDefault "01;31";
|
||||
".arc" = mkDefault "01;31";
|
||||
".arj" = mkDefault "01;31";
|
||||
".taz" = mkDefault "01;31";
|
||||
".lha" = mkDefault "01;31";
|
||||
".lz4" = mkDefault "01;31";
|
||||
".lzh" = mkDefault "01;31";
|
||||
".lzma" = mkDefault "01;31";
|
||||
".tlz" = mkDefault "01;31";
|
||||
".txz" = mkDefault "01;31";
|
||||
".tzo" = mkDefault "01;31";
|
||||
".t7z" = mkDefault "01;31";
|
||||
".zip" = mkDefault "01;31";
|
||||
".z" = mkDefault "01;31";
|
||||
".dz" = mkDefault "01;31";
|
||||
".gz" = mkDefault "01;31";
|
||||
".lrz" = mkDefault "01;31";
|
||||
".lz" = mkDefault "01;31";
|
||||
".lzo" = mkDefault "01;31";
|
||||
".xz" = mkDefault "01;31";
|
||||
".zst" = mkDefault "01;31";
|
||||
".tzst" = mkDefault "01;31";
|
||||
".bz2" = mkDefault "01;31";
|
||||
".bz" = mkDefault "01;31";
|
||||
".tbz" = mkDefault "01;31";
|
||||
".tbz2" = mkDefault "01;31";
|
||||
".tz" = mkDefault "01;31";
|
||||
".deb" = mkDefault "01;31";
|
||||
".rpm" = mkDefault "01;31";
|
||||
".jar" = mkDefault "01;31";
|
||||
".war" = mkDefault "01;31";
|
||||
".ear" = mkDefault "01;31";
|
||||
".sar" = mkDefault "01;31";
|
||||
".rar" = mkDefault "01;31";
|
||||
".alz" = mkDefault "01;31";
|
||||
".ace" = mkDefault "01;31";
|
||||
".zoo" = mkDefault "01;31";
|
||||
".cpio" = mkDefault "01;31";
|
||||
".7z" = mkDefault "01;31";
|
||||
".rz" = mkDefault "01;31";
|
||||
".cab" = mkDefault "01;31";
|
||||
".wim" = mkDefault "01;31";
|
||||
".swm" = mkDefault "01;31";
|
||||
".dwm" = mkDefault "01;31";
|
||||
".esd" = mkDefault "01;31";
|
||||
".jpg" = mkDefault "01;35";
|
||||
".jpeg" = mkDefault "01;35";
|
||||
".mjpg" = mkDefault "01;35";
|
||||
".mjpeg" = mkDefault "01;35";
|
||||
".gif" = mkDefault "01;35";
|
||||
".bmp" = mkDefault "01;35";
|
||||
".pbm" = mkDefault "01;35";
|
||||
".pgm" = mkDefault "01;35";
|
||||
".ppm" = mkDefault "01;35";
|
||||
".tga" = mkDefault "01;35";
|
||||
".xbm" = mkDefault "01;35";
|
||||
".xpm" = mkDefault "01;35";
|
||||
".tif" = mkDefault "01;35";
|
||||
".tiff" = mkDefault "01;35";
|
||||
".png" = mkDefault "01;35";
|
||||
".svg" = mkDefault "01;35";
|
||||
".svgz" = mkDefault "01;35";
|
||||
".mng" = mkDefault "01;35";
|
||||
".pcx" = mkDefault "01;35";
|
||||
".mov" = mkDefault "01;35";
|
||||
".mpg" = mkDefault "01;35";
|
||||
".mpeg" = mkDefault "01;35";
|
||||
".m2v" = mkDefault "01;35";
|
||||
".mkv" = mkDefault "01;35";
|
||||
".webm" = mkDefault "01;35";
|
||||
".ogm" = mkDefault "01;35";
|
||||
".mp4" = mkDefault "01;35";
|
||||
".m4v" = mkDefault "01;35";
|
||||
".mp4v" = mkDefault "01;35";
|
||||
".vob" = mkDefault "01;35";
|
||||
".qt" = mkDefault "01;35";
|
||||
".nuv" = mkDefault "01;35";
|
||||
".wmv" = mkDefault "01;35";
|
||||
".asf" = mkDefault "01;35";
|
||||
".rm" = mkDefault "01;35";
|
||||
".rmvb" = mkDefault "01;35";
|
||||
".flc" = mkDefault "01;35";
|
||||
".avi" = mkDefault "01;35";
|
||||
".fli" = mkDefault "01;35";
|
||||
".flv" = mkDefault "01;35";
|
||||
".gl" = mkDefault "01;35";
|
||||
".dl" = mkDefault "01;35";
|
||||
".xcf" = mkDefault "01;35";
|
||||
".xwd" = mkDefault "01;35";
|
||||
".yuv" = mkDefault "01;35";
|
||||
".cgm" = mkDefault "01;35";
|
||||
".emf" = mkDefault "01;35";
|
||||
".ogv" = mkDefault "01;35";
|
||||
".ogx" = mkDefault "01;35";
|
||||
".aac" = mkDefault "00;36";
|
||||
".au" = mkDefault "00;36";
|
||||
".flac" = mkDefault "00;36";
|
||||
".m4a" = mkDefault "00;36";
|
||||
".mid" = mkDefault "00;36";
|
||||
".midi" = mkDefault "00;36";
|
||||
".mka" = mkDefault "00;36";
|
||||
".mp3" = mkDefault "00;36";
|
||||
".mpc" = mkDefault "00;36";
|
||||
".ogg" = mkDefault "00;36";
|
||||
".ra" = mkDefault "00;36";
|
||||
".wav" = mkDefault "00;36";
|
||||
".oga" = mkDefault "00;36";
|
||||
".opus" = mkDefault "00;36";
|
||||
".spx" = mkDefault "00;36";
|
||||
".xspf" = mkDefault "00;36";
|
||||
};
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
eval $(${lib.getExe' cfg.package "dircolors"} -b ${dircolorsPath})
|
||||
'';
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
eval $(${lib.getExe' cfg.package "dircolors"} -b ${dircolorsPath})
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
eval (${lib.getExe' cfg.package "dircolors"} -c ${dircolorsPath})
|
||||
'';
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
eval (${lib.getExe' cfg.package "dircolors"} -c ${dircolorsPath})
|
||||
'';
|
||||
|
||||
# Set `LS_COLORS` before Oh My Zsh and `initExtra`.
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration
|
||||
(lib.mkOrder 550 ''
|
||||
eval $(${lib.getExe' cfg.package "dircolors"} -b ${dircolorsPath})
|
||||
'');
|
||||
}
|
||||
(mkIf (!config.home.preferXdgDirectories) {
|
||||
home.file.".dir_colors".text = dircolorsConfig;
|
||||
})
|
||||
(mkIf config.home.preferXdgDirectories {
|
||||
xdg.configFile.dir_colors.text = dircolorsConfig;
|
||||
})
|
||||
]);
|
||||
# Set `LS_COLORS` before Oh My Zsh and `initExtra`.
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration (
|
||||
lib.mkOrder 550 ''
|
||||
eval $(${lib.getExe' cfg.package "dircolors"} -b ${dircolorsPath})
|
||||
''
|
||||
);
|
||||
}
|
||||
(mkIf (!config.home.preferXdgDirectories) {
|
||||
home.file.".dir_colors".text = dircolorsConfig;
|
||||
})
|
||||
(mkIf config.home.preferXdgDirectories {
|
||||
xdg.configFile.dir_colors.text = dircolorsConfig;
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,50 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
mkOption mkRenamedOptionModule mkRemovedOptionModule mkEnableOption types
|
||||
mkPackageOption mkIf mkAfter getExe;
|
||||
mkOption
|
||||
mkRenamedOptionModule
|
||||
mkRemovedOptionModule
|
||||
mkEnableOption
|
||||
types
|
||||
mkPackageOption
|
||||
mkIf
|
||||
mkAfter
|
||||
getExe
|
||||
;
|
||||
|
||||
cfg = config.programs.direnv;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [
|
||||
(mkRenamedOptionModule
|
||||
[
|
||||
"programs"
|
||||
"direnv"
|
||||
"enableNixDirenvIntegration"
|
||||
]
|
||||
[ "programs" "direnv" "nix-direnv" "enable" ]
|
||||
)
|
||||
(mkRemovedOptionModule [
|
||||
"programs"
|
||||
"direnv"
|
||||
"enableNixDirenvIntegration"
|
||||
] [ "programs" "direnv" "nix-direnv" "enable" ])
|
||||
(mkRemovedOptionModule [ "programs" "direnv" "nix-direnv" "enableFlakes" ]
|
||||
"Flake support is now always enabled.")
|
||||
"nix-direnv"
|
||||
"enableFlakes"
|
||||
] "Flake support is now always enabled.")
|
||||
];
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ khaneliman rycee shikanime ];
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
khaneliman
|
||||
rycee
|
||||
shikanime
|
||||
];
|
||||
|
||||
options.programs.direnv = {
|
||||
enable = mkEnableOption "direnv, the environment switcher";
|
||||
|
|
@ -48,32 +73,31 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption {
|
||||
inherit config;
|
||||
extraDescription = ''
|
||||
Note, enabling the direnv module will always activate its functionality
|
||||
for Fish since the direnv package automatically gets loaded in Fish.
|
||||
If this is not the case try adding
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption {
|
||||
inherit config;
|
||||
extraDescription = ''
|
||||
Note, enabling the direnv module will always activate its functionality
|
||||
for Fish since the direnv package automatically gets loaded in Fish.
|
||||
If this is not the case try adding
|
||||
|
||||
```nix
|
||||
environment.pathsToLink = [ "/share/fish" ];
|
||||
```
|
||||
```nix
|
||||
environment.pathsToLink = [ "/share/fish" ];
|
||||
```
|
||||
|
||||
to the system configuration.
|
||||
'';
|
||||
} // {
|
||||
default = true;
|
||||
readOnly = true;
|
||||
};
|
||||
to the system configuration.
|
||||
'';
|
||||
}
|
||||
// {
|
||||
default = true;
|
||||
readOnly = true;
|
||||
};
|
||||
|
||||
enableNushellIntegration =
|
||||
lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
nix-direnv = {
|
||||
enable = mkEnableOption ''
|
||||
|
|
@ -105,8 +129,7 @@ in {
|
|||
source = "${cfg.nix-direnv.package}/share/nix-direnv/direnvrc";
|
||||
};
|
||||
|
||||
xdg.configFile."direnv/direnvrc" =
|
||||
lib.mkIf (cfg.stdlib != "") { text = cfg.stdlib; };
|
||||
xdg.configFile."direnv/direnvrc" = lib.mkIf (cfg.stdlib != "") { text = cfg.stdlib; };
|
||||
|
||||
xdg.configFile."direnv/lib/hm-mise.sh" = mkIf cfg.mise.enable {
|
||||
text = ''
|
||||
|
|
@ -119,7 +142,8 @@ in {
|
|||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
eval "$(${getExe cfg.package} hook bash)"
|
||||
'');
|
||||
''
|
||||
);
|
||||
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${getExe cfg.package} hook zsh)"
|
||||
|
|
@ -130,7 +154,8 @@ in {
|
|||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
${getExe cfg.package} hook fish | source
|
||||
'');
|
||||
''
|
||||
);
|
||||
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.discocss;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.discocss;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ kranzes ];
|
||||
|
||||
options = {
|
||||
programs.discocss = {
|
||||
enable = lib.mkEnableOption
|
||||
"discocss, a tiny Discord CSS injector for Linux and MacOS";
|
||||
enable = lib.mkEnableOption "discocss, a tiny Discord CSS injector for Linux and MacOS";
|
||||
|
||||
package = lib.mkPackageOption pkgs "discocss" { nullable = true; };
|
||||
|
||||
|
|
@ -27,13 +33,13 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [{
|
||||
assertion = cfg.discordAlias
|
||||
-> !(lib.any (p: p.name == cfg.discordPackage.name)
|
||||
config.home.packages);
|
||||
message =
|
||||
"To use discocss with discordAlias you have to remove discord from home.packages, or set discordAlias to false.";
|
||||
}];
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
cfg.discordAlias -> !(lib.any (p: p.name == cfg.discordPackage.name) config.home.packages);
|
||||
message = "To use discocss with discordAlias you have to remove discord from home.packages, or set discordAlias to false.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [
|
||||
(cfg.package.override {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,24 @@
|
|||
{ lib, pkgs, config, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) generators types mkIf mkEnableOption mkPackageOption mkOption;
|
||||
inherit (lib)
|
||||
generators
|
||||
types
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
;
|
||||
|
||||
cfg = config.programs.distrobox;
|
||||
|
||||
formatter = pkgs.formats.ini { listsAsDuplicateKeys = true; };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
|
||||
|
||||
options.programs.distrobox = {
|
||||
|
|
@ -57,18 +70,17 @@ in {
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.distrobox" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.distrobox" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."distrobox/containers.ini".source =
|
||||
(formatter.generate "containers.ini" cfg.containers);
|
||||
xdg.configFile."distrobox/containers.ini".source = (
|
||||
formatter.generate "containers.ini" cfg.containers
|
||||
);
|
||||
|
||||
systemd.user.services.distrobox-home-manager = {
|
||||
Unit.Description =
|
||||
"Build the containers declared in ~/.config/distrobox/containers.ini";
|
||||
Unit.Description = "Build the containers declared in ~/.config/distrobox/containers.ini";
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
|
||||
Service.ExecStart = "${pkgs.writeShellScript "distrobox-home-manager" ''
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -6,7 +11,8 @@ let
|
|||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.folliehiyuki ];
|
||||
|
||||
options.programs.earthly = {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption types;
|
||||
|
||||
cfg = config.programs.eclipse;
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
|
|
@ -11,7 +17,10 @@ in {
|
|||
enable = lib.mkEnableOption "Eclipse";
|
||||
|
||||
package = lib.mkPackageOption pkgs "eclipse" {
|
||||
default = [ "eclipses" "eclipse-platform" ];
|
||||
default = [
|
||||
"eclipses"
|
||||
"eclipse-platform"
|
||||
];
|
||||
example = "pkgs.eclipses.eclipse-java";
|
||||
};
|
||||
|
||||
|
|
@ -43,8 +52,9 @@ in {
|
|||
home.packages = [
|
||||
(pkgs.eclipses.eclipseWithPlugins {
|
||||
eclipse = cfg.package;
|
||||
jvmArgs = cfg.jvmArgs ++ lib.optional cfg.enableLombok
|
||||
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
|
||||
jvmArgs =
|
||||
cfg.jvmArgs
|
||||
++ lib.optional cfg.enableLombok "-javaagent:${pkgs.lombok}/share/java/lombok.jar";
|
||||
plugins = cfg.plugins;
|
||||
})
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,17 +1,31 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.emacs;
|
||||
|
||||
# Copied from all-packages.nix, with modifications to support
|
||||
# overrides.
|
||||
emacsPackages = let epkgs = pkgs.emacsPackagesFor cfg.package;
|
||||
in epkgs.overrideScope cfg.overrides;
|
||||
emacsPackages =
|
||||
let
|
||||
epkgs = pkgs.emacsPackagesFor cfg.package;
|
||||
in
|
||||
epkgs.overrideScope cfg.overrides;
|
||||
|
||||
emacsWithPackages = emacsPackages.emacsWithPackages;
|
||||
|
||||
extraPackages = epkgs:
|
||||
extraPackages =
|
||||
epkgs:
|
||||
let
|
||||
packages = cfg.extraPackages epkgs;
|
||||
userConfig = epkgs.trivialBuild {
|
||||
|
|
@ -20,17 +34,18 @@ let
|
|||
version = "0.1.0";
|
||||
packageRequires = packages;
|
||||
};
|
||||
in packages ++ lib.optional (cfg.extraConfig != "") userConfig;
|
||||
in
|
||||
packages ++ lib.optional (cfg.extraConfig != "") userConfig;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
programs.emacs = {
|
||||
enable = lib.mkEnableOption "Emacs";
|
||||
|
||||
package =
|
||||
lib.mkPackageOption pkgs "emacs" { example = "pkgs.emacs25-nox"; };
|
||||
package = lib.mkPackageOption pkgs "emacs" { example = "pkgs.emacs25-nox"; };
|
||||
|
||||
# NOTE: The config is placed in default.el instead of ~/.emacs.d so that
|
||||
# it won't conflict with Emacs configuration frameworks. Users of these
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
cfg = config.programs.eww;
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.mainrs ];
|
||||
|
||||
options.programs.eww = {
|
||||
|
|
@ -21,38 +27,37 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = let ewwCmd = lib.getExe cfg.package;
|
||||
in mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
xdg =
|
||||
mkIf (cfg.configDir != null) { configFile."eww".source = cfg.configDir; };
|
||||
config =
|
||||
let
|
||||
ewwCmd = lib.getExe cfg.package;
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
xdg = mkIf (cfg.configDir != null) { configFile."eww".source = cfg.configDir; };
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ $TERM != "dumb" ]]; then
|
||||
eval "$(${ewwCmd} shell-completions --shell bash)"
|
||||
fi
|
||||
'';
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ $TERM != "dumb" ]]; then
|
||||
eval "$(${ewwCmd} shell-completions --shell bash)"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
if [[ $TERM != "dumb" ]]; then
|
||||
eval "$(${ewwCmd} shell-completions --shell zsh)"
|
||||
fi
|
||||
'';
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration ''
|
||||
if [[ $TERM != "dumb" ]]; then
|
||||
eval "$(${ewwCmd} shell-completions --shell zsh)"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
if test "$TERM" != "dumb"
|
||||
eval "$(${ewwCmd} shell-completions --shell fish)"
|
||||
end
|
||||
'';
|
||||
};
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
if test "$TERM" != "dumb"
|
||||
eval "$(${ewwCmd} shell-completions --shell fish)"
|
||||
end
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +1,76 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let inherit (lib) mkOption optionalAttrs types;
|
||||
in {
|
||||
imports = let
|
||||
msg = ''
|
||||
'programs.eza.enableAliases' has been deprecated and replaced with integration
|
||||
options per shell, for example, 'programs.eza.enableBashIntegration'.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption optionalAttrs types;
|
||||
in
|
||||
{
|
||||
imports =
|
||||
let
|
||||
msg = ''
|
||||
'programs.eza.enableAliases' has been deprecated and replaced with integration
|
||||
options per shell, for example, 'programs.eza.enableBashIntegration'.
|
||||
|
||||
Note, the default for these options is 'true' so if you want to enable the
|
||||
aliases you can simply remove 'programs.eza.enableAliases' from your
|
||||
configuration.'';
|
||||
mkRenamed = opt:
|
||||
lib.mkRenamedOptionModule [ "programs" "exa" opt ] [
|
||||
"programs"
|
||||
"eza"
|
||||
opt
|
||||
];
|
||||
in (map mkRenamed [ "enable" "extraOptions" "icons" "git" ])
|
||||
++ [ (lib.mkRemovedOptionModule [ "programs" "eza" "enableAliases" ] msg) ];
|
||||
Note, the default for these options is 'true' so if you want to enable the
|
||||
aliases you can simply remove 'programs.eza.enableAliases' from your
|
||||
configuration.'';
|
||||
mkRenamed =
|
||||
opt:
|
||||
lib.mkRenamedOptionModule
|
||||
[ "programs" "exa" opt ]
|
||||
[
|
||||
"programs"
|
||||
"eza"
|
||||
opt
|
||||
];
|
||||
in
|
||||
(map mkRenamed [
|
||||
"enable"
|
||||
"extraOptions"
|
||||
"icons"
|
||||
"git"
|
||||
])
|
||||
++ [ (lib.mkRemovedOptionModule [ "programs" "eza" "enableAliases" ] msg) ];
|
||||
|
||||
meta.maintainers = [ lib.maintainers.cafkafk ];
|
||||
|
||||
options.programs.eza = {
|
||||
enable = lib.mkEnableOption "eza, a modern replacement for {command}`ls`";
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableIonIntegration =
|
||||
lib.hm.shell.mkIonIntegrationOption { inherit config; };
|
||||
enableIonIntegration = lib.hm.shell.mkIonIntegrationOption { inherit config; };
|
||||
|
||||
enableNushellIntegration =
|
||||
lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--group-directories-first" "--header" ];
|
||||
example = [
|
||||
"--group-directories-first"
|
||||
"--header"
|
||||
];
|
||||
description = ''
|
||||
Extra command line options passed to eza.
|
||||
'';
|
||||
};
|
||||
|
||||
icons = mkOption {
|
||||
type = types.enum [ null true false "auto" "always" "never" ];
|
||||
type = types.enum [
|
||||
null
|
||||
true
|
||||
false
|
||||
"auto"
|
||||
"always"
|
||||
"never"
|
||||
];
|
||||
default = null;
|
||||
description = ''
|
||||
Display icons next to file names ({option}`--icons` argument).
|
||||
|
|
@ -59,7 +81,12 @@ in {
|
|||
};
|
||||
|
||||
colors = mkOption {
|
||||
type = types.enum [ null "auto" "always" "never" ];
|
||||
type = types.enum [
|
||||
null
|
||||
"auto"
|
||||
"always"
|
||||
"never"
|
||||
];
|
||||
default = null;
|
||||
description = ''
|
||||
Use terminal colors in output ({option}`--color` argument).
|
||||
|
|
@ -77,60 +104,65 @@ in {
|
|||
package = lib.mkPackageOption pkgs "eza" { nullable = true; };
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.programs.eza;
|
||||
config =
|
||||
let
|
||||
cfg = config.programs.eza;
|
||||
|
||||
iconsOption = let
|
||||
v = if lib.isBool cfg.icons then
|
||||
(if cfg.icons then "auto" else null)
|
||||
else
|
||||
cfg.icons;
|
||||
in lib.optionals (v != null) [ "--icons" v ];
|
||||
iconsOption =
|
||||
let
|
||||
v = if lib.isBool cfg.icons then (if cfg.icons then "auto" else null) else cfg.icons;
|
||||
in
|
||||
lib.optionals (v != null) [
|
||||
"--icons"
|
||||
v
|
||||
];
|
||||
|
||||
args = lib.escapeShellArgs (iconsOption
|
||||
++ lib.optionals (cfg.colors != null) [ "--color" cfg.colors ]
|
||||
++ lib.optional cfg.git "--git" ++ cfg.extraOptions);
|
||||
args = lib.escapeShellArgs (
|
||||
iconsOption
|
||||
++ lib.optionals (cfg.colors != null) [
|
||||
"--color"
|
||||
cfg.colors
|
||||
]
|
||||
++ lib.optional cfg.git "--git"
|
||||
++ cfg.extraOptions
|
||||
);
|
||||
|
||||
optionsAlias = optionalAttrs (args != "") { eza = "eza ${args}"; };
|
||||
optionsAlias = optionalAttrs (args != "") { eza = "eza ${args}"; };
|
||||
|
||||
aliases = builtins.mapAttrs (_name: value: lib.mkDefault value) {
|
||||
ls = "eza";
|
||||
ll = "eza -l";
|
||||
la = "eza -a";
|
||||
lt = "eza --tree";
|
||||
lla = "eza -la";
|
||||
aliases = builtins.mapAttrs (_name: value: lib.mkDefault value) {
|
||||
ls = "eza";
|
||||
ll = "eza -l";
|
||||
la = "eza -a";
|
||||
lt = "eza --tree";
|
||||
lla = "eza -la";
|
||||
};
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
warnings = lib.optional (lib.isBool cfg.icons) ''
|
||||
Setting programs.eza.icons to a Boolean is deprecated.
|
||||
Please update your configuration so that
|
||||
|
||||
programs.eza.icons = ${if cfg.icons then ''"auto"'' else "null"}'';
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.bash.shellAliases = optionsAlias // optionalAttrs cfg.enableBashIntegration aliases;
|
||||
|
||||
programs.zsh.shellAliases = optionsAlias // optionalAttrs cfg.enableZshIntegration aliases;
|
||||
|
||||
programs.fish = lib.mkMerge [
|
||||
(lib.mkIf (!config.programs.fish.preferAbbrs) {
|
||||
shellAliases = optionsAlias // optionalAttrs cfg.enableFishIntegration aliases;
|
||||
})
|
||||
|
||||
(lib.mkIf config.programs.fish.preferAbbrs {
|
||||
shellAliases = optionsAlias;
|
||||
shellAbbrs = optionalAttrs cfg.enableFishIntegration aliases;
|
||||
})
|
||||
];
|
||||
|
||||
programs.ion.shellAliases = optionsAlias // optionalAttrs cfg.enableIonIntegration aliases;
|
||||
|
||||
programs.nushell.shellAliases = optionsAlias // optionalAttrs cfg.enableNushellIntegration aliases;
|
||||
};
|
||||
in lib.mkIf cfg.enable {
|
||||
warnings = lib.optional (lib.isBool cfg.icons) ''
|
||||
Setting programs.eza.icons to a Boolean is deprecated.
|
||||
Please update your configuration so that
|
||||
|
||||
programs.eza.icons = ${if cfg.icons then ''"auto"'' else "null"}'';
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.bash.shellAliases = optionsAlias
|
||||
// optionalAttrs cfg.enableBashIntegration aliases;
|
||||
|
||||
programs.zsh.shellAliases = optionsAlias
|
||||
// optionalAttrs cfg.enableZshIntegration aliases;
|
||||
|
||||
programs.fish = lib.mkMerge [
|
||||
(lib.mkIf (!config.programs.fish.preferAbbrs) {
|
||||
shellAliases = optionsAlias
|
||||
// optionalAttrs cfg.enableFishIntegration aliases;
|
||||
})
|
||||
|
||||
(lib.mkIf config.programs.fish.preferAbbrs {
|
||||
shellAliases = optionsAlias;
|
||||
shellAbbrs = optionalAttrs cfg.enableFishIntegration aliases;
|
||||
})
|
||||
];
|
||||
|
||||
programs.ion.shellAliases = optionsAlias
|
||||
// optionalAttrs cfg.enableIonIntegration aliases;
|
||||
|
||||
programs.nushell.shellAliases = optionsAlias
|
||||
// optionalAttrs cfg.enableNushellIntegration aliases;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,28 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkPackageOption mkOption mkIf literalExpression;
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
mkIf
|
||||
literalExpression
|
||||
;
|
||||
|
||||
cfg = config.programs.fastfetch;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
in {
|
||||
meta.maintainers =
|
||||
[ lib.hm.maintainers.afresquet lib.maintainers.khaneliman ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.hm.maintainers.afresquet
|
||||
lib.maintainers.khaneliman
|
||||
];
|
||||
|
||||
options.programs.fastfetch = {
|
||||
enable = mkEnableOption "Fastfetch";
|
||||
|
|
|
|||
|
|
@ -1,16 +1,25 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let inherit (lib) mkOption types;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.uncenter ];
|
||||
|
||||
options.programs.fd = {
|
||||
enable = lib.mkEnableOption
|
||||
"fd, a simple, fast and user-friendly alternative to {command}`find`";
|
||||
enable = lib.mkEnableOption "fd, a simple, fast and user-friendly alternative to {command}`find`";
|
||||
|
||||
ignores = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ ".git/" "*.bak" ];
|
||||
example = [
|
||||
".git/"
|
||||
"*.bak"
|
||||
];
|
||||
description = "List of paths that should be globally ignored.";
|
||||
};
|
||||
|
||||
|
|
@ -25,7 +34,10 @@ in {
|
|||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--no-ignore" "--absolute-path" ];
|
||||
example = [
|
||||
"--no-ignore"
|
||||
"--absolute-path"
|
||||
];
|
||||
description = ''
|
||||
Extra command line options passed to fd.
|
||||
'';
|
||||
|
|
@ -34,28 +46,29 @@ in {
|
|||
package = lib.mkPackageOption pkgs "fd" { nullable = true; };
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.programs.fd;
|
||||
config =
|
||||
let
|
||||
cfg = config.programs.fd;
|
||||
|
||||
args = lib.escapeShellArgs
|
||||
(lib.optional cfg.hidden "--hidden" ++ cfg.extraOptions);
|
||||
args = lib.escapeShellArgs (lib.optional cfg.hidden "--hidden" ++ cfg.extraOptions);
|
||||
|
||||
optionsAlias = lib.optionalAttrs (args != "") { fd = "fd ${args}"; };
|
||||
in lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
optionsAlias = lib.optionalAttrs (args != "") { fd = "fd ${args}"; };
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.bash.shellAliases = optionsAlias;
|
||||
programs.bash.shellAliases = optionsAlias;
|
||||
|
||||
programs.zsh.shellAliases = optionsAlias;
|
||||
programs.zsh.shellAliases = optionsAlias;
|
||||
|
||||
programs.fish.shellAliases = optionsAlias;
|
||||
programs.fish.shellAliases = optionsAlias;
|
||||
|
||||
programs.ion.shellAliases = optionsAlias;
|
||||
programs.ion.shellAliases = optionsAlias;
|
||||
|
||||
programs.nushell.shellAliases = optionsAlias;
|
||||
programs.nushell.shellAliases = optionsAlias;
|
||||
|
||||
xdg.configFile."fd/ignore" = lib.mkIf (cfg.ignores != [ ]) {
|
||||
text = lib.concatStringsSep "\n" cfg.ignores + "\n";
|
||||
xdg.configFile."fd/ignore" = lib.mkIf (cfg.ignores != [ ]) {
|
||||
text = lib.concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,39 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) filterAttrs mapAttrsToList mkOption types;
|
||||
inherit (lib)
|
||||
filterAttrs
|
||||
mapAttrsToList
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.feh;
|
||||
|
||||
bindingsOf = t: with types; attrsOf (nullOr (either t (listOf t)));
|
||||
|
||||
renderThemes = options:
|
||||
renderThemes =
|
||||
options:
|
||||
let
|
||||
render = mapAttrsToList
|
||||
(theme: options: "${theme} ${lib.escapeShellArgs options}");
|
||||
in lib.concatStringsSep "\n" (render options);
|
||||
render = mapAttrsToList (theme: options: "${theme} ${lib.escapeShellArgs options}");
|
||||
in
|
||||
lib.concatStringsSep "\n" (render options);
|
||||
|
||||
renderBindings = bindings:
|
||||
renderBindings =
|
||||
bindings:
|
||||
let
|
||||
enabled = filterAttrs (n: v: v != null) bindings;
|
||||
disabled = filterAttrs (n: v: v == null) bindings;
|
||||
render = mapAttrsToList renderBinding;
|
||||
in lib.concatStringsSep "\n" (render disabled ++ render enabled);
|
||||
in
|
||||
lib.concatStringsSep "\n" (render disabled ++ render enabled);
|
||||
|
||||
renderBinding = func: key:
|
||||
renderBinding =
|
||||
func: key:
|
||||
if key == null then
|
||||
func
|
||||
else if lib.isList key then
|
||||
|
|
@ -27,7 +41,8 @@ let
|
|||
else
|
||||
"${func} ${toString key}";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.programs.feh = {
|
||||
enable = lib.mkEnableOption "feh - a fast and light image viewer";
|
||||
|
||||
|
|
@ -39,7 +54,10 @@ in {
|
|||
example = {
|
||||
zoom_in = 4;
|
||||
zoom_out = "C-4";
|
||||
prev_img = [ 3 "C-3" ];
|
||||
prev_img = [
|
||||
3
|
||||
"C-3"
|
||||
];
|
||||
};
|
||||
description = ''
|
||||
Override feh's default mouse button mapping. If you want to disable an
|
||||
|
|
@ -56,7 +74,10 @@ in {
|
|||
example = {
|
||||
zoom_in = "plus";
|
||||
zoom_out = "minus";
|
||||
prev_img = [ "h" "Left" ];
|
||||
prev_img = [
|
||||
"h"
|
||||
"Left"
|
||||
];
|
||||
};
|
||||
description = ''
|
||||
Override feh's default keybindings. If you want to disable a keybinding
|
||||
|
|
@ -71,10 +92,27 @@ in {
|
|||
default = { };
|
||||
type = with types; attrsOf (listOf str);
|
||||
example = {
|
||||
feh = [ "--image-bg" "black" ];
|
||||
webcam = [ "--multiwindow" "--reload" "20" ];
|
||||
present = [ "--full-screen" "--sort" "name" "--hide-pointer" ];
|
||||
booth = [ "--full-screen" "--hide-pointer" "--slideshow-delay" "20" ];
|
||||
feh = [
|
||||
"--image-bg"
|
||||
"black"
|
||||
];
|
||||
webcam = [
|
||||
"--multiwindow"
|
||||
"--reload"
|
||||
"20"
|
||||
];
|
||||
present = [
|
||||
"--full-screen"
|
||||
"--sort"
|
||||
"name"
|
||||
"--hide-pointer"
|
||||
];
|
||||
booth = [
|
||||
"--full-screen"
|
||||
"--hide-pointer"
|
||||
"--slideshow-delay"
|
||||
"20"
|
||||
];
|
||||
imagemap = [
|
||||
"-rVq"
|
||||
"--thumb-width"
|
||||
|
|
@ -84,7 +122,10 @@ in {
|
|||
"--index-info"
|
||||
"%n\\n%wx%h"
|
||||
];
|
||||
example = [ "--info" "foo bar" ];
|
||||
example = [
|
||||
"--info"
|
||||
"foo bar"
|
||||
];
|
||||
};
|
||||
description = ''
|
||||
Define themes for feh.
|
||||
|
|
@ -96,11 +137,12 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [{
|
||||
assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == { });
|
||||
message =
|
||||
"To disable a keybinding, use `null` instead of an empty string.";
|
||||
}];
|
||||
assertions = [
|
||||
{
|
||||
assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == { });
|
||||
message = "To disable a keybinding, use `null` instead of an empty string.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
|
|
@ -112,7 +154,8 @@ in {
|
|||
text = renderBindings cfg.keybindings + "\n";
|
||||
};
|
||||
|
||||
xdg.configFile."feh/themes" =
|
||||
lib.mkIf (cfg.themes != { }) { text = renderThemes cfg.themes + "\n"; };
|
||||
xdg.configFile."feh/themes" = lib.mkIf (cfg.themes != { }) {
|
||||
text = renderThemes cfg.themes + "\n";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@
|
|||
let
|
||||
inherit (lib) mkRemovedOptionModule;
|
||||
|
||||
modulePath = [ "programs" "firefox" ];
|
||||
modulePath = [
|
||||
"programs"
|
||||
"firefox"
|
||||
];
|
||||
|
||||
moduleName = lib.concatStringsSep "." modulePath;
|
||||
|
||||
mkFirefoxModule = import ./firefox/mkFirefoxModule.nix;
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.maintainers.rycee
|
||||
lib.hm.maintainers.bricked
|
||||
|
|
@ -22,7 +26,9 @@ in {
|
|||
unwrappedPackageName = "firefox-unwrapped";
|
||||
visible = true;
|
||||
|
||||
platforms.linux = { configPath = ".mozilla/firefox"; };
|
||||
platforms.linux = {
|
||||
configPath = ".mozilla/firefox";
|
||||
};
|
||||
platforms.darwin = {
|
||||
configPath = "Library/Application Support/Firefox";
|
||||
};
|
||||
|
|
@ -36,11 +42,14 @@ in {
|
|||
to
|
||||
|
||||
${moduleName}.profiles.myprofile.extensions.packages = [ foo bar ];'')
|
||||
(mkRemovedOptionModule (modulePath ++ [ "enableAdobeFlash" ])
|
||||
"Support for this option has been removed.")
|
||||
(mkRemovedOptionModule (modulePath ++ [ "enableGoogleTalk" ])
|
||||
"Support for this option has been removed.")
|
||||
(mkRemovedOptionModule (modulePath ++ [ "enableIcedTea" ])
|
||||
"Support for this option has been removed.")
|
||||
(mkRemovedOptionModule (
|
||||
modulePath ++ [ "enableAdobeFlash" ]
|
||||
) "Support for this option has been removed.")
|
||||
(mkRemovedOptionModule (
|
||||
modulePath ++ [ "enableGoogleTalk" ]
|
||||
) "Support for this option has been removed.")
|
||||
(mkRemovedOptionModule (
|
||||
modulePath ++ [ "enableIcedTea" ]
|
||||
) "Support for this option has been removed.")
|
||||
];
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -5,71 +5,83 @@ let
|
|||
inherit (builtins) attrValues;
|
||||
inherit (lib) types mkOption;
|
||||
|
||||
in rec {
|
||||
settingsType = with types;
|
||||
in
|
||||
rec {
|
||||
settingsType =
|
||||
with types;
|
||||
coercedTo (addCheck (attrsOf nodeType)
|
||||
# Check whether attribute set is of correct type
|
||||
(attrs: !(attrs ? settings) || nodeType.check attrs.settings)) attrValues
|
||||
(listOf nodeType);
|
||||
# Check whether attribute set is of correct type
|
||||
(attrs: !(attrs ? settings) || nodeType.check attrs.settings)
|
||||
) attrValues (listOf nodeType);
|
||||
|
||||
bookmarkSubmodule = types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Bookmark name.";
|
||||
};
|
||||
bookmarkSubmodule =
|
||||
types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Bookmark name.";
|
||||
};
|
||||
|
||||
tags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "Bookmark tags.";
|
||||
};
|
||||
tags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "Bookmark tags.";
|
||||
};
|
||||
|
||||
keyword = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Bookmark search keyword.";
|
||||
};
|
||||
keyword = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Bookmark search keyword.";
|
||||
};
|
||||
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
description = "Bookmark url, use %s for search terms.";
|
||||
};
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
description = "Bookmark url, use %s for search terms.";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
// {
|
||||
description = "bookmark submodule";
|
||||
};
|
||||
}) // {
|
||||
description = "bookmark submodule";
|
||||
};
|
||||
|
||||
bookmarkType = types.addCheck bookmarkSubmodule (x: x ? "url");
|
||||
|
||||
directoryType = types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Directory name.";
|
||||
};
|
||||
directoryType =
|
||||
types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Directory name.";
|
||||
};
|
||||
|
||||
bookmarks = mkOption {
|
||||
type = types.listOf nodeType;
|
||||
default = [ ];
|
||||
description = "Bookmarks within directory.";
|
||||
};
|
||||
bookmarks = mkOption {
|
||||
type = types.listOf nodeType;
|
||||
default = [ ];
|
||||
description = "Bookmarks within directory.";
|
||||
};
|
||||
|
||||
toolbar = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Make this the toolbar directory. Note, this does _not_
|
||||
mean that this directory will be added to the toolbar,
|
||||
this directory _is_ the toolbar.
|
||||
'';
|
||||
};
|
||||
toolbar = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Make this the toolbar directory. Note, this does _not_
|
||||
mean that this directory will be added to the toolbar,
|
||||
this directory _is_ the toolbar.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
// {
|
||||
description = "directory submodule";
|
||||
};
|
||||
}) // {
|
||||
description = "directory submodule";
|
||||
};
|
||||
|
||||
nodeType = types.either bookmarkType directoryType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,43 @@
|
|||
{ config, lib, pkgs, modulePath }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulePath,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
escapeXML concatStringsSep mkOption maintainers types literalExpression;
|
||||
escapeXML
|
||||
concatStringsSep
|
||||
mkOption
|
||||
maintainers
|
||||
types
|
||||
literalExpression
|
||||
;
|
||||
|
||||
inherit (bookmarkTypes) settingsType;
|
||||
|
||||
bookmarkTypes = import ./bookmark-types.nix { inherit lib; };
|
||||
|
||||
bookmarksFile = bookmarks:
|
||||
bookmarksFile =
|
||||
bookmarks:
|
||||
let
|
||||
indent = level:
|
||||
lib.concatStringsSep "" (map (lib.const " ") (lib.range 1 level));
|
||||
indent = level: lib.concatStringsSep "" (map (lib.const " ") (lib.range 1 level));
|
||||
|
||||
bookmarkToHTML = indentLevel: bookmark:
|
||||
''
|
||||
${indent indentLevel}<DT><A HREF="${
|
||||
escapeXML bookmark.url
|
||||
}" ADD_DATE="1" LAST_MODIFIED="1"${
|
||||
lib.optionalString (bookmark.keyword != null)
|
||||
" SHORTCUTURL=\"${escapeXML bookmark.keyword}\""
|
||||
}${
|
||||
lib.optionalString (bookmark.tags != [ ])
|
||||
" TAGS=\"${escapeXML (concatStringsSep "," bookmark.tags)}\""
|
||||
}>${escapeXML bookmark.name}</A>'';
|
||||
bookmarkToHTML =
|
||||
indentLevel: bookmark:
|
||||
''${indent indentLevel}<DT><A HREF="${escapeXML bookmark.url}" ADD_DATE="1" LAST_MODIFIED="1"${
|
||||
lib.optionalString (bookmark.keyword != null) " SHORTCUTURL=\"${escapeXML bookmark.keyword}\""
|
||||
}${
|
||||
lib.optionalString (
|
||||
bookmark.tags != [ ]
|
||||
) " TAGS=\"${escapeXML (concatStringsSep "," bookmark.tags)}\""
|
||||
}>${escapeXML bookmark.name}</A>'';
|
||||
|
||||
directoryToHTML = indentLevel: directory: ''
|
||||
${indent indentLevel}<DT>${
|
||||
if directory.toolbar then
|
||||
''
|
||||
<H3 ADD_DATE="1" LAST_MODIFIED="1" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar''
|
||||
''<H3 ADD_DATE="1" LAST_MODIFIED="1" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar''
|
||||
else
|
||||
''<H3 ADD_DATE="1" LAST_MODIFIED="1">${escapeXML directory.name}''
|
||||
}</H3>
|
||||
|
|
@ -37,18 +45,16 @@ let
|
|||
${allItemsToHTML (indentLevel + 1) directory.bookmarks}
|
||||
${indent indentLevel}</DL><p>'';
|
||||
|
||||
itemToHTMLOrRecurse = indentLevel: item:
|
||||
if item ? "url" then
|
||||
bookmarkToHTML indentLevel item
|
||||
else
|
||||
directoryToHTML indentLevel item;
|
||||
itemToHTMLOrRecurse =
|
||||
indentLevel: item:
|
||||
if item ? "url" then bookmarkToHTML indentLevel item else directoryToHTML indentLevel item;
|
||||
|
||||
allItemsToHTML = indentLevel: bookmarks:
|
||||
lib.concatStringsSep "\n"
|
||||
(map (itemToHTMLOrRecurse indentLevel) bookmarks);
|
||||
allItemsToHTML =
|
||||
indentLevel: bookmarks: lib.concatStringsSep "\n" (map (itemToHTMLOrRecurse indentLevel) bookmarks);
|
||||
|
||||
bookmarkEntries = allItemsToHTML 1 bookmarks;
|
||||
in pkgs.writeText "bookmarks.html" ''
|
||||
in
|
||||
pkgs.writeText "bookmarks.html" ''
|
||||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
|
|
@ -60,7 +66,8 @@ let
|
|||
${bookmarkEntries}
|
||||
</DL>
|
||||
'';
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(pkgs.path + "/nixos/modules/misc/assertions.nix")
|
||||
(pkgs.path + "/nixos/modules/misc/meta.nix")
|
||||
|
|
@ -131,16 +138,14 @@ in {
|
|||
};
|
||||
|
||||
config = {
|
||||
assertions = [{
|
||||
assertion = config.enable -> config.force;
|
||||
message = ''
|
||||
Using '${
|
||||
lib.showAttrPath (modulePath ++ [ "settings" ])
|
||||
}' will override all previous bookmarks.
|
||||
Enable ${
|
||||
lib.showAttrPath (modulePath ++ [ "force" ])
|
||||
}' to acknowledge this.
|
||||
'';
|
||||
}];
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.enable -> config.force;
|
||||
message = ''
|
||||
Using '${lib.showAttrPath (modulePath ++ [ "settings" ])}' will override all previous bookmarks.
|
||||
Enable ${lib.showAttrPath (modulePath ++ [ "force" ])}' to acknowledge this.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,61 +1,87 @@
|
|||
{ config, lib, pkgs, appName, package, modulePath, profilePath }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
appName,
|
||||
package,
|
||||
modulePath,
|
||||
profilePath,
|
||||
}:
|
||||
let
|
||||
inherit (lib) mapAttrs mapAttrs' mkOption optionalAttrs types warn;
|
||||
inherit (lib)
|
||||
mapAttrs
|
||||
mapAttrs'
|
||||
mkOption
|
||||
optionalAttrs
|
||||
types
|
||||
warn
|
||||
;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
# Map of nice field names to internal field names.
|
||||
# This is intended to be exhaustive and should be
|
||||
# updated at every version bump.
|
||||
internalFieldNames = (lib.genAttrs [
|
||||
"name"
|
||||
"isAppProvided"
|
||||
"loadPath"
|
||||
"updateInterval"
|
||||
"updateURL"
|
||||
"iconMapObj"
|
||||
"metaData"
|
||||
"orderHint"
|
||||
"definedAliases"
|
||||
"urls"
|
||||
] (name: "_${name}")) // {
|
||||
searchForm = "__searchForm";
|
||||
};
|
||||
internalFieldNames =
|
||||
(lib.genAttrs [
|
||||
"name"
|
||||
"isAppProvided"
|
||||
"loadPath"
|
||||
"updateInterval"
|
||||
"updateURL"
|
||||
"iconMapObj"
|
||||
"metaData"
|
||||
"orderHint"
|
||||
"definedAliases"
|
||||
"urls"
|
||||
] (name: "_${name}"))
|
||||
// {
|
||||
searchForm = "__searchForm";
|
||||
};
|
||||
|
||||
# Convenience to specify absolute path to icon
|
||||
iconUrl = icon:
|
||||
if lib.isPath icon || lib.hasPrefix "/" icon then
|
||||
"file://${icon}"
|
||||
else
|
||||
icon;
|
||||
iconUrl = icon: if lib.isPath icon || lib.hasPrefix "/" icon then "file://${icon}" else icon;
|
||||
|
||||
processCustomEngineInput = input:
|
||||
processCustomEngineInput =
|
||||
input:
|
||||
{
|
||||
name = input.id;
|
||||
} // (removeAttrs input [ "icon" ])
|
||||
}
|
||||
// (removeAttrs input [ "icon" ])
|
||||
// optionalAttrs (input ? icon || input ? iconMapObj) {
|
||||
iconMapObj = mapAttrs (name: iconUrl) ((optionalAttrs (input ? icon) {
|
||||
# Convenience to specify single icon instead of map
|
||||
"16" = input.icon;
|
||||
}) // (input.iconMapObj or { }));
|
||||
} // {
|
||||
iconMapObj = mapAttrs (name: iconUrl) (
|
||||
(optionalAttrs (input ? icon) {
|
||||
# Convenience to specify single icon instead of map
|
||||
"16" = input.icon;
|
||||
})
|
||||
// (input.iconMapObj or { })
|
||||
);
|
||||
}
|
||||
// {
|
||||
# Required for custom engine configurations, loadPaths
|
||||
# are unique identifiers that are generally formatted
|
||||
# like: [source]/path/to/engine.xml
|
||||
loadPath = "[home-manager]/${
|
||||
lib.showAttrPath (modulePath ++ [ "engines" input.id ])
|
||||
}";
|
||||
lib.showAttrPath (
|
||||
modulePath
|
||||
++ [
|
||||
"engines"
|
||||
input.id
|
||||
]
|
||||
)
|
||||
}";
|
||||
};
|
||||
|
||||
processEngineInput = id: input:
|
||||
processEngineInput =
|
||||
id: input:
|
||||
let
|
||||
requiredInput = {
|
||||
inherit id;
|
||||
isAppProvided =
|
||||
input.isAppProvided or (removeAttrs input [ "metaData" ] == { });
|
||||
isAppProvided = input.isAppProvided or (removeAttrs input [ "metaData" ] == { });
|
||||
metaData = input.metaData or { };
|
||||
};
|
||||
in if requiredInput.isAppProvided then
|
||||
in
|
||||
if requiredInput.isAppProvided then
|
||||
requiredInput
|
||||
else
|
||||
lib.pipe (input // requiredInput) [
|
||||
|
|
@ -64,105 +90,123 @@ let
|
|||
processCustomEngineInput
|
||||
];
|
||||
|
||||
buildEngineConfig = name: input:
|
||||
buildEngineConfig =
|
||||
name: input:
|
||||
mapAttrs' (name: value: {
|
||||
name = internalFieldNames.${name} or name;
|
||||
inherit value;
|
||||
}) (processEngineInput name input);
|
||||
|
||||
sortEngineConfigs = configs:
|
||||
sortEngineConfigs =
|
||||
configs:
|
||||
let
|
||||
buildEngineConfigWithOrder = order: id:
|
||||
buildEngineConfigWithOrder =
|
||||
order: id:
|
||||
let
|
||||
config = configs.${id} or {
|
||||
inherit id;
|
||||
_isAppProvided = true;
|
||||
_metaData = { };
|
||||
config =
|
||||
configs.${id} or {
|
||||
inherit id;
|
||||
_isAppProvided = true;
|
||||
_metaData = { };
|
||||
};
|
||||
in
|
||||
config
|
||||
// {
|
||||
_metaData = config._metaData // {
|
||||
inherit order;
|
||||
};
|
||||
in config // { _metaData = config._metaData // { inherit order; }; };
|
||||
};
|
||||
|
||||
engineConfigsWithoutOrder =
|
||||
lib.attrValues (removeAttrs configs config.order);
|
||||
engineConfigsWithoutOrder = lib.attrValues (removeAttrs configs config.order);
|
||||
|
||||
sortedEngineConfigs = (lib.imap buildEngineConfigWithOrder config.order)
|
||||
++ engineConfigsWithoutOrder;
|
||||
in sortedEngineConfigs;
|
||||
sortedEngineConfigs =
|
||||
(lib.imap buildEngineConfigWithOrder config.order) ++ engineConfigsWithoutOrder;
|
||||
in
|
||||
sortedEngineConfigs;
|
||||
|
||||
engineInput = config.engines // {
|
||||
# Infer config.default as an app provided
|
||||
# engine if it's not in config.engines
|
||||
${config.default} = config.engines.${config.default} or { };
|
||||
} // {
|
||||
${config.privateDefault} = config.engines.${config.privateDefault} or { };
|
||||
};
|
||||
engineInput =
|
||||
config.engines
|
||||
// {
|
||||
# Infer config.default as an app provided
|
||||
# engine if it's not in config.engines
|
||||
${config.default} = config.engines.${config.default} or { };
|
||||
}
|
||||
// {
|
||||
${config.privateDefault} = config.engines.${config.privateDefault} or { };
|
||||
};
|
||||
|
||||
settings = {
|
||||
version = 12;
|
||||
engines = sortEngineConfigs (mapAttrs buildEngineConfig engineInput);
|
||||
|
||||
metaData = optionalAttrs (config.default != null) {
|
||||
defaultEngineId = config.default;
|
||||
defaultEngineIdHash = "@hash@";
|
||||
} // optionalAttrs (config.privateDefault != null) {
|
||||
privateDefaultEngineId = config.privateDefault;
|
||||
privateDefaultEngineIdHash = "@privateHash@";
|
||||
} // {
|
||||
useSavedOrder = config.order != [ ];
|
||||
};
|
||||
metaData =
|
||||
optionalAttrs (config.default != null) {
|
||||
defaultEngineId = config.default;
|
||||
defaultEngineIdHash = "@hash@";
|
||||
}
|
||||
// optionalAttrs (config.privateDefault != null) {
|
||||
privateDefaultEngineId = config.privateDefault;
|
||||
privateDefaultEngineIdHash = "@privateHash@";
|
||||
}
|
||||
// {
|
||||
useSavedOrder = config.order != [ ];
|
||||
};
|
||||
};
|
||||
|
||||
# Home Manager doesn't circumvent user consent and isn't acting
|
||||
# maliciously. We're modifying the search outside of the browser, but
|
||||
# a claim by Mozilla to remove this would be very anti-user, and
|
||||
# is unlikely to be an issue for our use case.
|
||||
disclaimer = "By modifying this file, I agree that I am doing so "
|
||||
disclaimer =
|
||||
"By modifying this file, I agree that I am doing so "
|
||||
+ "only within @appName@ itself, using official, user-driven search "
|
||||
+ "engine selection processes, and in a way which does not circumvent "
|
||||
+ "user consent. I acknowledge that any attempt to change this file "
|
||||
+ "from outside of @appName@ is a malicious act, and will be responded "
|
||||
+ "to accordingly.";
|
||||
|
||||
salt = if config.default != null then
|
||||
profilePath + config.default + disclaimer
|
||||
else
|
||||
null;
|
||||
salt = if config.default != null then profilePath + config.default + disclaimer else null;
|
||||
|
||||
privateSalt = if config.privateDefault != null then
|
||||
profilePath + config.privateDefault + disclaimer
|
||||
else
|
||||
null;
|
||||
privateSalt =
|
||||
if config.privateDefault != null then profilePath + config.privateDefault + disclaimer else null;
|
||||
|
||||
appNameVariable = if package == null then
|
||||
"appName=${lib.escapeShellArg appName}"
|
||||
else ''
|
||||
applicationIni="$(find ${lib.escapeShellArg package} -maxdepth 3 -path ${
|
||||
lib.escapeShellArg package
|
||||
}'/lib/*/application.ini' -print -quit)"
|
||||
if test -n "$applicationIni"; then
|
||||
appName="$(sed -n 's/^Name=\(.*\)$/\1/p' "$applicationIni" | head -n1)"
|
||||
appNameVariable =
|
||||
if package == null then
|
||||
"appName=${lib.escapeShellArg appName}"
|
||||
else
|
||||
appName=${lib.escapeShellArg appName}
|
||||
fi
|
||||
'';
|
||||
''
|
||||
applicationIni="$(find ${lib.escapeShellArg package} -maxdepth 3 -path ${lib.escapeShellArg package}'/lib/*/application.ini' -print -quit)"
|
||||
if test -n "$applicationIni"; then
|
||||
appName="$(sed -n 's/^Name=\(.*\)$/\1/p' "$applicationIni" | head -n1)"
|
||||
else
|
||||
appName=${lib.escapeShellArg appName}
|
||||
fi
|
||||
'';
|
||||
|
||||
file = pkgs.runCommand "search.json.mozlz4" {
|
||||
nativeBuildInputs = with pkgs; [ mozlz4a openssl ];
|
||||
json = builtins.toJSON settings;
|
||||
inherit salt privateSalt;
|
||||
} ''
|
||||
${appNameVariable}
|
||||
file =
|
||||
pkgs.runCommand "search.json.mozlz4"
|
||||
{
|
||||
nativeBuildInputs = with pkgs; [
|
||||
mozlz4a
|
||||
openssl
|
||||
];
|
||||
json = builtins.toJSON settings;
|
||||
inherit salt privateSalt;
|
||||
}
|
||||
''
|
||||
${appNameVariable}
|
||||
|
||||
salt=''${salt//@appName@/"$appName"}
|
||||
privateSalt=''${privateSalt//@appName@/"$appName"}
|
||||
salt=''${salt//@appName@/"$appName"}
|
||||
privateSalt=''${privateSalt//@appName@/"$appName"}
|
||||
|
||||
if [[ -n $salt ]]; then
|
||||
export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64)
|
||||
export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64)
|
||||
mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out"
|
||||
else
|
||||
mozlz4a <(echo "$json") "$out"
|
||||
fi
|
||||
'';
|
||||
if [[ -n $salt ]]; then
|
||||
export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64)
|
||||
export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64)
|
||||
mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out"
|
||||
else
|
||||
mozlz4a <(echo "$json") "$out"
|
||||
fi
|
||||
'';
|
||||
|
||||
engineNameToId = {
|
||||
# Derived from https://searchfox.org/mozilla-central/rev/e3f42ec9320748b2aab3d474d1e47075def9000c/services/settings/dumps/main/search-config-v2.json
|
||||
|
|
@ -322,47 +366,62 @@ let
|
|||
"Wikipedia (tr)" = "wikipedia-tr";
|
||||
};
|
||||
|
||||
migrateEngineNameToIdV7 = engine:
|
||||
migrateEngineNameToIdV7 =
|
||||
engine:
|
||||
if builtins.hasAttr engine engineNameToId then
|
||||
warn "Search engines are now referenced by id instead of by name, use '${
|
||||
warn
|
||||
"Search engines are now referenced by id instead of by name, use '${engineNameToId.${engine}}' instead of '${engine}'"
|
||||
engineNameToId.${engine}
|
||||
}' instead of '${engine}'" engineNameToId.${engine}
|
||||
else
|
||||
engine;
|
||||
|
||||
migrateEngineToV11 = engine:
|
||||
engine // lib.optionalAttrs (engine ? iconMapObj) {
|
||||
iconMapObj = mapAttrs' (name: value:
|
||||
let nameToIntResult = builtins.tryEval (lib.toInt name);
|
||||
in {
|
||||
name = if nameToIntResult.success then
|
||||
name
|
||||
else
|
||||
let size = toString (builtins.fromJSON name).width;
|
||||
in warn
|
||||
"JSON object names for 'iconMapObj' are deprecated, use '${size}' instead of '${name}'"
|
||||
size;
|
||||
migrateEngineToV11 =
|
||||
engine:
|
||||
engine
|
||||
// lib.optionalAttrs (engine ? iconMapObj) {
|
||||
iconMapObj = mapAttrs' (
|
||||
name: value:
|
||||
let
|
||||
nameToIntResult = builtins.tryEval (lib.toInt name);
|
||||
in
|
||||
{
|
||||
name =
|
||||
if nameToIntResult.success then
|
||||
name
|
||||
else
|
||||
let
|
||||
size = toString (builtins.fromJSON name).width;
|
||||
in
|
||||
warn "JSON object names for 'iconMapObj' are deprecated, use '${size}' instead of '${name}'" size;
|
||||
|
||||
inherit value;
|
||||
}) engine.iconMapObj;
|
||||
}
|
||||
) engine.iconMapObj;
|
||||
};
|
||||
|
||||
migrateEngineToV12 = engine:
|
||||
migrateEngineToV12 =
|
||||
engine:
|
||||
let
|
||||
iconMapObj = optionalAttrs (engine ? iconURL) {
|
||||
"16" = warn "'iconURL' is deprecated, use 'icon = ${
|
||||
lib.strings.escapeNixString engine.iconURL
|
||||
}' instead" engine.iconURL;
|
||||
} // optionalAttrs (engine ? iconUpdateURL) {
|
||||
"16" = warn "'iconUpdateURL' is deprecated, use 'icon = ${
|
||||
lib.strings.escapeNixString engine.iconUpdateURL
|
||||
}' instead" engine.iconUpdateURL;
|
||||
} // (engine.iconMapObj or { });
|
||||
in lib.throwIf (engine ? hasPreferredIcon)
|
||||
"hasPreferredIcon has been removed"
|
||||
(removeAttrs engine [ "iconURL" "iconUpdateURL" ])
|
||||
iconMapObj =
|
||||
optionalAttrs (engine ? iconURL) {
|
||||
"16" =
|
||||
warn "'iconURL' is deprecated, use 'icon = ${lib.strings.escapeNixString engine.iconURL}' instead" engine.iconURL;
|
||||
}
|
||||
// optionalAttrs (engine ? iconUpdateURL) {
|
||||
"16" =
|
||||
warn "'iconUpdateURL' is deprecated, use 'icon = ${lib.strings.escapeNixString engine.iconUpdateURL}' instead" engine.iconUpdateURL;
|
||||
}
|
||||
// (engine.iconMapObj or { });
|
||||
in
|
||||
lib.throwIf (engine ? hasPreferredIcon) "hasPreferredIcon has been removed" (
|
||||
removeAttrs engine [
|
||||
"iconURL"
|
||||
"iconUpdateURL"
|
||||
]
|
||||
)
|
||||
// lib.optionalAttrs (iconMapObj != { }) { inherit iconMapObj; };
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [ (pkgs.path + "/nixos/modules/misc/meta.nix") ];
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ kira-bruneau ];
|
||||
|
|
@ -370,8 +429,11 @@ in {
|
|||
options = {
|
||||
enable = mkOption {
|
||||
type = with types; bool;
|
||||
default = config.default != null || config.privateDefault != null
|
||||
|| config.order != [ ] || config.engines != { };
|
||||
default =
|
||||
config.default != null
|
||||
|| config.privateDefault != null
|
||||
|| config.order != [ ]
|
||||
|| config.engines != { };
|
||||
internal = true;
|
||||
};
|
||||
|
||||
|
|
@ -389,8 +451,7 @@ in {
|
|||
|
||||
default = mkOption {
|
||||
type = with types; nullOr str;
|
||||
apply = engine:
|
||||
if engine != null then migrateEngineNameToIdV7 engine else null;
|
||||
apply = engine: if engine != null then migrateEngineNameToIdV7 engine else null;
|
||||
default = null;
|
||||
example = "ddg";
|
||||
description = ''
|
||||
|
|
@ -401,8 +462,7 @@ in {
|
|||
|
||||
privateDefault = mkOption {
|
||||
type = with types; nullOr str;
|
||||
apply = engine:
|
||||
if engine != null then migrateEngineNameToIdV7 engine else null;
|
||||
apply = engine: if engine != null then migrateEngineNameToIdV7 engine else null;
|
||||
default = null;
|
||||
example = "ddg";
|
||||
description = ''
|
||||
|
|
@ -414,7 +474,10 @@ in {
|
|||
type = with types; uniq (listOf str);
|
||||
apply = builtins.map migrateEngineNameToIdV7;
|
||||
default = [ ];
|
||||
example = [ "ddg" "google" ];
|
||||
example = [
|
||||
"ddg"
|
||||
"google"
|
||||
];
|
||||
description = ''
|
||||
The order the search engines are listed in. Any engines that
|
||||
aren't included in this list will be listed after these in an
|
||||
|
|
@ -425,10 +488,12 @@ in {
|
|||
engines = mkOption {
|
||||
type = with types; attrsOf (attrsOf jsonFormat.type);
|
||||
|
||||
apply = mapAttrs' (name: value: {
|
||||
name = migrateEngineNameToIdV7 name;
|
||||
inherit value;
|
||||
});
|
||||
apply = mapAttrs' (
|
||||
name: value: {
|
||||
name = migrateEngineNameToIdV7 name;
|
||||
inherit value;
|
||||
}
|
||||
);
|
||||
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
|
|
|
|||
|
|
@ -1,31 +1,46 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) isAttrs literalExpression mkIf mkOption optional types;
|
||||
inherit (lib)
|
||||
isAttrs
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
optional
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.fish;
|
||||
|
||||
pluginModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to the plugin folder.
|
||||
pluginModule = types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to the plugin folder.
|
||||
|
||||
Relevant pieces will be added to the fish function path and
|
||||
the completion path. The {file}`init.fish` and
|
||||
{file}`key_binding.fish` files are sourced if
|
||||
they exist.
|
||||
'';
|
||||
};
|
||||
Relevant pieces will be added to the fish function path and
|
||||
the completion path. The {file}`init.fish` and
|
||||
{file}`key_binding.fish` files are sourced if
|
||||
they exist.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The name of the plugin.
|
||||
'';
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The name of the plugin.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
functionModule = types.submodule {
|
||||
options = {
|
||||
|
|
@ -110,7 +125,11 @@ let
|
|||
onSignal = mkOption {
|
||||
type = with types; nullOr (either str int);
|
||||
default = null;
|
||||
example = [ "SIGHUP" "HUP" 1 ];
|
||||
example = [
|
||||
"SIGHUP"
|
||||
"HUP"
|
||||
1
|
||||
];
|
||||
description = ''
|
||||
Tells fish to run this function when the specified signal is
|
||||
delivered. The signal can be a signal number or signal name.
|
||||
|
|
@ -195,49 +214,64 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
abbrsStr = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: def:
|
||||
let
|
||||
mods = lib.cli.toGNUCommandLineShell {
|
||||
mkOption = k: v:
|
||||
if v == null then
|
||||
[ ]
|
||||
else if k == "set-cursor" then
|
||||
[ "--${k}=${lib.generators.mkValueStringDefault { } v}" ]
|
||||
else [
|
||||
"--${k}"
|
||||
(lib.generators.mkValueStringDefault { } v)
|
||||
];
|
||||
} {
|
||||
inherit (def) position regex command function;
|
||||
set-cursor = def.setCursor;
|
||||
};
|
||||
modifiers = if isAttrs def then mods else "";
|
||||
expansion = if isAttrs def then def.expansion else def;
|
||||
in "abbr --add ${modifiers} -- ${name}"
|
||||
+ lib.optionalString (expansion != null) " ${lib.escapeShellArg expansion}")
|
||||
cfg.shellAbbrs);
|
||||
abbrsStr = lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (
|
||||
name: def:
|
||||
let
|
||||
mods =
|
||||
lib.cli.toGNUCommandLineShell
|
||||
{
|
||||
mkOption =
|
||||
k: v:
|
||||
if v == null then
|
||||
[ ]
|
||||
else if k == "set-cursor" then
|
||||
[ "--${k}=${lib.generators.mkValueStringDefault { } v}" ]
|
||||
else
|
||||
[
|
||||
"--${k}"
|
||||
(lib.generators.mkValueStringDefault { } v)
|
||||
];
|
||||
}
|
||||
{
|
||||
inherit (def)
|
||||
position
|
||||
regex
|
||||
command
|
||||
function
|
||||
;
|
||||
set-cursor = def.setCursor;
|
||||
};
|
||||
modifiers = if isAttrs def then mods else "";
|
||||
expansion = if isAttrs def then def.expansion else def;
|
||||
in
|
||||
"abbr --add ${modifiers} -- ${name}"
|
||||
+ lib.optionalString (expansion != null) " ${lib.escapeShellArg expansion}"
|
||||
) cfg.shellAbbrs
|
||||
);
|
||||
|
||||
aliasesStr = lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList (k: v: "alias ${k} ${lib.escapeShellArg v}")
|
||||
cfg.shellAliases);
|
||||
aliasesStr = lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (k: v: "alias ${k} ${lib.escapeShellArg v}") cfg.shellAliases
|
||||
);
|
||||
|
||||
fishIndent = name: text:
|
||||
fishIndent =
|
||||
name: text:
|
||||
pkgs.runCommand name {
|
||||
nativeBuildInputs = [ cfg.package ];
|
||||
inherit text;
|
||||
passAsFile = [ "text" ];
|
||||
} "env HOME=$(mktemp -d) fish_indent < $textPath > $out";
|
||||
|
||||
translatedSessionVariables =
|
||||
pkgs.runCommandLocal "hm-session-vars.fish" { } ''
|
||||
(echo "function setup_hm_session_vars;"
|
||||
${pkgs.buildPackages.babelfish}/bin/babelfish \
|
||||
<${config.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh
|
||||
echo "end"
|
||||
echo "setup_hm_session_vars") > $out
|
||||
'';
|
||||
translatedSessionVariables = pkgs.runCommandLocal "hm-session-vars.fish" { } ''
|
||||
(echo "function setup_hm_session_vars;"
|
||||
${pkgs.buildPackages.babelfish}/bin/babelfish \
|
||||
<${config.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh
|
||||
echo "end"
|
||||
echo "setup_hm_session_vars") > $out
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "programs" "fish" "promptInit" ] ''
|
||||
Prompt is now configured through the
|
||||
|
|
@ -254,8 +288,8 @@ in {
|
|||
|
||||
package = lib.mkPackageOption pkgs "fish" { };
|
||||
|
||||
generateCompletions = lib.mkEnableOption
|
||||
"the automatic generation of completions based upon installed man pages"
|
||||
generateCompletions =
|
||||
lib.mkEnableOption "the automatic generation of completions based upon installed man pages"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
|
@ -396,176 +430,204 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (lib.mkMerge [
|
||||
{ home.packages = [ cfg.package ]; }
|
||||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{ home.packages = [ cfg.package ]; }
|
||||
|
||||
(mkIf cfg.generateCompletions {
|
||||
# Support completion for `man` by building a cache for `apropos`.
|
||||
programs.man.generateCaches = lib.mkDefault true;
|
||||
(mkIf cfg.generateCompletions {
|
||||
# Support completion for `man` by building a cache for `apropos`.
|
||||
programs.man.generateCaches = lib.mkDefault true;
|
||||
|
||||
xdg.dataFile."fish/home-manager_generated_completions".source = let
|
||||
# Paths later in the list will overwrite those already linked
|
||||
destructiveSymlinkJoin = args_@{ name, paths, preferLocalBuild ? true
|
||||
, allowSubstitutes ? false, postBuild ? "", ... }:
|
||||
xdg.dataFile."fish/home-manager_generated_completions".source =
|
||||
let
|
||||
args = removeAttrs args_ [ "name" "postBuild" ] // {
|
||||
# pass the defaults
|
||||
inherit preferLocalBuild allowSubstitutes;
|
||||
};
|
||||
in pkgs.runCommand name args ''
|
||||
mkdir -p $out
|
||||
for i in $paths; do
|
||||
if [ -z "$(find $i -prune -empty)" ]; then
|
||||
cp -srf $i/* $out
|
||||
fi
|
||||
done
|
||||
${postBuild}
|
||||
'';
|
||||
# Paths later in the list will overwrite those already linked
|
||||
destructiveSymlinkJoin =
|
||||
args_@{
|
||||
name,
|
||||
paths,
|
||||
preferLocalBuild ? true,
|
||||
allowSubstitutes ? false,
|
||||
postBuild ? "",
|
||||
...
|
||||
}:
|
||||
let
|
||||
args =
|
||||
removeAttrs args_ [
|
||||
"name"
|
||||
"postBuild"
|
||||
]
|
||||
// {
|
||||
# pass the defaults
|
||||
inherit preferLocalBuild allowSubstitutes;
|
||||
};
|
||||
in
|
||||
pkgs.runCommand name args ''
|
||||
mkdir -p $out
|
||||
for i in $paths; do
|
||||
if [ -z "$(find $i -prune -empty)" ]; then
|
||||
cp -srf $i/* $out
|
||||
fi
|
||||
done
|
||||
${postBuild}
|
||||
'';
|
||||
|
||||
generateCompletions = let
|
||||
getName = attrs:
|
||||
attrs.name or "${attrs.pname or "«pname-missing»"}-${
|
||||
attrs.version or "«version-missing»"
|
||||
}";
|
||||
in package:
|
||||
pkgs.runCommand "${getName package}-fish-completions" {
|
||||
srcs = [ package ] ++ lib.filter (p: p != null)
|
||||
(builtins.map (outName: package.${outName} or null)
|
||||
config.home.extraOutputsToInstall);
|
||||
nativeBuildInputs = [ pkgs.python3 ];
|
||||
buildInputs = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
} ''
|
||||
mkdir -p $out
|
||||
for src in $srcs; do
|
||||
if [ -d $src/share/man ]; then
|
||||
find -L $src/share/man -type f \
|
||||
-exec python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out {} + \
|
||||
> /dev/null
|
||||
fi
|
||||
done
|
||||
generateCompletions =
|
||||
let
|
||||
getName =
|
||||
attrs: attrs.name or "${attrs.pname or "«pname-missing»"}-${attrs.version or "«version-missing»"}";
|
||||
in
|
||||
package:
|
||||
pkgs.runCommand "${getName package}-fish-completions"
|
||||
{
|
||||
srcs =
|
||||
[ package ]
|
||||
++ lib.filter (p: p != null) (
|
||||
builtins.map (outName: package.${outName} or null) config.home.extraOutputsToInstall
|
||||
);
|
||||
nativeBuildInputs = [ pkgs.python3 ];
|
||||
buildInputs = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
}
|
||||
''
|
||||
mkdir -p $out
|
||||
for src in $srcs; do
|
||||
if [ -d $src/share/man ]; then
|
||||
find -L $src/share/man -type f \
|
||||
-exec python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out {} + \
|
||||
> /dev/null
|
||||
fi
|
||||
done
|
||||
'';
|
||||
in
|
||||
destructiveSymlinkJoin {
|
||||
name = "${config.home.username}-fish-completions";
|
||||
paths =
|
||||
let
|
||||
cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
|
||||
in
|
||||
map generateCompletions (lib.sort cmp config.home.packages);
|
||||
};
|
||||
|
||||
programs.fish.interactiveShellInit = ''
|
||||
# add completions generated by Home Manager to $fish_complete_path
|
||||
begin
|
||||
set -l joined (string join " " $fish_complete_path)
|
||||
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
|
||||
set -l post_joined (string replace $prev_joined "" $joined)
|
||||
set -l prev (string split " " (string trim $prev_joined))
|
||||
set -l post (string split " " (string trim $post_joined))
|
||||
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
|
||||
end
|
||||
'';
|
||||
in destructiveSymlinkJoin {
|
||||
name = "${config.home.username}-fish-completions";
|
||||
paths =
|
||||
let cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
|
||||
in map generateCompletions (lib.sort cmp config.home.packages);
|
||||
};
|
||||
})
|
||||
|
||||
programs.fish.interactiveShellInit = ''
|
||||
# add completions generated by Home Manager to $fish_complete_path
|
||||
begin
|
||||
set -l joined (string join " " $fish_complete_path)
|
||||
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
|
||||
set -l post_joined (string replace $prev_joined "" $joined)
|
||||
set -l prev (string split " " (string trim $prev_joined))
|
||||
set -l post (string split " " (string trim $post_joined))
|
||||
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
|
||||
end
|
||||
'';
|
||||
})
|
||||
{
|
||||
xdg.configFile."fish/config.fish".source = fishIndent "config.fish" ''
|
||||
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated
|
||||
# automatically by home-manager.
|
||||
|
||||
{
|
||||
xdg.configFile."fish/config.fish".source = fishIndent "config.fish" ''
|
||||
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated
|
||||
# automatically by home-manager.
|
||||
# Only execute this file once per shell.
|
||||
set -q __fish_home_manager_config_sourced; and exit
|
||||
set -g __fish_home_manager_config_sourced 1
|
||||
|
||||
# Only execute this file once per shell.
|
||||
set -q __fish_home_manager_config_sourced; and exit
|
||||
set -g __fish_home_manager_config_sourced 1
|
||||
source ${translatedSessionVariables}
|
||||
|
||||
source ${translatedSessionVariables}
|
||||
${cfg.shellInit}
|
||||
|
||||
${cfg.shellInit}
|
||||
status is-login; and begin
|
||||
|
||||
status is-login; and begin
|
||||
# Login shell initialisation
|
||||
${cfg.loginShellInit}
|
||||
|
||||
# Login shell initialisation
|
||||
${cfg.loginShellInit}
|
||||
end
|
||||
|
||||
end
|
||||
status is-interactive; and begin
|
||||
|
||||
status is-interactive; and begin
|
||||
# Abbreviations
|
||||
${abbrsStr}
|
||||
|
||||
# Abbreviations
|
||||
${abbrsStr}
|
||||
# Aliases
|
||||
${aliasesStr}
|
||||
|
||||
# Aliases
|
||||
${aliasesStr}
|
||||
# Interactive shell initialisation
|
||||
${cfg.interactiveShellInit}
|
||||
|
||||
# Interactive shell initialisation
|
||||
${cfg.interactiveShellInit}
|
||||
end
|
||||
|
||||
end
|
||||
${cfg.shellInitLast}
|
||||
'';
|
||||
}
|
||||
{
|
||||
xdg.configFile = lib.mapAttrs' (name: def: {
|
||||
name = "fish/functions/${name}.fish";
|
||||
value = {
|
||||
source =
|
||||
let
|
||||
modifierStr = n: v: optional (v != null) ''--${n}="${toString v}"'';
|
||||
modifierStrs = n: v: optional (v != null) "--${n}=${toString v}";
|
||||
modifierBool = n: v: optional (v != null && v) "--${n}";
|
||||
|
||||
${cfg.shellInitLast}
|
||||
'';
|
||||
}
|
||||
{
|
||||
xdg.configFile = lib.mapAttrs' (name: def: {
|
||||
name = "fish/functions/${name}.fish";
|
||||
value = {
|
||||
source = let
|
||||
modifierStr = n: v: optional (v != null) ''--${n}="${toString v}"'';
|
||||
modifierStrs = n: v: optional (v != null) "--${n}=${toString v}";
|
||||
modifierBool = n: v: optional (v != null && v) "--${n}";
|
||||
mods =
|
||||
with def;
|
||||
modifierStr "description" description
|
||||
++ modifierStr "wraps" wraps
|
||||
++ lib.concatMap (modifierStr "on-event") (lib.toList onEvent)
|
||||
++ modifierStr "on-variable" onVariable
|
||||
++ modifierStr "on-job-exit" onJobExit
|
||||
++ modifierStr "on-process-exit" onProcessExit
|
||||
++ modifierStr "on-signal" onSignal
|
||||
++ modifierBool "no-scope-shadowing" noScopeShadowing
|
||||
++ modifierStr "inherit-variable" inheritVariable
|
||||
++ modifierStrs "argument-names" argumentNames;
|
||||
|
||||
mods = with def;
|
||||
modifierStr "description" description ++ modifierStr "wraps" wraps
|
||||
++ lib.concatMap (modifierStr "on-event") (lib.toList onEvent)
|
||||
++ modifierStr "on-variable" onVariable
|
||||
++ modifierStr "on-job-exit" onJobExit
|
||||
++ modifierStr "on-process-exit" onProcessExit
|
||||
++ modifierStr "on-signal" onSignal
|
||||
++ modifierBool "no-scope-shadowing" noScopeShadowing
|
||||
++ modifierStr "inherit-variable" inheritVariable
|
||||
++ modifierStrs "argument-names" argumentNames;
|
||||
modifiers = if isAttrs def then " ${toString mods}" else "";
|
||||
body = if isAttrs def then def.body else def;
|
||||
in
|
||||
fishIndent "${name}.fish" ''
|
||||
function ${name}${modifiers}
|
||||
${lib.strings.removeSuffix "\n" body}
|
||||
end
|
||||
'';
|
||||
};
|
||||
}) cfg.functions;
|
||||
}
|
||||
|
||||
modifiers = if isAttrs def then " ${toString mods}" else "";
|
||||
body = if isAttrs def then def.body else def;
|
||||
in fishIndent "${name}.fish" ''
|
||||
function ${name}${modifiers}
|
||||
${lib.strings.removeSuffix "\n" body}
|
||||
end
|
||||
'';
|
||||
};
|
||||
}) cfg.functions;
|
||||
}
|
||||
# Each plugin gets a corresponding conf.d/plugin-NAME.fish file to load
|
||||
# in the paths and any initialization scripts.
|
||||
(mkIf (lib.length cfg.plugins > 0) {
|
||||
xdg.configFile = lib.mkMerge (
|
||||
map (plugin: {
|
||||
"fish/conf.d/plugin-${plugin.name}.fish".source = fishIndent "${plugin.name}.fish" ''
|
||||
# Plugin ${plugin.name}
|
||||
set -l plugin_dir ${plugin.src}
|
||||
|
||||
# Each plugin gets a corresponding conf.d/plugin-NAME.fish file to load
|
||||
# in the paths and any initialization scripts.
|
||||
(mkIf (lib.length cfg.plugins > 0) {
|
||||
xdg.configFile = lib.mkMerge (map (plugin: {
|
||||
"fish/conf.d/plugin-${plugin.name}.fish".source =
|
||||
fishIndent "${plugin.name}.fish" ''
|
||||
# Plugin ${plugin.name}
|
||||
set -l plugin_dir ${plugin.src}
|
||||
|
||||
# Set paths to import plugin components
|
||||
if test -d $plugin_dir/functions
|
||||
set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1]
|
||||
end
|
||||
|
||||
if test -d $plugin_dir/completions
|
||||
set fish_complete_path $fish_complete_path[1] $plugin_dir/completions $fish_complete_path[2..-1]
|
||||
end
|
||||
|
||||
# Source initialization code if it exists.
|
||||
if test -d $plugin_dir/conf.d
|
||||
for f in $plugin_dir/conf.d/*.fish
|
||||
source $f
|
||||
# Set paths to import plugin components
|
||||
if test -d $plugin_dir/functions
|
||||
set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1]
|
||||
end
|
||||
end
|
||||
|
||||
if test -f $plugin_dir/key_bindings.fish
|
||||
source $plugin_dir/key_bindings.fish
|
||||
end
|
||||
if test -d $plugin_dir/completions
|
||||
set fish_complete_path $fish_complete_path[1] $plugin_dir/completions $fish_complete_path[2..-1]
|
||||
end
|
||||
|
||||
if test -f $plugin_dir/init.fish
|
||||
source $plugin_dir/init.fish
|
||||
end
|
||||
'';
|
||||
}) cfg.plugins);
|
||||
})
|
||||
]);
|
||||
# Source initialization code if it exists.
|
||||
if test -d $plugin_dir/conf.d
|
||||
for f in $plugin_dir/conf.d/*.fish
|
||||
source $f
|
||||
end
|
||||
end
|
||||
|
||||
if test -f $plugin_dir/key_bindings.fish
|
||||
source $plugin_dir/key_bindings.fish
|
||||
end
|
||||
|
||||
if test -f $plugin_dir/init.fish
|
||||
source $plugin_dir/init.fish
|
||||
end
|
||||
'';
|
||||
}) cfg.plugins
|
||||
);
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
modulePath = [ "programs" "floorp" ];
|
||||
modulePath = [
|
||||
"programs"
|
||||
"floorp"
|
||||
];
|
||||
|
||||
mkFirefoxModule = import ./firefox/mkFirefoxModule.nix;
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.bricked ];
|
||||
|
||||
imports = [
|
||||
|
|
@ -14,8 +18,12 @@ in {
|
|||
unwrappedPackageName = "floorp-unwrapped";
|
||||
visible = true;
|
||||
|
||||
platforms.linux = { configPath = ".floorp"; };
|
||||
platforms.darwin = { configPath = "Library/Application Support/Floorp"; };
|
||||
platforms.linux = {
|
||||
configPath = ".floorp";
|
||||
};
|
||||
platforms.darwin = {
|
||||
configPath = "Library/Application Support/Floorp";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.foot;
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ plabadens ];
|
||||
|
||||
options.programs.foot = {
|
||||
|
|
@ -39,8 +45,7 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.foot" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.foot" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
|
@ -52,8 +57,7 @@ in {
|
|||
systemd.user.services = lib.mkIf cfg.server.enable {
|
||||
foot = {
|
||||
Unit = {
|
||||
Description =
|
||||
"Fast, lightweight and minimalistic Wayland terminal emulator.";
|
||||
Description = "Fast, lightweight and minimalistic Wayland terminal emulator.";
|
||||
Documentation = "man:foot(1)";
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
After = [ "graphical-session.target" ];
|
||||
|
|
@ -65,7 +69,9 @@ in {
|
|||
OOMPolicy = "continue";
|
||||
};
|
||||
|
||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||
Install = {
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,21 +1,36 @@
|
|||
{ lib, pkgs, config, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
concatStringsSep mapAttrsToList mkIf mkEnableOption mkPackageOption mkOption
|
||||
literalExpression;
|
||||
concatStringsSep
|
||||
mapAttrsToList
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
literalExpression
|
||||
;
|
||||
|
||||
cfg = config.programs.freetube;
|
||||
|
||||
settings = settings:
|
||||
settings =
|
||||
settings:
|
||||
let
|
||||
convertSetting = name: value:
|
||||
convertSetting =
|
||||
name: value:
|
||||
builtins.toJSON {
|
||||
"_id" = name;
|
||||
"value" = value;
|
||||
};
|
||||
in concatStringsSep "\n" (mapAttrsToList convertSetting settings) + "\n";
|
||||
in {
|
||||
in
|
||||
concatStringsSep "\n" (mapAttrsToList convertSetting settings) + "\n";
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ vonixxx ];
|
||||
|
||||
options.programs.freetube = {
|
||||
|
|
@ -49,12 +64,14 @@ in {
|
|||
xdg.configFile."FreeTube/hm_settings.db" = {
|
||||
source = pkgs.writeText "hm_settings.db" (settings cfg.settings);
|
||||
|
||||
onChange = let
|
||||
hmSettingsDb = "${config.xdg.configHome}/FreeTube/hm_settings.db";
|
||||
settingsDb = "${config.xdg.configHome}/FreeTube/settings.db";
|
||||
in ''
|
||||
run install -Dm644 $VERBOSE_ARG '${hmSettingsDb}' '${settingsDb}'
|
||||
'';
|
||||
onChange =
|
||||
let
|
||||
hmSettingsDb = "${config.xdg.configHome}/FreeTube/hm_settings.db";
|
||||
settingsDb = "${config.xdg.configHome}/FreeTube/settings.db";
|
||||
in
|
||||
''
|
||||
run install -Dm644 $VERBOSE_ARG '${hmSettingsDb}' '${settingsDb}'
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
inherit (lib) literalExpression mkEnableOption mkPackageOption mkOption mkIf;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
mkIf
|
||||
;
|
||||
|
||||
cfg = config.programs.fuzzel;
|
||||
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.Scrumplex ];
|
||||
|
||||
options.programs.fuzzel = {
|
||||
|
|
@ -38,8 +50,7 @@ in {
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.fuzzel" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.fuzzel" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
|
|
|||
|
|
@ -1,46 +1,73 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) getExe literalExpression mkIf mkOption mkOrder types;
|
||||
inherit (lib)
|
||||
getExe
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
mkOrder
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.fzf;
|
||||
|
||||
renderedColors = colors:
|
||||
lib.concatStringsSep ","
|
||||
(lib.mapAttrsToList (name: value: "${name}:${value}") colors);
|
||||
renderedColors =
|
||||
colors: lib.concatStringsSep "," (lib.mapAttrsToList (name: value: "${name}:${value}") colors);
|
||||
|
||||
hasShellIntegrationEmbedded = lib.versionAtLeast cfg.package.version "0.48.0";
|
||||
|
||||
bashIntegration = if hasShellIntegrationEmbedded then ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
eval "$(${getExe cfg.package} --bash)"
|
||||
fi
|
||||
'' else ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
. ${cfg.package}/share/fzf/completion.bash
|
||||
. ${cfg.package}/share/fzf/key-bindings.bash
|
||||
fi
|
||||
'';
|
||||
bashIntegration =
|
||||
if hasShellIntegrationEmbedded then
|
||||
''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
eval "$(${getExe cfg.package} --bash)"
|
||||
fi
|
||||
''
|
||||
else
|
||||
''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
. ${cfg.package}/share/fzf/completion.bash
|
||||
. ${cfg.package}/share/fzf/key-bindings.bash
|
||||
fi
|
||||
'';
|
||||
|
||||
zshIntegration = if hasShellIntegrationEmbedded then ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${getExe cfg.package} --zsh)"
|
||||
fi
|
||||
'' else ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
. ${cfg.package}/share/fzf/completion.zsh
|
||||
. ${cfg.package}/share/fzf/key-bindings.zsh
|
||||
fi
|
||||
'';
|
||||
zshIntegration =
|
||||
if hasShellIntegrationEmbedded then
|
||||
''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${getExe cfg.package} --zsh)"
|
||||
fi
|
||||
''
|
||||
else
|
||||
''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
. ${cfg.package}/share/fzf/completion.zsh
|
||||
. ${cfg.package}/share/fzf/key-bindings.zsh
|
||||
fi
|
||||
'';
|
||||
|
||||
fishIntegration = if hasShellIntegrationEmbedded then ''
|
||||
${getExe cfg.package} --fish | source
|
||||
'' else ''
|
||||
source ${cfg.package}/share/fzf/key-bindings.fish && fzf_key_bindings
|
||||
'';
|
||||
in {
|
||||
fishIntegration =
|
||||
if hasShellIntegrationEmbedded then
|
||||
''
|
||||
${getExe cfg.package} --fish | source
|
||||
''
|
||||
else
|
||||
''
|
||||
source ${cfg.package}/share/fzf/key-bindings.fish && fzf_key_bindings
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "programs" "fzf" "historyWidgetCommand" ]
|
||||
"This option is no longer supported by fzf.")
|
||||
(lib.mkRemovedOptionModule [
|
||||
"programs"
|
||||
"fzf"
|
||||
"historyWidgetCommand"
|
||||
] "This option is no longer supported by fzf.")
|
||||
];
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ khaneliman ];
|
||||
|
|
@ -63,7 +90,10 @@ in {
|
|||
defaultOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--height 40%" "--border" ];
|
||||
example = [
|
||||
"--height 40%"
|
||||
"--border"
|
||||
];
|
||||
description = ''
|
||||
Extra command line options given to fzf by default.
|
||||
'';
|
||||
|
|
@ -110,7 +140,10 @@ in {
|
|||
historyWidgetOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--sort" "--exact" ];
|
||||
example = [
|
||||
"--sort"
|
||||
"--exact"
|
||||
];
|
||||
description = ''
|
||||
Command line options for the CTRL-R keybinding.
|
||||
'';
|
||||
|
|
@ -151,49 +184,44 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.sessionVariables = lib.mapAttrs (n: v: toString v)
|
||||
(lib.filterAttrs (n: v: v != [ ] && v != null) {
|
||||
home.sessionVariables = lib.mapAttrs (n: v: toString v) (
|
||||
lib.filterAttrs (n: v: v != [ ] && v != null) {
|
||||
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
|
||||
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
|
||||
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
|
||||
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
|
||||
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
|
||||
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
|
||||
FZF_DEFAULT_OPTS = cfg.defaultOptions
|
||||
++ lib.optionals (cfg.colors != { })
|
||||
[ "--color ${renderedColors cfg.colors}" ];
|
||||
FZF_DEFAULT_OPTS =
|
||||
cfg.defaultOptions
|
||||
++ lib.optionals (cfg.colors != { }) [ "--color ${renderedColors cfg.colors}" ];
|
||||
FZF_TMUX = if cfg.tmux.enableShellIntegration then "1" else null;
|
||||
FZF_TMUX_OPTS = cfg.tmux.shellIntegrationOptions;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
# Note, since fzf unconditionally binds C-r we use `mkOrder` to make the
|
||||
# initialization show up a bit earlier. This is to make initialization of
|
||||
# other history managers, like mcfly or atuin, take precedence.
|
||||
programs.bash.initExtra =
|
||||
mkIf cfg.enableBashIntegration (mkOrder 200 bashIntegration);
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (mkOrder 200 bashIntegration);
|
||||
|
||||
# Note, since fzf unconditionally binds C-r we use `mkOrder` to make the
|
||||
# initialization show up a bit earlier. This is to make initialization of
|
||||
# other history managers, like mcfly or atuin, take precedence.
|
||||
# Still needs to be initialized after oh-my-zsh (order 800), otherwise
|
||||
# omz will take precedence.
|
||||
programs.zsh.initContent =
|
||||
mkIf cfg.enableZshIntegration (mkOrder 910 zshIntegration);
|
||||
programs.zsh.initContent = mkIf cfg.enableZshIntegration (mkOrder 910 zshIntegration);
|
||||
|
||||
programs.fish.interactiveShellInit =
|
||||
mkIf cfg.enableFishIntegration (mkOrder 200 fishIntegration);
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration (mkOrder 200 fishIntegration);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.gallery-dl;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.programs.gallery-dl = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{ lib, ... }:
|
||||
let inherit (lib) mkOption types;
|
||||
in {
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
{
|
||||
options.getmail = {
|
||||
enable = lib.mkEnableOption "the getmail mail retriever for this account";
|
||||
|
||||
|
|
@ -16,7 +18,10 @@ in {
|
|||
mailboxes = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = [ ];
|
||||
example = [ "INBOX" "INBOX.spam" ];
|
||||
example = [
|
||||
"INBOX"
|
||||
"INBOX.spam"
|
||||
];
|
||||
description = ''
|
||||
A non-empty list of mailboxes. To download all mail you can
|
||||
use the `ALL` mailbox.
|
||||
|
|
|
|||
|
|
@ -1,27 +1,33 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
accounts = lib.filter (a: a.getmail.enable)
|
||||
(lib.attrValues config.accounts.email.accounts);
|
||||
accounts = lib.filter (a: a.getmail.enable) (lib.attrValues config.accounts.email.accounts);
|
||||
|
||||
renderAccountConfig = account:
|
||||
renderAccountConfig =
|
||||
account:
|
||||
let
|
||||
inherit (account) getmail imap passwordCommand;
|
||||
passCmd = lib.concatMapStringsSep ", " (x: "'${x}'") passwordCommand;
|
||||
renderedMailboxes =
|
||||
lib.concatMapStrings (x: "'${x}', ") getmail.mailboxes;
|
||||
retrieverType = if imap.tls.enable then
|
||||
"SimpleIMAPSSLRetriever"
|
||||
else
|
||||
"SimpleIMAPRetriever";
|
||||
destination = if getmail.destinationCommand != null then {
|
||||
destinationType = "MDA_external";
|
||||
destinationPath = getmail.destinationCommand;
|
||||
} else {
|
||||
destinationType = "Maildir";
|
||||
destinationPath = "${account.maildir.absPath}/";
|
||||
};
|
||||
renderedMailboxes = lib.concatMapStrings (x: "'${x}', ") getmail.mailboxes;
|
||||
retrieverType = if imap.tls.enable then "SimpleIMAPSSLRetriever" else "SimpleIMAPRetriever";
|
||||
destination =
|
||||
if getmail.destinationCommand != null then
|
||||
{
|
||||
destinationType = "MDA_external";
|
||||
destinationPath = getmail.destinationCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
destinationType = "Maildir";
|
||||
destinationPath = "${account.maildir.absPath}/";
|
||||
};
|
||||
renderGetmailBoolean = v: if v then "true" else "false";
|
||||
in ''
|
||||
in
|
||||
''
|
||||
# Generated by Home-Manager.
|
||||
[retriever]
|
||||
type = ${retrieverType}
|
||||
|
|
@ -41,25 +47,23 @@ let
|
|||
'';
|
||||
getmailEnabled = lib.length (lib.filter (a: a.getmail.enable) accounts) > 0;
|
||||
# Watch out! This is used by the getmail.service too!
|
||||
renderConfigFilepath = a:
|
||||
".getmail/getmail${if a.primary then "rc" else a.name}";
|
||||
renderConfigFilepath = a: ".getmail/getmail${if a.primary then "rc" else a.name}";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
accounts.email.accounts = lib.mkOption {
|
||||
type = with lib.types;
|
||||
attrsOf (submodule (import ./getmail-accounts.nix));
|
||||
type = with lib.types; attrsOf (submodule (import ./getmail-accounts.nix));
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf getmailEnabled {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.getmail" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.getmail" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.file = lib.foldl' (a: b: a // b) { }
|
||||
(map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; })
|
||||
accounts);
|
||||
home.file = lib.foldl' (a: b: a // b) { } (
|
||||
map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; }) accounts
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -6,7 +11,8 @@ let
|
|||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.janik ];
|
||||
|
||||
options.programs.gh-dash = {
|
||||
|
|
@ -36,7 +42,6 @@ in {
|
|||
|
||||
programs.gh.extensions = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."gh-dash/config.yml".source =
|
||||
yamlFormat.generate "gh-dash-config.yml" cfg.settings;
|
||||
xdg.configFile."gh-dash/config.yml".source = yamlFormat.generate "gh-dash-config.yml" cfg.settings;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.gh;
|
||||
|
||||
|
|
@ -42,27 +52,49 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ gerschtli berbiche ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
gerschtli
|
||||
berbiche
|
||||
];
|
||||
|
||||
imports = (map (x:
|
||||
lib.mkRenamedOptionModule [ "programs" "gh" x ] [
|
||||
"programs"
|
||||
"gh"
|
||||
"settings"
|
||||
x
|
||||
]) [ "aliases" "editor" ]) ++ [
|
||||
(lib.mkRenamedOptionModule [ "programs" "gh" "gitProtocol" ] [
|
||||
"programs"
|
||||
"gh"
|
||||
"settings"
|
||||
"git_protocol"
|
||||
])
|
||||
(lib.mkRenamedOptionModule [
|
||||
"programs"
|
||||
"gh"
|
||||
"enableGitCredentialHelper"
|
||||
] [ "programs" "gh" "gitCredentialHelper" "enable" ])
|
||||
imports =
|
||||
(map
|
||||
(
|
||||
x:
|
||||
lib.mkRenamedOptionModule
|
||||
[ "programs" "gh" x ]
|
||||
[
|
||||
"programs"
|
||||
"gh"
|
||||
"settings"
|
||||
x
|
||||
]
|
||||
)
|
||||
[
|
||||
"aliases"
|
||||
"editor"
|
||||
]
|
||||
)
|
||||
++ [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "programs" "gh" "gitProtocol" ]
|
||||
[
|
||||
"programs"
|
||||
"gh"
|
||||
"settings"
|
||||
"git_protocol"
|
||||
]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"programs"
|
||||
"gh"
|
||||
"enableGitCredentialHelper"
|
||||
]
|
||||
[ "programs" "gh" "gitCredentialHelper" "enable" ]
|
||||
)
|
||||
];
|
||||
|
||||
options.programs.gh = {
|
||||
|
|
@ -73,8 +105,7 @@ in {
|
|||
settings = mkOption {
|
||||
type = settingsType;
|
||||
default = { };
|
||||
description =
|
||||
"Configuration written to {file}`$XDG_CONFIG_HOME/gh/config.yml`.";
|
||||
description = "Configuration written to {file}`$XDG_CONFIG_HOME/gh/config.yml`.";
|
||||
example = literalExpression ''
|
||||
{
|
||||
git_protocol = "ssh";
|
||||
|
|
@ -96,7 +127,10 @@ in {
|
|||
|
||||
hosts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "https://github.com" "https://gist.github.com" ];
|
||||
default = [
|
||||
"https://github.com"
|
||||
"https://gist.github.com"
|
||||
];
|
||||
description = "GitHub hosts to enable the gh git credential helper for";
|
||||
example = literalExpression ''
|
||||
[ "https://github.com" "https://github.example.com" ]
|
||||
|
|
@ -117,8 +151,9 @@ in {
|
|||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."gh/config.yml".source =
|
||||
yamlFormat.generate "gh-config.yml" ({ version = "1"; } // cfg.settings);
|
||||
xdg.configFile."gh/config.yml".source = yamlFormat.generate "gh-config.yml" (
|
||||
{ version = "1"; } // cfg.settings
|
||||
);
|
||||
|
||||
# Version 2.40.0+ of `gh` needs to migrate account formats, this needs to
|
||||
# happen before the version = 1 is placed in the configuration file. Running
|
||||
|
|
@ -127,8 +162,10 @@ in {
|
|||
#
|
||||
# See https://github.com/nix-community/home-manager/issues/4744 for details.
|
||||
home.activation.migrateGhAccounts =
|
||||
let ghHosts = "${config.xdg.configHome}/gh/hosts.yml";
|
||||
in lib.hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
let
|
||||
ghHosts = "${config.xdg.configHome}/gh/hosts.yml";
|
||||
in
|
||||
lib.hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
if [[ ! -L "${ghHosts}" && -f "${ghHosts}" && $(grep --invert-match --quiet '^version:' ${ghHosts}) ]]; then
|
||||
(
|
||||
TMP_DIR=$(mktemp -d)
|
||||
|
|
@ -141,17 +178,24 @@ in {
|
|||
fi
|
||||
'';
|
||||
|
||||
programs.git.extraConfig.credential = mkIf cfg.gitCredentialHelper.enable
|
||||
(builtins.listToAttrs (map (host:
|
||||
lib.nameValuePair host {
|
||||
helper = "${cfg.package}/bin/gh auth git-credential";
|
||||
}) cfg.gitCredentialHelper.hosts));
|
||||
programs.git.extraConfig.credential = mkIf cfg.gitCredentialHelper.enable (
|
||||
builtins.listToAttrs (
|
||||
map (
|
||||
host:
|
||||
lib.nameValuePair host {
|
||||
helper = "${cfg.package}/bin/gh auth git-credential";
|
||||
}
|
||||
) cfg.gitCredentialHelper.hosts
|
||||
)
|
||||
);
|
||||
|
||||
xdg.dataFile."gh/extensions" = mkIf (cfg.extensions != [ ]) {
|
||||
source = pkgs.linkFarm "gh-extensions" (builtins.map (p: {
|
||||
name = p.pname;
|
||||
path = "${p}/bin";
|
||||
}) cfg.extensions);
|
||||
source = pkgs.linkFarm "gh-extensions" (
|
||||
builtins.map (p: {
|
||||
name = p.pname;
|
||||
path = "${p}/bin";
|
||||
}) cfg.extensions
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.ghostty;
|
||||
|
||||
|
|
@ -7,198 +12,210 @@ let
|
|||
mkKeyValue = lib.generators.mkKeyValueDefault { } " = ";
|
||||
};
|
||||
keyValue = pkgs.formats.keyValue keyValueSettings;
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ HeitorAugustoLN khaneliman ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
HeitorAugustoLN
|
||||
khaneliman
|
||||
];
|
||||
|
||||
options.programs.ghostty = let
|
||||
mkShellIntegrationOption = option:
|
||||
option // {
|
||||
options.programs.ghostty =
|
||||
let
|
||||
mkShellIntegrationOption =
|
||||
option:
|
||||
option
|
||||
// {
|
||||
description = ''
|
||||
${option.description}
|
||||
|
||||
This ensures that shell integration works in more scenarios, such as
|
||||
switching shells within Ghostty. But it is not needed to have shell
|
||||
integration.
|
||||
|
||||
See
|
||||
<https://ghostty.org/docs/features/shell-integration#manual-shell-integration-setup>
|
||||
for more information.
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
enable = lib.mkEnableOption "Ghostty";
|
||||
|
||||
package = lib.mkPackageOption pkgs "ghostty" {
|
||||
nullable = true;
|
||||
extraDescription = "Set programs.ghostty.package to null on platforms where ghostty is not available or marked broken";
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
inherit (keyValue) type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
theme = "catppuccin-mocha";
|
||||
font-size = 10;
|
||||
keybind = [
|
||||
"ctrl+h=goto_split:left"
|
||||
"ctrl+l=goto_split:right"
|
||||
];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
${option.description}
|
||||
Configuration written to {file}`$XDG_CONFIG_HOME/ghostty/config`.
|
||||
|
||||
This ensures that shell integration works in more scenarios, such as
|
||||
switching shells within Ghostty. But it is not needed to have shell
|
||||
integration.
|
||||
|
||||
See
|
||||
<https://ghostty.org/docs/features/shell-integration#manual-shell-integration-setup>
|
||||
for more information.
|
||||
See <https://ghostty.org/docs/config/reference> for more information.
|
||||
'';
|
||||
};
|
||||
in {
|
||||
enable = lib.mkEnableOption "Ghostty";
|
||||
|
||||
package = lib.mkPackageOption pkgs "ghostty" {
|
||||
nullable = true;
|
||||
extraDescription =
|
||||
"Set programs.ghostty.package to null on platforms where ghostty is not available or marked broken";
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
inherit (keyValue) type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
theme = "catppuccin-mocha";
|
||||
font-size = 10;
|
||||
keybind = [
|
||||
"ctrl+h=goto_split:left"
|
||||
"ctrl+l=goto_split:right"
|
||||
];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to {file}`$XDG_CONFIG_HOME/ghostty/config`.
|
||||
|
||||
See <https://ghostty.org/docs/config/reference> for more information.
|
||||
'';
|
||||
};
|
||||
|
||||
themes = lib.mkOption {
|
||||
type = lib.types.attrsOf keyValue.type;
|
||||
default = { };
|
||||
example = {
|
||||
catppuccin-mocha = {
|
||||
palette = [
|
||||
"0=#45475a"
|
||||
"1=#f38ba8"
|
||||
"2=#a6e3a1"
|
||||
"3=#f9e2af"
|
||||
"4=#89b4fa"
|
||||
"5=#f5c2e7"
|
||||
"6=#94e2d5"
|
||||
"7=#bac2de"
|
||||
"8=#585b70"
|
||||
"9=#f38ba8"
|
||||
"10=#a6e3a1"
|
||||
"11=#f9e2af"
|
||||
"12=#89b4fa"
|
||||
"13=#f5c2e7"
|
||||
"14=#94e2d5"
|
||||
"15=#a6adc8"
|
||||
];
|
||||
background = "1e1e2e";
|
||||
foreground = "cdd6f4";
|
||||
cursor-color = "f5e0dc";
|
||||
selection-background = "353749";
|
||||
selection-foreground = "cdd6f4";
|
||||
themes = lib.mkOption {
|
||||
type = lib.types.attrsOf keyValue.type;
|
||||
default = { };
|
||||
example = {
|
||||
catppuccin-mocha = {
|
||||
palette = [
|
||||
"0=#45475a"
|
||||
"1=#f38ba8"
|
||||
"2=#a6e3a1"
|
||||
"3=#f9e2af"
|
||||
"4=#89b4fa"
|
||||
"5=#f5c2e7"
|
||||
"6=#94e2d5"
|
||||
"7=#bac2de"
|
||||
"8=#585b70"
|
||||
"9=#f38ba8"
|
||||
"10=#a6e3a1"
|
||||
"11=#f9e2af"
|
||||
"12=#89b4fa"
|
||||
"13=#f5c2e7"
|
||||
"14=#94e2d5"
|
||||
"15=#a6adc8"
|
||||
];
|
||||
background = "1e1e2e";
|
||||
foreground = "cdd6f4";
|
||||
cursor-color = "f5e0dc";
|
||||
selection-background = "353749";
|
||||
selection-foreground = "cdd6f4";
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Custom themes written to {file}`$XDG_CONFIG_HOME/ghostty/themes`.
|
||||
|
||||
See <https://ghostty.org/docs/features/theme#authoring-a-custom-theme> for more information.
|
||||
'';
|
||||
};
|
||||
description = ''
|
||||
Custom themes written to {file}`$XDG_CONFIG_HOME/ghostty/themes`.
|
||||
|
||||
See <https://ghostty.org/docs/features/theme#authoring-a-custom-theme> for more information.
|
||||
'';
|
||||
};
|
||||
clearDefaultKeybinds = lib.mkEnableOption "" // {
|
||||
description = "Whether to clear default keybinds.";
|
||||
};
|
||||
|
||||
clearDefaultKeybinds = lib.mkEnableOption "" // {
|
||||
description = "Whether to clear default keybinds.";
|
||||
};
|
||||
installVimSyntax = lib.mkEnableOption "installation of Ghostty configuration syntax for Vim";
|
||||
|
||||
installVimSyntax =
|
||||
lib.mkEnableOption "installation of Ghostty configuration syntax for Vim";
|
||||
|
||||
installBatSyntax =
|
||||
lib.mkEnableOption "installation of Ghostty configuration syntax for bat"
|
||||
// {
|
||||
installBatSyntax = lib.mkEnableOption "installation of Ghostty configuration syntax for bat" // {
|
||||
default = cfg.package != null;
|
||||
defaultText =
|
||||
lib.literalMD "`true` if programs.ghostty.package is not null";
|
||||
defaultText = lib.literalMD "`true` if programs.ghostty.package is not null";
|
||||
};
|
||||
|
||||
enableBashIntegration = mkShellIntegrationOption
|
||||
(lib.hm.shell.mkBashIntegrationOption { inherit config; });
|
||||
enableBashIntegration = mkShellIntegrationOption (
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; }
|
||||
);
|
||||
|
||||
enableFishIntegration = mkShellIntegrationOption
|
||||
(lib.hm.shell.mkFishIntegrationOption { inherit config; });
|
||||
enableFishIntegration = mkShellIntegrationOption (
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; }
|
||||
);
|
||||
|
||||
enableZshIntegration = mkShellIntegrationOption
|
||||
(lib.hm.shell.mkZshIntegrationOption { inherit config; });
|
||||
};
|
||||
enableZshIntegration = mkShellIntegrationOption (
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; }
|
||||
);
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
home.packages = lib.optionals (cfg.package != null) [ cfg.package ];
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
home.packages = lib.optionals (cfg.package != null) [ cfg.package ];
|
||||
|
||||
programs.ghostty.settings = lib.mkIf cfg.clearDefaultKeybinds {
|
||||
keybind = lib.mkBefore [ "clear" ];
|
||||
};
|
||||
|
||||
# MacOS also supports XDG configuration directory, so we use it for both
|
||||
# Linux and macOS to reduce complexity
|
||||
xdg.configFile = let
|
||||
validate = file:
|
||||
lib.mkIf (cfg.package != null) "${
|
||||
lib.getExe cfg.package
|
||||
} +validate-config --config-file=${config.xdg.configHome}/ghostty/${file}";
|
||||
in lib.mkMerge [
|
||||
{
|
||||
"ghostty/config" = lib.mkIf (cfg.settings != { }) {
|
||||
source = keyValue.generate "ghostty-config" cfg.settings;
|
||||
onChange = validate "config";
|
||||
};
|
||||
}
|
||||
|
||||
(lib.mkIf (cfg.themes != { }) (lib.mapAttrs' (name: value: {
|
||||
name = "ghostty/themes/${name}";
|
||||
value = {
|
||||
source = keyValue.generate "ghostty-${name}-theme" value;
|
||||
onChange = validate "themes/${name}";
|
||||
};
|
||||
}) cfg.themes))
|
||||
];
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.installVimSyntax {
|
||||
assertions = [{
|
||||
assertion = cfg.installVimSyntax -> cfg.package != null;
|
||||
message =
|
||||
"programs.ghostty.installVimSyntax cannot be enabled when programs.ghostty.package is null";
|
||||
}];
|
||||
programs.vim.plugins =
|
||||
lib.optionals (cfg.package != null) [ cfg.package.vim ];
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.installBatSyntax {
|
||||
assertions = [{
|
||||
assertion = cfg.installBatSyntax -> cfg.package != null;
|
||||
message =
|
||||
"programs.ghostty.installBatSyntax cannot be enabled when programs.ghostty.package is null";
|
||||
}];
|
||||
programs.bat = lib.mkIf (cfg.package != null) {
|
||||
syntaxes.ghostty = {
|
||||
src = cfg.package;
|
||||
file = "share/bat/syntaxes/ghostty.sublime-syntax";
|
||||
programs.ghostty.settings = lib.mkIf cfg.clearDefaultKeybinds {
|
||||
keybind = lib.mkBefore [ "clear" ];
|
||||
};
|
||||
config.map-syntax =
|
||||
[ "${config.xdg.configHome}/ghostty/config:Ghostty Config" ];
|
||||
};
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.enableBashIntegration {
|
||||
# Make order 101 to be placed exactly after bash completions, as Ghostty
|
||||
# documentation suggests sourcing the script as soon as possible
|
||||
programs.bash.initExtra = lib.mkOrder 101 ''
|
||||
if [[ -n "''${GHOSTTY_RESOURCES_DIR}" ]]; then
|
||||
builtin source "''${GHOSTTY_RESOURCES_DIR}/shell-integration/bash/ghostty.bash"
|
||||
fi
|
||||
'';
|
||||
})
|
||||
# MacOS also supports XDG configuration directory, so we use it for both
|
||||
# Linux and macOS to reduce complexity
|
||||
xdg.configFile =
|
||||
let
|
||||
validate =
|
||||
file:
|
||||
lib.mkIf (cfg.package != null)
|
||||
"${lib.getExe cfg.package} +validate-config --config-file=${config.xdg.configHome}/ghostty/${file}";
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
"ghostty/config" = lib.mkIf (cfg.settings != { }) {
|
||||
source = keyValue.generate "ghostty-config" cfg.settings;
|
||||
onChange = validate "config";
|
||||
};
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.enableFishIntegration {
|
||||
programs.fish.shellInit = ''
|
||||
if set -q GHOSTTY_RESOURCES_DIR
|
||||
source "$GHOSTTY_RESOURCES_DIR/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish"
|
||||
end
|
||||
'';
|
||||
})
|
||||
(lib.mkIf (cfg.themes != { }) (
|
||||
lib.mapAttrs' (name: value: {
|
||||
name = "ghostty/themes/${name}";
|
||||
value = {
|
||||
source = keyValue.generate "ghostty-${name}-theme" value;
|
||||
onChange = validate "themes/${name}";
|
||||
};
|
||||
}) cfg.themes
|
||||
))
|
||||
];
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.enableZshIntegration {
|
||||
programs.zsh.initContent = ''
|
||||
if [[ -n $GHOSTTY_RESOURCES_DIR ]]; then
|
||||
source "$GHOSTTY_RESOURCES_DIR"/shell-integration/zsh/ghostty-integration
|
||||
fi
|
||||
'';
|
||||
})
|
||||
]);
|
||||
(lib.mkIf cfg.installVimSyntax {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.installVimSyntax -> cfg.package != null;
|
||||
message = "programs.ghostty.installVimSyntax cannot be enabled when programs.ghostty.package is null";
|
||||
}
|
||||
];
|
||||
programs.vim.plugins = lib.optionals (cfg.package != null) [ cfg.package.vim ];
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.installBatSyntax {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.installBatSyntax -> cfg.package != null;
|
||||
message = "programs.ghostty.installBatSyntax cannot be enabled when programs.ghostty.package is null";
|
||||
}
|
||||
];
|
||||
programs.bat = lib.mkIf (cfg.package != null) {
|
||||
syntaxes.ghostty = {
|
||||
src = cfg.package;
|
||||
file = "share/bat/syntaxes/ghostty.sublime-syntax";
|
||||
};
|
||||
config.map-syntax = [ "${config.xdg.configHome}/ghostty/config:Ghostty Config" ];
|
||||
};
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.enableBashIntegration {
|
||||
# Make order 101 to be placed exactly after bash completions, as Ghostty
|
||||
# documentation suggests sourcing the script as soon as possible
|
||||
programs.bash.initExtra = lib.mkOrder 101 ''
|
||||
if [[ -n "''${GHOSTTY_RESOURCES_DIR}" ]]; then
|
||||
builtin source "''${GHOSTTY_RESOURCES_DIR}/shell-integration/bash/ghostty.bash"
|
||||
fi
|
||||
'';
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.enableFishIntegration {
|
||||
programs.fish.shellInit = ''
|
||||
if set -q GHOSTTY_RESOURCES_DIR
|
||||
source "$GHOSTTY_RESOURCES_DIR/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish"
|
||||
end
|
||||
'';
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.enableZshIntegration {
|
||||
programs.zsh.initContent = ''
|
||||
if [[ -n $GHOSTTY_RESOURCES_DIR ]]; then
|
||||
source "$GHOSTTY_RESOURCES_DIR"/shell-integration/zsh/ghostty-integration
|
||||
fi
|
||||
'';
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.git-cliff;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.NateCox ];
|
||||
|
||||
options.programs.git-cliff = {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.git-credential-oauth;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.tomodachi94 ];
|
||||
|
||||
options = {
|
||||
|
|
@ -30,9 +36,10 @@ in {
|
|||
home.packages = [ cfg.package ];
|
||||
|
||||
programs.git.extraConfig.credential.helper = lib.mkAfter [
|
||||
("${cfg.package}/bin/git-credential-oauth"
|
||||
+ lib.optionalString (cfg.extraFlags != [ ])
|
||||
" ${lib.strings.concatStringsSep " " cfg.extraFlags}")
|
||||
(
|
||||
"${cfg.package}/bin/git-credential-oauth"
|
||||
+ lib.optionalString (cfg.extraFlags != [ ]) " ${lib.strings.concatStringsSep " " cfg.extraFlags}"
|
||||
)
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,46 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkPackageOption optionalString;
|
||||
|
||||
cfg = config.programs.git-worktree-switcher;
|
||||
|
||||
initScript = shell:
|
||||
if (shell == "fish") then ''
|
||||
${lib.getExe pkgs.git-worktree-switcher} init ${shell} | source
|
||||
'' else ''
|
||||
eval "$(${lib.getExe pkgs.git-worktree-switcher} init ${shell})"
|
||||
'';
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ jiriks74 mateusauler ];
|
||||
initScript =
|
||||
shell:
|
||||
if (shell == "fish") then
|
||||
''
|
||||
${lib.getExe pkgs.git-worktree-switcher} init ${shell} | source
|
||||
''
|
||||
else
|
||||
''
|
||||
eval "$(${lib.getExe pkgs.git-worktree-switcher} init ${shell})"
|
||||
'';
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
jiriks74
|
||||
mateusauler
|
||||
];
|
||||
|
||||
options.programs.git-worktree-switcher = {
|
||||
enable = mkEnableOption "git-worktree-switcher";
|
||||
package = mkPackageOption pkgs "git-worktree-switcher" { };
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
programs.bash.initExtra =
|
||||
optionalString cfg.enableBashIntegration (initScript "bash");
|
||||
programs.fish.interactiveShellInit =
|
||||
optionalString cfg.enableFishIntegration (initScript "fish");
|
||||
programs.zsh.initContent =
|
||||
optionalString cfg.enableZshIntegration (initScript "zsh");
|
||||
programs.bash.initExtra = optionalString cfg.enableBashIntegration (initScript "bash");
|
||||
programs.fish.interactiveShellInit = optionalString cfg.enableFishIntegration (initScript "fish");
|
||||
programs.zsh.initContent = optionalString cfg.enableZshIntegration (initScript "zsh");
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +1,102 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
concatStringsSep literalExpression mkDefault mkEnableOption mkIf mkOption
|
||||
mkOptionDefault mkPackageOption types;
|
||||
concatStringsSep
|
||||
literalExpression
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
mkOptionDefault
|
||||
mkPackageOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.git;
|
||||
|
||||
gitIniType = with types;
|
||||
gitIniType =
|
||||
with types;
|
||||
let
|
||||
primitiveType = either str (either bool int);
|
||||
multipleType = either primitiveType (listOf primitiveType);
|
||||
sectionType = attrsOf multipleType;
|
||||
supersectionType = attrsOf (either multipleType sectionType);
|
||||
in attrsOf supersectionType;
|
||||
in
|
||||
attrsOf supersectionType;
|
||||
|
||||
includeModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
condition = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Include this configuration only when {var}`condition`
|
||||
matches. Allowed conditions are described in
|
||||
{manpage}`git-config(1)`.
|
||||
'';
|
||||
};
|
||||
includeModule = types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
condition = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Include this configuration only when {var}`condition`
|
||||
matches. Allowed conditions are described in
|
||||
{manpage}`git-config(1)`.
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = with types; either str path;
|
||||
description = "Path of the configuration file to include.";
|
||||
};
|
||||
path = mkOption {
|
||||
type = with types; either str path;
|
||||
description = "Path of the configuration file to include.";
|
||||
};
|
||||
|
||||
contents = mkOption {
|
||||
type = types.attrsOf types.anything;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
user = {
|
||||
email = "bob@work.example.com";
|
||||
name = "Bob Work";
|
||||
signingKey = "1A2B3C4D5E6F7G8H";
|
||||
contents = mkOption {
|
||||
type = types.attrsOf types.anything;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
user = {
|
||||
email = "bob@work.example.com";
|
||||
name = "Bob Work";
|
||||
signingKey = "1A2B3C4D5E6F7G8H";
|
||||
};
|
||||
commit = {
|
||||
gpgSign = true;
|
||||
};
|
||||
};
|
||||
commit = {
|
||||
gpgSign = true;
|
||||
};
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
Configuration to include. If empty then a path must be given.
|
||||
'';
|
||||
description = ''
|
||||
Configuration to include. If empty then a path must be given.
|
||||
|
||||
This follows the configuration structure as described in
|
||||
{manpage}`git-config(1)`.
|
||||
'';
|
||||
This follows the configuration structure as described in
|
||||
{manpage}`git-config(1)`.
|
||||
'';
|
||||
};
|
||||
|
||||
contentSuffix = mkOption {
|
||||
type = types.str;
|
||||
default = "gitconfig";
|
||||
description = ''
|
||||
Nix store name for the git configuration text file,
|
||||
when generating the configuration text from nix options.
|
||||
'';
|
||||
|
||||
};
|
||||
};
|
||||
config.path = mkIf (config.contents != { }) (
|
||||
mkDefault (
|
||||
pkgs.writeText (lib.hm.strings.storeFileName config.contentSuffix) (
|
||||
lib.generators.toGitINI config.contents
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
contentSuffix = mkOption {
|
||||
type = types.str;
|
||||
default = "gitconfig";
|
||||
description = ''
|
||||
Nix store name for the git configuration text file,
|
||||
when generating the configuration text from nix options.
|
||||
'';
|
||||
|
||||
};
|
||||
};
|
||||
config.path = mkIf (config.contents != { }) (mkDefault
|
||||
(pkgs.writeText (lib.hm.strings.storeFileName config.contentSuffix)
|
||||
(lib.generators.toGitINI config.contents)));
|
||||
});
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ khaneliman rycee ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
khaneliman
|
||||
rycee
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.git = {
|
||||
|
|
@ -99,7 +125,9 @@ in {
|
|||
aliases = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = { co = "checkout"; };
|
||||
example = {
|
||||
co = "checkout";
|
||||
};
|
||||
description = "Git aliases to define.";
|
||||
};
|
||||
|
||||
|
|
@ -116,7 +144,13 @@ in {
|
|||
};
|
||||
|
||||
format = mkOption {
|
||||
type = types.nullOr (types.enum [ "openpgp" "ssh" "x509" ]);
|
||||
type = types.nullOr (
|
||||
types.enum [
|
||||
"openpgp"
|
||||
"ssh"
|
||||
"x509"
|
||||
]
|
||||
);
|
||||
defaultText = literalExpression ''
|
||||
"openpgp" for state version < 25.05,
|
||||
undefined for state version ≥ 25.05
|
||||
|
|
@ -143,7 +177,9 @@ in {
|
|||
type = types.either types.lines gitIniType;
|
||||
default = { };
|
||||
example = {
|
||||
core = { whitespace = "trailing-space,space-before-tab"; };
|
||||
core = {
|
||||
whitespace = "trailing-space,space-before-tab";
|
||||
};
|
||||
url."ssh://git@host".insteadOf = "otherhost";
|
||||
};
|
||||
description = ''
|
||||
|
|
@ -175,7 +211,10 @@ in {
|
|||
ignores = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "*~" "*.swp" ];
|
||||
example = [
|
||||
"*~"
|
||||
"*.swp"
|
||||
];
|
||||
description = "List of paths that should be globally ignored.";
|
||||
};
|
||||
|
||||
|
|
@ -264,7 +303,10 @@ in {
|
|||
pagerOpts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--tabs=4" "-RFX" ];
|
||||
example = [
|
||||
"--tabs=4"
|
||||
"-RFX"
|
||||
];
|
||||
description = ''
|
||||
Arguments to be passed to {command}`less`.
|
||||
'';
|
||||
|
|
@ -289,7 +331,10 @@ in {
|
|||
};
|
||||
|
||||
background = mkOption {
|
||||
type = types.enum [ "light" "dark" ];
|
||||
type = types.enum [
|
||||
"light"
|
||||
"dark"
|
||||
];
|
||||
default = "light";
|
||||
example = "dark";
|
||||
description = ''
|
||||
|
|
@ -299,7 +344,11 @@ in {
|
|||
};
|
||||
|
||||
color = mkOption {
|
||||
type = types.enum [ "always" "auto" "never" ];
|
||||
type = types.enum [
|
||||
"always"
|
||||
"auto"
|
||||
"never"
|
||||
];
|
||||
default = "auto";
|
||||
example = "always";
|
||||
description = ''
|
||||
|
|
@ -308,8 +357,11 @@ in {
|
|||
};
|
||||
|
||||
display = mkOption {
|
||||
type =
|
||||
types.enum [ "side-by-side" "side-by-side-show-both" "inline" ];
|
||||
type = types.enum [
|
||||
"side-by-side"
|
||||
"side-by-side-show-both"
|
||||
"inline"
|
||||
];
|
||||
default = "side-by-side";
|
||||
example = "inline";
|
||||
description = ''
|
||||
|
|
@ -329,11 +381,13 @@ in {
|
|||
package = mkPackageOption pkgs "delta" { };
|
||||
|
||||
options = mkOption {
|
||||
type = with types;
|
||||
type =
|
||||
with types;
|
||||
let
|
||||
primitiveType = either str (either bool int);
|
||||
sectionType = attrsOf primitiveType;
|
||||
in attrsOf (either primitiveType sectionType);
|
||||
in
|
||||
attrsOf (either primitiveType sectionType);
|
||||
default = { };
|
||||
example = {
|
||||
features = "decorations";
|
||||
|
|
@ -360,7 +414,10 @@ in {
|
|||
|
||||
pagerOpts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "--tabs=4" "-RFX" ];
|
||||
default = [
|
||||
"--tabs=4"
|
||||
"-RFX"
|
||||
];
|
||||
description = ''
|
||||
Arguments to be passed to {command}`less`.
|
||||
'';
|
||||
|
|
@ -443,300 +500,363 @@ in {
|
|||
};
|
||||
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "programs" "git" "signing" "gpgPath" ] [
|
||||
"programs"
|
||||
"git"
|
||||
"signing"
|
||||
"signer"
|
||||
])
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "programs" "git" "signing" "gpgPath" ]
|
||||
[
|
||||
"programs"
|
||||
"git"
|
||||
"signing"
|
||||
"signer"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
assertions = [{
|
||||
assertion = let
|
||||
enabled = [
|
||||
cfg.delta.enable
|
||||
cfg.diff-so-fancy.enable
|
||||
cfg.difftastic.enable
|
||||
cfg.diff-highlight.enable
|
||||
cfg.riff.enable
|
||||
];
|
||||
in lib.count lib.id enabled <= 1;
|
||||
message =
|
||||
"Only one of 'programs.git.delta.enable' or 'programs.git.difftastic.enable' or 'programs.git.diff-so-fancy.enable' or 'programs.git.diff-highlight' can be set to true at the same time.";
|
||||
}];
|
||||
|
||||
programs.git.iniContent.user = {
|
||||
name = mkIf (cfg.userName != null) cfg.userName;
|
||||
email = mkIf (cfg.userEmail != null) cfg.userEmail;
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"git/config".text = lib.generators.toGitINI cfg.iniContent;
|
||||
|
||||
"git/ignore" = mkIf (cfg.ignores != [ ]) {
|
||||
text = concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
|
||||
"git/attributes" = mkIf (cfg.attributes != [ ]) {
|
||||
text = concatStringsSep "\n" cfg.attributes + "\n";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
programs.git.iniContent = let
|
||||
hasSmtp = name: account: account.smtp != null;
|
||||
|
||||
genIdentity = name: account:
|
||||
let inherit (account) address realName smtp userName;
|
||||
in lib.nameValuePair "sendemail.${name}"
|
||||
(if account.msmtp.enable then {
|
||||
sendmailCmd = "${pkgs.msmtp}/bin/msmtp";
|
||||
envelopeSender = "auto";
|
||||
from = "${realName} <${address}>";
|
||||
} else
|
||||
{
|
||||
smtpEncryption = if smtp.tls.enable then
|
||||
(if smtp.tls.useStartTls
|
||||
|| lib.versionOlder config.home.stateVersion "20.09" then
|
||||
"tls"
|
||||
else
|
||||
"ssl")
|
||||
else
|
||||
"";
|
||||
smtpSslCertPath =
|
||||
mkIf smtp.tls.enable (toString smtp.tls.certificatesFile);
|
||||
smtpServer = smtp.host;
|
||||
smtpUser = userName;
|
||||
from = "${realName} <${address}>";
|
||||
} // lib.optionalAttrs (smtp.port != null) {
|
||||
smtpServerPort = smtp.port;
|
||||
});
|
||||
in lib.mapAttrs' genIdentity
|
||||
(lib.filterAttrs hasSmtp config.accounts.email.accounts);
|
||||
}
|
||||
|
||||
(mkIf (cfg.signing != { }) {
|
||||
programs.git = {
|
||||
signing = {
|
||||
format = if (lib.versionOlder config.home.stateVersion "25.05") then
|
||||
(mkOptionDefault "openpgp")
|
||||
else
|
||||
(mkOptionDefault null);
|
||||
signer = let
|
||||
defaultSigners = {
|
||||
openpgp = lib.getExe config.programs.gpg.package;
|
||||
ssh = lib.getExe' pkgs.openssh "ssh-keygen";
|
||||
x509 = lib.getExe' config.programs.gpg.package "gpgsm";
|
||||
};
|
||||
in mkIf (cfg.signing.format != null)
|
||||
(mkOptionDefault defaultSigners.${cfg.signing.format});
|
||||
};
|
||||
|
||||
iniContent = lib.mkMerge [
|
||||
(mkIf (cfg.signing.key != null) {
|
||||
user.signingKey = mkDefault cfg.signing.key;
|
||||
})
|
||||
(mkIf (cfg.signing.signByDefault != null) {
|
||||
commit.gpgSign = mkDefault cfg.signing.signByDefault;
|
||||
tag.gpgSign = mkDefault cfg.signing.signByDefault;
|
||||
})
|
||||
(mkIf (cfg.signing.format != null) {
|
||||
gpg = {
|
||||
format = mkDefault cfg.signing.format;
|
||||
${cfg.signing.format}.program = mkDefault cfg.signing.signer;
|
||||
};
|
||||
})
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
enabled = [
|
||||
cfg.delta.enable
|
||||
cfg.diff-so-fancy.enable
|
||||
cfg.difftastic.enable
|
||||
cfg.diff-highlight.enable
|
||||
cfg.riff.enable
|
||||
];
|
||||
in
|
||||
lib.count lib.id enabled <= 1;
|
||||
message = "Only one of 'programs.git.delta.enable' or 'programs.git.difftastic.enable' or 'programs.git.diff-so-fancy.enable' or 'programs.git.diff-highlight' can be set to true at the same time.";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.hooks != { }) {
|
||||
programs.git.iniContent = {
|
||||
core.hooksPath = let
|
||||
entries =
|
||||
lib.mapAttrsToList (name: path: { inherit name path; }) cfg.hooks;
|
||||
in toString (pkgs.linkFarm "git-hooks" entries);
|
||||
};
|
||||
})
|
||||
programs.git.iniContent.user = {
|
||||
name = mkIf (cfg.userName != null) cfg.userName;
|
||||
email = mkIf (cfg.userEmail != null) cfg.userEmail;
|
||||
};
|
||||
|
||||
(mkIf (cfg.aliases != { }) { programs.git.iniContent.alias = cfg.aliases; })
|
||||
xdg.configFile = {
|
||||
"git/config".text = lib.generators.toGitINI cfg.iniContent;
|
||||
|
||||
(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}";
|
||||
"git/ignore" = mkIf (cfg.ignores != [ ]) {
|
||||
text = concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
in lib.mkAfter (concatStringsSep "\n"
|
||||
(map lib.generators.toGitINI (map include cfg.includes)));
|
||||
})
|
||||
|
||||
(mkIf cfg.lfs.enable {
|
||||
home.packages = [ pkgs.git-lfs ];
|
||||
|
||||
programs.git.iniContent.filter.lfs =
|
||||
let skipArg = lib.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" ]);
|
||||
"git/attributes" = mkIf (cfg.attributes != [ ]) {
|
||||
text = concatStringsSep "\n" cfg.attributes + "\n";
|
||||
};
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
(mkIf cfg.maintenance.enable {
|
||||
programs.git.iniContent.maintenance.repo = cfg.maintenance.repositories;
|
||||
{
|
||||
programs.git.iniContent =
|
||||
let
|
||||
hasSmtp = name: account: account.smtp != null;
|
||||
|
||||
systemd.user.services."git-maintenance@" = {
|
||||
Unit = {
|
||||
Description = "Optimize Git repositories data";
|
||||
Documentation = [ "man:git-maintenance(1)" ];
|
||||
genIdentity =
|
||||
name: account:
|
||||
let
|
||||
inherit (account)
|
||||
address
|
||||
realName
|
||||
smtp
|
||||
userName
|
||||
;
|
||||
in
|
||||
lib.nameValuePair "sendemail.${name}" (
|
||||
if account.msmtp.enable then
|
||||
{
|
||||
sendmailCmd = "${pkgs.msmtp}/bin/msmtp";
|
||||
envelopeSender = "auto";
|
||||
from = "${realName} <${address}>";
|
||||
}
|
||||
else
|
||||
{
|
||||
smtpEncryption =
|
||||
if smtp.tls.enable then
|
||||
(if smtp.tls.useStartTls || lib.versionOlder config.home.stateVersion "20.09" then "tls" else "ssl")
|
||||
else
|
||||
"";
|
||||
smtpSslCertPath = mkIf smtp.tls.enable (toString smtp.tls.certificatesFile);
|
||||
smtpServer = smtp.host;
|
||||
smtpUser = userName;
|
||||
from = "${realName} <${address}>";
|
||||
}
|
||||
// lib.optionalAttrs (smtp.port != null) {
|
||||
smtpServerPort = smtp.port;
|
||||
}
|
||||
);
|
||||
in
|
||||
lib.mapAttrs' genIdentity (lib.filterAttrs hasSmtp config.accounts.email.accounts);
|
||||
}
|
||||
|
||||
(mkIf (cfg.signing != { }) {
|
||||
programs.git = {
|
||||
signing = {
|
||||
format =
|
||||
if (lib.versionOlder config.home.stateVersion "25.05") then
|
||||
(mkOptionDefault "openpgp")
|
||||
else
|
||||
(mkOptionDefault null);
|
||||
signer =
|
||||
let
|
||||
defaultSigners = {
|
||||
openpgp = lib.getExe config.programs.gpg.package;
|
||||
ssh = lib.getExe' pkgs.openssh "ssh-keygen";
|
||||
x509 = lib.getExe' config.programs.gpg.package "gpgsm";
|
||||
};
|
||||
in
|
||||
mkIf (cfg.signing.format != null) (mkOptionDefault defaultSigners.${cfg.signing.format});
|
||||
};
|
||||
|
||||
iniContent = lib.mkMerge [
|
||||
(mkIf (cfg.signing.key != null) {
|
||||
user.signingKey = mkDefault cfg.signing.key;
|
||||
})
|
||||
(mkIf (cfg.signing.signByDefault != null) {
|
||||
commit.gpgSign = mkDefault cfg.signing.signByDefault;
|
||||
tag.gpgSign = mkDefault cfg.signing.signByDefault;
|
||||
})
|
||||
(mkIf (cfg.signing.format != null) {
|
||||
gpg = {
|
||||
format = mkDefault cfg.signing.format;
|
||||
${cfg.signing.format}.program = mkDefault cfg.signing.signer;
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.hooks != { }) {
|
||||
programs.git.iniContent = {
|
||||
core.hooksPath =
|
||||
let
|
||||
entries = lib.mapAttrsToList (name: path: { inherit name path; }) cfg.hooks;
|
||||
in
|
||||
toString (pkgs.linkFarm "git-hooks" entries);
|
||||
};
|
||||
})
|
||||
|
||||
(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
|
||||
lib.mkAfter (concatStringsSep "\n" (map lib.generators.toGitINI (map include cfg.includes)));
|
||||
})
|
||||
|
||||
(mkIf cfg.lfs.enable {
|
||||
home.packages = [ pkgs.git-lfs ];
|
||||
|
||||
programs.git.iniContent.filter.lfs =
|
||||
let
|
||||
skipArg = lib.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"
|
||||
]
|
||||
);
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.maintenance.enable {
|
||||
programs.git.iniContent.maintenance.repo = cfg.maintenance.repositories;
|
||||
|
||||
systemd.user.services."git-maintenance@" = {
|
||||
Unit = {
|
||||
Description = "Optimize Git repositories data";
|
||||
Documentation = [ "man:git-maintenance(1)" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart =
|
||||
let
|
||||
exe = lib.getExe cfg.package;
|
||||
in
|
||||
''
|
||||
"${exe}" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i
|
||||
'';
|
||||
LockPersonality = "yes";
|
||||
MemoryDenyWriteExecute = "yes";
|
||||
NoNewPrivileges = "yes";
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_VSOCK";
|
||||
RestrictNamespaces = "yes";
|
||||
RestrictRealtime = "yes";
|
||||
RestrictSUIDSGID = "yes";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "@system-service";
|
||||
};
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = let exe = lib.getExe cfg.package;
|
||||
in ''
|
||||
"${exe}" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i
|
||||
'';
|
||||
LockPersonality = "yes";
|
||||
MemoryDenyWriteExecute = "yes";
|
||||
NoNewPrivileges = "yes";
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_VSOCK";
|
||||
RestrictNamespaces = "yes";
|
||||
RestrictRealtime = "yes";
|
||||
RestrictSUIDSGID = "yes";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "@system-service";
|
||||
};
|
||||
};
|
||||
systemd.user.timers =
|
||||
let
|
||||
toSystemdTimer =
|
||||
name: time:
|
||||
lib.attrsets.nameValuePair "git-maintenance@${name}" {
|
||||
Unit.Description = "Optimize Git repositories data";
|
||||
|
||||
systemd.user.timers = let
|
||||
toSystemdTimer = name: time:
|
||||
lib.attrsets.nameValuePair "git-maintenance@${name}" {
|
||||
Unit.Description = "Optimize Git repositories data";
|
||||
Timer = {
|
||||
OnCalendar = time;
|
||||
Persistent = true;
|
||||
};
|
||||
|
||||
Timer = {
|
||||
OnCalendar = time;
|
||||
Persistent = true;
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
in
|
||||
lib.attrsets.mapAttrs' toSystemdTimer cfg.maintenance.timers;
|
||||
})
|
||||
|
||||
(mkIf cfg.diff-highlight.enable {
|
||||
programs.git.iniContent =
|
||||
let
|
||||
dhCommand = "${cfg.package}/share/git/contrib/diff-highlight/diff-highlight";
|
||||
in
|
||||
{
|
||||
core.pager = "${dhCommand} | ${lib.getExe pkgs.less} ${lib.escapeShellArgs cfg.diff-highlight.pagerOpts}";
|
||||
interactive.diffFilter = dhCommand;
|
||||
};
|
||||
})
|
||||
|
||||
(
|
||||
let
|
||||
difftCommand = concatStringsSep " " [
|
||||
"${lib.getExe cfg.difftastic.package}"
|
||||
"--color ${cfg.difftastic.color}"
|
||||
"--background ${cfg.difftastic.background}"
|
||||
"--display ${cfg.difftastic.display}"
|
||||
];
|
||||
in
|
||||
(lib.mkMerge [
|
||||
(mkIf cfg.difftastic.enable {
|
||||
home.packages = [ cfg.difftastic.package ];
|
||||
programs.git.iniContent = {
|
||||
diff.external = difftCommand;
|
||||
};
|
||||
})
|
||||
(mkIf cfg.difftastic.enableAsDifftool {
|
||||
home.packages = [ cfg.difftastic.package ];
|
||||
programs.git.iniContent = {
|
||||
diff = {
|
||||
tool = lib.mkDefault "difftastic";
|
||||
};
|
||||
difftool = {
|
||||
difftastic = {
|
||||
cmd = "${difftCommand} $LOCAL $REMOTE";
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
])
|
||||
)
|
||||
|
||||
(
|
||||
let
|
||||
deltaPackage = cfg.delta.package;
|
||||
deltaCommand = "${deltaPackage}/bin/delta";
|
||||
in
|
||||
mkIf cfg.delta.enable {
|
||||
home.packages = [ deltaPackage ];
|
||||
|
||||
programs.git.iniContent = {
|
||||
core.pager = deltaCommand;
|
||||
interactive.diffFilter = "${deltaCommand} --color-only";
|
||||
delta = cfg.delta.options;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
(mkIf cfg.diff-so-fancy.enable {
|
||||
home.packages = [ pkgs.diff-so-fancy ];
|
||||
|
||||
programs.git.iniContent =
|
||||
let
|
||||
dsfCommand = "${pkgs.diff-so-fancy}/bin/diff-so-fancy";
|
||||
in
|
||||
{
|
||||
core.pager = "${dsfCommand} | ${pkgs.less}/bin/less ${lib.escapeShellArgs cfg.diff-so-fancy.pagerOpts}";
|
||||
interactive.diffFilter = "${dsfCommand} --patch";
|
||||
diff-so-fancy = {
|
||||
markEmptyLines = cfg.diff-so-fancy.markEmptyLines;
|
||||
changeHunkIndicators = cfg.diff-so-fancy.changeHunkIndicators;
|
||||
stripLeadingSymbols = cfg.diff-so-fancy.stripLeadingSymbols;
|
||||
useUnicodeRuler = cfg.diff-so-fancy.useUnicodeRuler;
|
||||
rulerWidth = mkIf (cfg.diff-so-fancy.rulerWidth != null) (cfg.diff-so-fancy.rulerWidth);
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(
|
||||
let
|
||||
riffExe = baseNameOf (lib.getExe cfg.riff.package);
|
||||
in
|
||||
mkIf cfg.riff.enable {
|
||||
home.packages = [ cfg.riff.package ];
|
||||
|
||||
# https://github.com/walles/riff/blob/b17e6f17ce807c8652bc59cd46758661d23ce358/README.md#usage
|
||||
programs.git.iniContent = {
|
||||
pager = {
|
||||
diff = riffExe;
|
||||
log = riffExe;
|
||||
show = riffExe;
|
||||
};
|
||||
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
interactive.diffFilter = "${riffExe} --color=on";
|
||||
};
|
||||
in lib.attrsets.mapAttrs' toSystemdTimer cfg.maintenance.timers;
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
(mkIf cfg.diff-highlight.enable {
|
||||
programs.git.iniContent = let
|
||||
dhCommand =
|
||||
"${cfg.package}/share/git/contrib/diff-highlight/diff-highlight";
|
||||
in {
|
||||
core.pager = "${dhCommand} | ${lib.getExe pkgs.less} ${
|
||||
lib.escapeShellArgs cfg.diff-highlight.pagerOpts
|
||||
}";
|
||||
interactive.diffFilter = dhCommand;
|
||||
};
|
||||
})
|
||||
|
||||
(let
|
||||
difftCommand = concatStringsSep " " [
|
||||
"${lib.getExe cfg.difftastic.package}"
|
||||
"--color ${cfg.difftastic.color}"
|
||||
"--background ${cfg.difftastic.background}"
|
||||
"--display ${cfg.difftastic.display}"
|
||||
];
|
||||
in (lib.mkMerge [
|
||||
(mkIf cfg.difftastic.enable {
|
||||
home.packages = [ cfg.difftastic.package ];
|
||||
programs.git.iniContent = { diff.external = difftCommand; };
|
||||
(mkIf (cfg.riff.enable && cfg.riff.commandLineOptions != "") {
|
||||
home.sessionVariables.RIFF = cfg.riff.commandLineOptions;
|
||||
})
|
||||
(mkIf cfg.difftastic.enableAsDifftool {
|
||||
home.packages = [ cfg.difftastic.package ];
|
||||
programs.git.iniContent = {
|
||||
diff = { tool = lib.mkDefault "difftastic"; };
|
||||
difftool = {
|
||||
difftastic = { cmd = "${difftCommand} $LOCAL $REMOTE"; };
|
||||
};
|
||||
};
|
||||
})
|
||||
]))
|
||||
|
||||
(let
|
||||
deltaPackage = cfg.delta.package;
|
||||
deltaCommand = "${deltaPackage}/bin/delta";
|
||||
in mkIf cfg.delta.enable {
|
||||
home.packages = [ deltaPackage ];
|
||||
|
||||
programs.git.iniContent = {
|
||||
core.pager = deltaCommand;
|
||||
interactive.diffFilter = "${deltaCommand} --color-only";
|
||||
delta = cfg.delta.options;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.diff-so-fancy.enable {
|
||||
home.packages = [ pkgs.diff-so-fancy ];
|
||||
|
||||
programs.git.iniContent =
|
||||
let dsfCommand = "${pkgs.diff-so-fancy}/bin/diff-so-fancy";
|
||||
in {
|
||||
core.pager = "${dsfCommand} | ${pkgs.less}/bin/less ${
|
||||
lib.escapeShellArgs cfg.diff-so-fancy.pagerOpts
|
||||
}";
|
||||
interactive.diffFilter = "${dsfCommand} --patch";
|
||||
diff-so-fancy = {
|
||||
markEmptyLines = cfg.diff-so-fancy.markEmptyLines;
|
||||
changeHunkIndicators = cfg.diff-so-fancy.changeHunkIndicators;
|
||||
stripLeadingSymbols = cfg.diff-so-fancy.stripLeadingSymbols;
|
||||
useUnicodeRuler = cfg.diff-so-fancy.useUnicodeRuler;
|
||||
rulerWidth = mkIf (cfg.diff-so-fancy.rulerWidth != null)
|
||||
(cfg.diff-so-fancy.rulerWidth);
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(let riffExe = baseNameOf (lib.getExe cfg.riff.package);
|
||||
in mkIf cfg.riff.enable {
|
||||
home.packages = [ cfg.riff.package ];
|
||||
|
||||
# https://github.com/walles/riff/blob/b17e6f17ce807c8652bc59cd46758661d23ce358/README.md#usage
|
||||
programs.git.iniContent = {
|
||||
pager = {
|
||||
diff = riffExe;
|
||||
log = riffExe;
|
||||
show = riffExe;
|
||||
};
|
||||
|
||||
interactive.diffFilter = "${riffExe} --color=on";
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.riff.enable && cfg.riff.commandLineOptions != "") {
|
||||
home.sessionVariables.RIFF = cfg.riff.commandLineOptions;
|
||||
})
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
||||
cfg = config.programs.gitui;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.mifom ];
|
||||
|
||||
options.programs.gitui = {
|
||||
enable = lib.mkEnableOption
|
||||
"gitui, blazing fast terminal-ui for git written in rust";
|
||||
enable = lib.mkEnableOption "gitui, blazing fast terminal-ui for git written in rust";
|
||||
|
||||
package = lib.mkPackageOption pkgs "gitui" { };
|
||||
|
||||
|
|
|
|||
|
|
@ -1,35 +1,42 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
||||
cfg = config.programs.gnome-shell;
|
||||
|
||||
extensionOpts = { config, ... }: {
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
example = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
||||
description = ''
|
||||
ID of the GNOME Shell extension. If not provided, it
|
||||
will be obtained from `package.extensionUuid`.
|
||||
'';
|
||||
extensionOpts =
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
example = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
||||
description = ''
|
||||
ID of the GNOME Shell extension. If not provided, it
|
||||
will be obtained from `package.extensionUuid`.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
example = "pkgs.gnome-shell-extensions";
|
||||
description = ''
|
||||
Package providing a GNOME Shell extension in
|
||||
`$out/share/gnome-shell/extensions/''${id}`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
example = "pkgs.gnome-shell-extensions";
|
||||
description = ''
|
||||
Package providing a GNOME Shell extension in
|
||||
`$out/share/gnome-shell/extensions/''${id}`.
|
||||
'';
|
||||
config = lib.mkIf (lib.hasAttr "extensionUuid" config.package) {
|
||||
id = lib.mkDefault config.package.extensionUuid;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (lib.hasAttr "extensionUuid" config.package) {
|
||||
id = lib.mkDefault config.package.extensionUuid;
|
||||
};
|
||||
};
|
||||
|
||||
themeOpts = {
|
||||
options = {
|
||||
name = mkOption {
|
||||
|
|
@ -52,7 +59,8 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.terlar ];
|
||||
|
||||
options.programs.gnome-shell = {
|
||||
|
|
@ -90,26 +98,29 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
(lib.mkIf (cfg.extensions != [ ]) {
|
||||
dconf.settings."org/gnome/shell" = {
|
||||
disable-user-extensions = false;
|
||||
enabled-extensions = lib.catAttrs "id" cfg.extensions;
|
||||
};
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
(lib.mkIf (cfg.extensions != [ ]) {
|
||||
dconf.settings."org/gnome/shell" = {
|
||||
disable-user-extensions = false;
|
||||
enabled-extensions = lib.catAttrs "id" cfg.extensions;
|
||||
};
|
||||
|
||||
home.packages = lib.catAttrs "package" cfg.extensions;
|
||||
})
|
||||
home.packages = lib.catAttrs "package" cfg.extensions;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.theme != null) {
|
||||
dconf.settings."org/gnome/shell/extensions/user-theme".name =
|
||||
cfg.theme.name;
|
||||
(lib.mkIf (cfg.theme != null) {
|
||||
dconf.settings."org/gnome/shell/extensions/user-theme".name = cfg.theme.name;
|
||||
|
||||
programs.gnome-shell.extensions = [{
|
||||
id = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
||||
package = pkgs.gnome-shell-extensions;
|
||||
}];
|
||||
programs.gnome-shell.extensions = [
|
||||
{
|
||||
id = "user-theme@gnome-shell-extensions.gcampax.github.com";
|
||||
package = pkgs.gnome-shell-extensions;
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = [ cfg.theme.package ];
|
||||
})
|
||||
]);
|
||||
home.packages = [ cfg.theme.package ];
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
||||
|
|
@ -12,206 +17,224 @@ let
|
|||
"tty"
|
||||
];
|
||||
|
||||
backForeSubModule = types.submodule ({ ... }: {
|
||||
options = {
|
||||
foreground = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
backForeSubModule = types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
foreground = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
};
|
||||
|
||||
background = mkOption {
|
||||
type = types.str;
|
||||
description = "The background color.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
background = mkOption {
|
||||
type = types.str;
|
||||
description = "The background color.";
|
||||
profileColorsSubModule = types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
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 terminal’s highlighted area.";
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
profileColorsSubModule = types.submodule ({ ... }: {
|
||||
options = {
|
||||
foregroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
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.";
|
||||
};
|
||||
|
||||
cursorBlinkMode = mkOption {
|
||||
default = "system";
|
||||
type = types.enum [
|
||||
"system"
|
||||
"on"
|
||||
"off"
|
||||
];
|
||||
description = "The cursor blink mode.";
|
||||
};
|
||||
|
||||
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 `true`, 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.
|
||||
'';
|
||||
};
|
||||
|
||||
customCommand = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The command to use to start the shell, or null for default shell.
|
||||
'';
|
||||
};
|
||||
|
||||
loginShell = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Run command as a login shell.";
|
||||
};
|
||||
|
||||
backspaceBinding = mkOption {
|
||||
default = "ascii-delete";
|
||||
type = eraseBinding;
|
||||
description = ''
|
||||
Which string the terminal should send to an application when the user
|
||||
presses the *Backspace* key.
|
||||
|
||||
`auto`
|
||||
: Attempt to determine the right value from the terminal's IO settings.
|
||||
|
||||
`ascii-backspace`
|
||||
: Send an ASCII backspace character (`0x08`).
|
||||
|
||||
`ascii-delete`
|
||||
: Send an ASCII delete character (`0x7F`).
|
||||
|
||||
`delete-sequence`
|
||||
: Send the `@7` control sequence.
|
||||
|
||||
`tty`
|
||||
: Send terminal's "erase" setting.
|
||||
'';
|
||||
};
|
||||
|
||||
boldIsBright = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.bool;
|
||||
description = "Whether bold text is shown in bright colors.";
|
||||
};
|
||||
|
||||
deleteBinding = mkOption {
|
||||
default = "delete-sequence";
|
||||
type = eraseBinding;
|
||||
description = ''
|
||||
Which string the terminal should send to an application when the user
|
||||
presses the *Delete* key.
|
||||
|
||||
`auto`
|
||||
: Send the `@7` control sequence.
|
||||
|
||||
`ascii-backspace`
|
||||
: Send an ASCII backspace character (`0x08`).
|
||||
|
||||
`ascii-delete`
|
||||
: Send an ASCII delete character (`0x7F`).
|
||||
|
||||
`delete-sequence`
|
||||
: Send the `@7` control sequence.
|
||||
|
||||
`tty`
|
||||
: Send terminal's "erase" setting.
|
||||
'';
|
||||
};
|
||||
|
||||
audibleBell = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Turn on/off the terminal's bell.";
|
||||
};
|
||||
|
||||
transparencyPercent = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr (types.ints.between 0 100);
|
||||
description = "Background transparency in percent.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
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 terminal’s 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.";
|
||||
};
|
||||
|
||||
cursorBlinkMode = mkOption {
|
||||
default = "system";
|
||||
type = types.enum [ "system" "on" "off" ];
|
||||
description = "The cursor blink mode.";
|
||||
};
|
||||
|
||||
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 `true`, 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.
|
||||
'';
|
||||
};
|
||||
|
||||
customCommand = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The command to use to start the shell, or null for default shell.
|
||||
'';
|
||||
};
|
||||
|
||||
loginShell = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Run command as a login shell.";
|
||||
};
|
||||
|
||||
backspaceBinding = mkOption {
|
||||
default = "ascii-delete";
|
||||
type = eraseBinding;
|
||||
description = ''
|
||||
Which string the terminal should send to an application when the user
|
||||
presses the *Backspace* key.
|
||||
|
||||
`auto`
|
||||
: Attempt to determine the right value from the terminal's IO settings.
|
||||
|
||||
`ascii-backspace`
|
||||
: Send an ASCII backspace character (`0x08`).
|
||||
|
||||
`ascii-delete`
|
||||
: Send an ASCII delete character (`0x7F`).
|
||||
|
||||
`delete-sequence`
|
||||
: Send the `@7` control sequence.
|
||||
|
||||
`tty`
|
||||
: Send terminal's "erase" setting.
|
||||
'';
|
||||
};
|
||||
|
||||
boldIsBright = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.bool;
|
||||
description = "Whether bold text is shown in bright colors.";
|
||||
};
|
||||
|
||||
deleteBinding = mkOption {
|
||||
default = "delete-sequence";
|
||||
type = eraseBinding;
|
||||
description = ''
|
||||
Which string the terminal should send to an application when the user
|
||||
presses the *Delete* key.
|
||||
|
||||
`auto`
|
||||
: Send the `@7` control sequence.
|
||||
|
||||
`ascii-backspace`
|
||||
: Send an ASCII backspace character (`0x08`).
|
||||
|
||||
`ascii-delete`
|
||||
: Send an ASCII delete character (`0x7F`).
|
||||
|
||||
`delete-sequence`
|
||||
: Send the `@7` control sequence.
|
||||
|
||||
`tty`
|
||||
: Send terminal's "erase" setting.
|
||||
'';
|
||||
};
|
||||
|
||||
audibleBell = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Turn on/off the terminal's bell.";
|
||||
};
|
||||
|
||||
transparencyPercent = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr (types.ints.between 0 100);
|
||||
description = "Background transparency in percent.";
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
buildProfileSet = pcfg:
|
||||
buildProfileSet =
|
||||
pcfg:
|
||||
{
|
||||
audible-bell = pcfg.audibleBell;
|
||||
visible-name = pcfg.visibleName;
|
||||
|
|
@ -223,53 +246,97 @@ let
|
|||
login-shell = pcfg.loginShell;
|
||||
backspace-binding = pcfg.backspaceBinding;
|
||||
delete-binding = pcfg.deleteBinding;
|
||||
} // (if (pcfg.customCommand != null) then {
|
||||
use-custom-command = true;
|
||||
custom-command = pcfg.customCommand;
|
||||
} else {
|
||||
use-custom-command = false;
|
||||
}) // (if (pcfg.font == null) then {
|
||||
use-system-font = true;
|
||||
} else {
|
||||
use-system-font = false;
|
||||
font = pcfg.font;
|
||||
}) // (if (pcfg.colors == null) then {
|
||||
use-theme-colors = true;
|
||||
} else
|
||||
({
|
||||
use-theme-colors = false;
|
||||
foreground-color = pcfg.colors.foregroundColor;
|
||||
background-color = pcfg.colors.backgroundColor;
|
||||
palette = pcfg.colors.palette;
|
||||
} // lib.optionalAttrs (pcfg.allowBold != null) {
|
||||
allow-bold = pcfg.allowBold;
|
||||
} // (if (pcfg.colors.boldColor == null) then {
|
||||
bold-color-same-as-fg = true;
|
||||
} else {
|
||||
bold-color-same-as-fg = false;
|
||||
bold-color = pcfg.colors.boldColor;
|
||||
}) // lib.optionalAttrs (pcfg.boldIsBright != null) {
|
||||
bold-is-bright = pcfg.boldIsBright;
|
||||
} // (if (pcfg.colors.cursor != null) then {
|
||||
cursor-colors-set = true;
|
||||
cursor-foreground-color = pcfg.colors.cursor.foreground;
|
||||
cursor-background-color = pcfg.colors.cursor.background;
|
||||
} else {
|
||||
cursor-colors-set = false;
|
||||
}) // (if (pcfg.colors.highlight != null) then {
|
||||
highlight-colors-set = true;
|
||||
highlight-foreground-color = pcfg.colors.highlight.foreground;
|
||||
highlight-background-color = pcfg.colors.highlight.background;
|
||||
} else {
|
||||
highlight-colors-set = false;
|
||||
}) // lib.optionalAttrs (pcfg.transparencyPercent != null) {
|
||||
background-transparency-percent = pcfg.transparencyPercent;
|
||||
use-theme-transparency = false;
|
||||
use-transparent-background = true;
|
||||
}));
|
||||
}
|
||||
// (
|
||||
if (pcfg.customCommand != null) then
|
||||
{
|
||||
use-custom-command = true;
|
||||
custom-command = pcfg.customCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
use-custom-command = false;
|
||||
}
|
||||
)
|
||||
// (
|
||||
if (pcfg.font == null) then
|
||||
{
|
||||
use-system-font = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
use-system-font = false;
|
||||
font = pcfg.font;
|
||||
}
|
||||
)
|
||||
// (
|
||||
if (pcfg.colors == null) then
|
||||
{
|
||||
use-theme-colors = true;
|
||||
}
|
||||
else
|
||||
(
|
||||
{
|
||||
use-theme-colors = false;
|
||||
foreground-color = pcfg.colors.foregroundColor;
|
||||
background-color = pcfg.colors.backgroundColor;
|
||||
palette = pcfg.colors.palette;
|
||||
}
|
||||
// lib.optionalAttrs (pcfg.allowBold != null) {
|
||||
allow-bold = pcfg.allowBold;
|
||||
}
|
||||
// (
|
||||
if (pcfg.colors.boldColor == null) then
|
||||
{
|
||||
bold-color-same-as-fg = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bold-color-same-as-fg = false;
|
||||
bold-color = pcfg.colors.boldColor;
|
||||
}
|
||||
)
|
||||
// lib.optionalAttrs (pcfg.boldIsBright != null) {
|
||||
bold-is-bright = pcfg.boldIsBright;
|
||||
}
|
||||
// (
|
||||
if (pcfg.colors.cursor != null) then
|
||||
{
|
||||
cursor-colors-set = true;
|
||||
cursor-foreground-color = pcfg.colors.cursor.foreground;
|
||||
cursor-background-color = pcfg.colors.cursor.background;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor-colors-set = false;
|
||||
}
|
||||
)
|
||||
// (
|
||||
if (pcfg.colors.highlight != null) then
|
||||
{
|
||||
highlight-colors-set = true;
|
||||
highlight-foreground-color = pcfg.colors.highlight.foreground;
|
||||
highlight-background-color = pcfg.colors.highlight.background;
|
||||
}
|
||||
else
|
||||
{
|
||||
highlight-colors-set = false;
|
||||
}
|
||||
)
|
||||
// lib.optionalAttrs (pcfg.transparencyPercent != null) {
|
||||
background-transparency-percent = pcfg.transparencyPercent;
|
||||
use-theme-transparency = false;
|
||||
use-transparent-background = true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ kamadorueda rycee ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
kamadorueda
|
||||
rycee
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.gnome-terminal = {
|
||||
|
|
@ -283,7 +350,12 @@ in {
|
|||
|
||||
themeVariant = mkOption {
|
||||
default = "default";
|
||||
type = types.enum [ "default" "light" "dark" "system" ];
|
||||
type = types.enum [
|
||||
"default"
|
||||
"light"
|
||||
"dark"
|
||||
"system"
|
||||
];
|
||||
description = "The theme variation to request";
|
||||
};
|
||||
|
||||
|
|
@ -301,37 +373,41 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(let
|
||||
uuidre =
|
||||
"[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}";
|
||||
erroneous = lib.filter (n: builtins.match uuidre n == null)
|
||||
(lib.attrNames cfg.profile);
|
||||
in {
|
||||
assertion = erroneous == [ ];
|
||||
message = ''
|
||||
The attribute name of a Gnome Terminal profile must be a UUID.
|
||||
Incorrect profile names: ${lib.concatStringsSep ", " erroneous}'';
|
||||
})
|
||||
(
|
||||
let
|
||||
uuidre = "[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}";
|
||||
erroneous = lib.filter (n: builtins.match uuidre n == null) (lib.attrNames cfg.profile);
|
||||
in
|
||||
{
|
||||
assertion = erroneous == [ ];
|
||||
message = ''
|
||||
The attribute name of a Gnome Terminal profile must be a UUID.
|
||||
Incorrect profile names: ${lib.concatStringsSep ", " erroneous}'';
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
home.packages = [ pkgs.gnome-terminal ];
|
||||
|
||||
dconf.settings = let dconfPath = "org/gnome/terminal/legacy";
|
||||
in {
|
||||
"${dconfPath}" = {
|
||||
default-show-menubar = cfg.showMenubar;
|
||||
theme-variant = cfg.themeVariant;
|
||||
schema-version = 3;
|
||||
};
|
||||
dconf.settings =
|
||||
let
|
||||
dconfPath = "org/gnome/terminal/legacy";
|
||||
in
|
||||
{
|
||||
"${dconfPath}" = {
|
||||
default-show-menubar = cfg.showMenubar;
|
||||
theme-variant = cfg.themeVariant;
|
||||
schema-version = 3;
|
||||
};
|
||||
|
||||
"${dconfPath}/profiles:" = {
|
||||
default = lib.head
|
||||
(lib.attrNames (lib.filterAttrs (n: v: v.default) cfg.profile));
|
||||
list = lib.attrNames cfg.profile;
|
||||
};
|
||||
} // lib.mapAttrs'
|
||||
(n: v: lib.nameValuePair "${dconfPath}/profiles:/:${n}" (buildProfileSet v))
|
||||
cfg.profile;
|
||||
"${dconfPath}/profiles:" = {
|
||||
default = lib.head (lib.attrNames (lib.filterAttrs (n: v: v.default) cfg.profile));
|
||||
list = lib.attrNames cfg.profile;
|
||||
};
|
||||
}
|
||||
// lib.mapAttrs' (
|
||||
n: v: lib.nameValuePair "${dconfPath}/profiles:/:${n}" (buildProfileSet v)
|
||||
) cfg.profile;
|
||||
|
||||
programs.bash.enableVteIntegration = true;
|
||||
programs.zsh.enableVteIntegration = true;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.go;
|
||||
|
||||
modeFileContent = "${cfg.telemetry.mode} ${cfg.telemetry.date}";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rvolosatovs ];
|
||||
|
||||
options = {
|
||||
|
|
@ -41,7 +52,10 @@ in {
|
|||
extraGoPaths = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "extraGoPath1" "extraGoPath2" ];
|
||||
example = [
|
||||
"extraGoPath1"
|
||||
"extraGoPath2"
|
||||
];
|
||||
description = ''
|
||||
Extra {env}`GOPATH`s relative to {env}`HOME` appended
|
||||
after [](#opt-programs.go.goPath), if that option is set.
|
||||
|
|
@ -58,7 +72,10 @@ in {
|
|||
goPrivate = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
example = [ "*.corp.example.com" "rsc.io/private" ];
|
||||
example = [
|
||||
"*.corp.example.com"
|
||||
"rsc.io/private"
|
||||
];
|
||||
description = ''
|
||||
The {env}`GOPRIVATE` environment variable controls
|
||||
which modules the go command considers to be private (not
|
||||
|
|
@ -71,7 +88,13 @@ in {
|
|||
type = types.submodule {
|
||||
options = {
|
||||
mode = mkOption {
|
||||
type = with types; nullOr (enum [ "off" "local" "on" ]);
|
||||
type =
|
||||
with types;
|
||||
nullOr (enum [
|
||||
"off"
|
||||
"local"
|
||||
"on"
|
||||
]);
|
||||
default = null;
|
||||
description = "Go telemetry mode to be set.";
|
||||
};
|
||||
|
|
@ -94,41 +117,46 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
config = mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.file = let
|
||||
goPath = if cfg.goPath != null then cfg.goPath else "go";
|
||||
mkSrc = n: v: { "${goPath}/src/${n}".source = v; };
|
||||
in lib.foldl' (a: b: a // b) { } (lib.mapAttrsToList mkSrc cfg.packages);
|
||||
}
|
||||
home.file =
|
||||
let
|
||||
goPath = if cfg.goPath != null then cfg.goPath else "go";
|
||||
mkSrc = n: v: { "${goPath}/src/${n}".source = v; };
|
||||
in
|
||||
lib.foldl' (a: b: a // b) { } (lib.mapAttrsToList mkSrc cfg.packages);
|
||||
}
|
||||
|
||||
(mkIf (cfg.goPath != null) {
|
||||
home.sessionVariables.GOPATH = lib.concatStringsSep ":"
|
||||
(map builtins.toPath (map (path: "${config.home.homeDirectory}/${path}")
|
||||
([ cfg.goPath ] ++ cfg.extraGoPaths)));
|
||||
})
|
||||
(mkIf (cfg.goPath != null) {
|
||||
home.sessionVariables.GOPATH = lib.concatStringsSep ":" (
|
||||
map builtins.toPath (
|
||||
map (path: "${config.home.homeDirectory}/${path}") ([ cfg.goPath ] ++ cfg.extraGoPaths)
|
||||
)
|
||||
);
|
||||
})
|
||||
|
||||
(mkIf (cfg.goBin != null) {
|
||||
home.sessionVariables.GOBIN =
|
||||
builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
|
||||
})
|
||||
(mkIf (cfg.goBin != null) {
|
||||
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
|
||||
})
|
||||
|
||||
(mkIf (cfg.goPrivate != [ ]) {
|
||||
home.sessionVariables.GOPRIVATE = lib.concatStringsSep "," cfg.goPrivate;
|
||||
})
|
||||
(mkIf (cfg.goPrivate != [ ]) {
|
||||
home.sessionVariables.GOPRIVATE = lib.concatStringsSep "," cfg.goPrivate;
|
||||
})
|
||||
|
||||
(mkIf (cfg.telemetry.mode != null) {
|
||||
home.file."Library/Application Support/go/telemetry/mode" = {
|
||||
enable = pkgs.stdenv.hostPlatform.isDarwin;
|
||||
text = modeFileContent;
|
||||
};
|
||||
(mkIf (cfg.telemetry.mode != null) {
|
||||
home.file."Library/Application Support/go/telemetry/mode" = {
|
||||
enable = pkgs.stdenv.hostPlatform.isDarwin;
|
||||
text = modeFileContent;
|
||||
};
|
||||
|
||||
xdg.configFile."go/telemetry/mode" = {
|
||||
enable = !pkgs.stdenv.hostPlatform.isDarwin;
|
||||
text = modeFileContent;
|
||||
};
|
||||
})
|
||||
]);
|
||||
xdg.configFile."go/telemetry/mode" = {
|
||||
enable = !pkgs.stdenv.hostPlatform.isDarwin;
|
||||
text = modeFileContent;
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkDefault mkIf mkOption optional types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkDefault
|
||||
mkIf
|
||||
mkOption
|
||||
optional
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.gpg;
|
||||
|
||||
mkKeyValue = key: value:
|
||||
if lib.isString value then
|
||||
"${key} ${value}"
|
||||
else
|
||||
lib.optionalString value key;
|
||||
mkKeyValue =
|
||||
key: value: if lib.isString value then "${key} ${value}" else lib.optionalString value key;
|
||||
|
||||
cfgText = lib.generators.toKeyValue {
|
||||
inherit mkKeyValue;
|
||||
|
|
@ -20,126 +29,141 @@ let
|
|||
listsAsDuplicateKeys = true;
|
||||
} cfg.scdaemonSettings;
|
||||
|
||||
primitiveType = types.oneOf [ types.str types.bool ];
|
||||
primitiveType = types.oneOf [
|
||||
types.str
|
||||
types.bool
|
||||
];
|
||||
|
||||
publicKeyOpts = { config, ... }: {
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Text of an OpenPGP public key.
|
||||
'';
|
||||
publicKeyOpts =
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Text of an OpenPGP public key.
|
||||
'';
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of an OpenPGP public key file.
|
||||
'';
|
||||
};
|
||||
|
||||
trust = mkOption {
|
||||
type = types.nullOr (
|
||||
types.enum [
|
||||
"unknown"
|
||||
1
|
||||
"never"
|
||||
2
|
||||
"marginal"
|
||||
3
|
||||
"full"
|
||||
4
|
||||
"ultimate"
|
||||
5
|
||||
]
|
||||
);
|
||||
default = null;
|
||||
apply =
|
||||
v:
|
||||
if lib.isString v then
|
||||
{
|
||||
unknown = 1;
|
||||
never = 2;
|
||||
marginal = 3;
|
||||
full = 4;
|
||||
ultimate = 5;
|
||||
}
|
||||
.${v}
|
||||
else
|
||||
v;
|
||||
description = ''
|
||||
The amount of trust you have in the key ownership and the care the
|
||||
owner puts into signing other keys. The available levels are
|
||||
|
||||
`unknown` or `1`
|
||||
: I don't know or won't say.
|
||||
|
||||
`never` or `2`
|
||||
: I do **not** trust.
|
||||
|
||||
`marginal` or `3`
|
||||
: I trust marginally.
|
||||
|
||||
`full` or `4`
|
||||
: I trust fully.
|
||||
|
||||
`ultimate` or `5`
|
||||
: I trust ultimately.
|
||||
|
||||
See the [Key Management chapter](https://www.gnupg.org/gph/en/manual/x334.html)
|
||||
of the GNU Privacy Handbook for more.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of an OpenPGP public key file.
|
||||
'';
|
||||
};
|
||||
|
||||
trust = mkOption {
|
||||
type = types.nullOr (types.enum [
|
||||
"unknown"
|
||||
1
|
||||
"never"
|
||||
2
|
||||
"marginal"
|
||||
3
|
||||
"full"
|
||||
4
|
||||
"ultimate"
|
||||
5
|
||||
]);
|
||||
default = null;
|
||||
apply = v:
|
||||
if lib.isString v then
|
||||
{
|
||||
unknown = 1;
|
||||
never = 2;
|
||||
marginal = 3;
|
||||
full = 4;
|
||||
ultimate = 5;
|
||||
}.${v}
|
||||
else
|
||||
v;
|
||||
description = ''
|
||||
The amount of trust you have in the key ownership and the care the
|
||||
owner puts into signing other keys. The available levels are
|
||||
|
||||
`unknown` or `1`
|
||||
: I don't know or won't say.
|
||||
|
||||
`never` or `2`
|
||||
: I do **not** trust.
|
||||
|
||||
`marginal` or `3`
|
||||
: I trust marginally.
|
||||
|
||||
`full` or `4`
|
||||
: I trust fully.
|
||||
|
||||
`ultimate` or `5`
|
||||
: I trust ultimately.
|
||||
|
||||
See the [Key Management chapter](https://www.gnupg.org/gph/en/manual/x334.html)
|
||||
of the GNU Privacy Handbook for more.
|
||||
'';
|
||||
config = {
|
||||
source = mkIf (config.text != null) (pkgs.writeText "gpg-pubkey" config.text);
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
source =
|
||||
mkIf (config.text != null) (pkgs.writeText "gpg-pubkey" config.text);
|
||||
};
|
||||
};
|
||||
importTrustBashFunctions =
|
||||
let
|
||||
gpg = "${cfg.package}/bin/gpg";
|
||||
in
|
||||
''
|
||||
function gpgKeyId() {
|
||||
${gpg} --show-key --with-colons "$1" \
|
||||
| grep ^pub: \
|
||||
| cut -d: -f5
|
||||
}
|
||||
|
||||
importTrustBashFunctions = let gpg = "${cfg.package}/bin/gpg";
|
||||
in ''
|
||||
function gpgKeyId() {
|
||||
${gpg} --show-key --with-colons "$1" \
|
||||
| grep ^pub: \
|
||||
| cut -d: -f5
|
||||
}
|
||||
function importTrust() {
|
||||
local keyIds trust
|
||||
IFS='\n' read -ra keyIds <<< "$(gpgKeyId "$1")"
|
||||
trust="$2"
|
||||
for id in "''${keyIds[@]}" ; do
|
||||
{ echo trust; echo "$trust"; (( trust == 5 )) && echo y; echo quit; } \
|
||||
| ${gpg} --no-tty --command-fd 0 --edit-key "$id"
|
||||
done
|
||||
}
|
||||
|
||||
function importTrust() {
|
||||
local keyIds trust
|
||||
IFS='\n' read -ra keyIds <<< "$(gpgKeyId "$1")"
|
||||
trust="$2"
|
||||
for id in "''${keyIds[@]}" ; do
|
||||
{ echo trust; echo "$trust"; (( trust == 5 )) && echo y; echo quit; } \
|
||||
| ${gpg} --no-tty --command-fd 0 --edit-key "$id"
|
||||
done
|
||||
}
|
||||
|
||||
'';
|
||||
|
||||
keyringFiles = let
|
||||
gpg = "${cfg.package}/bin/gpg";
|
||||
|
||||
importKey = { source, trust, ... }: ''
|
||||
${gpg} --import ${source}
|
||||
${lib.optionalString (trust != null)
|
||||
''importTrust "${source}" ${toString trust}''}
|
||||
'';
|
||||
|
||||
importKeys = lib.concatMapStringsSep "\n" importKey cfg.publicKeys;
|
||||
in pkgs.runCommand "gpg-pubring" { buildInputs = [ cfg.package ]; } ''
|
||||
export GNUPGHOME
|
||||
GNUPGHOME=$(mktemp -d)
|
||||
keyringFiles =
|
||||
let
|
||||
gpg = "${cfg.package}/bin/gpg";
|
||||
|
||||
${importTrustBashFunctions}
|
||||
${importKeys}
|
||||
importKey =
|
||||
{ source, trust, ... }:
|
||||
''
|
||||
${gpg} --import ${source}
|
||||
${lib.optionalString (trust != null) ''importTrust "${source}" ${toString trust}''}
|
||||
'';
|
||||
|
||||
mkdir $out
|
||||
cp $GNUPGHOME/pubring.kbx $out/pubring.kbx
|
||||
if [[ -e $GNUPGHOME/trustdb.gpg ]] ; then
|
||||
cp $GNUPGHOME/trustdb.gpg $out/trustdb.gpg
|
||||
fi
|
||||
'';
|
||||
importKeys = lib.concatMapStringsSep "\n" importKey cfg.publicKeys;
|
||||
in
|
||||
pkgs.runCommand "gpg-pubring" { buildInputs = [ cfg.package ]; } ''
|
||||
export GNUPGHOME
|
||||
GNUPGHOME=$(mktemp -d)
|
||||
|
||||
in {
|
||||
${importTrustBashFunctions}
|
||||
${importKeys}
|
||||
|
||||
mkdir $out
|
||||
cp $GNUPGHOME/pubring.kbx $out/pubring.kbx
|
||||
if [[ -e $GNUPGHOME/trustdb.gpg ]] ; then
|
||||
cp $GNUPGHOME/trustdb.gpg $out/trustdb.gpg
|
||||
fi
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
options.programs.gpg = {
|
||||
enable = lib.mkEnableOption "GnuPG";
|
||||
|
||||
|
|
@ -149,8 +173,7 @@ in {
|
|||
};
|
||||
|
||||
settings = mkOption {
|
||||
type =
|
||||
types.attrsOf (types.either primitiveType (types.listOf types.str));
|
||||
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
|
||||
example = literalExpression ''
|
||||
{
|
||||
no-comments = false;
|
||||
|
|
@ -169,8 +192,7 @@ in {
|
|||
};
|
||||
|
||||
scdaemonSettings = mkOption {
|
||||
type =
|
||||
types.attrsOf (types.either primitiveType (types.listOf types.str));
|
||||
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
|
||||
example = literalExpression ''
|
||||
{
|
||||
disable-ccid = true;
|
||||
|
|
@ -189,8 +211,7 @@ in {
|
|||
type = types.path;
|
||||
example = literalExpression ''"''${config.xdg.dataHome}/gnupg"'';
|
||||
default = "${config.home.homeDirectory}/.gnupg";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/.gnupg"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/.gnupg"'';
|
||||
description = "Directory to store keychains and configuration.";
|
||||
};
|
||||
|
||||
|
|
@ -242,8 +263,7 @@ in {
|
|||
personal-cipher-preferences = mkDefault "AES256 AES192 AES";
|
||||
personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256";
|
||||
personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed";
|
||||
default-preference-list = mkDefault
|
||||
"SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
|
||||
default-preference-list = mkDefault "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
|
||||
cert-digest-algo = mkDefault "SHA512";
|
||||
s2k-digest-algo = mkDefault "SHA512";
|
||||
s2k-cipher-algo = mkDefault "AES256";
|
||||
|
|
@ -265,56 +285,60 @@ in {
|
|||
};
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
home.sessionVariables = { GNUPGHOME = cfg.homedir; };
|
||||
home.sessionVariables = {
|
||||
GNUPGHOME = cfg.homedir;
|
||||
};
|
||||
|
||||
home.file."${cfg.homedir}/gpg.conf".text = cfgText;
|
||||
|
||||
home.file."${cfg.homedir}/scdaemon.conf".text = scdaemonCfgText;
|
||||
|
||||
# Link keyring if keys are not mutable
|
||||
home.file."${cfg.homedir}/pubring.kbx" =
|
||||
mkIf (!cfg.mutableKeys && cfg.publicKeys != [ ]) {
|
||||
source = "${keyringFiles}/pubring.kbx";
|
||||
};
|
||||
home.file."${cfg.homedir}/pubring.kbx" = mkIf (!cfg.mutableKeys && cfg.publicKeys != [ ]) {
|
||||
source = "${keyringFiles}/pubring.kbx";
|
||||
};
|
||||
|
||||
home.activation = {
|
||||
createGpgHomedir =
|
||||
lib.hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
run mkdir -m700 -p $VERBOSE_ARG ${lib.escapeShellArg cfg.homedir}
|
||||
'';
|
||||
createGpgHomedir = lib.hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||
run mkdir -m700 -p $VERBOSE_ARG ${lib.escapeShellArg cfg.homedir}
|
||||
'';
|
||||
|
||||
importGpgKeys = let
|
||||
gpg = "${cfg.package}/bin/gpg";
|
||||
importGpgKeys =
|
||||
let
|
||||
gpg = "${cfg.package}/bin/gpg";
|
||||
|
||||
importKey = { source, trust, ... }:
|
||||
# Import mutable keys
|
||||
optional cfg.mutableKeys "run ${gpg} $QUIET_ARG --import ${source}"
|
||||
importKey =
|
||||
{ source, trust, ... }:
|
||||
# Import mutable keys
|
||||
optional cfg.mutableKeys "run ${gpg} $QUIET_ARG --import ${source}"
|
||||
|
||||
# Import mutable trust
|
||||
++ optional (trust != null && cfg.mutableTrust)
|
||||
''run importTrust "${source}" ${toString trust}'';
|
||||
# Import mutable trust
|
||||
++ optional (trust != null && cfg.mutableTrust) ''run importTrust "${source}" ${toString trust}'';
|
||||
|
||||
anyTrust = lib.any (k: k.trust != null) cfg.publicKeys;
|
||||
anyTrust = lib.any (k: k.trust != null) cfg.publicKeys;
|
||||
|
||||
importKeys =
|
||||
lib.concatStringsSep "\n" (lib.concatMap importKey cfg.publicKeys);
|
||||
importKeys = lib.concatStringsSep "\n" (lib.concatMap importKey cfg.publicKeys);
|
||||
|
||||
# If any key/trust should be imported then create the block. Otherwise
|
||||
# leave it empty.
|
||||
block = lib.concatStringsSep "\n" (optional (importKeys != "") ''
|
||||
export GNUPGHOME=${lib.escapeShellArg cfg.homedir}
|
||||
if [[ ! -v VERBOSE ]]; then
|
||||
QUIET_ARG="--quiet"
|
||||
else
|
||||
QUIET_ARG=""
|
||||
fi
|
||||
${importTrustBashFunctions}
|
||||
${importKeys}
|
||||
unset GNUPGHOME QUIET_ARG keyId importTrust
|
||||
'' ++ optional (!cfg.mutableTrust && anyTrust) ''
|
||||
install -m 0700 ${keyringFiles}/trustdb.gpg "${cfg.homedir}/trustdb.gpg"'');
|
||||
in mkIf (cfg.publicKeys != [ ])
|
||||
(lib.hm.dag.entryAfter [ "linkGeneration" ] block);
|
||||
# If any key/trust should be imported then create the block. Otherwise
|
||||
# leave it empty.
|
||||
block = lib.concatStringsSep "\n" (
|
||||
optional (importKeys != "") ''
|
||||
export GNUPGHOME=${lib.escapeShellArg cfg.homedir}
|
||||
if [[ ! -v VERBOSE ]]; then
|
||||
QUIET_ARG="--quiet"
|
||||
else
|
||||
QUIET_ARG=""
|
||||
fi
|
||||
${importTrustBashFunctions}
|
||||
${importKeys}
|
||||
unset GNUPGHOME QUIET_ARG keyId importTrust
|
||||
''
|
||||
++ optional (
|
||||
!cfg.mutableTrust && anyTrust
|
||||
) ''install -m 0700 ${keyringFiles}/trustdb.gpg "${cfg.homedir}/trustdb.gpg"''
|
||||
);
|
||||
in
|
||||
mkIf (cfg.publicKeys != [ ]) (lib.hm.dag.entryAfter [ "linkGeneration" ] block);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption types;
|
||||
|
||||
|
|
@ -6,34 +11,41 @@ let
|
|||
defaultHomeDirectory = ".gradle";
|
||||
settingsFormat = pkgs.formats.javaProperties { };
|
||||
|
||||
initScript = types.submodule ({ name, config, ... }: {
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Text of the init script file. if this option is null
|
||||
then `source` must be set.
|
||||
'';
|
||||
initScript = types.submodule (
|
||||
{ name, config, ... }:
|
||||
{
|
||||
options = {
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Text of the init script file. if this option is null
|
||||
then `source` must be set.
|
||||
'';
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of the init script file. If
|
||||
`text` is non-null then this option will automatically point
|
||||
to a file containing that text.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of the init script file. If
|
||||
`text` is non-null then this option will automatically point
|
||||
to a file containing that text.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config.source = mkIf (config.text != null) (lib.mkDefault
|
||||
(pkgs.writeTextFile {
|
||||
inherit (config) text;
|
||||
name = lib.hm.strings.storeFileName name;
|
||||
}));
|
||||
});
|
||||
in {
|
||||
config.source = mkIf (config.text != null) (
|
||||
lib.mkDefault (
|
||||
pkgs.writeTextFile {
|
||||
inherit (config) text;
|
||||
name = lib.hm.strings.storeFileName name;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.britter ];
|
||||
|
||||
options.programs.gradle = {
|
||||
|
|
@ -96,19 +108,26 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let gradleHome = "${config.home.homeDirectory}/${cfg.home}";
|
||||
in mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
config =
|
||||
let
|
||||
gradleHome = "${config.home.homeDirectory}/${cfg.home}";
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file = lib.mkMerge ([{
|
||||
"${cfg.home}/gradle.properties" = mkIf (cfg.settings != { }) {
|
||||
source = settingsFormat.generate "gradle.properties" cfg.settings;
|
||||
home.file = lib.mkMerge (
|
||||
[
|
||||
{
|
||||
"${cfg.home}/gradle.properties" = mkIf (cfg.settings != { }) {
|
||||
source = settingsFormat.generate "gradle.properties" cfg.settings;
|
||||
};
|
||||
}
|
||||
]
|
||||
++ lib.mapAttrsToList (k: v: { "${cfg.home}/init.d/${k}".source = v.source; }) cfg.initScripts
|
||||
);
|
||||
|
||||
home.sessionVariables = mkIf (cfg.home != defaultHomeDirectory) {
|
||||
GRADLE_USER_HOME = gradleHome;
|
||||
};
|
||||
}] ++ lib.mapAttrsToList
|
||||
(k: v: { "${cfg.home}/init.d/${k}".source = v.source; }) cfg.initScripts);
|
||||
|
||||
home.sessionVariables = mkIf (cfg.home != defaultHomeDirectory) {
|
||||
GRADLE_USER_HOME = gradleHome;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.granted;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.granted;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.wcarlsen ];
|
||||
|
||||
options.programs.granted = {
|
||||
|
|
@ -8,11 +15,9 @@ in {
|
|||
|
||||
package = lib.mkPackageOption pkgs "granted" { };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration =
|
||||
lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.havoc;
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ AndersonTorres ];
|
||||
|
||||
options.programs.havoc = {
|
||||
|
|
@ -47,8 +53,7 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.havoc" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.havoc" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
|
|
|||
|
|
@ -1,10 +1,21 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.helix;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.Philipp-M ];
|
||||
|
||||
options.programs.helix = {
|
||||
|
|
@ -70,8 +81,10 @@ in {
|
|||
};
|
||||
|
||||
languages = mkOption {
|
||||
type = with types;
|
||||
coercedTo (listOf tomlFormat.type) (language:
|
||||
type =
|
||||
with types;
|
||||
coercedTo (listOf tomlFormat.type) (
|
||||
language:
|
||||
lib.warn ''
|
||||
The syntax of programs.helix.languages has changed.
|
||||
It now generates the whole languages.toml file instead of just the language array in that file.
|
||||
|
|
@ -79,7 +92,8 @@ in {
|
|||
Use
|
||||
programs.helix.languages = { language = <languages list>; }
|
||||
instead.
|
||||
'' { inherit language; }) (addCheck tomlFormat.type builtins.isAttrs);
|
||||
'' { inherit language; }
|
||||
) (addCheck tomlFormat.type builtins.isAttrs);
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
|
|
@ -106,7 +120,10 @@ in {
|
|||
ignores = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ ".build/" "!.gitignore" ];
|
||||
example = [
|
||||
".build/"
|
||||
"!.gitignore"
|
||||
];
|
||||
description = ''
|
||||
List of paths that should be globally ignored for file picker.
|
||||
Supports the usual ignore and negative ignore (unignore) rules used in `.gitignore` files.
|
||||
|
|
@ -185,48 +202,53 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = if cfg.extraPackages != [ ] then
|
||||
[
|
||||
(pkgs.symlinkJoin {
|
||||
name =
|
||||
"${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}";
|
||||
paths = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/hx \
|
||||
--suffix PATH : ${lib.makeBinPath cfg.extraPackages}
|
||||
'';
|
||||
})
|
||||
]
|
||||
else
|
||||
[ cfg.package ];
|
||||
home.packages =
|
||||
if cfg.extraPackages != [ ] then
|
||||
[
|
||||
(pkgs.symlinkJoin {
|
||||
name = "${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}";
|
||||
paths = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/hx \
|
||||
--suffix PATH : ${lib.makeBinPath cfg.extraPackages}
|
||||
'';
|
||||
})
|
||||
]
|
||||
else
|
||||
[ cfg.package ];
|
||||
|
||||
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "hx"; };
|
||||
|
||||
xdg.configFile = let
|
||||
settings = {
|
||||
"helix/config.toml" = mkIf (cfg.settings != { }) {
|
||||
source = let
|
||||
configFile = tomlFormat.generate "config.toml" cfg.settings;
|
||||
extraConfigFile =
|
||||
pkgs.writeText "extra-config.toml" ("\n" + cfg.extraConfig);
|
||||
in pkgs.runCommand "helix-config.toml" { } ''
|
||||
cat ${configFile} ${extraConfigFile} >> $out
|
||||
'';
|
||||
xdg.configFile =
|
||||
let
|
||||
settings = {
|
||||
"helix/config.toml" = mkIf (cfg.settings != { }) {
|
||||
source =
|
||||
let
|
||||
configFile = tomlFormat.generate "config.toml" cfg.settings;
|
||||
extraConfigFile = pkgs.writeText "extra-config.toml" ("\n" + cfg.extraConfig);
|
||||
in
|
||||
pkgs.runCommand "helix-config.toml" { } ''
|
||||
cat ${configFile} ${extraConfigFile} >> $out
|
||||
'';
|
||||
};
|
||||
"helix/languages.toml" = mkIf (cfg.languages != { }) {
|
||||
source = tomlFormat.generate "helix-languages-config" cfg.languages;
|
||||
};
|
||||
"helix/ignore" = mkIf (cfg.ignores != [ ]) {
|
||||
text = lib.concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
};
|
||||
"helix/languages.toml" = mkIf (cfg.languages != { }) {
|
||||
source = tomlFormat.generate "helix-languages-config" cfg.languages;
|
||||
};
|
||||
"helix/ignore" = mkIf (cfg.ignores != [ ]) {
|
||||
text = lib.concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
};
|
||||
|
||||
themes = lib.mapAttrs' (n: v:
|
||||
lib.nameValuePair "helix/themes/${n}.toml" {
|
||||
source = tomlFormat.generate "helix-theme-${n}" v;
|
||||
}) cfg.themes;
|
||||
in settings // themes;
|
||||
themes = lib.mapAttrs' (
|
||||
n: v:
|
||||
lib.nameValuePair "helix/themes/${n}.toml" {
|
||||
source = tomlFormat.generate "helix-theme-${n}" v;
|
||||
}
|
||||
) cfg.themes;
|
||||
in
|
||||
settings // themes;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkIf mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.hexchat;
|
||||
|
||||
|
|
@ -44,13 +54,18 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
modChannelOption = with types;
|
||||
modChannelOption =
|
||||
with types;
|
||||
submodule {
|
||||
options = {
|
||||
autojoin = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "#home-manager" "#linux" "#nix" ];
|
||||
example = [
|
||||
"#home-manager"
|
||||
"#linux"
|
||||
"#nix"
|
||||
];
|
||||
description = "Channels list to autojoin on connecting to server.";
|
||||
};
|
||||
|
||||
|
|
@ -163,16 +178,14 @@ let
|
|||
|
||||
transformField = k: v: if (v != null) then "${k}=${v}" else null;
|
||||
|
||||
listChar = c: l:
|
||||
if l != [ ] then
|
||||
lib.concatMapStringsSep "\n" (transformField c) l
|
||||
else
|
||||
null;
|
||||
listChar = c: l: if l != [ ] then lib.concatMapStringsSep "\n" (transformField c) l else null;
|
||||
|
||||
computeFieldsValue = channel:
|
||||
computeFieldsValue =
|
||||
channel:
|
||||
let
|
||||
ifTrue = p: n: if p then n else 0;
|
||||
result = with channel.options;
|
||||
result =
|
||||
with channel.options;
|
||||
lib.foldl' (a: b: a + b) 0 [
|
||||
(ifTrue (!connectToSelectedServerOnly) 1)
|
||||
(ifTrue useGlobalUserInformation 2)
|
||||
|
|
@ -181,7 +194,8 @@ let
|
|||
(ifTrue (!bypassProxy) 16)
|
||||
(ifTrue acceptInvalidSSLCertificates 32)
|
||||
];
|
||||
in toString (if channel.options == null then 0 else result);
|
||||
in
|
||||
toString (if channel.options == null then 0 else result);
|
||||
|
||||
loginMethodMap = {
|
||||
nickServMsg = 1;
|
||||
|
|
@ -193,30 +207,38 @@ let
|
|||
saslExternal = 10;
|
||||
};
|
||||
|
||||
loginMethod = channel:
|
||||
transformField "L" (lib.optionalString (channel.loginMethod != null)
|
||||
(toString loginMethodMap.${channel.loginMethod}));
|
||||
loginMethod =
|
||||
channel:
|
||||
transformField "L" (
|
||||
lib.optionalString (channel.loginMethod != null) (toString loginMethodMap.${channel.loginMethod})
|
||||
);
|
||||
|
||||
# Note: Missing option `D=`.
|
||||
transformChannel = channelName:
|
||||
let channel = cfg.channels.${channelName};
|
||||
in lib.concatStringsSep "\n" (lib.remove null [
|
||||
"" # Leave a space between one server and another
|
||||
(transformField "N" channelName)
|
||||
(loginMethod channel)
|
||||
(transformField "E" channel.charset)
|
||||
(transformField "F" (computeFieldsValue channel))
|
||||
(transformField "I" channel.nickname)
|
||||
(transformField "i" channel.nickname2)
|
||||
(transformField "R" channel.realName)
|
||||
(transformField "U" channel.userName)
|
||||
(transformField "P" channel.password)
|
||||
(listChar "S" channel.servers)
|
||||
(listChar "J" channel.autojoin)
|
||||
(listChar "C" channel.commands)
|
||||
]);
|
||||
transformChannel =
|
||||
channelName:
|
||||
let
|
||||
channel = cfg.channels.${channelName};
|
||||
in
|
||||
lib.concatStringsSep "\n" (
|
||||
lib.remove null [
|
||||
"" # Leave a space between one server and another
|
||||
(transformField "N" channelName)
|
||||
(loginMethod channel)
|
||||
(transformField "E" channel.charset)
|
||||
(transformField "F" (computeFieldsValue channel))
|
||||
(transformField "I" channel.nickname)
|
||||
(transformField "i" channel.nickname2)
|
||||
(transformField "R" channel.realName)
|
||||
(transformField "U" channel.userName)
|
||||
(transformField "P" channel.password)
|
||||
(listChar "S" channel.servers)
|
||||
(listChar "J" channel.autojoin)
|
||||
(listChar "C" channel.commands)
|
||||
]
|
||||
);
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ thiagokokada ];
|
||||
|
||||
options.programs.hexchat = {
|
||||
|
|
@ -320,8 +342,7 @@ in {
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.hexchat" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.hexchat" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
|
@ -333,15 +354,13 @@ in {
|
|||
|
||||
xdg.configFile."hexchat/hexchat.conf" = mkIf (cfg.settings != null) {
|
||||
force = cfg.overwriteConfigFiles;
|
||||
text = lib.concatMapStringsSep "\n" (x: x + " = " + cfg.settings.${x})
|
||||
(lib.attrNames cfg.settings);
|
||||
text = lib.concatMapStringsSep "\n" (x: x + " = " + cfg.settings.${x}) (lib.attrNames cfg.settings);
|
||||
};
|
||||
|
||||
xdg.configFile."hexchat/servlist.conf" = mkIf (cfg.channels != { }) {
|
||||
force = cfg.overwriteConfigFiles;
|
||||
# Final line breaks is required to avoid cropping last field value.
|
||||
text = lib.concatMapStringsSep "\n" transformChannel
|
||||
(lib.attrNames cfg.channels) + "\n\n";
|
||||
text = lib.concatMapStringsSep "\n" transformChannel (lib.attrNames cfg.channels) + "\n\n";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption optionalAttrs types;
|
||||
|
||||
|
|
@ -15,7 +20,8 @@ let
|
|||
|
||||
# make encryption config based on the given home-manager email
|
||||
# account TLS config
|
||||
mkEncryptionConfig = tls:
|
||||
mkEncryptionConfig =
|
||||
tls:
|
||||
if tls.useStartTls then
|
||||
"start-tls"
|
||||
else if tls.enable then
|
||||
|
|
@ -25,12 +31,12 @@ let
|
|||
|
||||
# make a himalaya account config based on the given home-manager
|
||||
# email account config
|
||||
mkAccountConfig = _: account:
|
||||
mkAccountConfig =
|
||||
_: account:
|
||||
let
|
||||
notmuchEnabled = account.notmuch.enable;
|
||||
imapEnabled = !isNull account.imap && !notmuchEnabled;
|
||||
maildirEnabled = !isNull account.maildir && !imapEnabled
|
||||
&& !notmuchEnabled;
|
||||
maildirEnabled = !isNull account.maildir && !imapEnabled && !notmuchEnabled;
|
||||
|
||||
globalConfig = {
|
||||
email = account.address;
|
||||
|
|
@ -44,13 +50,12 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
signatureConfig =
|
||||
optionalAttrs (account.signature.showSignature == "append") {
|
||||
# TODO: signature cannot be attached yet
|
||||
# https://github.com/pimalaya/himalaya/issues/534
|
||||
signature = account.signature.text;
|
||||
signature-delim = account.signature.delimiter;
|
||||
};
|
||||
signatureConfig = optionalAttrs (account.signature.showSignature == "append") {
|
||||
# TODO: signature cannot be attached yet
|
||||
# https://github.com/pimalaya/himalaya/issues/534
|
||||
signature = account.signature.text;
|
||||
signature-delim = account.signature.delimiter;
|
||||
};
|
||||
|
||||
imapConfig = optionalAttrs imapEnabled (compactAttrs {
|
||||
backend.type = "imap";
|
||||
|
|
@ -59,8 +64,7 @@ let
|
|||
backend.encryption.type = mkEncryptionConfig account.imap.tls;
|
||||
backend.login = account.userName;
|
||||
backend.auth.type = "password";
|
||||
backend.auth.cmd =
|
||||
builtins.concatStringsSep " " account.passwordCommand;
|
||||
backend.auth.cmd = builtins.concatStringsSep " " account.passwordCommand;
|
||||
});
|
||||
|
||||
maildirConfig = optionalAttrs maildirEnabled (compactAttrs {
|
||||
|
|
@ -77,19 +81,16 @@ let
|
|||
message.send.backend.type = "smtp";
|
||||
message.send.backend.host = account.smtp.host;
|
||||
message.send.backend.port = account.smtp.port;
|
||||
message.send.backend.encryption.type =
|
||||
mkEncryptionConfig account.smtp.tls;
|
||||
message.send.backend.encryption.type = mkEncryptionConfig account.smtp.tls;
|
||||
message.send.backend.login = account.userName;
|
||||
message.send.backend.auth.type = "password";
|
||||
message.send.backend.auth.cmd =
|
||||
builtins.concatStringsSep " " account.passwordCommand;
|
||||
message.send.backend.auth.cmd = builtins.concatStringsSep " " account.passwordCommand;
|
||||
});
|
||||
|
||||
sendmailConfig =
|
||||
optionalAttrs (isNull account.smtp && !isNull account.msmtp) {
|
||||
message.send.backend.type = "sendmail";
|
||||
message.send.backend.cmd = lib.getExe pkgs.msmtp;
|
||||
};
|
||||
sendmailConfig = optionalAttrs (isNull account.smtp && !isNull account.msmtp) {
|
||||
message.send.backend.type = "sendmail";
|
||||
message.send.backend.cmd = lib.getExe pkgs.msmtp;
|
||||
};
|
||||
|
||||
config = lib.attrsets.mergeAttrsList [
|
||||
globalConfig
|
||||
|
|
@ -101,10 +102,15 @@ let
|
|||
sendmailConfig
|
||||
];
|
||||
|
||||
in lib.recursiveUpdate config account.himalaya.settings;
|
||||
in
|
||||
lib.recursiveUpdate config account.himalaya.settings;
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.hm.maintainers; [ soywod toastal ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [
|
||||
soywod
|
||||
toastal
|
||||
];
|
||||
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "services" "himalaya-watch" "enable" ] ''
|
||||
|
|
@ -133,21 +139,22 @@ in {
|
|||
};
|
||||
|
||||
accounts.email.accounts = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options.himalaya = {
|
||||
enable = lib.mkEnableOption
|
||||
"the email client Himalaya CLI for this email account";
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options.himalaya = {
|
||||
enable = lib.mkEnableOption "the email client Himalaya CLI for this email account";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule { freeformType = tomlFormat.type; };
|
||||
default = { };
|
||||
description = ''
|
||||
Himalaya CLI configuration for this email account.
|
||||
See <https://github.com/pimalaya/himalaya/blob/master/config.sample.toml> for supported values.
|
||||
'';
|
||||
settings = mkOption {
|
||||
type = types.submodule { freeformType = tomlFormat.type; };
|
||||
default = { };
|
||||
description = ''
|
||||
Himalaya CLI configuration for this email account.
|
||||
See <https://github.com/pimalaya/himalaya/blob/master/config.sample.toml> for supported values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -155,26 +162,37 @@ in {
|
|||
home.packages = lib.mkIf (himalaya.package != null) [ himalaya.package ];
|
||||
|
||||
xdg = {
|
||||
configFile."himalaya/config.toml".source = let
|
||||
enabledAccounts = lib.filterAttrs (_: account: account.himalaya.enable)
|
||||
config.accounts.email.accounts;
|
||||
accountsConfig = lib.mapAttrs mkAccountConfig enabledAccounts;
|
||||
globalConfig = compactAttrs himalaya.settings;
|
||||
allConfig = globalConfig // { accounts = accountsConfig; };
|
||||
in tomlFormat.generate "himalaya.config.toml" allConfig;
|
||||
configFile."himalaya/config.toml".source =
|
||||
let
|
||||
enabledAccounts = lib.filterAttrs (
|
||||
_: account: account.himalaya.enable
|
||||
) config.accounts.email.accounts;
|
||||
accountsConfig = lib.mapAttrs mkAccountConfig enabledAccounts;
|
||||
globalConfig = compactAttrs himalaya.settings;
|
||||
allConfig = globalConfig // {
|
||||
accounts = accountsConfig;
|
||||
};
|
||||
in
|
||||
tomlFormat.generate "himalaya.config.toml" allConfig;
|
||||
|
||||
desktopEntries.himalaya = lib.mkIf
|
||||
(pkgs.stdenv.hostPlatform.isLinux && (himalaya.package != null)) {
|
||||
type = "Application";
|
||||
name = "himalaya";
|
||||
genericName = "Email Client";
|
||||
comment = "CLI to manage emails";
|
||||
terminal = true;
|
||||
exec = "himalaya %u";
|
||||
categories = [ "Network" ];
|
||||
mimeType = [ "x-scheme-handler/mailto" "message/rfc822" ];
|
||||
settings = { Keywords = "email"; };
|
||||
};
|
||||
desktopEntries.himalaya =
|
||||
lib.mkIf (pkgs.stdenv.hostPlatform.isLinux && (himalaya.package != null))
|
||||
{
|
||||
type = "Application";
|
||||
name = "himalaya";
|
||||
genericName = "Email Client";
|
||||
comment = "CLI to manage emails";
|
||||
terminal = true;
|
||||
exec = "himalaya %u";
|
||||
categories = [ "Network" ];
|
||||
mimeType = [
|
||||
"x-scheme-handler/mailto"
|
||||
"message/rfc822"
|
||||
];
|
||||
settings = {
|
||||
Keywords = "email";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.home-manager;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.home-manager;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
|
|
@ -22,7 +29,6 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf (cfg.enable && !config.submoduleSupport.enable) {
|
||||
home.packages =
|
||||
[ (pkgs.callPackage ../../home-manager { inherit (cfg) path; }) ];
|
||||
home.packages = [ (pkgs.callPackage ../../home-manager { inherit (cfg) path; }) ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let cfg = config.programs.hstr;
|
||||
in {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.hstr;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.Dines97 ];
|
||||
|
||||
options.programs.hstr = {
|
||||
|
|
@ -10,11 +17,9 @@ in {
|
|||
|
||||
package = lib.mkPackageOption pkgs "hstr" { };
|
||||
|
||||
enableBashIntegration =
|
||||
lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration =
|
||||
lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,20 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
cfg = config.programs.htop;
|
||||
|
||||
formatOption = n: v:
|
||||
let v' = if lib.isBool v then (if v then "1" else "0") else toString v;
|
||||
in "${n}=${v'}";
|
||||
formatOption =
|
||||
n: v:
|
||||
let
|
||||
v' = if lib.isBool v then (if v then "1" else "0") else toString v;
|
||||
in
|
||||
"${n}=${v'}";
|
||||
|
||||
formatMeters = side: meters: {
|
||||
"${side}_meters" = lib.concatMap (lib.mapAttrsToList (x: _: x)) meters;
|
||||
|
|
@ -103,15 +111,25 @@ let
|
|||
led = meter modes.LED;
|
||||
blank = text "Blank";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.bjpbakker ];
|
||||
|
||||
options.programs.htop = {
|
||||
enable = lib.mkEnableOption "htop";
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types;
|
||||
attrsOf (oneOf [ bool int str (listOf (oneOf [ int str ])) ]);
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
(listOf (oneOf [
|
||||
int
|
||||
str
|
||||
]))
|
||||
]);
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
|
|
@ -158,31 +176,41 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
lib.htop = {
|
||||
inherit fields defaultFields modes leftMeters rightMeters bar text graph
|
||||
led blank;
|
||||
inherit
|
||||
fields
|
||||
defaultFields
|
||||
modes
|
||||
leftMeters
|
||||
rightMeters
|
||||
bar
|
||||
text
|
||||
graph
|
||||
led
|
||||
blank
|
||||
;
|
||||
};
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."htop" = let
|
||||
defaults = {
|
||||
fields = if isDarwin then
|
||||
lib.remove fields.M_SHARE defaultFields
|
||||
else
|
||||
defaultFields;
|
||||
xdg.configFile."htop" =
|
||||
let
|
||||
defaults = {
|
||||
fields = if isDarwin then lib.remove fields.M_SHARE defaultFields else defaultFields;
|
||||
};
|
||||
|
||||
before = lib.optionalAttrs (cfg.settings ? header_layout) {
|
||||
inherit (cfg.settings) header_layout;
|
||||
};
|
||||
|
||||
settings = defaults // (removeAttrs cfg.settings (lib.attrNames before));
|
||||
|
||||
formatOptions = lib.mapAttrsToList formatOption;
|
||||
|
||||
in
|
||||
lib.mkIf (cfg.settings != { }) {
|
||||
source = pkgs.writeTextDir "htoprc" (
|
||||
lib.concatStringsSep "\n" (formatOptions before ++ formatOptions settings) + "\n"
|
||||
);
|
||||
};
|
||||
|
||||
before = lib.optionalAttrs (cfg.settings ? header_layout) {
|
||||
inherit (cfg.settings) header_layout;
|
||||
};
|
||||
|
||||
settings = defaults // (removeAttrs cfg.settings (lib.attrNames before));
|
||||
|
||||
formatOptions = lib.mapAttrsToList formatOption;
|
||||
|
||||
in lib.mkIf (cfg.settings != { }) {
|
||||
source = pkgs.writeTextDir "htoprc" (lib.concatStringsSep "\n"
|
||||
(formatOptions before ++ formatOptions settings) + "\n");
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.hyfetch;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.lilyinstarlight ];
|
||||
|
||||
options.programs.hyfetch = {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.hyprlock;
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ khaneliman fufexan ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
khaneliman
|
||||
fufexan
|
||||
];
|
||||
|
||||
options.programs.hyprlock = {
|
||||
enable = lib.mkEnableOption "" // {
|
||||
|
|
@ -28,20 +37,24 @@ in {
|
|||
package = lib.mkPackageOption pkgs "hyprlock" { nullable = true; };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types;
|
||||
type =
|
||||
with lib.types;
|
||||
let
|
||||
valueType = nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
(listOf valueType)
|
||||
]) // {
|
||||
description = "Hyprlock configuration value";
|
||||
};
|
||||
in valueType;
|
||||
valueType =
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
(listOf valueType)
|
||||
])
|
||||
// {
|
||||
description = "Hyprlock configuration value";
|
||||
};
|
||||
in
|
||||
valueType;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
|
|
@ -92,17 +105,28 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
sourceFirst = lib.mkEnableOption ''
|
||||
putting source entries at the top of the configuration
|
||||
'' // {
|
||||
default = true;
|
||||
};
|
||||
sourceFirst =
|
||||
lib.mkEnableOption ''
|
||||
putting source entries at the top of the configuration
|
||||
''
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
importantPrefixes = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ "$" "bezier" "monitor" "size" ]
|
||||
++ lib.optionals cfg.sourceFirst [ "source" ];
|
||||
example = [ "$" "bezier" "monitor" "size" ];
|
||||
default = [
|
||||
"$"
|
||||
"bezier"
|
||||
"monitor"
|
||||
"size"
|
||||
] ++ lib.optionals cfg.sourceFirst [ "source" ];
|
||||
example = [
|
||||
"$"
|
||||
"bezier"
|
||||
"monitor"
|
||||
"size"
|
||||
];
|
||||
description = ''
|
||||
List of prefix of attributes to source at the top of the config.
|
||||
'';
|
||||
|
|
@ -113,13 +137,18 @@ in {
|
|||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."hypr/hyprlock.conf" =
|
||||
let shouldGenerate = cfg.extraConfig != "" || cfg.settings != { };
|
||||
in lib.mkIf shouldGenerate {
|
||||
text = lib.optionalString (cfg.settings != { })
|
||||
(lib.hm.generators.toHyprconf {
|
||||
attrs = cfg.settings;
|
||||
inherit (cfg) importantPrefixes;
|
||||
}) + lib.optionalString (cfg.extraConfig != null) cfg.extraConfig;
|
||||
let
|
||||
shouldGenerate = cfg.extraConfig != "" || cfg.settings != { };
|
||||
in
|
||||
lib.mkIf shouldGenerate {
|
||||
text =
|
||||
lib.optionalString (cfg.settings != { }) (
|
||||
lib.hm.generators.toHyprconf {
|
||||
attrs = cfg.settings;
|
||||
inherit (cfg) importantPrefixes;
|
||||
}
|
||||
)
|
||||
+ lib.optionalString (cfg.extraConfig != null) cfg.extraConfig;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) types;
|
||||
|
||||
|
|
@ -7,15 +12,24 @@ let
|
|||
# Re-make the atom type for the INI files.
|
||||
# For some reason, the normal INI type seems to be incompatible with
|
||||
# DAG
|
||||
configAtomType = let
|
||||
# Keep the INI atom type here
|
||||
optType = with types; (nullOr (oneOf [ int bool str float ]));
|
||||
in types.mkOptionType {
|
||||
name = "INI config atom";
|
||||
description = "INI atom (null, int, bool, string, or float)";
|
||||
check = x: optType.check x;
|
||||
merge = (loc: defs: (optType.merge loc defs));
|
||||
};
|
||||
configAtomType =
|
||||
let
|
||||
# Keep the INI atom type here
|
||||
optType =
|
||||
with types;
|
||||
(nullOr (oneOf [
|
||||
int
|
||||
bool
|
||||
str
|
||||
float
|
||||
]));
|
||||
in
|
||||
types.mkOptionType {
|
||||
name = "INI config atom";
|
||||
description = "INI atom (null, int, bool, string, or float)";
|
||||
check = x: optType.check x;
|
||||
merge = (loc: defs: (optType.merge loc defs));
|
||||
};
|
||||
|
||||
# Create the type of the actual config type
|
||||
configType = types.attrsOf configAtomType;
|
||||
|
|
@ -23,7 +37,8 @@ let
|
|||
# The INI generator
|
||||
mkIni = lib.generators.toINI { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.noodlez1232 ];
|
||||
|
||||
options.programs.i3blocks = {
|
||||
|
|
@ -63,46 +78,46 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
# A function to create the file that will be put into the XDG config home.
|
||||
makeFile = config:
|
||||
let
|
||||
# Takes a singular name value pair and turns it into an attrset
|
||||
nameValuePairToAttr = value: (builtins.listToAttrs [ value ]);
|
||||
# Converts a dag entry to a name-value pair
|
||||
dagEntryToNameValue = entry: (lib.nameValuePair entry.name entry.data);
|
||||
config =
|
||||
let
|
||||
# A function to create the file that will be put into the XDG config home.
|
||||
makeFile =
|
||||
config:
|
||||
let
|
||||
# Takes a singular name value pair and turns it into an attrset
|
||||
nameValuePairToAttr = value: (builtins.listToAttrs [ value ]);
|
||||
# Converts a dag entry to a name-value pair
|
||||
dagEntryToNameValue = entry: (lib.nameValuePair entry.name entry.data);
|
||||
|
||||
# Try to sort the blocks
|
||||
trySortedBlocks = lib.hm.dag.topoSort config;
|
||||
# Try to sort the blocks
|
||||
trySortedBlocks = lib.hm.dag.topoSort config;
|
||||
|
||||
# Get the blocks if successful, abort if not
|
||||
blocks = if trySortedBlocks ? result then
|
||||
trySortedBlocks.result
|
||||
else
|
||||
abort
|
||||
"Dependency cycle in i3blocks: ${builtins.toJSON trySortedBlocks}";
|
||||
# Get the blocks if successful, abort if not
|
||||
blocks =
|
||||
if trySortedBlocks ? result then
|
||||
trySortedBlocks.result
|
||||
else
|
||||
abort "Dependency cycle in i3blocks: ${builtins.toJSON trySortedBlocks}";
|
||||
|
||||
# Turn the blocks back into their name value pairs
|
||||
orderedBlocks =
|
||||
(map (value: (nameValuePairToAttr (dagEntryToNameValue value)))
|
||||
blocks);
|
||||
in {
|
||||
# We create an "INI" file for each bar, then append them all in order
|
||||
text =
|
||||
lib.concatStringsSep "\n" (map (value: (mkIni value)) orderedBlocks);
|
||||
};
|
||||
# Turn the blocks back into their name value pairs
|
||||
orderedBlocks = (map (value: (nameValuePairToAttr (dagEntryToNameValue value))) blocks);
|
||||
in
|
||||
{
|
||||
# We create an "INI" file for each bar, then append them all in order
|
||||
text = lib.concatStringsSep "\n" (map (value: (mkIni value)) orderedBlocks);
|
||||
};
|
||||
|
||||
# Make our config (if enabled
|
||||
in lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.i3blocks" pkgs
|
||||
lib.platforms.linux)
|
||||
];
|
||||
# Make our config (if enabled
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.i3blocks" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile = (lib.mapAttrs'
|
||||
(name: value: lib.nameValuePair "i3blocks/${name}" (makeFile value))
|
||||
cfg.bars);
|
||||
};
|
||||
xdg.configFile = (
|
||||
lib.mapAttrs' (name: value: lib.nameValuePair "i3blocks/${name}" (makeFile value)) cfg.bars
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
||||
|
|
@ -6,124 +11,132 @@ let
|
|||
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ farlion thiagokokada ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
farlion
|
||||
thiagokokada
|
||||
];
|
||||
|
||||
options.programs.i3status-rust = {
|
||||
enable = lib.mkEnableOption "a replacement for i3-status written in Rust";
|
||||
|
||||
bars = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
|
||||
blocks = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = [
|
||||
{ block = "cpu"; }
|
||||
{
|
||||
block = "disk_space";
|
||||
path = "/";
|
||||
info_type = "available";
|
||||
interval = 20;
|
||||
warning = 20.0;
|
||||
alert = 10.0;
|
||||
format = " $icon root: $available.eng(w:2) ";
|
||||
}
|
||||
{
|
||||
block = "memory";
|
||||
format = " $icon $mem_total_used_percents.eng(w:2) ";
|
||||
format_alt = " $icon_swap $swap_used_percents.eng(w:2) ";
|
||||
}
|
||||
{
|
||||
block = "sound";
|
||||
click = [{
|
||||
button = "left";
|
||||
cmd = "pavucontrol";
|
||||
}];
|
||||
}
|
||||
{
|
||||
block = "time";
|
||||
interval = 5;
|
||||
format = " $timestamp.datetime(f:'%a %d/%m %R') ";
|
||||
}
|
||||
];
|
||||
description = ''
|
||||
Configuration blocks to add to i3status-rust
|
||||
{file}`config`. See
|
||||
<https://github.com/greshake/i3status-rust/blob/master/blocks.md>
|
||||
for block options.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
blocks = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = [
|
||||
{ block = "cpu"; }
|
||||
{
|
||||
block = "disk_space";
|
||||
path = "/";
|
||||
info_type = "available";
|
||||
interval = 60;
|
||||
interval = 20;
|
||||
warning = 20.0;
|
||||
alert = 10.0;
|
||||
format = " $icon root: $available.eng(w:2) ";
|
||||
}
|
||||
{
|
||||
block = "memory";
|
||||
format = " $icon $mem_total_used_percents.eng(w:2) ";
|
||||
format_alt = " $icon_swap $swap_used_percents.eng(w:2) ";
|
||||
}
|
||||
{
|
||||
block = "sound";
|
||||
format = " $icon $output_name {$volume.eng(w:2) |}";
|
||||
click = [
|
||||
{
|
||||
button = "left";
|
||||
cmd = "pavucontrol --tab=3";
|
||||
cmd = "pavucontrol";
|
||||
}
|
||||
];
|
||||
mappings = {
|
||||
"alsa_output.pci-0000_00_1f.3.analog-stereo" = "";
|
||||
"bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = "";
|
||||
};
|
||||
}
|
||||
{
|
||||
block = "time";
|
||||
interval = 5;
|
||||
format = " $timestamp.datetime(f:'%a %d/%m %R') ";
|
||||
}
|
||||
];
|
||||
'';
|
||||
};
|
||||
description = ''
|
||||
Configuration blocks to add to i3status-rust
|
||||
{file}`config`. See
|
||||
<https://github.com/greshake/i3status-rust/blob/master/blocks.md>
|
||||
for block options.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
block = "disk_space";
|
||||
path = "/";
|
||||
info_type = "available";
|
||||
interval = 60;
|
||||
warning = 20.0;
|
||||
alert = 10.0;
|
||||
}
|
||||
{
|
||||
block = "sound";
|
||||
format = " $icon $output_name {$volume.eng(w:2) |}";
|
||||
click = [
|
||||
{
|
||||
button = "left";
|
||||
cmd = "pavucontrol --tab=3";
|
||||
}
|
||||
];
|
||||
mappings = {
|
||||
"alsa_output.pci-0000_00_1f.3.analog-stereo" = "";
|
||||
"bluez_sink.70_26_05_DA_27_A4.a2dp_sink" = "";
|
||||
};
|
||||
}
|
||||
];
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = { };
|
||||
description = ''
|
||||
Any extra options to add to i3status-rust
|
||||
{file}`config`.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
theme = {
|
||||
theme = "solarized-dark";
|
||||
overrides = {
|
||||
idle_bg = "#123456";
|
||||
idle_fg = "#abcdef";
|
||||
settings = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = { };
|
||||
description = ''
|
||||
Any extra options to add to i3status-rust
|
||||
{file}`config`.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
theme = {
|
||||
theme = "solarized-dark";
|
||||
overrides = {
|
||||
idle_bg = "#123456";
|
||||
idle_fg = "#abcdef";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
icons = mkOption {
|
||||
type = types.str;
|
||||
default = "none";
|
||||
description = ''
|
||||
The icons set to use. See
|
||||
<https://github.com/greshake/i3status-rust/blob/master/doc/themes.md>
|
||||
for a list of available icon sets.
|
||||
'';
|
||||
example = "awesome6";
|
||||
};
|
||||
icons = mkOption {
|
||||
type = types.str;
|
||||
default = "none";
|
||||
description = ''
|
||||
The icons set to use. See
|
||||
<https://github.com/greshake/i3status-rust/blob/master/doc/themes.md>
|
||||
for a list of available icon sets.
|
||||
'';
|
||||
example = "awesome6";
|
||||
};
|
||||
|
||||
theme = mkOption {
|
||||
type = types.str;
|
||||
default = "plain";
|
||||
description = ''
|
||||
The theme to use. See
|
||||
<https://github.com/greshake/i3status-rust/blob/master/doc/themes.md>
|
||||
for a list of available themes.
|
||||
'';
|
||||
example = "gruvbox-dark";
|
||||
theme = mkOption {
|
||||
type = types.str;
|
||||
default = "plain";
|
||||
description = ''
|
||||
The theme to use. See
|
||||
<https://github.com/greshake/i3status-rust/blob/master/doc/themes.md>
|
||||
for a list of available themes.
|
||||
'';
|
||||
example = "gruvbox-dark";
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
default = {
|
||||
default = {
|
||||
|
|
@ -225,35 +238,44 @@ in {
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "programs.i3status-rust" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "programs.i3status-rust" pkgs lib.platforms.linux)
|
||||
{
|
||||
assertion = lib.versionOlder cfg.package.version "0.31.0"
|
||||
|| lib.versionAtLeast cfg.package.version "0.31.2";
|
||||
message =
|
||||
"Only i3status-rust <0.31.0 or ≥0.31.2 is supported due to a config format incompatibility.";
|
||||
assertion =
|
||||
lib.versionOlder cfg.package.version "0.31.0" || lib.versionAtLeast cfg.package.version "0.31.2";
|
||||
message = "Only i3status-rust <0.31.0 or ≥0.31.2 is supported due to a config format incompatibility.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile = lib.mapAttrs' (cfgFileSuffix: cfgBar:
|
||||
xdg.configFile = lib.mapAttrs' (
|
||||
cfgFileSuffix: cfgBar:
|
||||
lib.nameValuePair "i3status-rust/config-${cfgFileSuffix}.toml" {
|
||||
onChange = ''
|
||||
${pkgs.procps}/bin/pkill -u $USER -USR2 i3status-rs || true
|
||||
'';
|
||||
|
||||
source = settingsFormat.generate "config-${cfgFileSuffix}.toml" ({
|
||||
theme = if lib.versionAtLeast cfg.package.version "0.30.0" then {
|
||||
theme = cfgBar.theme;
|
||||
} else
|
||||
cfgBar.theme;
|
||||
icons = if lib.versionAtLeast cfg.package.version "0.30.0" then {
|
||||
icons = cfgBar.icons;
|
||||
} else
|
||||
cfgBar.icons;
|
||||
block = cfgBar.blocks;
|
||||
} // cfgBar.settings);
|
||||
}) cfg.bars;
|
||||
source = settingsFormat.generate "config-${cfgFileSuffix}.toml" (
|
||||
{
|
||||
theme =
|
||||
if lib.versionAtLeast cfg.package.version "0.30.0" then
|
||||
{
|
||||
theme = cfgBar.theme;
|
||||
}
|
||||
else
|
||||
cfgBar.theme;
|
||||
icons =
|
||||
if lib.versionAtLeast cfg.package.version "0.30.0" then
|
||||
{
|
||||
icons = cfgBar.icons;
|
||||
}
|
||||
else
|
||||
cfgBar.icons;
|
||||
block = cfgBar.blocks;
|
||||
}
|
||||
// cfgBar.settings
|
||||
);
|
||||
}
|
||||
) cfg.bars;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) literalExpression mkDefault mkOption types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkDefault
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.i3status;
|
||||
|
||||
|
|
@ -8,30 +18,45 @@ let
|
|||
|
||||
formatOrder = n: ''order += "${n}"'';
|
||||
|
||||
formatModule = n: v:
|
||||
formatModule =
|
||||
n: v:
|
||||
let
|
||||
formatLine = n: v:
|
||||
formatLine =
|
||||
n: v:
|
||||
let
|
||||
formatValue = v:
|
||||
formatValue =
|
||||
v:
|
||||
if lib.isBool v then
|
||||
(if v then "true" else "false")
|
||||
else if lib.isString v then
|
||||
''"${v}"''
|
||||
else
|
||||
toString v;
|
||||
in "${n} = ${formatValue v}";
|
||||
in ''
|
||||
in
|
||||
"${n} = ${formatValue v}";
|
||||
in
|
||||
''
|
||||
${n} {
|
||||
${lib.concatStringsSep "\n " (lib.mapAttrsToList formatLine v)}
|
||||
}
|
||||
'';
|
||||
|
||||
settingsType = with types; attrsOf (oneOf [ bool int str ]);
|
||||
settingsType =
|
||||
with types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
]);
|
||||
|
||||
sortAttrNamesByPosition = comparator: set:
|
||||
let pos = n: set."${n}".position;
|
||||
in lib.sort (a: b: comparator (pos a) (pos b)) (lib.attrNames set);
|
||||
in {
|
||||
sortAttrNamesByPosition =
|
||||
comparator: set:
|
||||
let
|
||||
pos = n: set."${n}".position;
|
||||
in
|
||||
lib.sort (a: b: comparator (pos a) (pos b)) (lib.attrNames set);
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.justinlovinger ];
|
||||
|
||||
options.programs.i3status = {
|
||||
|
|
@ -68,40 +93,42 @@ in {
|
|||
};
|
||||
|
||||
modules = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether or not to enable this module.
|
||||
'';
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether or not to enable this module.
|
||||
'';
|
||||
};
|
||||
position = mkOption {
|
||||
type = with types; either int float;
|
||||
description = ''
|
||||
Position of this module in i3status `order`.
|
||||
'';
|
||||
};
|
||||
settings = mkOption {
|
||||
type = settingsType;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration to add to this i3status module.
|
||||
See
|
||||
{manpage}`i3status(1)`
|
||||
for options.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
format = "♪ %volume";
|
||||
format_muted = "♪ muted (%volume)";
|
||||
device = "pulse:1";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
position = mkOption {
|
||||
type = with types; either int float;
|
||||
description = ''
|
||||
Position of this module in i3status `order`.
|
||||
'';
|
||||
};
|
||||
settings = mkOption {
|
||||
type = settingsType;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration to add to this i3status module.
|
||||
See
|
||||
{manpage}`i3status(1)`
|
||||
for options.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
format = "♪ %volume";
|
||||
format_muted = "♪ muted (%volume)";
|
||||
device = "pulse:1";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
description = ''
|
||||
Modules to add to i3status {file}`config` file.
|
||||
|
|
@ -140,7 +167,9 @@ in {
|
|||
};
|
||||
|
||||
modules = {
|
||||
ipv6 = { position = mkDefault 1; };
|
||||
ipv6 = {
|
||||
position = mkDefault 1;
|
||||
};
|
||||
|
||||
"wireless _first_" = {
|
||||
position = mkDefault 2;
|
||||
|
|
@ -160,17 +189,23 @@ in {
|
|||
|
||||
"battery all" = {
|
||||
position = mkDefault 4;
|
||||
settings = { format = mkDefault "%status %percentage %remaining"; };
|
||||
settings = {
|
||||
format = mkDefault "%status %percentage %remaining";
|
||||
};
|
||||
};
|
||||
|
||||
"disk /" = {
|
||||
position = mkDefault 5;
|
||||
settings = { format = mkDefault "%avail"; };
|
||||
settings = {
|
||||
format = mkDefault "%avail";
|
||||
};
|
||||
};
|
||||
|
||||
load = {
|
||||
position = mkDefault 6;
|
||||
settings = { format = mkDefault "%1min"; };
|
||||
settings = {
|
||||
format = mkDefault "%1min";
|
||||
};
|
||||
};
|
||||
|
||||
memory = {
|
||||
|
|
@ -184,17 +219,20 @@ in {
|
|||
|
||||
"tztime local" = {
|
||||
position = mkDefault 8;
|
||||
settings = { format = mkDefault "%Y-%m-%d %H:%M:%S"; };
|
||||
settings = {
|
||||
format = mkDefault "%Y-%m-%d %H:%M:%S";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile."i3status/config".text = lib.concatStringsSep "\n" ([ ]
|
||||
xdg.configFile."i3status/config".text = lib.concatStringsSep "\n" (
|
||||
[ ]
|
||||
++ lib.optional (cfg.general != { }) (formatModule "general" cfg.general)
|
||||
++ map formatOrder (sortAttrNamesByPosition lib.lessThan enabledModules)
|
||||
++ lib.mapAttrsToList formatModule
|
||||
(lib.mapAttrs (n: v: v.settings) enabledModules));
|
||||
++ lib.mapAttrsToList formatModule (lib.mapAttrs (n: v: v.settings) enabledModules)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.iamb;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.programs.iamb = {
|
||||
enable = lib.mkEnableOption "iamb";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,38 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.imv;
|
||||
|
||||
toConfig = attrs:
|
||||
toConfig =
|
||||
attrs:
|
||||
''
|
||||
# Generated by Home Manager.
|
||||
'' + lib.generators.toINI { } attrs;
|
||||
in {
|
||||
''
|
||||
+ lib.generators.toINI { } attrs;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.christoph-heiss ];
|
||||
|
||||
options.programs.imv = {
|
||||
enable = lib.mkEnableOption
|
||||
"imv: a command line image viewer intended for use with tiling window managers";
|
||||
enable = lib.mkEnableOption "imv: a command line image viewer intended for use with tiling window managers";
|
||||
|
||||
package = lib.mkPackageOption pkgs "imv" { nullable = true; };
|
||||
|
||||
settings = lib.mkOption {
|
||||
default = { };
|
||||
type = with lib.types; attrsOf (attrsOf (oneOf [ bool int str ]));
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
])
|
||||
);
|
||||
description = ''
|
||||
Configuration options for imv. See
|
||||
{manpage}`imv(5)`.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@
|
|||
# two files, showing you a unified table of contents for all packages.
|
||||
# This is really nice.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
cfg = config.programs.info;
|
||||
|
|
@ -27,7 +32,8 @@ let
|
|||
# from this package in the activation script.
|
||||
infoPkg = pkgs.texinfoInteractive;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "programs" "info" "homeInfoDirLocation" ] ''
|
||||
The `dir` file is now generated as part of the Home Manager profile and
|
||||
|
|
@ -48,13 +54,21 @@ in {
|
|||
|
||||
home.extraOutputsToInstall = [ "info" ];
|
||||
|
||||
home.extraProfileCommands = let infoPath = "$out/share/info";
|
||||
in ''
|
||||
if [[ -w "${infoPath}" && ! -e "${infoPath}/dir" ]]; then
|
||||
PATH="${lib.makeBinPath [ pkgs.gzip infoPkg ]}''${PATH:+:}$PATH" \
|
||||
find -L "${infoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
|
||||
-exec install-info '{}' "${infoPath}/dir" ';'
|
||||
fi
|
||||
'';
|
||||
home.extraProfileCommands =
|
||||
let
|
||||
infoPath = "$out/share/info";
|
||||
in
|
||||
''
|
||||
if [[ -w "${infoPath}" && ! -e "${infoPath}/dir" ]]; then
|
||||
PATH="${
|
||||
lib.makeBinPath [
|
||||
pkgs.gzip
|
||||
infoPkg
|
||||
]
|
||||
}''${PATH:+:}$PATH" \
|
||||
find -L "${infoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
|
||||
-exec install-info '{}' "${infoPath}/dir" ';'
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
||||
cfg = config.programs.ion;
|
||||
|
||||
aliasesStr = lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList (k: v: "alias ${k} = ${lib.escapeShellArg v}")
|
||||
cfg.shellAliases);
|
||||
in {
|
||||
aliasesStr = lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (k: v: "alias ${k} = ${lib.escapeShellArg v}") cfg.shellAliases
|
||||
);
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.jo1gi ];
|
||||
|
||||
options.programs.ion = {
|
||||
enable =
|
||||
lib.mkEnableOption "the Ion Shell. Compatible with Redox and Linux";
|
||||
enable = lib.mkEnableOption "the Ion Shell. Compatible with Redox and Linux";
|
||||
|
||||
package = lib.mkPackageOption pkgs "ion" { };
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) concatStringsSep flip mapAttrsToList mkOption types;
|
||||
inherit (lib)
|
||||
concatStringsSep
|
||||
flip
|
||||
mapAttrsToList
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.irssi;
|
||||
|
||||
|
|
@ -11,50 +22,58 @@ let
|
|||
,
|
||||
'';
|
||||
|
||||
assignFormat = set:
|
||||
concatStringsSep "\n"
|
||||
(mapAttrsToList (k: v: " ${k} = \"${quoteStr v}\";") set);
|
||||
assignFormat =
|
||||
set: concatStringsSep "\n" (mapAttrsToList (k: v: " ${k} = \"${quoteStr v}\";") set);
|
||||
|
||||
chatnetString = concatStringsSep "\n" (flip mapAttrsToList cfg.networks
|
||||
(k: v: ''
|
||||
${k} = {
|
||||
type = "${v.type}";
|
||||
nick = "${quoteStr v.nick}";
|
||||
autosendcmd = "${lib.concatMapStringsSep ";" quoteStr v.autoCommands}";
|
||||
${
|
||||
lib.optionalString (v.saslExternal) ''
|
||||
chatnetString = concatStringsSep "\n" (
|
||||
flip mapAttrsToList cfg.networks (
|
||||
k: v: ''
|
||||
${k} = {
|
||||
type = "${v.type}";
|
||||
nick = "${quoteStr v.nick}";
|
||||
autosendcmd = "${lib.concatMapStringsSep ";" quoteStr v.autoCommands}";
|
||||
${lib.optionalString (v.saslExternal) ''
|
||||
sasl_username = "${quoteStr v.nick}";
|
||||
sasl_mechanism = "EXTERNAL";''
|
||||
}
|
||||
};
|
||||
''));
|
||||
sasl_mechanism = "EXTERNAL";''}
|
||||
};
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
serversString = concatStringsSep cnl (flip mapAttrsToList cfg.networks
|
||||
(k: v: ''
|
||||
{
|
||||
chatnet = "${k}";
|
||||
address = "${v.server.address}";
|
||||
port = "${toString v.server.port}";
|
||||
use_ssl = "${lib.hm.booleans.yesNo v.server.ssl.enable}";
|
||||
ssl_verify = "${lib.hm.booleans.yesNo v.server.ssl.verify}";
|
||||
autoconnect = "${lib.hm.booleans.yesNo v.server.autoConnect}";
|
||||
${
|
||||
lib.optionalString (v.server.ssl.certificateFile != null) ''
|
||||
ssl_cert = "${v.server.ssl.certificateFile}";
|
||||
''
|
||||
}
|
||||
}
|
||||
''));
|
||||
|
||||
channelString = concatStringsSep cnl (lib.concatLists
|
||||
(flip mapAttrsToList cfg.networks (k: v:
|
||||
(flip mapAttrsToList v.channels (c: cv: ''
|
||||
serversString = concatStringsSep cnl (
|
||||
flip mapAttrsToList cfg.networks (
|
||||
k: v: ''
|
||||
{
|
||||
chatnet = "${k}";
|
||||
name = "${c}";
|
||||
autojoin = "${lib.hm.booleans.yesNo cv.autoJoin}";
|
||||
address = "${v.server.address}";
|
||||
port = "${toString v.server.port}";
|
||||
use_ssl = "${lib.hm.booleans.yesNo v.server.ssl.enable}";
|
||||
ssl_verify = "${lib.hm.booleans.yesNo v.server.ssl.verify}";
|
||||
autoconnect = "${lib.hm.booleans.yesNo v.server.autoConnect}";
|
||||
${lib.optionalString (v.server.ssl.certificateFile != null) ''
|
||||
ssl_cert = "${v.server.ssl.certificateFile}";
|
||||
''}
|
||||
}
|
||||
'')))));
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
channelString = concatStringsSep cnl (
|
||||
lib.concatLists (
|
||||
flip mapAttrsToList cfg.networks (
|
||||
k: v:
|
||||
(flip mapAttrsToList v.channels (
|
||||
c: cv: ''
|
||||
{
|
||||
chatnet = "${k}";
|
||||
name = "${c}";
|
||||
autojoin = "${lib.hm.booleans.yesNo cv.autoJoin}";
|
||||
}
|
||||
''
|
||||
))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
channelType = types.submodule {
|
||||
options = {
|
||||
|
|
@ -73,91 +92,95 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
networkType = types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
visible = false;
|
||||
default = name;
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
nick = mkOption {
|
||||
type = types.str;
|
||||
description = "Nickname in that network.";
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.str;
|
||||
description = "Type of the network.";
|
||||
default = "IRC";
|
||||
};
|
||||
|
||||
autoCommands = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "List of commands to execute on connect.";
|
||||
};
|
||||
|
||||
server = {
|
||||
address = mkOption {
|
||||
networkType = types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
name = mkOption {
|
||||
visible = false;
|
||||
default = name;
|
||||
type = types.str;
|
||||
description = "Address of the chat server.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 6667;
|
||||
description = "Port of the chat server.";
|
||||
nick = mkOption {
|
||||
type = types.str;
|
||||
description = "Nickname in that network.";
|
||||
};
|
||||
|
||||
ssl = {
|
||||
enable = mkOption {
|
||||
type = mkOption {
|
||||
type = types.str;
|
||||
description = "Type of the network.";
|
||||
default = "IRC";
|
||||
};
|
||||
|
||||
autoCommands = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "List of commands to execute on connect.";
|
||||
};
|
||||
|
||||
server = {
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
description = "Address of the chat server.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 6667;
|
||||
description = "Port of the chat server.";
|
||||
};
|
||||
|
||||
ssl = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether SSL should be used.";
|
||||
};
|
||||
|
||||
verify = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether the SSL certificate should be verified.";
|
||||
};
|
||||
|
||||
certificateFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a file containing the certificate used for
|
||||
client authentication to the server.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
autoConnect = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether SSL should be used.";
|
||||
};
|
||||
|
||||
verify = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether the SSL certificate should be verified.";
|
||||
};
|
||||
|
||||
certificateFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a file containing the certificate used for
|
||||
client authentication to the server.
|
||||
'';
|
||||
default = false;
|
||||
description = "Whether Irssi connects to the server on launch.";
|
||||
};
|
||||
};
|
||||
|
||||
autoConnect = mkOption {
|
||||
channels = mkOption {
|
||||
description = "Channels for the given network.";
|
||||
type = types.attrsOf channelType;
|
||||
default = { };
|
||||
};
|
||||
|
||||
saslExternal = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether Irssi connects to the server on launch.";
|
||||
description = ''
|
||||
Enable SASL external authentication. This requires setting a path in
|
||||
[](#opt-programs.irssi.networks._name_.server.ssl.certificateFile).
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
channels = mkOption {
|
||||
description = "Channels for the given network.";
|
||||
type = types.attrsOf channelType;
|
||||
default = { };
|
||||
};
|
||||
|
||||
saslExternal = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable SASL external authentication. This requires setting a path in
|
||||
[](#opt-programs.irssi.networks._name_.server.ssl.certificateFile).
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
|
||||
options = {
|
||||
programs.irssi = {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
# This module provides JAVA_HOME, with a different way to install java locally.
|
||||
# This module is modified from the NixOS module `programs.java`
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
cfg = config.programs.java;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ ShamrockLee ];
|
||||
|
||||
options = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{ config, lib, ... }:
|
||||
let cfg = config.programs.jetbrains-remote;
|
||||
in {
|
||||
let
|
||||
cfg = config.programs.jetbrains-remote;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ genericnerdyusername ];
|
||||
|
||||
options.programs.jetbrains-remote = {
|
||||
|
|
@ -19,14 +21,19 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf (cfg.enable && cfg.ides != [ ]) {
|
||||
home.activation.jetBrainsRemote = let
|
||||
mkLine = ide:
|
||||
# Errors out if the symlink already exists
|
||||
"${ide}/bin/${ide.meta.mainProgram}-remote-dev-server registerBackendLocationForGateway || true";
|
||||
lines = map mkLine cfg.ides;
|
||||
linesStr = ''
|
||||
rm $HOME/.cache/JetBrains/RemoteDev/userProvidedDist/_nix_store* || true
|
||||
'' + lib.concatStringsSep "\n" lines;
|
||||
in lib.hm.dag.entryAfter [ "writeBoundary" ] linesStr;
|
||||
home.activation.jetBrainsRemote =
|
||||
let
|
||||
mkLine =
|
||||
ide:
|
||||
# Errors out if the symlink already exists
|
||||
"${ide}/bin/${ide.meta.mainProgram}-remote-dev-server registerBackendLocationForGateway || true";
|
||||
lines = map mkLine cfg.ides;
|
||||
linesStr =
|
||||
''
|
||||
rm $HOME/.cache/JetBrains/RemoteDev/userProvidedDist/_nix_store* || true
|
||||
''
|
||||
+ lib.concatStringsSep "\n" lines;
|
||||
in
|
||||
lib.hm.dag.entryAfter [ "writeBoundary" ] linesStr;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -9,7 +14,8 @@ let
|
|||
# config path is the same for linux and mac
|
||||
configPath = "${config.xdg.configHome}/joplin-desktop/settings.json";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.zorrobert ];
|
||||
|
||||
options.programs.joplin-desktop = {
|
||||
|
|
@ -89,47 +95,57 @@ in {
|
|||
home.packages = [ cfg.package ];
|
||||
|
||||
home.activation = {
|
||||
activateJoplinDesktopConfig = let
|
||||
newConfig = jsonFormat.generate "joplin-settings.json"
|
||||
(lib.attrsets.filterAttrs (n: v: (v != null) && (v != "")) ({
|
||||
# TODO: find a better way to convert nix attribute names to strings:
|
||||
# sync.interval = ... -> "sync.interval" = ...
|
||||
activateJoplinDesktopConfig =
|
||||
let
|
||||
newConfig = jsonFormat.generate "joplin-settings.json" (
|
||||
lib.attrsets.filterAttrs (n: v: (v != null) && (v != "")) (
|
||||
{
|
||||
# TODO: find a better way to convert nix attribute names to strings:
|
||||
# sync.interval = ... -> "sync.interval" = ...
|
||||
|
||||
"editor" = cfg.general.editor;
|
||||
"editor" = cfg.general.editor;
|
||||
|
||||
"sync.target" = {
|
||||
"undefined" = null;
|
||||
"none" = 0;
|
||||
"file-system" = 2;
|
||||
"onedrive" = 3;
|
||||
"nextcloud" = 5;
|
||||
"webdav" = 6;
|
||||
"dropbox" = 7;
|
||||
"s3" = 8;
|
||||
"joplin-server" = 9;
|
||||
"joplin-cloud" = 10;
|
||||
}.${cfg.sync.target};
|
||||
"sync.target" =
|
||||
{
|
||||
"undefined" = null;
|
||||
"none" = 0;
|
||||
"file-system" = 2;
|
||||
"onedrive" = 3;
|
||||
"nextcloud" = 5;
|
||||
"webdav" = 6;
|
||||
"dropbox" = 7;
|
||||
"s3" = 8;
|
||||
"joplin-server" = 9;
|
||||
"joplin-cloud" = 10;
|
||||
}
|
||||
.${cfg.sync.target};
|
||||
|
||||
"sync.interval" = {
|
||||
"undefined" = null;
|
||||
"disabled" = 0;
|
||||
"5m" = 300;
|
||||
"10m" = 600;
|
||||
"30m" = 1800;
|
||||
"1h" = 3600;
|
||||
"12h" = 43200;
|
||||
"1d" = 86400;
|
||||
}.${cfg.sync.interval};
|
||||
} // cfg.extraConfig));
|
||||
in lib.hm.dag.entryAfter [ "linkGeneration" ] ''
|
||||
# Ensure that settings.json exists.
|
||||
mkdir -p ${builtins.dirOf configPath}
|
||||
touch ${configPath}
|
||||
# Config has to be written to temporary variable because jq cannot edit files in place.
|
||||
config="$(jq -s '.[0] + .[1]' ${configPath} ${newConfig})"
|
||||
printf '%s\n' "$config" > ${configPath}
|
||||
unset config
|
||||
'';
|
||||
"sync.interval" =
|
||||
{
|
||||
"undefined" = null;
|
||||
"disabled" = 0;
|
||||
"5m" = 300;
|
||||
"10m" = 600;
|
||||
"30m" = 1800;
|
||||
"1h" = 3600;
|
||||
"12h" = 43200;
|
||||
"1d" = 86400;
|
||||
}
|
||||
.${cfg.sync.interval};
|
||||
}
|
||||
// cfg.extraConfig
|
||||
)
|
||||
);
|
||||
in
|
||||
lib.hm.dag.entryAfter [ "linkGeneration" ] ''
|
||||
# Ensure that settings.json exists.
|
||||
mkdir -p ${builtins.dirOf configPath}
|
||||
touch ${configPath}
|
||||
# Config has to be written to temporary variable because jq cannot edit files in place.
|
||||
config="$(jq -s '.[0] + .[1]' ${configPath} ${newConfig})"
|
||||
printf '%s\n' "$config" > ${configPath}
|
||||
unset config
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption types;
|
||||
|
||||
cfg = config.programs.joshuto;
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.rasmus-kirk ];
|
||||
|
||||
options.programs.joshuto = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption types;
|
||||
|
||||
|
|
@ -24,7 +29,8 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.jq = {
|
||||
enable = lib.mkEnableOption "the jq command-line JSON processor";
|
||||
|
|
@ -71,10 +77,12 @@ in {
|
|||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.sessionVariables = let c = cfg.colors;
|
||||
in {
|
||||
JQ_COLORS =
|
||||
"${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}:${c.objectKeys}";
|
||||
};
|
||||
home.sessionVariables =
|
||||
let
|
||||
c = cfg.colors;
|
||||
in
|
||||
{
|
||||
JQ_COLORS = "${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}:${c.objectKeys}";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.jqp;
|
||||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.programs.jqp = {
|
||||
enable = lib.mkEnableOption "jqp, jq playground";
|
||||
|
||||
|
|
@ -15,7 +21,9 @@ in {
|
|||
example = {
|
||||
theme = {
|
||||
name = "monokai";
|
||||
chromaStyleOverrides = { kc = "#009900 underline"; };
|
||||
chromaStyleOverrides = {
|
||||
kc = "#009900 underline";
|
||||
};
|
||||
};
|
||||
};
|
||||
description = "Jqp configuration";
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue