diff --git a/modules/programs/alot.nix b/modules/programs/alot.nix index 2b28f34ca..62d0720da 100644 --- a/modules/programs/alot.nix +++ b/modules/programs/alot.nix @@ -12,6 +12,55 @@ let boolStr = v: if v then "True" else "False"; + mkKeyValue = key: value: + let + value' = + if 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 . + ''; + }; + + focus = mkOption { + type = types.nullOr types.str; + default = null; + description = "How to display the tag when focused."; + }; + }; + }; + accountStr = account: with account; concatStringsSep "\n" ( [ "[[${name}]]" ] @@ -41,7 +90,7 @@ let ++ [ alot.extraConfig ] ++ [ "[[[abook]]]" ] ++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion - ); + ); configFile = let @@ -52,8 +101,19 @@ let # Generated by Home Manager. # See http://alot.readthedocs.io/en/latest/configuration/config_options.html + ${generators.toKeyValue { inherit mkKeyValue; } cfg.settings} ${cfg.extraConfig} - + [tags] + '' + + ( + let + submoduleToAttrs = m: + filterAttrs (name: v: name != "_module" && v != null) m; + in + generators.toINI { mkSectionName = mk2ndLevelSectionName; } + (mapAttrs (name: x: submoduleToAttrs x) cfg.tags) + ) + + '' [bindings] ${bindingsToStr cfg.bindings.global} @@ -142,17 +202,39 @@ in ''; }; + 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 = literalExample '' + { + 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 = '' - auto_remove_unread = True - ask_subject = False - handle_mouse = True - initial_command = "search tag:inbox AND NOT tag:killed" - input_timeout = 0.3 - prefer_plaintext = True - thread_indent_replies = 4 - ''; + default = ""; description = '' Extra lines added to alot configuration file. ''; @@ -164,10 +246,11 @@ in xdg.configFile."alot/config".text = configFile; - xdg.configFile."alot/hooks.py".text = - '' + xdg.configFile."alot/hooks.py" = mkIf (cfg.hooks != "") { + text = '' # Generated by Home Manager. '' + cfg.hooks; + }; }; } diff --git a/tests/default.nix b/tests/default.nix index 9eb5afcde..940126827 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -35,6 +35,7 @@ import nmt { ./modules/home-environment ./modules/misc/fontconfig ./modules/programs/alacritty + ./modules/programs/alot ./modules/programs/bash ./modules/programs/browserpass ./modules/programs/fish diff --git a/tests/modules/programs/alot/alot-expected.conf b/tests/modules/programs/alot/alot-expected.conf new file mode 100644 index 000000000..6d3ace4a3 --- /dev/null +++ b/tests/modules/programs/alot/alot-expected.conf @@ -0,0 +1,37 @@ +# Generated by Home Manager. +# See http://alot.readthedocs.io/en/latest/configuration/config_options.html + +auto_remove_unread = True +handle_mouse = True +initial_command = search tag:inbox AND NOT tag:killed +prefer_plaintext = True + + +[tags] +[bindings] + + +[[bufferlist]] + +[[search]] + +[[envelope]] + +[[taglist]] + +[[thread]] + + +[accounts] + +[[hm@example.com]] +address=hm@example.com +draft_box=maildir:///home/hm-user/Mail/hm@example.com/Drafts +realname=H. M. Test +sendmail_command= +sent_box=maildir:///home/hm-user/Mail/hm@example.com/Sent +auto_remove_unread = True +ask_subject = False +handle_mouse = True + +[[[abook]]] diff --git a/tests/modules/programs/alot/alot.nix b/tests/modules/programs/alot/alot.nix new file mode 100644 index 000000000..40028b7aa --- /dev/null +++ b/tests/modules/programs/alot/alot.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ../../accounts/email-test-accounts.nix ]; + + config = { + accounts.email.accounts = { + "hm@example.com" = { + primary = true; + notmuch.enable = true; + alot = { + contactCompletion = { }; + extraConfig = '' + auto_remove_unread = True + ask_subject = False + handle_mouse = True + ''; + }; + imap.port = 993; + }; + }; + + programs.alot = { enable = true; }; + + nixpkgs.overlays = + [ (self: super: { alot = pkgs.writeScriptBin "dummy-alot" ""; }) ]; + + nmt.script = '' + assertFileExists home-files/.config/alot/config + assertFileContent home-files/.config/alot/config ${./alot-expected.conf} + ''; + }; +} + diff --git a/tests/modules/programs/alot/default.nix b/tests/modules/programs/alot/default.nix new file mode 100644 index 000000000..9c912fdb4 --- /dev/null +++ b/tests/modules/programs/alot/default.nix @@ -0,0 +1 @@ +{ alot = ./alot.nix; }