mirror of https://github.com/djcb/mu.git
mu4e (ical): Allow to reply to icalendar invitations
Fixes https://github.com/djcb/mu/issues/994
This commit is contained in:
parent
c639a939f4
commit
1078fee2c5
|
@ -28,6 +28,7 @@ dist_lisp_LISP= \
|
|||
mu4e-contrib.el \
|
||||
mu4e-draft.el \
|
||||
mu4e-headers.el \
|
||||
mu4e-icalendar.el \
|
||||
mu4e-lists.el \
|
||||
mu4e-main.el \
|
||||
mu4e-mark.el \
|
||||
|
|
|
@ -413,14 +413,17 @@ You can append flags."
|
|||
Replying-to-self is special; in that case, the To and Cc fields
|
||||
will be the same as in the original."
|
||||
(let* ((reply-to-self (mu4e-message-contact-field-matches-me origmsg :from))
|
||||
(recipnum
|
||||
(+ (length (mu4e~draft-create-to-lst origmsg))
|
||||
(length (mu4e~draft-create-cc-lst origmsg t))))
|
||||
;; reply-to-self implies reply-all
|
||||
(reply-all (or reply-to-self (mu4e~draft-reply-all-p origmsg)))
|
||||
(old-msgid (plist-get origmsg :message-id))
|
||||
(subject (concat mu4e~draft-reply-prefix
|
||||
(message-strip-subject-re
|
||||
(recipnum
|
||||
(+ (length (mu4e~draft-create-to-lst origmsg))
|
||||
(length (mu4e~draft-create-cc-lst origmsg t))))
|
||||
;; reply-to-self implies reply-all
|
||||
(reply-all (or reply-to-self
|
||||
(eq mu4e-compose-reply-recipients 'all)
|
||||
(and (not (eq mu4e-compose-reply-recipients 'sender))
|
||||
(mu4e~draft-reply-all-p origmsg))))
|
||||
(old-msgid (plist-get origmsg :message-id))
|
||||
(subject (concat mu4e~draft-reply-prefix
|
||||
(message-strip-subject-re
|
||||
(or (plist-get origmsg :subject) "")))))
|
||||
(concat
|
||||
(mu4e~draft-header "From" (or (mu4e~draft-from-construct) ""))
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
;;; mu4e-icalendar.el --- reply to iCalendar meeting requests
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; To install:
|
||||
;; (require 'gnus-icalendar)
|
||||
;; (gnus-icalendar-setup)
|
||||
|
||||
;; to enable optional iCalendar->Org sync functionality
|
||||
;; NOTE: both the capture file and the headline(s) inside must already exist
|
||||
;; (setq gnus-icalendar-org-capture-file "~/org/notes.org")
|
||||
;; (setq gnus-icalendar-org-capture-headline '("Calendar"))
|
||||
;; (gnus-icalendar-org-setup)
|
||||
|
||||
(require 'mu4e)
|
||||
(require 'gnus-icalendar)
|
||||
|
||||
(eval-when-compile (require 'cl))
|
||||
|
||||
|
||||
(defun mu4e-icalendar-setup ()
|
||||
(gnus-icalendar-setup)
|
||||
(cl-defmethod gnus-icalendar-event:inline-reply-buttons :around
|
||||
((event gnus-icalendar-event) handle)
|
||||
(if (and (boundp 'mu4e~view-rendering)
|
||||
(gnus-icalendar-event:rsvp event))
|
||||
`(("Accept" mu4e-icalendar-reply (,handle accepted ,event))
|
||||
("Tentative" mu4e-icalendar-reply (,handle tentative ,event))
|
||||
("Decline" mu4e-icalendar-reply (,handle declined ,event)))
|
||||
(cl-call-next-method event handle))))
|
||||
|
||||
(defun mu4e-icalendar-reply (data)
|
||||
"Reply to a text/calendar event."
|
||||
;; Based on `gnus-icalendar-reply'.
|
||||
(let* ((handle (car data))
|
||||
(status (cadr data))
|
||||
(event (caddr data))
|
||||
(reply (gnus-icalendar-with-decoded-handle handle
|
||||
(gnus-icalendar-event-reply-from-buffer
|
||||
(current-buffer) status (gnus-icalendar-identities))))
|
||||
(msg (mu4e-message-at-point 'noerror)))
|
||||
|
||||
(when reply
|
||||
(cl-labels
|
||||
((fold-icalendar-buffer
|
||||
()
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)
|
||||
(replace-match "\\1\n \\2")
|
||||
(goto-char (line-beginning-position)))))
|
||||
(let ((subject (concat (capitalize (symbol-name status))
|
||||
": " (gnus-icalendar-event:summary event))))
|
||||
|
||||
(with-current-buffer (get-buffer-create gnus-icalendar-reply-bufname)
|
||||
(delete-region (point-min) (point-max))
|
||||
(insert reply)
|
||||
(fold-icalendar-buffer)
|
||||
(mu4e-icalendar-reply-with-buffer msg subject (buffer-name)))
|
||||
|
||||
;; Back in article buffer
|
||||
(setq-local gnus-icalendar-reply-status status)
|
||||
(when gnus-icalendar-org-enabled-p
|
||||
(gnus-icalendar--update-org-event event status)
|
||||
;; refresh article buffer to update the reply status
|
||||
(with-current-buffer mu4e~headers-buffer-name
|
||||
(mu4e-headers-rerun-search))))))))
|
||||
|
||||
(defun mu4e~icalendar-delete-citation ()
|
||||
(delete-region (point-min) (point-max)))
|
||||
|
||||
(defun mu4e-icalendar-reply-with-buffer (original-msg subject buffer-name)
|
||||
(let ((message-signature nil))
|
||||
(let ((mu4e-compose-cite-function #'mu4e~icalendar-delete-citation)
|
||||
(mu4e-sent-messages-behavior 'delete)
|
||||
(mu4e-compose-reply-recipients 'sender))
|
||||
;; FIXME: only reply to the original sender (do not ask)
|
||||
(mu4e~compose-handler 'reply original-msg))
|
||||
(message-goto-body)
|
||||
(insert "\n\n")
|
||||
(mml-insert-multipart "alternative")
|
||||
(mml-insert-empty-tag 'part 'type "text/plain")
|
||||
(mml-attach-buffer buffer-name "text/calendar; method=REPLY; charset=UTF-8")
|
||||
(message-goto-subject)
|
||||
(delete-region (line-beginning-position) (line-end-position))
|
||||
(insert "Subject: " subject)
|
||||
; (message-send-and-exit)
|
||||
))
|
||||
|
||||
|
||||
|
||||
(provide 'mu4e-icalendar)
|
||||
;;; mu4e-icalendar.el ends here
|
|
@ -405,6 +405,14 @@ predicate function. A value of nil keeps all the addresses."
|
|||
(repeat string))
|
||||
:group 'mu4e-compose)
|
||||
|
||||
(defcustom mu4e-compose-reply-recipients 'ask
|
||||
"Which recipients to use when replying to a message.
|
||||
May be 'ask, 'all, 'sender."
|
||||
:type '(choice ask
|
||||
all
|
||||
sender)
|
||||
:group 'mu4e-compose)
|
||||
|
||||
(defcustom mu4e-compose-reply-to-address nil
|
||||
"The Reply-To address.
|
||||
Useful when this is not equal to the From: address."
|
||||
|
|
|
@ -381,7 +381,8 @@ article-mode."
|
|||
gnus-summary-buffer (get-buffer-create " *appease-gnus*")
|
||||
gnus-original-article-buffer (current-buffer))
|
||||
(run-hooks 'gnus-article-decode-hook)
|
||||
(let ((max-specpdl-size mu4e-view-max-specpdl-size))
|
||||
(let ((mu4e~view-rendering t) ; customize gnus in mu4e
|
||||
(max-specpdl-size mu4e-view-max-specpdl-size))
|
||||
(gnus-article-prepare-display))
|
||||
(mu4e-view-mode)
|
||||
(setq mu4e~view-message msg)
|
||||
|
|
Loading…
Reference in New Issue