I read a lot of mailing lists in mu4e. Sometimes a thread that I'm not interested in gets a lot of activity, and I'd like to unsubscribe from that thread in particular without unsubscribing from the whole mailing list.

How can I ask mu4e to take future replies to a thread and send them straight to my archive?

1 Answer 1


You need to tag at least one message in the thread with the value "muted" (press aM in the headers buffer), then add a predicate function to mu4e-headers-hide-predicate to determine whether the thread should be muted/shown. Note: This will only hide muted threads from view.

(add-to-list 'mu4e-headers-actions
             '("Mute thread" . (lambda (msg)
                                 (mu4e-action-retag-message msg "+muted")
                                 ;; This part is for demonstration

(setq mu4e-headers-hide-predicate
      (lambda (msg)
        (let* ((msgid (mu4e-message-field msg :message-id))
               (cmd (format "mu find 'msgid:%s' -r --format=sexp" msgid))
               (result (concat "(list " (shell-command-to-string cmd) ")"))
               (msgs (car (read-from-string result))))
          (catch 'muted
            (cl-loop for msg in msgs
                     when (member "muted" (plist-get msg :tags))
                     collect (throw 'muted t))))))

To mute by archiving messages you can try the following:

(add-to-list 'mu4e-headers-actions
             '("Mute thread" .
               (lambda (msg)
                 (let ((docid (mu4e-message-field msg :docid))
                       (refloc (if (stringp mu4e-refile-folder)
                                 (funcall mu4e-refile-folder msg))))
                   (mu4e-action-retag-message msg "+muted")
                   (mu4e~proc-move docid refloc "+S-N")))))

(defun mu4e-archive-if-muted ()
  (let* ((cmd "mu find tag:muted --format=sexp -r")
         (result (concat "(list " (shell-command-to-string cmd) ")"))
         (msgs (car (read-from-string result))))
    (dolist (msg (cdr msgs))
      (let ((maildir (mu4e-message-field msg :maildir))
            (docid (mu4e-message-field msg :docid))
            (refloc (if (stringp mu4e-refile-folder)
                      (funcall mu4e-refile-folder msg))))
        (unless (or (string= refloc maildir)
                    (string= "/sent" maildir))
          (when (and docid (> docid 0))
            (mu4e~proc-move docid refloc "+S-N")))))))

(add-to-list 'mu4e-index-updated-hook 'mu4e-archive-if-muted t)

What this does is it finds all muted messages, including messages of the same thread, and moves them to the archive directory when the indexing process had one or more messages updated.

  • 1
    This merely hides, rather than archives, the thread in question. I would like each message to be refiled to archive, as if I had pressed r (mu4e-headers-mark-for-refile). Commented Aug 7, 2019 at 1:50
  • @MatthewPiziak Can you try now.
    – jagrg
    Commented Aug 7, 2019 at 22:54
  • It's not working for me. I'm still seeing new messages appear from previously muted threads. Commented Aug 9, 2019 at 12:44
  • Moreover, if I mute one indexed message in a thread, other existing child messages in that thread are not archived upon indexing. Commented Aug 9, 2019 at 12:50
  • 1
    I have noticed that the function itself works though! For some reason I cannot make it work with that particular hook, but if I run it elsewhere it seems fine. Thank you for your answer! Commented Aug 9, 2019 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.