Skip to content

Instantly share code, notes, and snippets.

@lgatto
Last active April 19, 2023 18:52
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lgatto/7091552 to your computer and use it in GitHub Desktop.
Save lgatto/7091552 to your computer and use it in GitHub Desktop.
;; grep -h X-Key */*/cur/* | sed -e 's/X-Keywords: //; s/, /\n/g' | sort | uniq > xkeys.txt
(setq mu4e-xkeys "~/Maildir/xkeys.txt")
(defun read-lines (f)
"Return a list of lines of a file at f."
(with-temp-buffer
(insert-file-contents f)
(split-string (buffer-string) "\n" t)))
(defun mu4e-action-retag-message (msg &optional retag-arg)
"Change tags of a message. Example: +tag \"+long tag\" -oldtag
adds 'tag' and 'long tag', and removes oldtag."
(let* ((retag (or retag-arg (completing-read "Tags: " (read-lines mu4e-xkeys))))
(path (mu4e-message-field msg :path))
(maildir (mu4e-message-field msg :maildir))
(oldtags (mu4e-message-field msg :tags))
(header mu4e-action-tags-header)
(sep (cond ((string= header "Keywords") " ")
((string= header "X-Label") " ")
((string= header "X-Keywords") ", ")
(t ", ")))
(taglist (if oldtags (copy-sequence oldtags) '()))
tagstr)
(dolist (tag (split-string-and-unquote retag) taglist)
(cond
((string-match "^\\+\\(.+\\)" tag)
(setq taglist (push (match-string 1 tag) taglist)))
((string-match "^\\-\\(.+\\)" tag)
(setq taglist (delete (match-string 1 tag) taglist)))
(t
(setq taglist (push tag taglist)))))
(setq taglist (sort (delete-dups taglist) 'string<))
(setq tagstr (mapconcat 'identity taglist sep))
(setq tagstr (replace-regexp-in-string "[\\&]" "\\\\\\&" tagstr))
(setq tagstr (replace-regexp-in-string "[/]" "\\&" tagstr))
(if (not (mu4e~contains-line-matching (concat header ":.*") path))
;; Add tags header just before the content
(mu4e~replace-first-line-matching
"^$" (concat header ": " tagstr "\n") path)
;; replaces keywords, restricted to the header
(mu4e~replace-first-line-matching
(concat header ":.*")
(concat header ": " tagstr)
path))
(mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", ")))
(mu4e-refresh-message path maildir)))
;; Current issues: -tag does not autocomplete.
@sje30
Copy link

sje30 commented Oct 21, 2013

"Not bad" for a first piece of lisp!!! Beautifully crafted...

@sje30
Copy link

sje30 commented Oct 21, 2013

only thing I'd change is perhaps "read-lines" to "read-lines-from-file"?

There also some conventions for doc strings; M-x checkdoc will send you crazy checking them all!

@DaisukeIkeda
Copy link

Thank you, I like it.

I use it with mu-1.6.10 and found a bug. In recent versions, maybe from mu-1.3.0, mu4e-refresh-message requires only one argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment