mu4e-actions: fix whitespace, flycheck warnings

This commit is contained in:
djcb 2019-04-15 07:38:58 +03:00
parent da1cb4e97b
commit e9970fb890
1 changed files with 132 additions and 142 deletions

View File

@ -1,6 +1,6 @@
;;; mu4e-actions.el -- part of mu4e, the mu mail user agent ;;; mu4e-actions.el -- part of mu4e, the mu mail user agent
;; ;;
;; Copyright (C) 2011-2017 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -37,7 +37,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-action-count-lines (msg) (defun mu4e-action-count-lines (msg)
"Count the number of lines in the e-mail message. "Count the number of lines in the e-mail MSG.
Works for headers view and message-view." Works for headers view and message-view."
(message "Number of lines: %s" (message "Number of lines: %s"
(shell-command-to-string (shell-command-to-string
@ -54,17 +54,17 @@ Works for headers view and message-view."
"Path to the msg2pdf toy.") "Path to the msg2pdf toy.")
(defun mu4e-action-view-as-pdf (msg) (defun mu4e-action-view-as-pdf (msg)
"Convert the message to pdf, then show it. "Convert MSG to pdf, then show it.
Works for the message view." Works for the message view."
(unless (file-executable-p mu4e-msg2pdf) (unless (file-executable-p mu4e-msg2pdf)
(mu4e-error "msg2pdf not found; please set `mu4e-msg2pdf'")) (mu4e-error "Program msg2pdf not found; please set `mu4e-msg2pdf'"))
(let* ((pdf (let* ((pdf
(shell-command-to-string (shell-command-to-string
(concat mu4e-msg2pdf " " (concat mu4e-msg2pdf " "
(shell-quote-argument (mu4e-message-field msg :path)) (shell-quote-argument (mu4e-message-field msg :path))
" 2> /dev/null"))) " 2> /dev/null")))
(pdf (and pdf (> (length pdf) 5) (pdf (and pdf (> (length pdf) 5)
(substring pdf 0 -1)))) ;; chop \n (substring pdf 0 -1)))) ;; chop \n
(unless (and pdf (file-exists-p pdf)) (unless (and pdf (file-exists-p pdf))
(mu4e-warn "Failed to create PDF file")) (mu4e-warn "Failed to create PDF file"))
(find-file pdf))) (find-file pdf)))
@ -72,15 +72,15 @@ Works for the message view."
(defun mu4e~write-body-to-html (msg) (defun mu4e~write-body-to-html (msg)
"Write the body (either html or text) to a temporary file; "Write MSG's body (either html or text) to a temporary file;
return the filename." return the filename."
(let* ((html (mu4e-message-field msg :body-html)) (let* ((html (mu4e-message-field msg :body-html))
(txt (mu4e-message-field msg :body-txt)) (txt (mu4e-message-field msg :body-txt))
(tmpfile (mu4e-make-temp-file "html")) (tmpfile (mu4e-make-temp-file "html"))
(attachments (cl-remove-if (lambda (part) (attachments (cl-remove-if (lambda (part)
(or (null (plist-get part :attachment)) (or (null (plist-get part :attachment))
(null (plist-get part :cid)))) (null (plist-get part :cid))))
(mu4e-message-field msg :parts)))) (mu4e-message-field msg :parts))))
(unless (or html txt) (unless (or html txt)
(mu4e-error "No body part for this message")) (mu4e-error "No body part for this message"))
(with-temp-buffer (with-temp-buffer
@ -96,37 +96,37 @@ return the filename."
(write-file tmpfile) (write-file tmpfile)
;; rewrite attachment urls ;; rewrite attachment urls
(mapc (lambda (attachment) (mapc (lambda (attachment)
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward (format "src=\"cid:%s\"" (while (re-search-forward (format "src=\"cid:%s\""
(plist-get attachment :cid)) nil t) (plist-get attachment :cid)) nil t)
(if (plist-get attachment :temp) (if (plist-get attachment :temp)
(replace-match (format "src=\"%s\"" (replace-match (format "src=\"%s\""
(plist-get attachment :temp))) (plist-get attachment :temp)))
(replace-match (format "src=\"%s%s\"" temporary-file-directory (replace-match (format "src=\"%s%s\"" temporary-file-directory
(plist-get attachment :name))) (plist-get attachment :name)))
(let ((tmp-attachment-name (let ((tmp-attachment-name
(format "%s%s" temporary-file-directory (format "%s%s" temporary-file-directory
(plist-get attachment :name)))) (plist-get attachment :name))))
(mu4e~proc-extract 'save (mu4e-message-field msg :docid) (mu4e~proc-extract 'save (mu4e-message-field msg :docid)
(plist-get attachment :index) (plist-get attachment :index)
mu4e-decryption-policy tmp-attachment-name) mu4e-decryption-policy tmp-attachment-name)
(mu4e-remove-file-later tmp-attachment-name))))) (mu4e-remove-file-later tmp-attachment-name)))))
attachments) attachments)
(save-buffer) (save-buffer)
tmpfile))) tmpfile)))
(defun mu4e-action-view-in-browser (msg) (defun mu4e-action-view-in-browser (msg)
"View the body of the message in a browser. "View the body of MSG in a web browser.
You can influence the browser to use with the variable You can influence the browser to use with the variable
`browse-url-generic-program', and see the discussion of privacy `browse-url-generic-program', and see the discussion of privacy
aspects in `(mu4e) Displaying rich-text messages'." aspects in `(mu4e) Displaying rich-text messages'."
(browse-url (concat "file://" (browse-url (concat "file://"
(mu4e~write-body-to-html msg)))) (mu4e~write-body-to-html msg))))
(defun mu4e-action-view-with-xwidget (msg) (defun mu4e-action-view-with-xwidget (msg)
"View the body of the message inside xwidget-webkit. This is "View the body of MSG inside xwidget-webkit.
only available in emacs 25+; also see the discussion of privacy This is only available in Emacs 25+; also see the discussion of
aspects in `(mu4e) Displaying rich-text messages'." privacy aspects in `(mu4e) Displaying rich-text messages'."
(unless (fboundp 'xwidget-webkit-browse-url) (unless (fboundp 'xwidget-webkit-browse-url)
(mu4e-error "No xwidget support available")) (mu4e-error "No xwidget support available"))
(xwidget-webkit-browse-url (xwidget-webkit-browse-url
@ -138,10 +138,10 @@ aspects in `(mu4e) Displaying rich-text messages'."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defconst mu4e-text2speech-command "festival --tts" (defconst mu4e-text2speech-command "festival --tts"
"Program that speaks out text it receives on standard-input.") "Program that speaks out text it receives on standard input.")
(defun mu4e-action-message-to-speech (msg) (defun mu4e-action-message-to-speech (msg)
"Pronounce the message text using `mu4e-text2speech-command'." "Pronounce MSG's body text using `mu4e-text2speech-command'."
(unless (mu4e-message-field msg :body-txt) (unless (mu4e-message-field msg :body-txt)
(mu4e-warn "No text body for this message")) (mu4e-warn "No text body for this message"))
(with-temp-buffer (with-temp-buffer
@ -151,18 +151,15 @@ aspects in `(mu4e) Displaying rich-text messages'."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e-captured-message nil (defvar mu4e-captured-message nil
"The last-captured message (the s-expression).") "The most recently captured message.")
(defun mu4e-action-capture-message (msg) (defun mu4e-action-capture-message (msg)
"Remember MSG; we can create a an attachment based on this msg "Remember MSG.
with `mu4e-compose-attach-captured-message'." Later, we can create an attachment based on this message with
`mu4e-compose-attach-captured-message'."
(setq mu4e-captured-message msg) (setq mu4e-captured-message msg)
(message "Message has been captured")) (message "Message has been captured"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -171,13 +168,10 @@ with `mu4e-compose-attach-captured-message'."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-action-copy-message-file-path (msg) (defun mu4e-action-copy-message-file-path (msg)
"Save the full path the message file for the current message to "Save the full path for the current MSG to the kill ring."
the kill-ring."
(kill-new (mu4e-message-field msg :path))) (kill-new (mu4e-message-field msg :path)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e-org-contacts-file nil (defvar mu4e-org-contacts-file nil
@ -189,32 +183,31 @@ Needed by `mu4e-action-add-org-contact'.")
(defvar org-capture-templates nil))) (defvar org-capture-templates nil)))
(defun mu4e-action-add-org-contact (msg) (defun mu4e-action-add-org-contact (msg)
"Add an org-contact entry based on the From: address of the "Add an org-contact based on the sender ddress of the current MSG.
current message (in headers or view). You need to set You need to set `mu4e-org-contacts-file' to the full path to the
`mu4e-org-contacts-file' to the full path to the file where you file where you store your org-contacts."
store your org-contacts."
(unless (require 'org-capture nil 'noerror) (unless (require 'org-capture nil 'noerror)
(mu4e-error "org-capture is not available.")) (mu4e-error "Feature org-capture is not available"))
(unless mu4e-org-contacts-file (unless mu4e-org-contacts-file
(mu4e-error "`mu4e-org-contacts-file' is not defined.")) (mu4e-error "Variable `mu4e-org-contacts-file' is nil"))
(let* ((sender (car-safe (mu4e-message-field msg :from))) (let* ((sender (car-safe (mu4e-message-field msg :from)))
(name (car-safe sender)) (email (cdr-safe sender)) (name (car-safe sender)) (email (cdr-safe sender))
(blurb (blurb
(format (format
(concat (concat
"* %%?%s\n" "* %%?%s\n"
":PROPERTIES:\n" ":PROPERTIES:\n"
":EMAIL: %s\n" ":EMAIL: %s\n"
":NICK:\n" ":NICK:\n"
":BIRTHDAY:\n" ":BIRTHDAY:\n"
":END:\n\n") ":END:\n\n")
(or name email "") (or name email "")
(or email ""))) (or email "")))
(key "mu4e-add-org-contact-key") (key "mu4e-add-org-contact-key")
(org-capture-templates (org-capture-templates
(append org-capture-templates (append org-capture-templates
(list (list key "contacts" 'entry (list (list key "contacts" 'entry
(list 'file mu4e-org-contacts-file) blurb))))) (list 'file mu4e-org-contacts-file) blurb)))))
(message "%S" org-capture-templates) (message "%S" org-capture-templates)
(when (fboundp 'org-capture) (when (fboundp 'org-capture)
(org-capture nil key)))) (org-capture nil key))))
@ -234,16 +227,16 @@ store your org-contacts."
(unless prompt (unless prompt
(setq prompt "Target directory:")) (setq prompt "Target directory:"))
(file-truename (file-truename
(completing-read prompt 'read-file-name-internal #'file-directory-p (completing-read prompt 'read-file-name-internal #'file-directory-p
nil nil 'mu4e~patch-directory-history))) nil nil 'mu4e~patch-directory-history)))
(defun mu4e-action-git-apply-patch (msg) (defun mu4e-action-git-apply-patch (msg)
"Apply `MSG' as a git patch." "Apply `MSG' as a git patch."
(let ((path (mu4e~read-patch-directory "Target directory: "))) (let ((path (mu4e~read-patch-directory "Target directory: ")))
(let ((default-directory path)) (let ((default-directory path))
(shell-command (shell-command
(format "git apply %s" (format "git apply %s"
(shell-quote-argument (mu4e-message-field msg :path))))))) (shell-quote-argument (mu4e-message-field msg :path)))))))
(defun mu4e-action-git-apply-mbox (msg &optional signoff) (defun mu4e-action-git-apply-mbox (msg &optional signoff)
"Apply `MSG' a git patch with optional `SIGNOFF'. "Apply `MSG' a git patch with optional `SIGNOFF'.
@ -252,15 +245,15 @@ If the `default-directory' matches the most recent history entry don't
bother asking for the git tree again (useful for bulk actions)." bother asking for the git tree again (useful for bulk actions)."
(let ((cwd (substring-no-properties (let ((cwd (substring-no-properties
(or (car mu4e~patch-directory-history) (or (car mu4e~patch-directory-history)
"not-a-dir")))) "not-a-dir"))))
(unless (and (stringp cwd) (string= default-directory cwd)) (unless (and (stringp cwd) (string= default-directory cwd))
(setq cwd (mu4e~read-patch-directory "Target directory: "))) (setq cwd (mu4e~read-patch-directory "Target directory: ")))
(let ((default-directory cwd)) (let ((default-directory cwd))
(shell-command (shell-command
(format "git am %s %s" (format "git am %s %s"
(if signoff "--signoff" "") (if signoff "--signoff" "")
(shell-quote-argument (mu4e-message-field msg :path))))))) (shell-quote-argument (mu4e-message-field msg :path)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -268,73 +261,70 @@ bother asking for the git tree again (useful for bulk actions)."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e-action-tags-header "X-Keywords" (defvar mu4e-action-tags-header "X-Keywords"
"Header where tags are stored. Used by `mu4e-action-retag-message'. "Header where tags are stored.
Make sure it is one of the headers mu recognizes for storing Used by `mu4e-action-retag-message'. Make sure it is one of the
tags: X-Keywords, X-Label, Keywords. Also note that changing headers mu recognizes for storing tags: X-Keywords, X-Label,
this setting on already tagged messages can lead to messages Keywords. Also note that changing this setting on already tagged
with multiple tags headers.") messages can lead to messages with multiple tags headers.")
(defvar mu4e-action-tags-completion-list '() (defvar mu4e-action-tags-completion-list '()
"List of tags to show for autocompletion in "List of tags for completion in `mu4e-action-retag-message'.")
`mu4e-action-retag-message'.")
(defun mu4e~contains-line-matching (regexp path) (defun mu4e~contains-line-matching (regexp path)
"Determine whether the file at path contains a line matching "Does file at PATH contain a line matching the given REGEXP?"
the given regexp."
(with-temp-buffer (with-temp-buffer
(insert-file-contents path) (insert-file-contents path)
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(if (re-search-forward regexp nil t) (if (re-search-forward regexp nil t)
t t
nil)))) nil))))
(defun mu4e~replace-first-line-matching (regexp to-string path) (defun mu4e~replace-first-line-matching (regexp to-string path)
"Replace the first line in the file at path that matches regexp "Replace first line matching REGEXP in PATH with TO-STRING."
with the string replace."
(with-temp-file path (with-temp-file path
(insert-file-contents path) (insert-file-contents path)
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(if (re-search-forward regexp nil t) (if (re-search-forward regexp nil t)
(replace-match to-string nil nil))))) (replace-match to-string nil nil)))))
(defun mu4e-action-retag-message (msg &optional retag-arg) (defun mu4e-action-retag-message (msg &optional retag-arg)
"Change tags of a message. Accepts a comma-separated list of "Change tags of MSG with RETAG-ARG.
additions and removals.
Example: +tag,+long tag,-oldtag RETAG-ARG is a comma-separated list of additions and removals.
would add 'tag' and 'long tag', and remove 'oldtag'." Example: +tag,+long tag,-oldtag
would add 'tag' and 'long tag', and remove 'oldtag'."
(let* ( (let* (
(path (mu4e-message-field msg :path)) (path (mu4e-message-field msg :path))
(maildir (mu4e-message-field msg :maildir)) (maildir (mu4e-message-field msg :maildir))
(oldtags (mu4e-message-field msg :tags)) (oldtags (mu4e-message-field msg :tags))
(tags-completion (tags-completion
(append (append
mu4e-action-tags-completion-list mu4e-action-tags-completion-list
(mapcar (lambda (tag) (format "+%s" tag)) (mapcar (lambda (tag) (format "+%s" tag))
mu4e-action-tags-completion-list) mu4e-action-tags-completion-list)
(mapcar (lambda (tag) (format "-%s" tag)) (mapcar (lambda (tag) (format "-%s" tag))
oldtags))) oldtags)))
(retag (if retag-arg (retag (if retag-arg
(split-string retag-arg ",") (split-string retag-arg ",")
(completing-read-multiple "Tags: " tags-completion))) (completing-read-multiple "Tags: " tags-completion)))
(header mu4e-action-tags-header) (header mu4e-action-tags-header)
(sep (cond ((string= header "Keywords") ", ") (sep (cond ((string= header "Keywords") ", ")
((string= header "X-Label") " ") ((string= header "X-Label") " ")
((string= header "X-Keywords") ", ") ((string= header "X-Keywords") ", ")
(t ", "))) (t ", ")))
(taglist (if oldtags (copy-sequence oldtags) '())) (taglist (if oldtags (copy-sequence oldtags) '()))
tagstr) tagstr)
(dolist (tag retag taglist) (dolist (tag retag taglist)
(cond (cond
((string-match "^\\+\\(.+\\)" tag) ((string-match "^\\+\\(.+\\)" tag)
(setq taglist (push (match-string 1 tag) taglist))) (setq taglist (push (match-string 1 tag) taglist)))
((string-match "^\\-\\(.+\\)" tag) ((string-match "^\\-\\(.+\\)" tag)
(setq taglist (delete (match-string 1 tag) taglist))) (setq taglist (delete (match-string 1 tag) taglist)))
(t (t
(setq taglist (push tag taglist))))) (setq taglist (push tag taglist)))))
(setq taglist (sort (delete-dups taglist) 'string<)) (setq taglist (sort (delete-dups taglist) 'string<))
(setq tagstr (mapconcat 'identity taglist sep)) (setq tagstr (mapconcat 'identity taglist sep))
@ -345,32 +335,32 @@ bother asking for the git tree again (useful for bulk actions)."
(if (not (mu4e~contains-line-matching (concat header ":.*") path)) (if (not (mu4e~contains-line-matching (concat header ":.*") path))
;; Add tags header just before the content ;; Add tags header just before the content
(mu4e~replace-first-line-matching (mu4e~replace-first-line-matching
"^$" (concat header ": " tagstr "\n") path) "^$" (concat header ": " tagstr "\n") path)
;; replaces keywords, restricted to the header ;; replaces keywords, restricted to the header
(mu4e~replace-first-line-matching (mu4e~replace-first-line-matching
(concat header ":.*") (concat header ":.*")
(concat header ": " tagstr) (concat header ": " tagstr)
path)) path))
(mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", "))) (mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", ")))
(mu4e-refresh-message path maildir))) (mu4e-refresh-message path maildir)))
(defun mu4e-action-show-thread (msg) (defun mu4e-action-show-thread (msg)
"Show all messages that are in the same thread as the message "Show thread for message at point with point remaining on MSG.
at point. Point remains on the message with the message-id where I.e., point remains on the message with the message-id where the
the action was invoked. If invoked in view-mode, continue to action was invoked. If invoked in view mode, continue to display
display the message." the message."
(let ((msgid (mu4e-message-field msg :message-id))) (let ((msgid (mu4e-message-field msg :message-id)))
(when msgid (when msgid
(let ((mu4e-headers-show-threads t) (let ((mu4e-headers-show-threads t)
(mu4e-headers-include-related t)) (mu4e-headers-include-related t))
(mu4e-headers-search (mu4e-headers-search
(format "msgid:%s" msgid) (format "msgid:%s" msgid)
nil nil nil nil nil nil
msgid (and (eq major-mode 'mu4e-view-mode) msgid (and (eq major-mode 'mu4e-view-mode)
(not (eq mu4e-split-view 'single-window)))))))) (not (eq mu4e-split-view 'single-window))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'mu4e-actions) (provide 'mu4e-actions)
;;; mu4e-actions.el ends here