1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 11:36:05 +01:00
home-manager/modules/programs/alot/default.nix
Austin Horstman b4752b0eda treewide: format with latest stable formatter
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-07-23 10:27:52 -05:00

290 lines
7.6 KiB
Nix

# alot config loader is sensitive to leading space !
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
concatStringsSep
mapAttrsToList
mkOption
optionalAttrs
optionalString
types
;
cfg = config.programs.alot;
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'}";
mk2ndLevelSectionName = name: "[" + name + "]";
tagSubmodule = types.submodule {
options = {
translated = mkOption {
type = types.nullOr types.str;
description = ''
Fixed string representation for this tag. The tag can be
hidden from view, if the key translated is set to
`""`, the empty string.
'';
};
translation = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
A pair of strings that define a regular substitution to
compute the string representation on the fly using
`re.sub`.
'';
};
normal = mkOption {
type = types.nullOr types.str;
default = null;
example = "'','', 'white','light red', 'white','#d66'";
description = ''
How to display the tag when unfocused.
See <https://alot.readthedocs.io/en/latest/configuration/theming.html#tagstring-formatting>.
'';
};
focus = mkOption {
type = types.nullOr types.str;
default = null;
description = "How to display the tag when focused.";
};
};
};
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
);
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}
[[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]
${lib.concatStringsSep "\n\n" (map accountStr alotAccounts)}
'';
in
{
options = {
programs.alot = {
enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to enable the Alot mail user agent. Alot uses the
Notmuch email system and will therefore be automatically
enabled for each email account that is managed by Notmuch.
'';
};
package = lib.mkPackageOption pkgs "alot" { nullable = true; };
hooks = mkOption {
type = types.lines;
default = "";
description = ''
Content of the hooks file.
'';
};
bindings = mkOption {
type = types.submodule {
options = {
global = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Global keybindings.";
};
bufferlist = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Bufferlist mode keybindings.";
};
search = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Search mode keybindings.";
};
envelope = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Envelope mode keybindings.";
};
taglist = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Taglist mode keybindings.";
};
thread = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Thread mode keybindings.";
};
};
};
default = { };
description = ''
Keybindings.
'';
};
tags = mkOption {
type = types.attrsOf tagSubmodule;
default = { };
description = "How to display the tags.";
};
settings = mkOption {
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;
handle_mouse = true;
prefer_plaintext = true;
};
example = lib.literalExpression ''
{
auto_remove_unread = true;
ask_subject = false;
thread_indent_replies = 2;
}
'';
description = ''
Configuration options added to alot configuration file.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra lines added to alot configuration file.
'';
};
};
accounts.email.accounts = mkOption {
type = with types; attrsOf (submodule (import ./accounts.nix pkgs));
};
};
config = lib.mkIf cfg.enable {
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
xdg.configFile."alot/config".text = configFile;
xdg.configFile."alot/hooks.py" = lib.mkIf (cfg.hooks != "") {
text = ''
# Generated by Home Manager.
''
+ cfg.hooks;
};
};
}