転載・引用について

ユーザ用ツール

サイト用ツール


userapps:emacs:mu4e

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
userapps:emacs:mu4e [2024/08/27 02:16] – [mu4e] seiriosuserapps:emacs:mu4e [2026/01/06 04:05] (現在) – [mu4e] seirios
行 317: 行 317:
   * 送信サーバーは、メールのFromフィールドを見て自動で決定するようにした   * 送信サーバーは、メールのFromフィールドを見て自動で決定するようにした
  
-まぁ、色々なところから色々設定持ってきたり、Perplexityのお世話になったりしてます。+まぁ、色々なところから色々設定持ってきたり、PerplexityやMS copilotのお世話になったりしてます。
 難しいcodeは書いてないから、コメント見ながら読めばわかると思いたい。 難しいcodeは書いてないから、コメント見ながら読めばわかると思いたい。
 というかわかるということにします。 というかわかるということにします。
- 
-あと、これだけでかいと leaf に書き換えるのは面倒くさい... 
  
 <code - mu4e-init.el> <code - mu4e-init.el>
-;;;;  .emacs.d/mu4e-init.el +;;; -*- lexical-binding: t-*- 
-;;;; mu4e configuration +;;; ~/.config/emacs/mu4e-init.el 
-;;;; +;;; 
-;;;; last updated: 2024/08/26 +;;; last updated: 2026/01/02 
-;;;; Author: HEO SeonMeyong <seirios@seirios.org>+;;; Author: HEO SeonMeyong <seirios@seirios.org> 
 +;;;         Microsoft Copilot (Rewrite and support leaf)
  
