On 2026-04-05 22:37, Sébastien Hinderer wrote:
Dear Org and Mutt friends,

Before diving into trying to implement a new Org hyperlink type for mutt
mailboxes and mails, I am wondering whether this maybe already exists?

I did check org-contrib but the only mutt-related thing I found
there is support for accessing Mairix through Mutt. Which is great
but not exactly what I am looking for.

I am using following since years:

(defun hyperscope-mutt-view-by-message-id (link argument)
  "Open mutt at folder LINK, searching for MESSAGE-ID ARGUMENT.
Escapes '=' chars in ARGUMENT for mutt's search syntax."
  (let* ((folder link)
         (message-id (replace-regexp-in-string "=" "\\\\=" argument))
         (push (format "push '<search>=i %s<enter><enter>'" message-id)))
    (let ((default-directory folder))
      (setenv "muttdir" folder)
(start-process "mutt" "mutt" "xterm" "-e" "mutt" "-f" folder "-e" push))))

So the above one would be your Org link function.

LINK is folder, like: "~/Maildir/[email protected]"
MESSAGE-ID is like this: "[email protected]"

For Org, here are helper functions:

(defun hyperscope-mutt-insert-org-link ()
  "Interactively insert an Org link to an email in mutt."
  (interactive)
(let ((folder (read-directory-name "Mail folder: " "~/Maildir/" nil t))
        (message-id (read-string "Message-ID: ")))
    ;; Store as "folder||message-id"
(org-insert-link nil (format "mutt:%s||%s" folder message-id) message-id)))

You could rework the function to ask you for different link display name.

(defun hyperscope-mutt-open-link (link _description)
  "Open mutt from Org link with format FOLDER||MESSAGE-ID."
  (let* ((parts (split-string link "||"))
         (folder (car parts))
         (message-id (cadr parts)))
    (if (and folder message-id)
        (hyperscope-mutt-view-by-message-id folder message-id)
      (error "Invalid mutt link format. Use FOLDER||MESSAGE-ID"))))

(org-link-set-parameters "mutt" :follow #'hyperscope-mutt-open-link)

Now what you do in Org file:

M-x hyperscope-mutt-insert-org-link RET

enter:

~/Maildir/[email protected]/

and Message-ID: [email protected]

Then you get the link like this:

[[mutt:~/Maildir/[email protected]/||[email protected]][[email protected]]]

you click on it, and mutt opens with that message.

So that works on Maildirs, and you may need to fiddle with it.

There is attached file mutt-org-link.sh, you use it as Mutt helper to quickly capture Message-ID as Org link:

macro pager \e1 "<pipe-entry>/home/data1/protected/bin/rcd/mutt-org-link.sh<enter>" "Extract Message-ID and copy Org link for Emacs Org mode"

You can configure Mutt macro as you wish to set up the right path of different key.

Once link is in clipboard, you can go to Org mode and insert it.

--
Jean Louis
#!/bin/bash
# mutt-org-link - Extract Message-ID from email and copy Org link to clipboard

# Read the email from stdin
email=$(cat)

# Extract Message-ID
message_id=$(echo "$email" | grep -i "^Message-ID:" | head -1 | sed 's/^Message-ID: //i' | tr -d ' \r')

# Remove angle brackets if present
message_id_clean=$(echo "$message_id" | sed 's/^<//;s/>$//')

# Ask for folder (default to ~/Maildir)
read -p "Mail folder (default: ~/Maildir): " folder
folder=${folder:-~/Maildir}

# Create the Org link
org_link="[[mutt:${folder}||${message_id_clean}][${message_id_clean}]]"

# Copy to clipboard (works with both xclip and pbcopy)
if command -v xclip >/dev/null 2>&1; then
    echo -n "$org_link" | xclip -selection clipboard
elif command -v pbcopy >/dev/null 2>&1; then
    echo -n "$org_link" | pbcopy
else
    echo "$org_link"
fi

echo "Copied to clipboard: $org_link"

Reply via email to