1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-22 10:19:39 +01:00

neomutt: Initial IMAP support (#4597)

neomutt: Updated options and added tests

neomutt: Added test for individual mailbox type

neomutt: Formatted code

neomutt: Enable ssl_force_tls based on IMAP instead of SMTP

neomutt: Applied suggestions from @chayleaf

neomutt: fix breaking tests
This commit is contained in:
Christian Dannie Storgaard 2024-02-11 19:22:37 +02:00 committed by GitHub
parent bfd0ae29a8
commit a09cfdbaf1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 360 additions and 14 deletions

View file

@ -17,6 +17,14 @@ let
default = null;
description = "Name to display";
};
type = mkOption {
type = types.nullOr (types.enum [ "maildir" "imap" ]);
example = "imap";
default = null;
description =
"Whether this mailbox is a maildir folder or an IMAP mailbox";
};
};
};
@ -75,6 +83,14 @@ in {
description = "Use a different name as mailbox name";
};
mailboxType = mkOption {
type = types.enum [ "maildir" "imap" ];
default = "maildir";
example = "imap";
description =
"Whether this account uses maildir folders or IMAP mailboxes";
};
extraMailboxes = mkOption {
type = with types; listOf (either str (submodule extraMailboxOptions));
default = [ ];

View file

@ -8,6 +8,59 @@ let
neomuttAccounts =
filter (a: a.neomutt.enable) (attrValues config.accounts.email.accounts);
accountCommandNeeded = any (a:
a.neomutt.enable && (a.neomutt.mailboxType == "imap"
|| (any (m: !isString m && m.type == "imap") a.neomutt.extraMailboxes)))
(attrValues config.accounts.email.accounts);
accountCommand = let
imapAccounts = filter (a:
a.neomutt.enable && a.imap.host != null && a.userName != null
&& a.passwordCommand != null) (attrValues config.accounts.email.accounts);
accountCase = account:
let passwordCmd = toString account.passwordCommand;
in ''
${account.userName}@${account.imap.host})
found=1
username="${account.userName}"
password="$(${passwordCmd})"
;;'';
in pkgs.writeShellScriptBin "account-command.sh" ''
# Automatically set login variables based on the current account.
# This requires NeoMutt >= 2022-05-16
while [ ! -z "$1" ]; do
case "$1" in
--hostname)
shift
hostname="$1"
;;
--username)
shift
username="$1@"
;;
--type)
shift
type="$1"
;;
*)
exit 1
;;
esac
shift
done
found=
case "''${username}''${hostname}" in
${concatMapStringsSep "\n" accountCase imapAccounts}
esac
if [ -n "$found" ]; then
echo "username: $username"
echo "password: $password"
fi
'';
sidebarModule = types.submodule {
options = {
enable = mkEnableOption "sidebar support";
@ -101,6 +154,21 @@ let
accountFilename = account: config.xdg.configHome + "/neomutt/" + account.name;
accountRootIMAP = account:
let
userName =
lib.optionalString (account.userName != null) "${account.userName}@";
port = lib.optionalString (account.imap.port != null)
":${toString account.imap.port}";
protocol = if account.imap.tls.enable then "imaps" else "imap";
in "${protocol}://${userName}${account.imap.host}${port}";
accountRoot = account:
if account.neomutt.mailboxType == "imap" then
accountRootIMAP account
else
account.maildir.absPath;
genCommonFolderHooks = account:
with account; {
from = "'${address}'";
@ -128,12 +196,12 @@ let
smtp_pass = ''"`${passCmd}`"'';
};
genMaildirAccountConfig = account:
genAccountConfig = account:
with account;
let
folderHook = mapAttrsToList setOption (genCommonFolderHooks account
// optionalAttrs cfg.changeFolderWhenSourcingAccount {
folder = "'${account.maildir.absPath}'";
folder = "'${accountRoot account}'";
});
in ''
${concatStringsSep "\n" folderHook}
@ -145,29 +213,40 @@ let
"mailboxes"
else
''named-mailboxes "${account.neomutt.mailboxName}"'';
mailroot = accountRoot account;
hookName = if account.neomutt.mailboxType == "imap" then
"account-hook"
else
"folder-hook";
extraMailboxes = concatMapStringsSep "\n" (extra:
if isString extra then
''mailboxes "${account.maildir.absPath}/${extra}"''
let
mailboxroot = if !isString extra && extra.type == "imap" then
accountRootIMAP account
else if !isString extra && extra.type == "maildir" then
account.maildir.absPath
else
mailroot;
in if isString extra then
''mailboxes "${mailboxroot}/${extra}"''
else if extra.name == null then
''mailboxes "${account.maildir.absPath}/${extra.mailbox}"''
''mailboxes "${mailboxroot}/${extra.mailbox}"''
else
''
named-mailboxes "${extra.name}" "${account.maildir.absPath}/${extra.mailbox}"'')
''named-mailboxes "${extra.name}" "${mailboxroot}/${extra.mailbox}"'')
account.neomutt.extraMailboxes;
in with account; ''
# register account ${name}
${mailboxes} "${maildir.absPath}/${folders.inbox}"
${mailboxes} "${mailroot}/${folders.inbox}"
${extraMailboxes}
folder-hook ${maildir.absPath}/ " \
${hookName} ${mailroot}/ " \
source ${accountFilename account} "
'';
mraSection = account:
with account;
if account.maildir != null then
genMaildirAccountConfig account
if account.imap.host != null || account.maildir != null then
genAccountConfig account
else
throw "Only maildir is supported at the moment";
throw "Only maildir and IMAP is supported at the moment";
optionsStr = attrs: concatStringsSep "\n" (mapAttrsToList setOption attrs);
@ -219,7 +298,7 @@ let
in ''
# Generated by Home Manager.
set ssl_force_tls = ${
lib.hm.booleans.yesNo (smtp.tls.enable || smtp.tls.useStartTls)
lib.hm.booleans.yesNo (imap.tls.enable || imap.tls.useStartTls)
}
set certificate_file=${toString config.accounts.email.certificatesFile}
@ -366,7 +445,11 @@ in {
"source ${pkgs.neomutt}/share/doc/neomutt/vim-keys/vim-keys.rc"}
# Register accounts
${concatMapStringsSep "\n" registerAccount neomuttAccounts}
${
optionalString (accountCommandNeeded) ''
set account_command = '${accountCommand}/bin/account-command.sh'
''
}${concatMapStringsSep "\n" registerAccount neomuttAccounts}
# Source primary account
source ${accountFilename primary}