-;;; Require packages upfront +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu/mu4e/") +;;; Tips 
-(require 'mu4e) mu4e +;;; * Create new refile folder 
-;; (require 'mu4e-speedbar) Speedbar +;;;   $ mkdir -p ~/Maildir/[Mailbox]/some/where/{new,cur/tmp} 
-(require 'smtpmail) Compose and send+;;;   $ chmod -R 700 ~/Maildir/[Mailbox]/some/where/{new,cur/tmp} 
 +;;;   $ mbsync -
 +;;;   $ mu index 
 +;;;   * 要するに、正しいpermissionで正しくFolder(Directory)を作成してmbsyncで同期してindexを張ればOK 
 +;;  * 逆に削除はDirectoryごと全部削除すればよさそう
  
-;;; Debugging +;;; Informations(Links) 
-;; (setq mu4e-mu-debug t) for mu debbuging +;;; * https://www.djcbsoftware.nl/code/mu/mu4e/HV-Custom-headers.html
-;; (setq mu4e-debug t) ; for mu4e debugging+
  
-;;; for mu4e general settings +;;; 定義・機能一覧: 
-;; external Binaries. +;;;  - my/which: Homebrew と環境 PATH の両方で実行ファイルを探索するヘルパー 
-(setq mu4e-get-mail-command (concat (executable-find "mbsync") " -a")) ; this command is called to sync imap servers +;;;  - my-mu4e-update-mail-and-index-async: 非同期 mbsync + mu index 
-(setq mu4e-mu-binary (executable-find "mu")) ; mu binary filename. Installed by HomeBrew. +;;;  my/mu4e-start-background-update: タイマーで定期バックグラウンド更新開始 
-(setq sendmail-program (executable-find "msmtp")) send Email program+;;;  - my/mu4e-stop-background-update: タイマー停止 
 +;;;  - キーバインド: U → 非同期更新 (mu4e メインビュー/ヘッダビュー) 
 +;;;  - ポリシー: 起動時自動更新は無効・インデックス更新は常にバックグラウンド 
 +;;; 
 +;;; よく調整するパラメータ (本ファイル内のコメントを検索してください): 
 +;;;  * 定期更新間隔分: (my/mu4e-start-background-update 30 30分 
 +;;;  * mbsync/mu/msmtp のパス探索候補: my/which の引数リスト 
 +;;;  * mu4e-context-policy / mu4e-compose-context-policy: 
 +;;;     'pick-first / 'ask / 'ask-if-none / nil 
 +;;;  * mu4e-headers-results-limit: ヘッダの最大取得件数 (性能/読みやすさのトレードオフ) 
 +;;;  * display-buffer-alist: 本文ビューを右側へ固定表示するウィンドウ設定 
 +;;; ----------------------------------------------------------------------
  
-;; Directories. +;;; 小さなユーティリティ(実行ファイル探索と簡易コンテキスト生成) 
-(setq mu4e-maildir "~/Maildir") ; this is the directory we created before. +(defun my/which (&rest candidates
-(setq mu4e-attachment-dir "~/Desktop") ; save attachment to desktop+  "CANDIDATES のうち、最初に見つかった実行ファイルの絶対パスを返す。ない場合は nil。 
 +候補は、絶対パス文字列とコマンド名の混在でよい。 
 +絶対パスが渡された場合: 実行可能ならそのパスを返す 
 +コマンド名が渡された場合: `executable-find` で PATH 上を探索する
  
-;; Manipulate mails +例: 
-(setq mu4e-change-filenames-when-moving t) ; rename files when moving - needed for mbsync + (my/which \"/usr/local/bin/mbsync\" \"/opt/homebrew/bin/mbsync\" \"mbsync\")" 
-(setq mu4e-update-interval (* 10 60)) ; how often to call it in seconds+  (seq-some (lambda (c) 
 +              (cond 
 +               ((file-name-absolute-p c) (and (file-executable-p c) c)) 
 +               (t (executable-find c)))) 
 +            candidates))
  
-;; overall behavivior +(defun my/mk-context (name maildir-prefix email &optional signature
-(setq mu4e-confirm-quit nil) ; don't have to confirm when quitting +  "mu4e 用コンテキストを簡潔に生成する。 
-(setq mu4e-modeline-show-global t) ; mu4e shares information on the modeline +NAME は識別名、MAILDIR-PREFIX は \"/XXXX\形式、EMAIL は送信元。 
-(add-hook 'mu4e-headers-search-hook +SIGNATURE を与えると `message-signatureを設定する。
-  (lambda (query) +
-    (setq-local global-mode-string +
-      '(:eval +
-        (concat +
-          (mu4e-context-label) +
-          " " +
-          (propertize +
-            (mu4e~quote-for-modeline mu4e~headers-last-query) +
-            'face 'mu4e-modeline-face +
-            'help-echo (format "%s" mu4e~headers-last-query))))))) +
-(setq mu4e-modeline-max-width 100) ; Change mu4e modeline to 100 chars +
-(setq mode-name "mu4e-headers") ; Add mode name to modeline +
-(add-hook 'mu4e-headers-search-hook +
-  (lambda (query) +
-    (setq mode-name "mu4e"))) +
-(setq mu4e-split-view "vertical") ; Split-View. Using with display-buffer-alist +
-(add-to-list 'display-buffer-alist ; for Body-view window +
-             `(,(regexp-quote mu4e-view-buffer-name) +
-               display-buffer-in-side-window +
-               (side . right) +
-               (window-width . 0.5))) +
-(setq mu4e-hide-index-messages t) ; hide annoying "mu4e Retrieving mail..." msg in mini buffer +
-(setq mu4e-context-policy 'pick-first) ; start with the first (default) context. (pick-first, ask, ask-if-none, nil)+
  
-;; headers-view +例: 
-(setq mu4e-headers-include-related nil) ; by default do not show related emails + (my/mk-context \"1seirios_seirios\" \"/seirios_seirios\" \"seirios@seirios.org\" \"=====\nHEO ...\")" 
-(setq mu4e-headers-results-limit 5000) ; Limit of message view search results. default is 500 +  (make-mu4e-context 
-(setq mu4e-headers-show-threads t) ; by default do not show threads +   :name name 
-(setq mu4e-headers-date-format "%Y-%m-%dT%H:%M:%S") ; Header's time format. +   :enter-func (lambda () (mu4e-message (format "Enter %s context" email))
-(setq mu4e-headers-fields ; Show headers list -- field and width(nil means unlimited+   :leave-func (lambda () (mu4e-message (format "Leave %s contextemail))
-      '( (:date           20) ; alternativelyuse :human-date +   :match-func (lambda (msg) 
-         (:flags           6) ; Mail flags +                 (when msg 
-         (:from           20) ; From field +                   (string-prefix-p maildir-prefix 
-         (:to             20) ; To field +                                    (mu4e-message-field msg :maildir)))
-         (:subject        nil))) ; alternatively, use :thread-subject+   :vars (append 
 +          `((user-mail-address . ,email) 
 +            (user-full-name   . "HEO SeonMeyong"
 +            (mu4e-drafts-folder ,(concat maildir-prefix "/Drafts")
 +            (mu4e-sent-folder   ,(concat maildir-prefix "/Sent")
 +            (mu4e-trash-folder  . ,(concat maildir-prefix "/Trash"))) 
 +          (when signature 
 +            `((message-signature . ,signature))))))
  
-;; Body-view 
-;; prefer text messages. 
-(with-eval-after-load "mm-decode" 
-  (add-to-list 'mm-discouraged-alternatives "text/html") 
-  (add-to-list 'mm-discouraged-alternatives "text/richtext")) 
-(setq mu4e-view-date-format "%Y-%m-%dT%H:%M:%S") 
-(setq mu4e-view-fields '(:from ; From field 
-                         :to ; To field 
-                         :cc ; Cc field 
-                         :subject ; Subject field 
-                         :flags ; Mail flags 
-                         :date ; Date field(maybe send date and time) 
-                         :maildir ; maildir information 
-                         :mailing-list ; Mailing list field 
-                         :tags ; Tags 
-                         :attachments ; Attachment information 
-                         :signature ; Message signature 
-                         :decryption ; Decryption 
-                         :message-id ; Message-ID 
-                         :path ; Mail stored directory 
-                         :user-agent ; User agent information 
-                         )) 
  
-;; Draft and Compose +;;;; mu4e のロードパスを動的に追加(Intel / Apple Silicon 両対応) 
-(setq mu4e-compose-context-policy 'ask-if-none) ; ask for context if no context matches.(pick-first, ask, ask-if-none, nil+(dolist (cand '("/usr/local/share/emacs/site-lisp/mu/mu4e/" 
-(setq mu4e-compose-signature-auto-include nil) ; Signature auto include when composed +                "/opt/homebrew/share/emacs/site-lisp/mu/mu4e/")
-(defvaralias 'mu4e-compose-signature 'message-signature) ; Use signature variables. +  (when (file-directory-p cand
-(setq message-citation-line-format "%N @ %Y-%m-%d %H:%M:%S :\n") ; customize the reply-quote-string: +    (add-to-list 'load-path cand)))
-(setq message-citation-line-function 'message-insert-formatted-citation-line) +
- ; M-x find-function RET message-citation-line-format for docs+
  
-;; Sending mails +;;;; 起動時の自動更新を制御するトグル 
-(setq mail-user-agent 'mu4e-user-agent) Use mu4e for e-mail in emacs +;; Toggle for legacy mu4e auto-update (built-in interval & startup hook) 
-(setq send-mail-function 'sendmail-send-it +; - When t: mu4e の定期更新 (`mu4e-update-interval`) を使う 
-      message-send-mail-function 'sendmail-send-it) ; Reconfigure Email send function +;;  When nil: 組み込みの auto update は無効にして、代わりに自作タイマーを使う 
-(setq message-kill-buffer-on-exit t) ; don'keep message compose buffers around after sending: +(defvar my/mu4e-auto-update t 
-(setq message-sendmail-envelope-from 'header) ; select the right sender email from the context.+  "mu4eの組み込み自動更新を使うなら t。nil なら起動時/定期更新とも無効。")
  
-;; Additional supports +(leaf mu4e 
-(setq mu4e-eldoc-support t) get info about the current header in the echo-area. +  :load-path "/usr/local/share/emacs/site-lisp/mu/mu4e/" ; Homebrew の mu4e パス 
-(add-hook 'mu4e-compose-mode-hook 'company-mode) ; mu4e address completion +  :require t 
-(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) ; attach files to mu4e messages using dired. See info "13.9 Dired"+  :preface 
 +  ;; MIMEのHTML等を抑止(ロード前定義でOK) 
 +  ;; これにより本文表示は極力 text/plain を優先する。 
 +  (with-eval-after-load "mm-decode" 
 +    (add-to-list 'mm-discouraged-alternatives "text/html"
 +    (add-to-list 'mm-discouraged-alternatives "text/richtext"))
  
-;;; Personal environment/Variables +  :custom 
-;;; Contexts +  ;; ---- 全体動作/UI系をまとめて :custom で設定 ---- 
-(setq mu4e-contexts +  ;; インデックス更新は常にバックグラウンドで(UIフリーズを避ける) 
-      (list +  ((mu4e-index-update-in-background . t)  ; Run mu index update asynchronously to avoid UI blocking 
-       ;; sample@example.com +   ;; Maildir と添付保存先 
-       (make-mu4e-context +   (mu4e-maildir . "~/Maildir") 
-        :name "sample_example" +   (mu4e-attachment-dir . "~/Desktop"
-        :match-func (lambda (msg+   ;; mbsync でメール移動時、ファイル名を変更(重複衝突などを回避) 
-                      (when msg +   (mu4e-change-filenames-when-moving . t
-                        (string-prefix-"/sample_example" (mu4e-message-field msg :maildir)))+   ;; 終了確認やモードライン表示 
-        :vars '((user-mail-address  "sample@example.com" +   (mu4e-confirm-quit nil
-                (user-full-name     "dovecot sample"+   (mu4e-modeline-show-global t
-                (mu4e-drafts-folder "/sample_example/Drafts"+   (mu4e-modeline-max-width 100
-                (mu4e-sent-folder   . "/sample_example/Sent") +   ;; 表示:本文ビューを右側へ固定(display-buffer-alist 併用) 
-                (mu4e-trash-folder  "/sample_example/Trash"+   (mu4e-split-view . "vertical") 
-                )) +   ;; ミニバッファに出る「Retrieving…」などの雑音を極力隠す 
-       ;; sample@icloud.com +   (mu4e-hide-index-messages t
-       (make-mu4e-context +   ;; コンテキストの選択ポリシー(起動時は最初を採用) 
-        :name "sample_icloud" +   (mu4e-context-policy . 'pick-first) 
-        :match-func (lambda (msg+   ;; ヘッダ表示系(関連メッセージ非表示、結果上限、スレッド表示等) 
-                      (when msg +   (mu4e-headers-include-related . nil) 
-                        (string-prefix-"/sample_icloud" (mu4e-message-field msg :maildir)))) +   (mu4e-headers-results-limit . 5000
-        :vars '((user-mail-address  . "sample@icloud.com") +   (mu4e-headers-show-threads . t) 
-                (user-full-name     "iCloud example"+   (mu4e-headers-date-format . "%Y-%m-%dT%H:%M:%S"
-                (mu4e-drafts-folder "/sample_icloud/Drafts"+   (mu4e-headers-fields 
-                (mu4e-sent-folder   . "/sample_icloud/Sent"+    . '((:date . 20(:flags . 6(:from . 16(:to . 16(:subject . nil))) 
-                (mu4e-trash-folder  "/sample_icloud/Trash"+   ;; 本文ビューのフィールド 
-                )) +   (mu4e-view-date-format . "%Y-%m-%dT%H:%M:%S") 
-       ;; sample@gmail.com +   (mu4e-view-fields 
-       (make-mu4e-context +    . '(:from :to :cc :subject :flags :date :maildir :mailing-list 
-        :name "sample_gmail+              :tags :attachments :signature :decryption :message-id 
-        :enter-func (lambda () (mu4e-message "Enter sample@gmail.com context")+              :path :user-agent)) 
-        :leave-func (lambda () (mu4e-message "Leave sample@gmail.com context")+   ;; Compose 時のコンテキスト選択ポリシー(マッチしなければ確認) 
-        :match-func (lambda (msg+   (mu4e-compose-context-policy 'ask-if-none
-                      (when msg +   ;; 署名の自動挿入は無効(コンテキストで signature を持つもののみ) 
-                        (string-prefix-p "/sample_gmail" (mu4e-message-field msg :maildir)))+   (mu4e-compose-signature-auto-include nil
-        :vars '((user-mail-address "sample@gmail.com") +   ;; 送信系(mu4e を使い、sendmail 経由で送る) 
-                (user-full-name     . "Gmail sample") +   (mail-user-agent . 'mu4e-user-agent) 
-                (mu4e-drafts-folder . "/sample_gmail/Drafts") +   (send-mail-function 'sendmail-send-it
-                (mu4e-sent-folder   . "/sample_gmail/Sent") +   (message-send-mail-function 'message-send-mail-with-sendmail
-                (mu4e-trash-folder "/sample_gmail/Trash") +   (message-kill-buffer-on-exit . t) 
-                )) +   (message-sendmail-envelope-from . 'header
-       ))+   ;; 既定ブックマーク(InboxやSPAMなどショートカット検索) 
 +   (mu4e-bookmarks 
 +    . '((:name "Unread messages :query "flag:unread AND NOT flag:trashed" :favorite t :key ?u) 
 +        (:name "seirios.seirios"  :query "maildir:/seirios_seirios/Inbox"   :favorite t :key ?1) 
 +        (:name "sheo.seirios    :query "maildir:/sheo_seirios/Inbox"      :favorite t :key ?2
 +        (:name "mls.seirios"      :query "maildir:/mls_seirios/Inbox"       :favorite t :key ?3) 
 +        (:name "seirios.icloud  :query "maildir:/seirios_icloud/Inbox"    :favorite t :key ?4
 +        (:name "sheo0147.yahoo"   :query "maildir:/sheo0147_yahoo/Inbox"    :favorite t :key ?5
 +        (:name "seirios.RRcom"    :query "maildir:/seirios_RRcom/Inbox"     :favorite t :key ?6) 
 +        (:name "seirios.RRnet"    :query "maildir:/seirios_RRnet/Inbox    :favorite t :key ?7) 
 +        (:name "sheo0147.gmail"   :query "maildir:/sheo0147_gmail/Inbox"    :favorite t :key ?8
 +        (:name "seirios.wm.gmail" :query "maildir:/seirios.wm_gmail/Inbox :favorite t :key ?9
 +        (:name "seirios.silanui :query "maildir:/seirios_silanui/Inbox"   :favorite t :key ?0
 +        (:name "SPAM/UCE" 
 +         :query "maildir:/seirios_seirios/Spam OR maildir:/sheo_seirios/Spam OR maildir:/mls_seirios/Spam OR maildir:/seirios_icloud/Spam OR maildir:/sheo0147_yahoo/Spam OR maildir:/seirios_RRcom/Spam OR maildir:/seirios_RRnet/Spam OR maildir:/sheo0147_gmail/Spam OR maildir:/seirios.wm_gmail/Spam OR maildir:/seirios_silanui/Spam" 
 +                                                                           :favorite t :key ?s) 
 +        (:name "Trash" 
 +         :query "maildir:/seirios_seirios/Trash OR maildir:/sheo_seirios/Trash OR maildir:/mls_seirios/Trash OR maildir:/seirios_icloud/Trash OR maildir:/sheo0147_yahoo/Trash OR maildir:/sheo0147_gmail/Trash OR maildir:/seirios_RRnet/Trash OR maildir:/seirios_RRcom/Trash OR maildir:/seirios.wm_gmail/Trash OR maildir:/seirios_silanui/Trash" 
 +                                                                           :favorite t :key ?t))
 +   ;; Maildir ショートカット(ジャンプキー) 
 +   (mu4e-maildir-shortcuts 
 +    '( 
 +        (:maildir "/seirios_seirios/UT                      :name "UT"       :key ?u
 +        (:maildir "/seirios_seirios/ISII                    :name "ISII"     :key ?i
 +        (:maildir "/seirios_seirios/silanui"                  :name "しらぬい" :key ?s) 
 +        (:maildir "/seirios_seirios/NCom"                     :name "NCom"     :key ?n
 +        (:maildir "/seirios_seirios/NTT-MM"                   :name "N-MM"     :key ?m) 
 +        (:maildir "/seirios_RRnet/Rookie"                     :name "Rookie"   :key ?r)
  
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +        (:maildir "/seirios_seirios/Finance                 :name "Fin     :key ?F
-;;; Bookmarks +        (:maildir "/seirios_seirios/WIDE                    :name "WIDE    :key ?W
-(setq mu4e-bookmarks ""+        (:maildir "/seirios_seirios/Logs                    :name "Logs    :key ?L
-(setq mu4e-bookmarks +        (:maildir "/seirios_seirios/Logs/ShadowServer       :name "影鯖    :key ?S
-      '( +        (:maildir "/seirios_seirios/Logs/DMARC              :name "DMARC   :key ?D)
-        ( :name  "Unread messages" +
-          :query "flag:unread AND NOT flag:trashed" +
-   :favorite t +
-          :key ?u+
-        ( :name  "Inbox - sample@example" +
-          :query "maildir:/sample_example/Inbox" +
-   :favorite t +
-          :key ?1+
-        ( :name "Inbox - sample.icloud" +
-          :query "maildir:/sample_icloud/Inbox" +
-   :favorite t +
-          :key ?2) +
-        ( :name "Inbox - sample.yahoo" +
-          :query "maildir:/sample_yahoo/Inbox" +
-   :favorite t +
-          :key ?3+
-        ( :name "Inbox - sample.gmail" +
-          :query "maildir:/sample_gmail/Inbox" +
-   :favorite t +
-          :key ?4) +
-        :name "SPAM/UCE" +
-          :query "maildir:/sample_example/Spam OR maildir:/sample_icloud/Spam OR maildir:/sample_gmail/Spam OR maildir:/sample_yahoo/Spam" +
-   :favorite t +
-          :key ?s+
-        ( :name "Trash" +
-          :query "maildir:/sample_example/Trash OR maildir:/sample_icloud/Trash OR maildir:/sample_gmail/Trash OR maildir:/sample_yahoo/Trash" +
-   :favorite t +
-          :key ?t) +
-        ( :name "Today's messages" +
-          :query "date:today..now" +
-   :favorite t +
-          :key ?T) +
-        ))+
  
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +        (:maildir "/seirios_seirios/Individual/Personal"      :name "個人"     :key ?P) 
-;;; Maildir Shortcuts +        (:maildir "/seirios_seirios/Individual/Family       :name "家族    :key ?f) 
-(setq mu4e-maildir-shortcuts ;; Set IMAP Sub-directories... +        (:maildir "/seirios_seirios/Individual/Game"          :name "Game    :key ?G) 
-      '( +        (:maildir "/seirios_seirios/Individual/Services     :name "Service"  :key ?P
- (:maildir "/sample_icloud/Finamce                  :name "Fin      :key ?f) +        (:maildir "/seirios_seirios/Activity/JNSA           :name "JNSA    :key ?J
- (:maildir "/sample_icloud/Game"                      :name "Game"      :key ?g+        (:maildir "/seirios_seirios/Activity/ISC2           :name "ISC     :key ?I
- (:maildir "/sample_gmail/MyDiv                     :name "MyDiv    :key ?d+        (:maildir "/seirios_seirios/Activity/GitHub         :name "GHUB    :key ?g
- (:maildir "/sample_gmail/Logs                      :name "Logs     :key ?l+        (:maildir "/seirios_seirios/Activity/ISOG-J         :name "ISOG    :key ?j
- (:maildir "/sample_yahoo/Agent                     :name "Agent    :key ?a+        ;; 以下は「一覧に見せるため」の要素。:key がないものはジャンプキー無し。 
- (:maildir "/sample_example/Family                  :name "Fam      :key ?f+        (:maildir "/seirios_seirios/ISII/GA"
- ))+        (:maildir "/seirios_seirios/Individual"
 +        (:maildir "/seirios_seirios/Individual/Tech"
 +        (:maildir "/seirios_seirios/Individual/UnivD2"
 +        (:maildir "/seirios_seirios/Activity"
 +        (:maildir "/seirios_seirios/Activity/ISACA"
 +        (:maildir "/seirios_seirios/Olds"
 +        (:maildir "/seirios_RRnet/Olds"
 +        (:maildir "/seirios_seirios/Trash"
 +        (:maildir "/seirios_icloud/Trash"
 +        (:maildir "/sheo0147_yahoo/Trash"
 +        (:maildir "/sheo0147_gmail/Trash"
 +        (:maildir "/seirios_RRnet/Trash"
 +        (:maildir "/sheo_seirios/Trash"
 +        (:maildir "/seirios_RRcom/Trash"
 +        (:maildir "/seirios_silanui/Trash"
 +        (:maildir "/seirios.wm_gmail/Trash"
 +        (:maildir "/mls_seirios/Trash"))))
  
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +  :config 
-;;; Refile rules +  ;; ---- 実行ファイルの場所を自動検出(Homebrew/Path両対応)---- 
-(makunbound 'my-mu4e-refile-rules) +  ;; mu/msmtp の実行パスは GUI 起動時(PATHが引き継がれないケース)でも見つかるよう、 
-(defvar my-mu4e-refile-rules +  ;; 絶対パス候補 → PATH の順に探索します。 
-  '( +  (setq mu4e-mu-binary   (my/which "/usr/local/bin/mu    "/opt/homebrew/bin/mu    "mu")
-    ;; === Financial +  (setq sendmail-program (my/which "/usr/local/bin/msmtp "/opt/homebrew/bin/msmtp "msmtp"))
-    ("/sample_icloud/Finamce" "from" "foobank\\.co\\.jp$") +
-    ("/sample_icloud/Finamce" "from" "barbank\\.co\\.jp$"+
-    ("/sample_icloud/Finamce" "from" "bazcard\\.co\\.jp$"+
-    ("/sample_icloud/Finamce" "from" "hogepoint\\.jp$"+
-    ;; === Game +
-    ("/sample_icloud/Game" "from" "ninnin\\.\\(com\\|net\\|co\\.jp\\)$"+
-    ("/sample_icloud/Game" "from" "FourToKnight@mail\\.epicgames\\.com$"+
-    ;; === MyDiv +
-    ("/sample_gmail/MyDiv" "from" "sample@gmail\\.com$"+
-    ;; === Log +
-    ("/sample_gmail/Logs" "to" "log@example\\.com$"+
-    ("/sample_gmail/Logs" "to" "log@gmail\\.com$"+
-    ("/sample_gmail/Logs" "from" "^root@") +
-    ("/sample_gmail/Logs" "subj" "^Cron"+
-    ("/sample_gmail/Logs" "subj" "run\\.output$"+
-    ;; === Agent +
-    ("/sample_yahoo/Agent" "to" "sample+agent@\\(yahoo\\.co\\.jp\\|example\\.com\\)"+
-    ;; === Family +
-    ("/sample_example/Family" "from" "wife@foo\\.jp$"+
-    ("/sample_example/Family" "from" "son@bar\\.ac\\.jp$") +
-    ) +
-  "List of (refile-folder field regex) triples for refiling. +
-Field can be 'to', 'cc', 'bcc', 'rcpt', 'from', 'subject', 'any', 'msgid' or 'list' for mailing lists.")+
  
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +  ;; メールを取得するための設定 
-;;; Personal functions +  (with-eval-after-load 'mu4e 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +    ;; U(取得)で使うコマンドは常に設定しておく(スマートラッパーを使わない場面向け互換) 
-;;; Select SMTP account from from header at composed email +    (let ((mbsync (my/which "/usr/local/bin/mbsync" "/opt/homebrew/bin/mbsync" "mbsync"))) 
-(defun my-mu4e-set-msmtp-account () ; chose from account before sending +      (setq mu4e-get-mail-command (and mbsync (concat mbsync " -a"))))  Keep string form for compatibility (some commands read this variable) 
-  (if (message-mail-p)+ 
 +    ;; 起動時/定期の自動を使うかはトグルで制御 
 +    (if my/mu4e-auto-update 
 +        (progn 
 +          ;; 自動更新ON: mu4e の built-in interval を有効化(起動時フックも既定動作) 
 +          (setq mu4e-update-interval (* 10 60))  10分(任意で変更) 
 +          ;; 既定の起動時更新フックは mu4e が勝手に登録するため、ここでは何もしない 
 +          ) 
 +      ;; 自動更新OFF: built-in interval を止め、起動時の更新フックも外す 
 +      (setq mu4e-update-interval nil) 
 +      (remove-hook 'mu4e-main-mode-hook #'mu4e-update-mail-and-index) 
 +      ;; U で取得したいので mu4e-get-mail-command は nil にしない(上で保持) 
 +      ) 
 + 
 +    ;; ビューの分割(本文は右側へ表示) 
 +    (add-to-list 'display-buffer-alist 
 +                 `(,(regexp-quote mu4e-view-buffer-name) 
 +                   display-buffer-in-side-window 
 +                   (side . right) (window-width . 0.5))) 
 + 
 +    ;; モードライン名の微調整(ヘッダ検索中は短く) 
 +    (setq mode-name "mu4e-headers"
 +    (add-hook 'mu4e-headers-search-hook (lambda (_q) (setq mode-name "mu4e"))) 
 + 
 +    ;; ---- コンテキスト(簡潔化)---- 
 +    ;; 複数アカウント構成(各 :vars で Drafts/Sent/Trash を設定) 
 +    (setq mu4e-contexts 
 +          (list 
 +           (my/mk-context "1seirios_seirios"  "/seirios_seirios"  "seirios@seirios.org" 
 +                          (concat "=====\n" "HEO SeonMeyong")) 
 +           (my/mk-context "2sheo_seirios"     "/sheo_seirios"     "sheo@seirios.org"
 +           (my/mk-context "3mls_seirios"      "/mls_seirios"      "mls@seirios.org"
 +           (my/mk-context "4seirios_icloud"   "/seirios_icloud"   "seirios@mac.com"
 +           (my/mk-context "5sheo0147_yahoo"   "/sheo0147_yahoo"   "sheo0147@yahoo.co.jp"
 +           (my/mk-context "6seirios_RRcom"    "/seirios_RRcom"    "seirios@rusty-raven.com"
 +           (my/mk-context "7seirios_RRnet"    "/seirios_RRnet"    "seirios@rusty-raven.net"
 +           (my/mk-context "8sheo0147_gmail"   "/sheo0147_gmail"   "sheo0147@gmail.com"
 +           (my/mk-context "9seirios.wm_gmail" "/seirios.wm_gmail" "seirios.wm@gmail.com"
 +           (my/mk-context "0seirios_silanui"  "/seirios_silanui"  "seirios@silanui.com"))) 
 + 
 +    ;; ---- Refile ルール(データ駆動)---- 
 +    ;; ルールは (FOLDER FIELD REGEX) のリスト。 
 +    ;; FIELD は 'to'/'cc'/'bcc'/'rcpt'/'from'/'subj'/'msgid'/'list'/'any' が指定可能。 
 +    ;; `my-mu4e-refile-message` は、MSG に適用して最初にマッチした folder を返す。 
 +    (defvar my-mu4e-refile-rules 
 +      '(("/seirios_seirios/ISII"                "rcpt" "redmine@interlink\\.or\\.jp$"
 +        ("/seirios_seirios/Olds/NTT-Myanmar"    "rcpt" "cnip@ml\\.ntt\\.com"
 +        ("/seirios_seirios/Olds/KDS"            "rcpt" "support@zscaler\\.com$"
 +        ("/seirios_seirios/Olds/KDS"            "rcpt" "zsc-support@kddi-dsec\\.com$"
 +        ("/seirios_seirios/Olds/KDS"            "from" "do-not-reply@kds\\.seirios\\.org$"
 +        ("/seirios_seirios/Olds/KDS"            "rcpt" "zsc-support@k-evolva\\.com$"
 +        ("/seirios_seirios/Activity/GitHub"     "to"   "seirios\\+gh@seirios\\.org"
 +        ("/seirios_seirios/Logs/DMARC"          "from" "noreply-dmarc-support@google\\.com$"
 +        ("/seirios_seirios/Logs/DMARC"          "from" "dmarcreport@microsoft\\.com$"
 +        ("/seirios_seirios/Logs/DMARC"          "from" "reporting@dmarc25\\.jp$"
 +        ("/seirios_seirios/Logs/DMARC"          "from" "noreply@dmarc\\.yahoo\\.com$"
 +        ("/seirios_seirios/Logs/DMARC"          "from" "dmarc_support@corp\\.mail\\.ru$"
 +        ("/seirios_seirios/Logs/DMARC"          "from" "dmarc-reports@lolipop\\.jp$"
 +        ("/seirios_seirios/Logs/ShadowServer"   "from" "@shadowserver\\.org$"
 +        ("/seirios_seirios/Logs"                "to"   "mgmt\\.seirios\\.org$"
 +        ("/seirios_seirios/Logs"                "to"   "mgmt\\.rookie-inc\\.com$"
 +        ("/seirios_seirios/Logs"                "from" "^root@"
 +        ("/seirios_seirios/Logs"                "from" "^www@bbf-wb"
 +        ("/seirios_seirios/Logs"                "subj" "^Cron"
 +        ("/seirios_seirios/Logs"                "subj" "run\\.output$"
 +        ("/seirios_seirios/Individual/Game"     "from" "nintendo\\.(com|net|co\\.jp)$"
 +        ("/seirios_seirios/Individual/Game"     "from" "fortnite@mail\\.epicgames\\.com$"
 +        ("/seirios_seirios/Individual/Game"     "from" "familysafety@microsoft\\.com$"
 +        ("/seirios_seirios/Finance"             "from" "smbc\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "tokyostarbank\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "surugabank\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "mizuhobank\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "japannetbank\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "paypay-bank\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "sevenbank\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "nicos\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "jaccs\\.co\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "viewsnet\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "jrepoint\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "vpass\\.ne\\.jp$"
 +        ("/seirios_seirios/Finance"             "from" "paypal\\.com$"
 +        ("/seirios_seirios/Finance"             "from" "credit\\.orix\\.co\\.jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "amazon\\..co\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "uqmobile\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "auction-master@mail\\..yahoo\\..co\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "payment-master@mail\\..yahoo\\..co\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "ana\\..co\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "member@point\\..recruit\\..co\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "iijmio\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "booking\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "Apple\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "banggood\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "lambdanote\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "community_cycle_info@docomo-cycle\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "connpass\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "dropbox\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "ebay\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "evernote\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "fiberjp\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "gandi\\..net$"
 +        ("/seirios_seirios/Individual/Services" "from" "icloud\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "sakura\\..ad\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "mydocomo\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "suicainternetservice\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "@interlink\\..or\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "flets\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "itunes\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "makuake\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "macdvdripperpro\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "omnigroup\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "eki-net\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "cloudsign\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "biccamera\\..com$"
 +        ("/seirios_seirios/Individual/Services" "from" "morisawa\\..co\\..jp$"
 +        ("/seirios_seirios/Individual/Services" "from" "kuronekoyamato\\..co\\..jp$"
 +        ("/seirios_seirios/WIDE"                "msgid" "wide\\.ad\\.jp"
 +        ("/seirios_seirios/WIDE"                "subj" "^\\[(wide|two-core|two|ixp-ops|irc-wg|dns) ") 
 +        ("/seirios_seirios/WIDE"                "rcpt" "as2500@nspixp\\.wide\\.ad\\.jp"
 +        ("/seirios_seirios/WIDE"                "rcpt" "(ixp|lens-wg)@wide\\.ad\\.jp"
 +        ("/seirios_seirios/Activity/ISC2"       "from" "/@isc2\\.org$"
 +        ("/seirios_seirios/Activity/JNSA"       "list" "jnsa\\.org$"
 +        ("/seirios_seirios/Activity/ISOG-J"     "list" "member\\.isog-j\\.org$"
 +        ("/seirios_seirios/Activity/ISC2"       "from" "isc2\\.org$"
 +        ("/seirios_seirios/Activity/ISC2"       "from" "isc2chapter\\.jp$"
 +        ("/seirios_seirios/Spam"                "from" "nikkeibp\\.(co\\.jp|com)$"
 +        ("/seirios_seirios/Spam"                "from" "itmedia\\.jp$"
 +        ("/seirios_seirios/Spam"                "from" "info@twitter\\.com"))) 
 +    (defun my-mu4e-refile-message (msg) 
 +      "ルールに基づき MSG のリファイル先を返す。未マッチなら nil。 
 +- 'any は to/cc/bcc/from の全てに対して正規表現判定を行う 
 +- 'rcpt は to/cc/bcc の受信側集合で判定" 
 +      (cl-loop for (folder field regex) in my-mu4e-refile-rules 
 +               for addresses = (pcase field 
 +                                 ("any"  (append (mu4e-message-field msg :to) 
 +                                                 (mu4e-message-field msg :cc) 
 +                                                 (mu4e-message-field msg :bcc) 
 +                                                 (mu4e-message-field msg :from))) 
 +                                 ("rcpt" (append (mu4e-message-field msg :to) 
 +                                                 (mu4e-message-field msg :cc) 
 +                                                 (mu4e-message-field msg :bcc))) 
 +                                 ("subj"  (list  (mu4e-message-field msg :subject))) 
 +                                 ("msgid" (list  (mu4e-message-field msg :msgid))) 
 +                                 ("list"  (list  (mu4e-message-field msg :list))) 
 +                                 (_      (mu4e-message-field msg (intern (concat ":" field))))) 
 +               when (seq-some (lambda (addr) 
 +                                (and addr (string-match-p regex 
 +                                                          (downcase (if (listp addr) 
 +                                                                        (or (plist-get addr :email) ""
 +                                                                      addr))))) 
 +                              addresses) 
 +               return folder 
 +               finally return nil)) 
 + 
 +    ;; mu4e が参照するリファイル先決定関数。ルールマッチしなければ現在フォルダ。 
 +    (setq mu4e-refile-folder 
 +          (lambda (msg) 
 +            (or (my-mu4e-refile-message msg) 
 +                (mu4e-message-field msg :maildir)))) 
 + 
 +    ;; ヘッダビュー内で「自動的にrefileマークを付ける」補助コマンド 
 +    (defun my-mu4e-auto-refile-process (msg) 
 +      (let ((target (funcall mu4e-refile-folder msg))) 
 +        (when (and target 
 +                   (not (string= target (mu4e-message-field msg :maildir)))) 
 +          (mu4e-mark-set 'refile target)))) 
 +    (defun my-mu4e-auto-refile () 
 +      "現在フォルダの新着/未読を検索し、ルールに基づき refile マークを付ける。" 
 +      (interactive) 
 +      (let* ((current (mu4e-message-field (mu4e-message-at-point) :maildir)) 
 +             (query (concat "maildir:" current " AND (flag:new OR flag:unread) AND NOT flag:trashed"))) 
 +        (mu4e-headers-search query) 
 +        (add-hook 'mu4e-headers-found-hook #'my-mu4e-auto-refile-hook))) 
 +    (defun my-mu4e-auto-refile-hook () 
 +      (remove-hook 'mu4e-headers-found-hook #'my-mu4e-auto-refile-hook) 
 +      (goto-char (point-min)) 
 +      (while (not (eobp)) 
 +        (let ((msg (mu4e-message-at-point))) 
 +          (my-mu4e-auto-refile-process msg)) 
 +        (forward-line)) 
 +      ;; マーク後、次の未読へ移動 
 +      (mu4e-headers-next nil)) 
 +    (keymap-set mu4e-headers-mode-map "e" #'my-mu4e-auto-refile) 
 + 
 +    ;; ---- 送信補助(msmtp選択/Cc/Bcc/件名空確認)---- 
 +    ;; Fromヘッダと msmtp アカウントの対応表(追加・変更はここへ) 
 +    (defvar my/msmtp-accounts 
 +      '(("seirios@seirios.org"     . "seirios_seirios"
 +        ("sheo@seirios.org"        . "sheo_seirios"
 +        ("mls@seirios.org"         . "mls_seirios"
 +        ("seirios@mac.com"         . "seirios_icloud"
 +        ("sheo0147@yahoo.co.jp"    . "sheo0147_yahoo"
 +        ("seirios@rusty-raven.com" . "seirios_RRcom"
 +        ("seirios@rusty-raven.net" . "seirios_RRnet"
 +        ("sheo0147@gmail.com"      . "sheo0147_gmail"
 +        ("seirios.wm@gmail.com"    . "seirios.wm_gmail"
 +        ("seirios@silanui.com"     . "seirios_silanui"))) 
 +    (defun my-mu4e-set-msmtp-account () 
 +      "From ヘッダに基づき msmtp アカウントを自動選択する。 
 +- ヘッダから送信者アドレスを取り出し、`my/msmtp-accounts` で最初に一致したものを採用 
 +- 一致がない場合は何もしない(ユーザ手動選択に委ねる)" 
 +      (when (message-mail-p) 
 +        (save-excursion 
 +          (let* ((from (save-restriction 
 +                         (message-narrow-to-headers) 
 +                         (or (message-fetch-field "from") ""))) 
 +                 (acct (seq-some (lambda (pair) 
 +                                   (and (string-match (regexp-quote (car pair)) from) 
 +                                        (cdr pair))) 
 +                                 my/msmtp-accounts))) 
 +            (when acct 
 +              (message "Using msmtp account: %s" acct) 
 +              (setq message-sendmail-extra-arguments (list "-a" acct))))))) 
 +    (add-hook 'message-send-hook #'my-mu4e-set-msmtp-account) 
 + 
 +    (defun my-add-cc-and-bcc () 
 +      "Compose 中に Cc に自アドレスがなければ追記し、Bcc を空で付与する。 
 +- Cc 行が存在しない場合は新規に付与 
 +- 既に自アドレスが含まれていれば何もしない"
       (save-excursion       (save-excursion
-        (let* +        (goto-char (point-min)) 
-            ((from (save-restriction +        (if (re-search-forward "^Cc:" nil t) 
-                     (message-narrow-to-headers+            (unless (re-search-forward (concat (regexp-quote user-mail-address)
-                     (message-fetch-field "from"))) +                                       (line-end-positiont
-             (account +              (end-of-line) 
-              (cond +              (insert (if (looking-back "[, \t]" (max (point-min) (1(point)))) 
-               ((string-match "sample@example.com     from) "sample_example"+                          user-mail-address 
-               ((string-match "sample@icloud.com"       from"sample_icloud"+                        (concat "user-mail-address)))) 
-               ((string-match "sample@yahoo.co.jp"      from"sample_yahoo"+          (message-add-header (format "Cc: %s\nuser-mail-address)))) 
-               ((string-match "sample@gmail.com       from"sample_gmail"+      (save-excursion (message-add-header "Bcc: \n"))) 
-               ))) +    (add-hook 'mu4e-compose-mode-hook #'my-add-cc-and-bcc)
-          (setq message-sendmail-extra-arguments (list '"-aaccount))) +
-        ))) +
-(add-hook 'message-send-mail-hook 'my-mu4e-set-msmtp-account)+
  
-;;; Add Cc and Bcc field when compose Email. +    (defun confirm-empty-subject () 
-(add-hook 'mu4e-compose-mode-hook ; mu4e cc & bcc +      "件名が空なら送信前に確認ダイアログを出す。 
-          (defun my-add-cc-and-bcc () +誤送信防止のための軽量ガード。
-            "My Function to automatically add Cc & Bcc: headers. +      (let ((sub (message-field-value "Subject"))) 
-This is in the mu4e compose mode.+        (or (and sub (not (string-match "\\`[ \t]*\\'sub))) 
-            (save-excursion (message-add-header +            (yes-or-no-"Really send without Subject? ") 
-                             (concat "Cc: user-mail-address "\n"))) +            (keyboard-quit)))) 
-            (save-excursion (message-add-header "Bcc:\n"))))+    (add-hook 'message-send-hook #'confirm-empty-subject)
  
-;;; Require confirmation before sending mail without subject. +    ;; === ヘッダ表示のページング(N=残り全件を一気に追記) === 
-(defun confirm-empty-subject () +    (defun my/mu4e--headers-last-message-id () 
-  "Require confirmation before sending without subject.+      "ヘッダバッファ末尾のメッセージID(:message-id)を返す。なければ nil。
-  (let ((sub (message-field-value "Subject"))+      (when (mu4e-current-buffer-type-p 'headers
-    (or (and sub (not (string-match "\\`[ \t]*\\'" sub))) +        (save-excursion 
-        (yes-or-no-p "Really send without Subject? "+          (goto-char (point-max)) 
-        (keyboard-quit))))+          (forward-line -1
 +          (plist-get (mu4e-message-at-point) :message-id))))
  
-(add-hook 'message-send-hook #'confirm-empty-subject)+    (defun my-mu4e-append-all-remaining () 
 +      "現在クエリの『末尾からさらに先(残り全件)』を一気に追記する。 
 +この呼び出し中のみ `mu4e-search-full` を t にして上限を外す。" 
 +      (interactive) 
 +      (when (mu4e-current-buffer-type-p 'headers) 
 +        (let* ((mu4e-search-full t)                ;; ★ この関数の間だけ全件モード 
 +               (mu4e-search-sort-field 'date) 
 +               (mu4e-search-sort-direction 'descending) 
 +               ;; 念のため「ほぼ無限」上限もローカルに設定(古いmu4eへの互換) 
 +               (mu4e-headers-results-limit most-positive-fixnum) 
 +               (last-msg (my/mu4e--headers-last-message-id))) 
 +          (when-let ((query (mu4e-last-query))) 
 +            (message "[mu4e] append all remaining headers ..."
 +            ;; append=t で結果を追記。last-msg をアンカーに、それより古い側を取得。 
 +            (mu4e-search query nil nil t last-msg) 
 +            ;; 視認性のため末尾へ移動 
 +            (goto-char (point-max)) 
 +            (forward-line -1) 
 +            ;; スレッド折りたたみを使っている場合は全畳みで見通しを確保 
 +            (when (bound-and-true-p mu4e-thread-folding-mode) 
 +              (mu4e-headers-fold-all)) 
 +            (message "[mu4e] all remaining headers appended.")))))
  
-;;; Header viewでmail Search時にMaxmumを拡張て全部を検索する +    ;; キーバインドの差替え(N) 
-(defvar my-mu4e-page 1 "Current page in mu4e search."+    (keymap-set mu4e-headers-mode-map "N#'my-mu4e-append-all-remaining)
-(defun my-mu4e-reset-page (&rest _r) +
-  "Reset ‘my-mu4e-page’ to 1." +
-  (setq my-mu4e-page 1))+
  
-;; Need to reset the "standard searcheswhen invoking an interactive search +    ;; === 非同期取得+インデックス更新(背景実行)と定期バックグラウンド更新 === 
-(add-hook 'mu4e-search-bookmark-hook #'my-mu4e-reset-page) +    ;; Parameters: 
-(advice-add 'mu4e-search-maildir :before #'my-mu4e-reset-page)+    ;;  - mbsync path resolution: my/which tries /usr/local/bin, /opt/homebrew/bin, then PATH 
 +    ;;  - Timer interval: call (my/mu4e-start-background-update MINUTES) to change 
 +    ;;  - Log buffer: *mu4e-mbsync*stores stdout/stderr of mbsync for diagnostics 
 +    ;; Behavior: 
 +    ;;  U: triggers async mbsync followed by mu4e-index-update when exit-code=0 
 +    ;;  Startup: built-in mu4e auto update disabled; we rely on custom timer 
 +    ;;  Index updates run with mu4e-index-update-in-background=t to avoid blocking 
 +    (setq mu4e-index-update-in-background t)
  
-(defun my-mu4e-next-messages-for-query () +    (defun my-mu4e-update-mail-and-index-async () 
-  "Fetch the next number of messages for current mu4e query+      "Run mbsync asynchronously and, upon success, trigger mu4e index update in background
-Move to last message in current view so that newly fetched +ENV/PATH NOTES: 
-messages are visible.+  - GUI起動のEmacsでは Homebrew の PATH が見えないことがある。必要なら exec-path-from-shell を併用。 
-  (interactive) +LOGGING: 
-  (when (and (mu4e-current-buffer-type-p 'headers+  - mbsync の標準出力/エラーはバッファ \*mu4e-mbsync*\" に格納。 
-             (not mu4e-search-full)) +ERROR HANDLING: 
-    (when-let ((query (mu4e-last-query))) +  - 非ゼロ終了コードの場合はバッファを表示して詳細を確認できる。" 
-      (cl-incf my-mu4e-page+      (interactive) 
-      (let ((mu4e-search-results-limit +      (let* ((mbsync (my/which "/usr/local/bin/mbsync" "/opt/homebrew/bin/mbsync" "mbsync")
-             (* my-mu4e-page -1)+             (args   '("-a"))) 
-            (last-msg (save-excursion +        (unless mbsync 
-                        (goto-char (point-max)) +          (user-error "mbsync が見つかりません。PATHやインストールを確認してください。")) 
-                        (forward-line -1+        (let ((buf (get-buffer-create " *mu4e-mbsync*"))) 
-                        (plist-get +          (with-current-buffer buf (erase-buffer)) 
-                         (mu4e-message-at-point+          (message "[mu4e] start mbsync -a (background)"
-                         :message-id)))) +          (let ((proc (apply #'start-process "mu4e-mbsync" buf mbsync args))) 
-        (mu4e-search query nil nil t last-msg)))))+            (set-process-query-on-exit-flag proc nil
 +            (set-process-sentinel 
 +             proc 
 +             (lambda (p event) 
 +               (when (eq (process-status p'exit
 +                 (let ((code (process-exit-status p))
 +                   (if (= code 0) 
 +                       (progn 
 +                         (message "[mu4e] mbsync done. start mu index (background)") 
 +                         (mu4e-update-index); 非同期インデックス更新(UI非ブロッキング) 
 +                     (progn 
 +                       (message "[mu4e] mbsync failed (exit=%d). バッファ %s を確認" 
 +                                code (buffer-name (process-buffer p))) 
 +                       (display-buffer (process-buffer p))))))))))))
  
-(keymap-set mu4e-headers-mode-map "N" #'my-mu4e-next-messages-for-query)+    ;; Uキーを非同期版に差し替え(メイン/ヘッダ両方) 
 +    (define-key mu4e-main-mode-map    (kbd "U" ; U = async mbsync + mu index (non-blocking) 
 +      #'my-mu4e-update-mail-and-index-async) 
 +    (define-key mu4e-headers-mode-map (kbd "U")  ; U = async mbsync + mu index (non-blocking) 
 +      #'my-mu4e-update-mail-and-index-async)
  
-;;; Refile +    ;; mu4e 自体の同期更新コマンドを使う場面へ互換のため文字列版も保持 
-(makunbound 'my-mu4e-refile-message) +    (let ((mbsync (my/which "/usr/local/bin/mbsync" "/opt/homebrew/bin/mbsync" "mbsync"))) 
-(defun my-mu4e-refile-message (msg) +      (setq mu4e-get-mail-command (and mbsync (concat mbsync " -a")))) ; Keep string form for compatibility
-  "Determine the refile folder for mu4e messages based on specified fields in MSG." +
-  (cl-loop for (folder field regex) in my-mu4e-refile-rules +
-           for addresses = (cond +
-                            ((string= field "any")     (append (mu4e-message-field msg :to) +
-                                                               (mu4e-message-field msg :cc) +
-                                                               (mu4e-message-field msg :bcc) +
-                                                               (mu4e-message-field msg :from))) +
-                            ((string= field "rcpt")    (append (mu4e-message-field msg :to) +
-                                                               (mu4e-message-field msg :cc) +
-                                                               (mu4e-message-field msg :bcc))) +
-                            ((string= field "subj")    (list (mu4e-message-field msg :subject))) +
-                            ((string= field "msgid"  (list (mu4e-message-field msg :msgid))) +
-                            ((string= field "list"   (list (mu4e-message-field msg :list))) +
-                            (t (mu4e-message-field msg (intern (concat ":" field))))) +
-           when (seq-some (lambda (addr) +
-                            (when addr +
-                              (string-match-p regex +
-                                              (downcase +
-                                               (if (listp addr) +
-                                                   (or (plist-get addr :email) "") +
-                                                 addr))))) +
-                          addresses) +
-           return folder refile先を相対pathで返す +
-           finally return nil)) ; 条件にマッチしない場合はnilを返す+
  
-;; mu4e-refile-message関数を利用してrefileする +    ;; --- 定期バックグラウンド更新(独自タイマー) --- 
-(setq mu4e-refile-folder ""+    (defvar my/mu4e-background-timer nil 
-(setq mu4e-refile-folder +      "バックグラウンド更新用のタマー。nil ら未稼働。")
-      (lambda (msg) +
-        (or (my-mu4e-refile-message msg) +
-            (mu4e-message-field msg :maildir)))) ; リファル先が決定できい場合は現在のフォルダを返す+
  
-(makunbound 'my-mu4e-auto-refile-process) +    (defun my/mu4e-start-background-update (minutes
-(defun my-mu4e-auto-refile-process (msg+      "MINUTES 分間隔で非同期取得+インデックス更新を開始する。
-  "Process a single message for auto-refiling." +
-  (let ((target-folder (funcall mu4e-refile-folder msg))) +
-    (when (and target-folder +
-               (not (string= target-folder (mu4e-message-field msg :maildir)))) +
-      (mu4e-mark-set 'refile target-folder))))+
  
-(makunbound 'my-mu4e-auto-refile) +Parameters: 
-(defun my-mu4e-auto-refile () +  MINUTES  整数。間隔(分)を指定(例: 10) 
-  "Automatically mark messages for refiling in the current folder based on mu4e-refile-folder rules." +Behavior: 
-  (interactive) +  既存タイマーがあればキャンセル。 
-  (let* ((current-folder (mu4e-message-field (mu4e-message-at-point) :maildir)) +  最初の実行は 10 秒後、その後 MINUTES ごとに繰り返し。 
-         (query (concat "maildir:" current-folder " " +  - 非同期関数 my-mu4e-update-mail-and-index-async を使用。 
-                        "AND (flag:new OR flag:unread) " +Tuning: 
-                        "AND NOT flag:trashed"))) +  - 初回遅延 10 秒は必要に応じて変更可能(run-at-time の第一引数)。" 
-    (mu4e-headers-search query) +      (when my/mu4e-background-timer 
-    (add-hook 'mu4e-headers-found-hook 'my-mu4e-auto-refile-hook)))+        (cancel-timer my/mu4e-background-timer)) 
 +      (setq my/mu4e-background-timer 
 +            (run-at-time 30 (* minutes 60) #'my-mu4e-update-mail-and-index-async)
 +      (message "[mu4e] background update every %d minutes" minutes))
  
-(makunbound 'my-mu4e-auto-refile-hook) +    (defun my/mu4e-stop-background-update () 
-(defun my-mu4e-auto-refile-hook () +      "バックグラウンド更新タイマーを停止する。 
-  "Hook to process messages after headers search.+従量制ネットワークや一時的に負荷を避けたい場合に使用。
-  (remove-hook 'mu4e-headers-found-hook 'my-mu4e-auto-refile-hook) +      (interactive) 
-  (goto-char (point-min)) +      (when my/mu4e-background-timer 
-  (while (not (eobp)) +        (cancel-timer my/mu4e-background-timer
-    (let ((msg (mu4e-message-at-point))+        (setq my/mu4e-background-timer nil
-      (my-mu4e-auto-refile-process msg)+        (message "[mu4e] background update stopped")))
-    (forward-line)) +
-  (mu4e-headers-next nil)) ; Move to the next unread message after marking+
  
-(makunbound 'my-mu4e-headers-auto-refile) +    ;; 既定では 10 分間隔で開始(好みに合わせて値を変更) 
-(defun my-mu4e-headers-auto-refile () +    (my/mu4e-start-background-update 30)))
-  "Run auto-refile marking in headers view." +
-  (interactive) +
-  (my-mu4e-auto-refile))+
  
-(keymap-set mu4e-headers-mode-map "e" #'my-mu4e-headers-auto-refile) ; Refile key bind+;;; 追加: スレッド折りたたみ(見通しを良くするUI拡張) 
 +(leaf mu4e-thread-folding 
 +  :vc (:url "https://github.com/rougier/mu4e-thread-folding"
 +  :require t 
 +  :config 
 +  (define-key mu4e-headers-mode-map (kbd "<tab>")     #'mu4e-headers-toggle-at-point) 
 +  (define-key mu4e-headers-mode-map (kbd "<S-tab>"  #'mu4e-headers-toggle-fold-all) 
 +  (define-key mu4e-headers-mode-map (kbd "<left>"   #'mu4e-headers-fold-at-point) 
 +  (define-key mu4e-headers-mode-map (kbd "<S-left>" #'mu4e-headers-fold-all) 
 +  (define-key mu4e-headers-mode-map (kbd "<right>"  #'mu4e-headers-unfold-at-point) 
 +  (define-key mu4e-headers-mode-map (kbd "<S-right>") #'mu4e-headers-unfold-all) 
 +  (add-hook 'mu4e-headers-mode-hook #'mu4e-thread-folding-mode))
  
-;; Local Variables: +;;; 必要なら明示ロード(smtpmail は組み込みだが、leaf で明示しておくと見通しが良い) 
-;; coding: utf-8 +(leaf smtpmail :require t)
-;; comment-column: 72 +
-;; version-control: t +
-;; kept-old-versions:+
-;; kept-new-versions:+
-;; End:+
 </code> </code>
userapps/emacs/mu4e.txt · 最終更新: by seirios

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki