mirror of
https://github.com/nix-community/home-manager.git
synced 2025-12-15 21:41:09 +01:00
parent
d8d5f85ab7
commit
fba87f8998
10 changed files with 477 additions and 0 deletions
|
|
@ -391,6 +391,7 @@ in
|
|||
(import ../programs/getmail-accounts.nix)
|
||||
(import ../programs/mbsync-accounts.nix)
|
||||
(import ../programs/msmtp-accounts.nix)
|
||||
(import ../programs/neomutt-accounts.nix)
|
||||
(import ../programs/notmuch-accounts.nix)
|
||||
(import ../programs/offlineimap-accounts.nix)
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1311,6 +1311,13 @@ in
|
|||
A new module is available: 'services.grobi'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-01-26T19:37:57+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.neomutt'.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ let
|
|||
(loadModule ./programs/mercurial.nix { })
|
||||
(loadModule ./programs/mpv.nix { })
|
||||
(loadModule ./programs/msmtp.nix { })
|
||||
(loadModule ./programs/neomutt.nix { })
|
||||
(loadModule ./programs/neovim.nix { })
|
||||
(loadModule ./programs/newsboat.nix { })
|
||||
(loadModule ./programs/noti.nix { })
|
||||
|
|
|
|||
35
modules/programs/neomutt-accounts.nix
Normal file
35
modules/programs/neomutt-accounts.nix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.neomutt = {
|
||||
enable = mkEnableOption "NeoMutt";
|
||||
|
||||
sendMailCommand = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "msmtpq --read-envelope-from --read-recipients";
|
||||
description = ''
|
||||
Command to send a mail. If not set, neomutt will be in charge of sending mails.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "color status cyan default";
|
||||
description = ''
|
||||
Extra lines to add to the folder hook for this account.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.neomutt.enable {
|
||||
neomutt.sendMailCommand = mkOptionDefault (
|
||||
if config.msmtp.enable
|
||||
then "msmtpq --read-envelope-from --read-recipients"
|
||||
else null
|
||||
);
|
||||
};
|
||||
}
|
||||
319
modules/programs/neomutt.nix
Normal file
319
modules/programs/neomutt.nix
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.neomutt;
|
||||
|
||||
neomuttAccounts = filter (a: a.neomutt.enable)
|
||||
(attrValues config.accounts.email.accounts);
|
||||
|
||||
sidebarModule = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "sidebar support";
|
||||
|
||||
width = mkOption {
|
||||
type = types.int;
|
||||
default = 22;
|
||||
description = "Width of the sidebar";
|
||||
};
|
||||
|
||||
shortPath = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
By default sidebar shows the full path of the mailbox, but
|
||||
with this enabled only the relative name is shown.
|
||||
'';
|
||||
};
|
||||
|
||||
format = mkOption {
|
||||
type = types.str;
|
||||
default = "%B%?F? [%F]?%* %?N?%N/?%S";
|
||||
description = ''
|
||||
Sidebar format. Check neomutt documentation for details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
bindModule = types.submodule {
|
||||
options = {
|
||||
map = mkOption {
|
||||
type = types.enum [
|
||||
"alias"
|
||||
"attach"
|
||||
"browser"
|
||||
"compose"
|
||||
"editor"
|
||||
"generic"
|
||||
"index"
|
||||
"mix"
|
||||
"pager"
|
||||
"pgp"
|
||||
"postpone"
|
||||
"query"
|
||||
"smime"
|
||||
];
|
||||
default = "index";
|
||||
description = "Select the menu to bind the command to.";
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
example = "<left>";
|
||||
description = "The key to bind.";
|
||||
};
|
||||
|
||||
action = mkOption {
|
||||
type = types.str;
|
||||
example = "<enter-command>toggle sidebar_visible<enter><refresh>";
|
||||
description = "Specify the action to take.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
yesno = x: if x then "yes" else "no";
|
||||
setOption = n: v: if v == null then "unset ${n}" else "set ${n}=${v}";
|
||||
escape = replaceStrings ["%"] ["%25"];
|
||||
|
||||
accountFilename = account:
|
||||
config.xdg.configHome + "/neomutt/" + account.name;
|
||||
|
||||
genCommonFolderHooks = account: with account;
|
||||
{
|
||||
from = "'${address}'";
|
||||
realname = "'${realName}'";
|
||||
spoolfile = "'+${folders.inbox}'";
|
||||
record = if folders.sent == null then null else "'+${folders.sent}'";
|
||||
postponed = "'+${folders.drafts}'";
|
||||
trash = "'+${folders.trash}'";
|
||||
};
|
||||
|
||||
mtaSection = account: with account;
|
||||
let
|
||||
passCmd = concatStringsSep " " passwordCommand;
|
||||
in
|
||||
if neomutt.sendMailCommand != null then {
|
||||
sendmail = "'${neomutt.sendMailCommand}'";
|
||||
} else let
|
||||
smtpProto = if smtp.tls.enable then "smtps" else "smtp";
|
||||
smtpBaseUrl = "${smtpProto}://${escape userName}@${smtp.host}";
|
||||
in {
|
||||
smtp_url = "'${smtpBaseUrl}'";
|
||||
smtp_pass = "'`${passCmd}`'";
|
||||
};
|
||||
|
||||
genMaildirAccountConfig = account: with account;
|
||||
let
|
||||
folderHook =
|
||||
mapAttrsToList setOption (
|
||||
genCommonFolderHooks account
|
||||
// { folder = "'${account.maildir.absPath}'"; }
|
||||
)
|
||||
++ optional (neomutt.extraConfig != "") neomutt.extraConfig;
|
||||
in
|
||||
''
|
||||
${concatStringsSep "\n" folderHook}
|
||||
'';
|
||||
|
||||
registerAccount = account: with account;
|
||||
''
|
||||
# register account ${name}
|
||||
mailboxes "${account.maildir.absPath}/${folders.inbox}"
|
||||
folder-hook ${account.maildir.absPath}/ " \
|
||||
source ${accountFilename account} "
|
||||
'';
|
||||
|
||||
mraSection = account: with account;
|
||||
if account.maildir != null
|
||||
then genMaildirAccountConfig account
|
||||
else throw "Only maildir is supported at the moment";
|
||||
|
||||
optionsStr = attrs:
|
||||
concatStringsSep "\n" (mapAttrsToList setOption attrs);
|
||||
|
||||
|
||||
sidebarSection = ''
|
||||
# Sidebar
|
||||
set sidebar_visible = yes
|
||||
set sidebar_short_path = ${yesno cfg.sidebar.shortPath}
|
||||
set sidebar_width = ${toString cfg.sidebar.width}
|
||||
set sidebar_format = '${cfg.sidebar.format}'
|
||||
'';
|
||||
|
||||
bindSection =
|
||||
concatMapStringsSep
|
||||
"\n"
|
||||
(bind: "bind ${bind.map} ${bind.key} \"${bind.action}\"")
|
||||
cfg.binds;
|
||||
|
||||
macroSection =
|
||||
concatMapStringsSep
|
||||
"\n"
|
||||
(bind: "macro ${bind.map} ${bind.key} \"${bind.action}\"")
|
||||
cfg.macros;
|
||||
|
||||
mailCheckSection = ''
|
||||
set mail_check_stats
|
||||
set mail_check_stats_interval = ${toString cfg.checkStatsInterval}
|
||||
'';
|
||||
|
||||
notmuchSection = account: with account; ''
|
||||
# notmuch section
|
||||
set nm_default_uri = "notmuch://${config.accounts.email.maildirBasePath}"
|
||||
virtual-mailboxes "My INBOX" "notmuch://?query=tag:inbox"
|
||||
'';
|
||||
|
||||
accountStr = account: with account; ''
|
||||
# Generated by Home Manager.
|
||||
set ssl_force_tls = yes
|
||||
set certificate_file=${config.accounts.email.certificatesFile}
|
||||
|
||||
# GPG section
|
||||
set crypt_use_gpgme = yes
|
||||
set crypt_autosign = ${yesno (gpg.signByDefault or false)}
|
||||
set pgp_use_gpg_agent = yes
|
||||
set mbox_type = ${if maildir != null then "Maildir" else "mbox"}
|
||||
set sort = "${cfg.sort}"
|
||||
|
||||
# MTA section
|
||||
${optionsStr (mtaSection account)}
|
||||
|
||||
${optionalString (cfg.checkStatsInterval != null) mailCheckSection}
|
||||
|
||||
${optionalString cfg.sidebar.enable sidebarSection}
|
||||
|
||||
# MRA section
|
||||
${mraSection account}
|
||||
|
||||
# Extra configuration
|
||||
${account.neomutt.extraConfig}
|
||||
''
|
||||
+ optionalString (account.signature.showSignature != "none") ''
|
||||
set signature = ${pkgs.writeText "signature.txt" account.signature.text}
|
||||
''
|
||||
+ optionalString account.notmuch.enable (notmuchSection account);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.neomutt = {
|
||||
enable = mkEnableOption "the NeoMutt mail client";
|
||||
|
||||
sidebar = mkOption {
|
||||
type = sidebarModule;
|
||||
default = {};
|
||||
description = "Options related to the sidebar.";
|
||||
};
|
||||
|
||||
binds = mkOption {
|
||||
type = types.listOf bindModule;
|
||||
default = [];
|
||||
description = "List of keybindings.";
|
||||
};
|
||||
|
||||
macros = mkOption {
|
||||
type = types.listOf bindModule;
|
||||
default = [];
|
||||
description = "List of macros.";
|
||||
};
|
||||
|
||||
sort = mkOption {
|
||||
type = types.enum [
|
||||
"date"
|
||||
"date-received"
|
||||
"from"
|
||||
"mailbox-order"
|
||||
"score"
|
||||
"size"
|
||||
"spam"
|
||||
"subject"
|
||||
"threads"
|
||||
"to"
|
||||
];
|
||||
default = "threads";
|
||||
description = "Sorting method on messages.";
|
||||
};
|
||||
|
||||
vimKeys = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable vim-like bindings.";
|
||||
};
|
||||
|
||||
checkStatsInterval = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
example = 60;
|
||||
description = "Enable and set the interval of automatic mail check.";
|
||||
};
|
||||
|
||||
editor = mkOption {
|
||||
type = types.str;
|
||||
default = "$EDITOR";
|
||||
description = "Select the editor used for writing mail.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = "Extra configuration appended to the end.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Extra configuration appended to the end.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.neomutt ];
|
||||
home.file = let
|
||||
rcFile = account: {
|
||||
"${accountFilename account}".text = accountStr account;
|
||||
};
|
||||
in
|
||||
foldl' (a: b: a // b) {} (map rcFile neomuttAccounts);
|
||||
|
||||
xdg.configFile."neomutt/neomuttrc" = mkIf (neomuttAccounts != []) {
|
||||
text =
|
||||
let
|
||||
primary = filter (a: a.primary) neomuttAccounts;
|
||||
in
|
||||
''
|
||||
# Generated by Home Manager.
|
||||
set header_cache = "${config.xdg.cacheHome}/neomutt/headers/"
|
||||
set message_cachedir = "${config.xdg.cacheHome}/neomutt/messages/"
|
||||
set editor = "${cfg.editor}"
|
||||
set implicit_autoview = yes
|
||||
|
||||
alternative_order text/enriched text/plain text
|
||||
|
||||
set delete = yes
|
||||
|
||||
# Binds
|
||||
${bindSection}
|
||||
|
||||
# Macros
|
||||
${macroSection}
|
||||
|
||||
${optionalString cfg.vimKeys "source ${pkgs.neomutt}/share/doc/neomutt/vim-keys/vim-keys.rc"}
|
||||
|
||||
# Extra configuration
|
||||
${optionsStr cfg.settings}
|
||||
|
||||
${cfg.extraConfig}
|
||||
''
|
||||
+
|
||||
concatMapStringsSep "\n" registerAccount neomuttAccounts
|
||||
+
|
||||
# source primary account
|
||||
"source ${accountFilename (builtins.head primary)}";
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue