X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch-mua.el;h=bbf059a22cb5487f669497631363a7c924b1d3d8;hp=2e4dc71a8d5a7358e4addf1036a2d169ee6fc2e3;hb=HEAD;hpb=692acdf9da2ca93d46259ca31780ed632c2975c4 diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 2e4dc71a..bf62b656 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -21,9 +21,10 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(eval-when-compile (require 'subr-x)) (require 'message) +(require 'gmm-utils) (require 'mm-view) (require 'format-spec) @@ -219,11 +220,10 @@ Typically this is added to `notmuch-mua-send-hook'." (defun notmuch-mua-reply-crypto (parts) "Add mml sign-encrypt flag if any part of original message is encrypted." (cl-loop for part in parts - if (notmuch-match-content-type (plist-get part :content-type) - "multipart/encrypted") + for type = (plist-get part :content-type) + if (notmuch-match-content-type type "multipart/encrypted") do (mml-secure-message-sign-encrypt) - else if (notmuch-match-content-type (plist-get part :content-type) - "multipart/*") + else if (notmuch-match-content-type type "multipart/*") do (notmuch-mua-reply-crypto (plist-get part :content)))) ;; There is a bug in Emacs' message.el that results in a newline @@ -237,11 +237,12 @@ Typically this is added to `notmuch-mua-send-hook'." ;;; Mua reply -(defun notmuch-mua-reply (query-string &optional sender reply-all) - (let ((args '("reply" "--format=sexp" "--format-version=4")) - (process-crypto notmuch-show-process-crypto) - reply - original) +(defun notmuch-mua-reply (query-string &optional sender reply-all duplicate) + (let* ((duparg (and duplicate (list (format "--duplicate=%d" duplicate)))) + (args `("reply" "--format=sexp" "--format-version=5" ,@duparg)) + (process-crypto notmuch-show-process-crypto) + reply + original) (when process-crypto (setq args (append args '("--decrypt=true")))) (if reply-all @@ -319,7 +320,9 @@ Typically this is added to `notmuch-mua-send-hook'." ;; text. (notmuch-show-process-crypto process-crypto) ;; Don't indent multipart sub-parts. - (notmuch-show-indent-multipart nil)) + (notmuch-show-indent-multipart nil) + ;; Stop certain mime types from being inlined + (mm-inline-override-types (notmuch--inline-override-types))) ;; We don't want sigstatus buttons (an information leak and usually wrong anyway). (cl-letf (((symbol-function 'notmuch-crypto-insert-sigstatus-button) #'ignore) ((symbol-function 'notmuch-crypto-insert-encstatus-button) #'ignore)) @@ -344,8 +347,8 @@ Typically this is added to `notmuch-mua-send-hook'." (defvar notmuch-message-mode-map (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-c C-c") #'notmuch-mua-send-and-exit) - (define-key map (kbd "C-c C-s") #'notmuch-mua-send) + (define-key map [remap message-send-and-exit] #'notmuch-mua-send-and-exit) + (define-key map [remap message-send] #'notmuch-mua-send) (define-key map (kbd "C-c C-p") #'notmuch-draft-postpone) (define-key map (kbd "C-x C-s") #'notmuch-draft-save) map) @@ -383,20 +386,37 @@ instead of `message-mode' and SWITCH-FUNCTION is mandatory." (erase-buffer) (notmuch-message-mode))) +(defun notmuch-mua--remove-dont-reply-to-names () + (when-let* ((nr (if (functionp message-dont-reply-to-names) + message-dont-reply-to-names + (gmm-regexp-concat message-dont-reply-to-names))) + (nr-filter + (if (functionp nr) + (lambda (mail) (and (not (funcall nr mail)) mail)) + (lambda (mail) (and (not (string-match-p nr mail)) mail))))) + (dolist (header '("To" "Cc")) + (when-let ((v (message-fetch-field header))) + (let* ((tokens (mapcar #'string-trim (message-tokenize-header v))) + (good-tokens (delq nil (mapcar nr-filter tokens))) + (addr (and good-tokens (mapconcat #'identity good-tokens ", ")))) + (message-replace-header header addr)))))) + +;;;#autoload (defun notmuch-mua-mail (&optional to subject other-headers _continue switch-function yank-action send-actions - return-action &rest ignored) - "Invoke the notmuch mail composition window." + return-action &rest _ignored) + "Invoke the notmuch mail composition window. + +The position of point when the function returns differs depending +on the values of TO and SUBJECT. If both are non-nil, point is +moved to the message's body. If SUBJECT is nil but TO isn't, +point is moved to the \"Subject:\" header. Otherwise, point is +moved to the \"To:\" header." (interactive) (when notmuch-mua-user-agent-function (let ((user-agent (funcall notmuch-mua-user-agent-function))) - (unless (string= "" user-agent) + (unless (string-empty-p user-agent) (push (cons 'User-Agent user-agent) other-headers)))) - (unless (assq 'From other-headers) - (push (cons 'From (message-make-from - (notmuch-user-name) - (notmuch-user-primary-email))) - other-headers)) (notmuch-mua-pop-to-buffer (message-buffer-name "mail" to) (or switch-function (notmuch-mua-get-switch-function))) @@ -415,13 +435,22 @@ instead of `message-mode' and SWITCH-FUNCTION is mandatory." ;; Cause `message-setup-1' to do things relevant for mail, ;; such as observe `message-default-mail-headers'. (message-this-is-mail t)) + (unless (assq 'From headers) + (push (cons 'From (message-make-from + (notmuch-user-name) + (notmuch-user-primary-email))) + headers)) (message-setup-1 headers yank-action send-actions return-action)) (notmuch-fcc-header-setup) + (notmuch-mua--remove-dont-reply-to-names) (message-sort-headers) (message-hide-headers) (set-buffer-modified-p nil) (notmuch-mua-maybe-set-window-dedicated) - (message-goto-to)) + (cond + ((and to subject) (message-goto-body)) + (to (message-goto-subject)) + (t (message-goto-to)))) (defvar notmuch-mua-sender-history nil) @@ -477,7 +506,7 @@ the From: address." (with-current-buffer temp-buffer (erase-buffer) (let ((coding-system-for-read 'no-conversion)) - (call-process notmuch-command nil t nil + (notmuch--call-process notmuch-command nil t nil "show" "--format=raw" id)) ;; Because we process the messages in reverse order, ;; always generate a forwarded subject, then use the @@ -513,12 +542,13 @@ the From: address." (message-hide-headers) (set-buffer-modified-p nil)))) -(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all) +(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all duplicate) "Compose a reply to the message identified by QUERY-STRING. If PROMPT-FOR-SENDER is non-nil, the user will be prompted for the From: address first. If REPLY-ALL is non-nil, the message -will be addressed to all recipients of the source message." +will be addressed to all recipients of the source message. If +DUPLICATE is non-nil, based the reply on that duplicate file" ;; `select-active-regions' is t by default. The reply insertion code ;; sets the region to the quoted message to make it easy to delete ;; (kill-region or C-w). These two things combine to put the quoted @@ -533,7 +563,7 @@ will be addressed to all recipients of the source message." (let ((sender (and prompt-for-sender (notmuch-mua-prompt-for-sender))) (select-active-regions nil)) - (notmuch-mua-reply query-string sender reply-all) + (notmuch-mua-reply query-string sender reply-all duplicate) (deactivate-mark))) ;;; Checks @@ -593,20 +623,24 @@ unencrypted. Really send? ")))) (message-send-and-exit arg) (message-send arg))))) +;;;#autoload (defun notmuch-mua-send-and-exit (&optional arg) (interactive "P") (notmuch-mua-send-common arg t)) +;;;#autoload (defun notmuch-mua-send (&optional arg) (interactive "P") (notmuch-mua-send-common arg)) +;;;#autoload (defun notmuch-mua-kill-buffer () (interactive) (message-kill-buffer)) ;;; _ +;;;#autoload (define-mail-user-agent 'notmuch-user-agent 'notmuch-mua-mail 'notmuch-mua-send-and-exit