X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch-mua.el;h=24eebffa3b97699d0d566d85f8c17dc40fc69642;hp=6aae3a0578f6651a54758cc459476782f0b0a9fd;hb=2cdb3f54f71e5e415a930aaa36452ffe1db04d06;hpb=2ee1d8e1c70ce20728bc3faada389a4802636352 diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 6aae3a05..24eebffa 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -21,6 +21,7 @@ (require 'json) (require 'message) +(require 'mm-view) (require 'format-spec) (require 'notmuch-lib) @@ -36,6 +37,26 @@ :group 'notmuch-send :group 'notmuch-hooks) +(defcustom notmuch-mua-compose-in 'current-window + (concat + "Where to create the mail buffer used to compose a new message. +Possible values are `current-window' (default), `new-window' and +`new-frame'. If set to `current-window', the mail buffer will be +displayed in the current window, so the old buffer will be +restored when the mail buffer is killed. If set to `new-window' +or `new-frame', the mail buffer will be displayed in a new +window/frame that will be destroyed when the buffer is killed. +You may want to customize `message-kill-buffer-on-exit' +accordingly." + (when (< emacs-major-version 24) + " Due to a known bug in Emacs 23, you should not set +this to `new-window' if `message-kill-buffer-on-exit' is +disabled: this would result in an incorrect behavior.")) + :group 'notmuch-send + :type '(choice (const :tag "Compose in the current window" current-window) + (const :tag "Compose mail in a new window" new-window) + (const :tag "Compose mail in a new frame" new-frame))) + (defcustom notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full "Function used to generate a `User-Agent:' string. If this is `nil' then no `User-Agent:' will be generated." @@ -55,6 +76,23 @@ list." ;; +(defun notmuch-mua-get-switch-function () + "Get a switch function according to `notmuch-mua-compose-in'." + (cond ((eq notmuch-mua-compose-in 'current-window) + 'switch-to-buffer) + ((eq notmuch-mua-compose-in 'new-window) + 'switch-to-buffer-other-window) + ((eq notmuch-mua-compose-in 'new-frame) + 'switch-to-buffer-other-frame) + (t (error "Invalid value for `notmuch-mua-compose-in'")))) + +(defun notmuch-mua-maybe-set-window-dedicated () + "Set the selected window as dedicated according to +`notmuch-mua-compose-in'." + (when (or (eq notmuch-mua-compose-in 'new-frame) + (eq notmuch-mua-compose-in 'new-window)) + (set-window-dedicated-p (selected-window) t))) + (defun notmuch-mua-user-agent-full () "Generate a `User-Agent:' string suitable for notmuch." (concat (notmuch-mua-user-agent-notmuch) @@ -90,8 +128,25 @@ list." else if (notmuch-match-content-type (plist-get part :content-type) "text/*") collect part)) +(defun notmuch-mua-insert-quotable-part (message part) + (save-restriction + (narrow-to-region (point) (point)) + (notmuch-mm-display-part-inline message part (plist-get part :id) + (plist-get part :content-type) + notmuch-show-process-crypto) + (goto-char (point-max)))) + +;; There is a bug in emacs 23's message.el that results in a newline +;; not being inserted after the References header, so the next header +;; is concatenated to the end of it. This function fixes the problem, +;; while guarding against the possibility that some current or future +;; version of emacs has the bug fixed. +(defun notmuch-mua-insert-references (original-func header references) + (funcall original-func header references) + (unless (bolp) (insert "\n"))) + (defun notmuch-mua-reply (query-string &optional sender reply-all) - (let ((args '("reply" "--format=json")) + (let ((args '("reply" "--format=json" "--format-version=1")) reply original) (when notmuch-show-process-crypto @@ -103,13 +158,7 @@ list." (setq args (append args (list query-string))) ;; Get the reply object as JSON, and parse it into an elisp object. - (with-temp-buffer - (apply 'call-process (append (list notmuch-command nil (list t t) nil) args)) - (goto-char (point-min)) - (let ((json-object-type 'plist) - (json-array-type 'list) - (json-false 'nil)) - (setq reply (json-read)))) + (setq reply (apply #'notmuch-call-notmuch-json args)) ;; Extract the original message to simplify the following code. (setq original (plist-get reply :original)) @@ -125,9 +174,23 @@ list." ;; Overlay the composition window on that being used to read ;; the original message. ((same-window-regexps '("\\*mail .*"))) - (notmuch-mua-mail (plist-get reply-headers :To) - (plist-get reply-headers :Subject) - (notmuch-plist-to-alist reply-headers))) + + ;; We modify message-header-format-alist to get around a bug in message.el. + ;; See the comment above on notmuch-mua-insert-references. + (let ((message-header-format-alist + (loop for pair in message-header-format-alist + if (eq (car pair) 'References) + collect (cons 'References + (apply-partially + 'notmuch-mua-insert-references + (cdr pair))) + else + collect pair))) + (notmuch-mua-mail (plist-get reply-headers :To) + (plist-get reply-headers :Subject) + (notmuch-headers-plist-to-alist reply-headers) + nil (notmuch-mua-get-switch-function)))) + ;; Insert the message body - but put it in front of the signature ;; if one is present (goto-char (point-max)) @@ -147,11 +210,7 @@ list." ;; Get the parts of the original message that should be quoted; this includes ;; all the text parts, except the non-preferred ones in a multipart/alternative. (let ((quotable-parts (notmuch-mua-get-quotable-parts (plist-get original :body)))) - (mapc (lambda (part) - (insert (notmuch-get-bodypart-content original part - (plist-get part :id) - notmuch-show-process-crypto))) - quotable-parts)) + (mapc (apply-partially 'notmuch-mua-insert-quotable-part original) quotable-parts)) (set-mark (point)) (goto-char start) @@ -164,6 +223,7 @@ list." (set-buffer-modified-p nil)) (defun notmuch-mua-forward-message () + (funcall (notmuch-mua-get-switch-function) (current-buffer)) (message-forward) (when notmuch-mua-user-agent-function @@ -173,6 +233,7 @@ list." (message-sort-headers) (message-hide-headers) (set-buffer-modified-p nil) + (notmuch-mua-maybe-set-window-dedicated) (message-goto-to)) @@ -185,16 +246,17 @@ OTHER-ARGS are passed through to `message-mail'." (when notmuch-mua-user-agent-function (let ((user-agent (funcall notmuch-mua-user-agent-function))) (when (not (string= "" user-agent)) - (push (cons "User-Agent" user-agent) other-headers)))) + (push (cons 'User-Agent user-agent) other-headers)))) - (unless (mail-header 'From other-headers) - (push (cons "From" (concat - (notmuch-user-name) " <" (notmuch-user-primary-email) ">")) other-headers)) + (unless (assq 'From other-headers) + (push (cons 'From (concat + (notmuch-user-name) " <" (notmuch-user-primary-email) ">")) other-headers)) (apply #'message-mail to subject other-headers other-args) (message-sort-headers) (message-hide-headers) (set-buffer-modified-p nil) + (notmuch-mua-maybe-set-window-dedicated) (message-goto-to)) @@ -251,7 +313,7 @@ the From: address first." (let ((other-headers (when (or prompt-for-sender notmuch-always-prompt-for-sender) (list (cons 'From (notmuch-mua-prompt-for-sender)))))) - (notmuch-mua-mail nil nil other-headers))) + (notmuch-mua-mail nil nil other-headers nil (notmuch-mua-get-switch-function)))) (defun notmuch-mua-new-forward-message (&optional prompt-for-sender) "Invoke the notmuch message forwarding window.