From b2550155de22f34a19e99877ce79c7d8a23c9731 Mon Sep 17 00:00:00 2001 From: Cytrogen Date: Wed, 11 Mar 2026 19:22:18 -0400 Subject: [PATCH] =?UTF-8?q?feat(email):=20=E5=AE=8C=E5=96=84=20mu4e=20?= =?UTF-8?q?=E5=A4=9A=E8=B4=A6=E6=88=B7=E9=85=8D=E7=BD=AE=E5=92=8C=20HTML?= =?UTF-8?q?=20=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修正 Copyright 年份为 2026 - 加载 mu4e-autoloads 确保延迟加载正常 - 重写 context :vars 使用 list/cons 替代反引号,修复 maildir-shortcuts 显示名称缺失问题 - 添加 HTML 邮件渲染配置:shr 渲染器、图片比例限制、禁用动画 - 添加 gnus 图片安全策略:阻止追踪图片 - 启用 mu4e modeline 支持和 visual-line-mode --- config/pkg-email.el | 107 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 16 deletions(-) diff --git a/config/pkg-email.el b/config/pkg-email.el index e25e169034519810e351a579ff8f2b9fa9ef994a..067d51901a6c2d9b26aae02a7bd555d8b4491f87 100644 --- a/config/pkg-email.el +++ b/config/pkg-email.el @@ -1,6 +1,6 @@ ;;; pkg-email.el --- Email client configuration -*- lexical-binding: t -*- -;; Copyright (C) 2024 Cytrogen +;; Copyright (C) 2026 Cytrogen ;;; Commentary: @@ -32,10 +32,11 @@ ;;; mu4e Setup (延迟加载) ;;; ============================================================ -;; 添加 mu4e 路径 +;; 添加 mu4e 路径并加载 autoloads (let ((mu4e-path "/usr/share/emacs/site-lisp/mu4e")) (when (file-directory-p mu4e-path) - (add-to-list 'load-path mu4e-path))) + (add-to-list 'load-path mu4e-path) + (load "mu4e-autoloads" t t))) (with-eval-after-load 'mu4e ;; Context 生成函数 @@ -59,18 +60,19 @@ (when msg (string-prefix-p maildir-prefix (mu4e-message-field msg :maildir)))) - :vars `((user-mail-address . ,email) - (user-full-name . ,fullname) - (mu4e-sent-folder . ,(concat maildir-prefix "/" sent)) - (mu4e-drafts-folder . ,(concat maildir-prefix "/" drafts)) - (mu4e-trash-folder . ,(concat maildir-prefix "/" trash)) - (mu4e-refile-folder . ,(concat maildir-prefix "/" archive)) - (mu4e-maildir-shortcuts - . ((:maildir ,(concat maildir-prefix "/" inbox) :key ?i) - (:maildir ,(concat maildir-prefix "/" sent) :key ?s) - (:maildir ,(concat maildir-prefix "/" drafts) :key ?d) - (:maildir ,(concat maildir-prefix "/" trash) :key ?t) - (:maildir ,(concat maildir-prefix "/" archive) :key ?a))))))) + :vars (list (cons 'user-mail-address email) + (cons 'user-full-name fullname) + (cons 'mu4e-sent-folder (concat maildir-prefix "/" sent)) + (cons 'mu4e-drafts-folder (concat maildir-prefix "/" drafts)) + (cons 'mu4e-trash-folder (concat maildir-prefix "/" trash)) + (cons 'mu4e-refile-folder (concat maildir-prefix "/" archive)) + (cons 'mu4e-maildir-shortcuts + (list + (list :maildir (concat maildir-prefix "/" inbox) :key ?i :name (concat maildir-prefix "/" inbox)) + (list :maildir (concat maildir-prefix "/" sent) :key ?s :name (concat maildir-prefix "/" sent)) + (list :maildir (concat maildir-prefix "/" drafts) :key ?d :name (concat maildir-prefix "/" drafts)) + (list :maildir (concat maildir-prefix "/" trash) :key ?t :name (concat maildir-prefix "/" trash)) + (list :maildir (concat maildir-prefix "/" archive) :key ?a :name (concat maildir-prefix "/" archive)))))))) (defun my/email--setup-contexts () "Generate mu4e-contexts from `my/email-accounts'." @@ -91,6 +93,25 @@ (setq mu4e-view-show-addresses t) (setq mu4e-use-fancy-chars t) (setq mu4e-compose-dont-reply-to-self t) + (setq mu4e-modeline-support t) + + ;; HTML 渲染配置 + (setq mm-text-html-renderer 'shr) + (setq shr-use-colors t) + (setq shr-use-fonts nil) + (setq shr-max-image-proportion 0.6) + (setq shr-image-animate nil) + (setq shr-width nil) + (setq shr-discard-aria-hidden t) + (setq shr-cookie-policy nil) + + ;; Gnus 图片配置 + (setq gnus-inhibit-images nil) + (setq gnus-blocked-images ".") ; 阻止追踪图片 + + ;; 自动换行 + (add-hook 'mu4e-view-mode-hook #'visual-line-mode) + (setq mm-fill-flowed t) ;; msmtp 发送配置 (setq sendmail-program "/usr/bin/msmtp") @@ -99,8 +120,62 @@ (setq message-sendmail-f-is-evil t) (setq message-sendmail-extra-arguments '("--read-envelope-from")) + ;; 动态标记为垃圾邮件(支持所有账户) + (defun my/mu4e-mark-as-spam () + "Mark message at point as spam (move to Spam folder of current account)." + (interactive) + (let* ((ctx (mu4e-context-current)) + (ctx-name (when ctx (mu4e-context-name ctx))) + (spam-folder (cond + ((string= ctx-name "Gmail") "/Gmail/[Gmail]/Spam") + ((string= ctx-name "iCloud") "/iCloud/Junk") + ((string= ctx-name "Boo") "/Cytrogen/Junk Mail") + (t "/Gmail/[Gmail]/Spam")))) ; 默认 + (mu4e-mark-set 'move spam-folder))) + + (define-key mu4e-headers-mode-map (kbd "C-d") #'my/mu4e-mark-as-spam) + (define-key mu4e-view-mode-map (kbd "C-d") #'my/mu4e-mark-as-spam) + + ;; 垃圾邮件过滤查询 + (defvar my/spam-filter-query + (concat + "NOT flag:trashed " ; 排除已删除 + "NOT maildir:/Gmail/\\[Gmail\\]/Spam " ; 排除垃圾文件夹 + "NOT from:noreply " ; 排除无回复地址 + "NOT from:no-reply " + "NOT subject:unsubscribe " ; 排除退订相关 + "NOT subject:\"verify your\" " ; 排除验证邮件 + "NOT subject:\"confirm your\" " + "NOT subject:\"your order\" ") ; 可根据需要扩展 + "Query to filter out spam-like messages.") + + ;; 添加书签:过滤后的 inbox 视图 + (add-to-list 'mu4e-bookmarks + '(:name "Clean Inbox" + :query (lambda () + (concat "maildir:/Gmail/Inbox " + my/spam-filter-query)) + :key ?c)) + + (add-to-list 'mu4e-bookmarks + '(:name "All Inboxes (Clean)" + :query (lambda () + (concat "(maildir:/Gmail/Inbox OR " + "maildir:/iCloud/Inbox OR " + "maildir:/Cytrogen/Inbox) " + my/spam-filter-query)) + :key ?C)) + ;; 设置 contexts - (my/email--setup-contexts)) + (my/email--setup-contexts) + + ;; 修复 context 切换时 maildir shortcuts 不更新的问题 + (add-hook 'mu4e-context-changed-hook + (lambda () + (setq mu4e--maildir-items-cached nil))) + + ;; 链接点击支持 + (define-key mu4e-view-mode-map (kbd "RET") #'mu4e-view-browse-url-from-binding)) ;;; ============================================================ ;;; Interactive Commands