From dd5be819f24454edfa4749818bbc8860856b3e9d Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Wed, 6 Aug 2025 00:28:09 +0200 Subject: [PATCH 1/7] fix(neomutt): fix change account keybinding --- modules/home-manager/accounts/email/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index af9d1b1..3f5651d 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -99,7 +99,7 @@ in lib.attrsets.mapAttrsToList ( n: _: { "action" = "source ~/.config/neomutt/${n}=InboxUnread";} - ) inputs.nix-private.mail); + ) cfg.accountConfigs); in { enable = true; unmailboxes = true; From 28020e17e148619d3d84241ff394c9abf56a0f08 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Wed, 6 Aug 2025 00:29:28 +0200 Subject: [PATCH 2/7] chore(email): propagate email deletion --- modules/home-manager/accounts/email/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index 3f5651d..31ae461 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -37,6 +37,7 @@ in enable = true; create = "maildir"; expunge = "both"; + remove = "both"; }; msmtp = { enable = true; From fab0ec3696b8041673962a27c396fbe83da20e64 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 11 Aug 2025 00:06:36 +0200 Subject: [PATCH 3/7] feat(mail): add urlscan to view url in mails --- .../home-manager/accounts/email/default.nix | 1 + .../accounts/email/files/urlscan.config.json | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 modules/home-manager/accounts/email/files/urlscan.config.json diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index 31ae461..13717e1 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -227,5 +227,6 @@ in programs.msmtp = { enable = true; }; + home.file."${config.xdg.configHome}/urlscan/config.json".source = ./files/urlscan.config.json; }; } diff --git a/modules/home-manager/accounts/email/files/urlscan.config.json b/modules/home-manager/accounts/email/files/urlscan.config.json new file mode 100644 index 0000000..961c5ce --- /dev/null +++ b/modules/home-manager/accounts/email/files/urlscan.config.json @@ -0,0 +1,54 @@ +{ + "palettes": { + "default": [ + [ "header", "white", "dark blue", "standout", "#d8d8d8", "#383838" ], + [ "footer", "white", "dark red", "standout", "#d8d8d8", "#383838" ], + [ "search", "white", "dark green", "standout", "#282828", "#f7ca88" ], + [ "msgtext", "", "", "", "", "" ], + [ "msgtext:ellipses", "light gray", "black", "bold", "#f7ca88", "#383838" ], + [ "urlref:number:braces", "light gray", "black", "bold", "#f8f8f8", "#383838"], + [ "urlref:number","yellow", "black","bold", "#f7ca88", "#383838" ], + [ "urlref:url", "white", "black", "italics", "#7cafc2", "#181818" ], + [ "url:sel", "white", "dark blue", "underline", "#7cafc2", "#383838" ] + ] + + }, + "keys": { + "/": "search_key", + "0": "digits", + "1": "digits", + "2": "digits", + "3": "digits", + "4": "digits", + "5": "digits", + "6": "digits", + "7": "digits", + "8": "digits", + "9": "digits", + "a": "add_url", + "C": "clipboard", + "c": "context", + "ctrl l": "clear_screen", + "ctrl f": "page_down", + "ctrl b": "page_up", + "d": "del_url", + "f1": "help_menu", + "G": "bottom", + "g": "top", + "j": "down", + "k": "up", + "J": "next", + "K": "previous", + "P": "clipboard_pri", + "l": "link_handler", + "o": "open_queue", + "O": "open_queue_win", + "p": "palette", + "Q": "quit", + "q": "quit", + "R": "reverse", + "S": "all_shorten", + "s": "shorten", + "u": "all_escape" + } +} From 30ebf1e5d058656f98cd99ced6fa6fc2524f29ed Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 11 Aug 2025 00:08:50 +0200 Subject: [PATCH 4/7] fix(mail): use email address suffix in inbox folder --- modules/home-manager/accounts/email/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index 13717e1..25bbde6 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -98,8 +98,8 @@ in key = ""; }) ( lib.attrsets.mapAttrsToList ( - n: _: - { "action" = "source ~/.config/neomutt/${n}=InboxUnread";} + n: c: + { "action" = "source ~/.config/neomutt/${n}Unread:${c.config.address}";} ) cfg.accountConfigs); in { enable = true; From a023323e3439192261e2d7f87d654fdc9cb6d7e9 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 11 Aug 2025 00:10:35 +0200 Subject: [PATCH 5/7] fix(mail): afew filters was never applied because misplaced --- modules/home-manager/accounts/email/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index 25bbde6..069583a 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -86,8 +86,8 @@ in [KillThreadsFilter] [ArchiveSentMailsFilter] sent_tag = sent - [InboxFilter] ${lib.concatImapStrings (p: e: "\n\n[Filter.${toString p}]\n ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "${n} = ${v}") e)}") mailFilterRules} + [InboxFilter] ''; }; programs.neomutt = let From 97051b5cc27f514c9c1d81ede97a86b70f9694a5 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 11 Aug 2025 00:17:39 +0200 Subject: [PATCH 6/7] chore(mail): rework neomutt configuration * add mailcap to handle attachment * add per-account mutt hook * remove Trash folder sync and unassign Trash for each accounts * remove `dd` keybinding * add `Ctrl+b` macro to launch urlscan --- .../home-manager/accounts/email/default.nix | 56 +++++++++++++------ .../accounts/email/files/theme.muttrc | 35 +++++++----- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index 069583a..d9c1152 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -35,9 +35,14 @@ in defaultSetting = { mbsync = { enable = true; - create = "maildir"; + create = "both"; expunge = "both"; remove = "both"; + patterns = [ + "*" + # Trash is a pain in the ass to manage with notmuch + "!Trash" + ]; }; msmtp = { enable = true; @@ -76,7 +81,7 @@ in extraConfig = '' [FolderNameFilter] folder_explicit_list = archives - folder_transforms = archives:archive + folder_transforms = archives:archived maildir_separator = / [MailMover] folders = ${lib.concatStringsSep " " (lib.unique (lib.mapAttrsToList (n: v: "${n}") mailMoverRules))} @@ -104,13 +109,15 @@ in in { enable = true; unmailboxes = true; + changeFolderWhenSourcingAccount = true; + sourcePrimaryAccount = false; editor = "nvim +/^$/ +':nohl'"; settings = { sleep_time = "1"; mbox_type = "Maildir"; header_color_partial = "yes"; duplicate_threads = "yes"; - index_format = "'%4C| %24.24?GS?%F %GS &%F? %?GR?%GR &%?GU?%GU & ??%?GA?%GA & ?%?GE?%GE & ?%?M?󰘕 %s&%s? %* %?g?  %g? %<[y?%<[m?%<[d?%9[%H:%M ]&%9[%a %d ]>&%9[%b %d ]>&%9[%m/%y ]>'"; + index_format = "'%4C| %24.24?GS?%F %GS &%F? %?GD?%GD &%?GR?%GR &%?GU?%GU & ???%?GA?%GA & ?%?GE?%GE & ?%?M?󰘕 %s&%s? %* %?g?  %g? %<[y?%<[m?%<[d?%9[%H:%M ]&%9[%a %d ]>&%9[%b %d ]>&%9[%m/%y ]>'"; sort_aux = "last-date-sent"; mail_check = "120"; hidden_tags = "inbox,unread,draft,flagged,passed,replied,signed,encrypted,attachment,sent"; @@ -131,24 +138,37 @@ in my_pager = "'  %F |  %s %* Pos: %P '"; compose_format = "' COMPOSE  %a | 󰉉 %l'"; query_command = "'${pkgs.khard}/bin/khard email --parsable --search-in-source-files %s'"; + virtual_spoolfile = "yes"; + mail_check_stats = "yes"; + mh_purge = "yes"; + mailcap_path= "${config.xdg.configHome}/neomutt/mailcap"; }; extraConfig = '' ${(builtins.readFile ./files/theme.muttrc)} charset-hook ^iso-8859-1$ cp1252 ignore * + unignore from date subject to cc bcc tags user-agent x-mailer + + # Attachment auto_view text/x-vcard text/html text/enriched text/calendar alternative_order text/html text/enriched text/plain text/* - tag-transforms "attachment" "󰁦" \ + + tag-transforms "attachment" "󰁦" \ "encrypted" "󱧈" \ "signed" "󱅞" \ "unread" "" \ "replied" "" - tag-formats "attachment" "GA" \ - "encrypted" "GE" \ - "signed" "GS" \ - "unread" "GU" \ - "replied" "GR" + tag-formats "attachment" "GA" \ + "encrypted" "GE" \ + "signed" "GS" \ + "unread" "GU" \ + "replied" "GR" + + ${lib.concatStrings (lib.attrsets.mapAttrsToList ( _: v: if lib.hasAttrByPath [ "neomuttHooks" ] v then v.neomuttHooks else "" ) cfg.accountConfigs)} + # manually source first account instead of use home-manager parameter because + # of $my_pager expansion does not work as this variable is not already set + source ${config.xdg.configHome}/neomutt/${cfg.primary} ''; binds = [ { map = [ "attach" "browser" "index" "pager" ]; key = "g"; action = "noop"; } @@ -172,12 +192,8 @@ in { map = [ "index" ]; key = "\\Ce"; action = "next-line";} { map = [ "index" ]; key = "\\Cy"; action = "previous-line";} - # Delete - { map = [ "pager" "index" ]; key = "d "; action = "noop";} - { map = [ "pager" "index" ]; key = "dd "; action = "delete-message";} - # Reply - { map =[ "pager" "index" ]; key = "R "; action = "group-reply";} + { map =[ "pager" "index" ];gkey = "R"; action = "group-reply";} # sidebar { map = [ "index" "pager" ]; key = ""; action = "sidebar-toggle-visible";} @@ -196,17 +212,15 @@ in { map = [ "index" "pager" ]; key = "\\eX"; action = "vfolder-from-query";} # generate virtual folder from query with time window - { map = [ "index" ]; key = "<"; action = "vfolder-window-backward";} - { map = [ "index" ]; key = ">"; action = "vfolder-window-forward";} { map = [ "index" "pager" ]; key = "\\CD"; action = "modify-tags";} # Editor { map = [ "editor" ]; key = ""; action = "complete-query";} - { map = [ "editor" ]; key = "^T "; action = "complete";} + { map = [ "editor" ]; key = "^T"; action = "complete";} ]; macros = [ - #Define some macros here + { map = [ "pager" ]; key = "\\CB"; action = "${pkgs.urlscan}/bin/urlscan -d -c --color true"; } ] ++ accountMacros; }; programs.mbsync = { @@ -228,5 +242,11 @@ in enable = true; }; home.file."${config.xdg.configHome}/urlscan/config.json".source = ./files/urlscan.config.json; + xdg.configFile."neomutt/mailcap".text = '' + text/html; ${pkgs.xdg-utils}/bin/xdg-open %s; nametemplate=%html + text/html; ${pkgs.w3m}/bin/w3m -I %{charset} -cols 90 -T text/html %s; copiousoutput + application/pdf; ${pkgs.xdg-utils}/bin/xdg-open %s & + image/*; ${pkgs.xdg-utils}/bin/xdg-open %s & + ''; }; } diff --git a/modules/home-manager/accounts/email/files/theme.muttrc b/modules/home-manager/accounts/email/files/theme.muttrc index e7ea68c..e3e0baa 100644 --- a/modules/home-manager/accounts/email/files/theme.muttrc +++ b/modules/home-manager/accounts/email/files/theme.muttrc @@ -1,5 +1,4 @@ # vi: ft=muttrc -# base16-mutt: base16-shell support for mutt ## Base color normal color20 default # softer, bold @@ -30,7 +29,7 @@ color index_author color20 default color index_date color20 default color index_flags color20 default color index_tag color20 default -color index_tags color20 default +color index_tags italic color08 default color index_author italic color06 default "~g !~V" color index_author color04 default "~g ~V" @@ -48,14 +47,16 @@ color index_date italic color00 color06 "~T" color index_tags italic color00 color06 "~T" color index_tag italic color00 color06 "~T" +color index_subject color01 color18 "~D" # deleted messages + color index_subject italic bold color00 default "~T (~U|~N|~O)" ## Weak -color index color01 default "~v~(~F)" # collapsed thread with flagged inside +color index color01 default "~v~(~F)" # collapsed thread with flagged inside # Selection color index italic color00 color06 "~T" # tagged messages -color index color01 color18 "~D" # deleted messages +color index default color18 "~D" # deleted messages ### Message Headers ---------------------------------------------------- @@ -77,22 +78,26 @@ color header color06 color00 "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0- # When possible, these regular expressions attempt to match http://spec.commonmark.org/ ## Weak # ~~~ Horizontal rules ~~~ -color body color08 color00 "([[:space:]]*[-+=#*~_]){3,}[[:space:]]*" -## Strong +color body color08 default "([[:space:]]*[-+=#*~_]){3,}[[:space:]]*" + # *Bold* span -color body brightcolor03 color00 "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)" +color body brightcolor03 default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)" + # _Underline_ span -color body color05 color00 "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)" +color body underline color20 default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)" + # /Italic/ span (Sometimes gets directory names) -color body color05 color00 "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)" +color body italic color20 default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)" + # ATX headers -color body color04 color00 "^[[:space:]]{0,3}#+[[:space:]].*$" -## Highlight +color body color04 default "^[[:space:]]{0,3}#+[[:space:]].*$" + # `Code` span -color body color02 color00 "(^|[[:space:][:punct:]])\`[^\`]+\`([[:space:][:punct:]]|$)" -# Indented code block -color body color02 color00 "^[[:space:]]{4,}.*$" -# URLs +color body color05 default "(^|[[:space:][:punct:]])\`[^\`]+\`([[:space:][:punct:]]|$)" + +color body bold color01 default "^(\\*[[:space:]])" + +## URI color body italic color04 color00 "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]" # Email addresses color body color06 color00 "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])" From 6ec9a0c4e5f815c9dea9471c8fa2734385b43242 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Mon, 11 Aug 2025 00:35:49 +0200 Subject: [PATCH 7/7] chore(morty): rework mail configuration --- hosts/morty/home-config.nix | 7 ++++--- modules/home-manager/accounts/email/default.nix | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hosts/morty/home-config.nix b/hosts/morty/home-config.nix index 17453be..ed063e5 100644 --- a/hosts/morty/home-config.nix +++ b/hosts/morty/home-config.nix @@ -3,10 +3,11 @@ email = { enable = true; accountConfigs = { - ubordeaux = inputs.nix-private.mail.ubordeaux; - xiemeart = inputs.nix-private.mail.xiemeart; + a = inputs.nix-private.mail.xiemeart; + b = inputs.nix-private.mail.ephase; + c = inputs.nix-private.mail.ubordeaux; }; - primary = "xiemeart"; + primary = "a"; }; application = { gnupg = { diff --git a/modules/home-manager/accounts/email/default.nix b/modules/home-manager/accounts/email/default.nix index d9c1152..0f9b089 100644 --- a/modules/home-manager/accounts/email/default.nix +++ b/modules/home-manager/accounts/email/default.nix @@ -117,7 +117,7 @@ in mbox_type = "Maildir"; header_color_partial = "yes"; duplicate_threads = "yes"; - index_format = "'%4C| %24.24?GS?%F %GS &%F? %?GD?%GD &%?GR?%GR &%?GU?%GU & ???%?GA?%GA & ?%?GE?%GE & ?%?M?󰘕 %s&%s? %* %?g?  %g? %<[y?%<[m?%<[d?%9[%H:%M ]&%9[%a %d ]>&%9[%b %d ]>&%9[%m/%y ]>'"; + index_format = "'%4C| %24.24?GS?%F %GS &%F? %?GR?%GR &%?GU?%GU & ??%?GA?%GA & ?%?GE?%GE & ?%?M?󰘕 %s&%s? %* %?g?  %g? %<[y?%<[m?%<[d?%9[%H:%M ]&%9[%a %d ]>&%9[%b %d ]>&%9[%m/%y ]>'"; sort_aux = "last-date-sent"; mail_check = "120"; hidden_tags = "inbox,unread,draft,flagged,passed,replied,signed,encrypted,attachment,sent"; @@ -193,7 +193,7 @@ in { map = [ "index" ]; key = "\\Cy"; action = "previous-line";} # Reply - { map =[ "pager" "index" ];gkey = "R"; action = "group-reply";} + { map =[ "pager" "index" ]; key = "R"; action = "group-reply";} # sidebar { map = [ "index" "pager" ]; key = ""; action = "sidebar-toggle-visible";}