X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=emacs%2Fnotmuch-mua.el;h=e205fa4c92ff9ce7451e1e9c908acac101a978aa;hb=0a9fc49b90dc9fd1ae737f45a0b145f42ef6df36;hp=cfdac0ef803a1f86b0a6e8d9317ee4519aecb92b;hpb=dc13fcbf8755506b2681ef3c44da98737ddab8e8;p=notmuch
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index cfdac0ef..e205fa4c 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -1,4 +1,4 @@
-;; notmuch-mua.el --- emacs style mail-user-agent
+;;; notmuch-mua.el --- emacs style mail-user-agent
;;
;; Copyright © David Edmondson
;;
@@ -15,22 +15,27 @@
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see .
+;; along with Notmuch. If not, see .
;;
;; Authors: David Edmondson
+;;; Code:
+
(require 'message)
(require 'mm-view)
(require 'format-spec)
(require 'notmuch-lib)
(require 'notmuch-address)
+(require 'notmuch-draft)
(eval-when-compile (require 'cl))
(declare-function notmuch-show-insert-body "notmuch-show" (msg body depth))
(declare-function notmuch-fcc-header-setup "notmuch-maildir-fcc" ())
-(declare-function notmuch-fcc-handler "notmuch-maildir-fcc" (destdir))
+(declare-function notmuch-maildir-message-do-fcc "notmuch-maildir-fcc" ())
+(declare-function notmuch-draft-postpone "notmuch-draft" ())
+(declare-function notmuch-draft-save "notmuch-draft" ())
;;
@@ -60,7 +65,7 @@ disabled: this would result in an incorrect behavior."))
(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
+(defcustom notmuch-mua-user-agent-function nil
"Function used to generate a `User-Agent:' string. If this is
`nil' then no `User-Agent:' will be generated."
:type '(choice (const :tag "No user agent string" nil)
@@ -71,7 +76,7 @@ disabled: this would result in an incorrect behavior."))
:value notmuch-mua-user-agent-full))
:group 'notmuch-send)
-(defcustom notmuch-mua-hidden-headers '("^User-Agent:")
+(defcustom notmuch-mua-hidden-headers nil
"Headers that are added to the `message-mode' hidden headers
list."
:type '(repeat string)
@@ -98,7 +103,7 @@ Note that these functions use `mail-citation-hook' if that is non-nil."
"Function to decide which parts get a header when replying.
This function specifies which parts of a mime message with
-mutiple parts get a header."
+multiple parts get a header."
:type '(radio (const :tag "No part headers"
notmuch-show-reply-insert-header-p-never)
(const :tag "All except multipart/* and hidden parts"
@@ -140,7 +145,7 @@ mutiple parts get a header."
(let ((notmuch-version (if (string= notmuch-emacs-version "unknown")
(notmuch-cli-version)
notmuch-emacs-version)))
- (concat "Notmuch/" notmuch-version " (http://notmuchmail.org)")))
+ (concat "Notmuch/" notmuch-version " (https://notmuchmail.org)")))
(defun notmuch-mua-user-agent-emacs ()
"Generate a `User-Agent:' string suitable for notmuch."
@@ -171,12 +176,12 @@ mutiple parts get a header."
(unless (bolp) (insert "\n")))
(defun notmuch-mua-reply (query-string &optional sender reply-all)
- (let ((args '("reply" "--format=sexp" "--format-version=1"))
+ (let ((args '("reply" "--format=sexp" "--format-version=4"))
(process-crypto notmuch-show-process-crypto)
reply
original)
(when process-crypto
- (setq args (append args '("--decrypt"))))
+ (setq args (append args '("--decrypt=true"))))
(if reply-all
(setq args (append args '("--reply-to=all")))
@@ -213,7 +218,7 @@ mutiple parts get a header."
else
collect pair)))
(notmuch-mua-mail (plist-get reply-headers :To)
- (plist-get reply-headers :Subject)
+ (notmuch-sanitize (plist-get reply-headers :Subject))
(notmuch-headers-plist-to-alist reply-headers)
nil (notmuch-mua-get-switch-function))))
@@ -248,9 +253,18 @@ mutiple parts get a header."
;; Don't omit long parts.
(notmuch-show-max-text-part-size 0)
;; Insert headers for parts as appropriate for replying.
- (notmuch-show-insert-header-p-function notmuch-mua-reply-insert-header-p-function))
- (notmuch-show-insert-body original (plist-get original :body) 0)
- (buffer-substring-no-properties (point-min) (point-max)))))
+ (notmuch-show-insert-header-p-function notmuch-mua-reply-insert-header-p-function)
+ ;; Ensure that any encrypted parts are
+ ;; decrypted during the generation of the reply
+ ;; text.
+ (notmuch-show-process-crypto process-crypto)
+ ;; Don't indent multipart sub-parts.
+ (notmuch-show-indent-multipart nil))
+ ;; We don't want sigstatus buttons (an information leak and usually wrong anyway).
+ (letf (((symbol-function 'notmuch-crypto-insert-sigstatus-button) #'ignore)
+ ((symbol-function 'notmuch-crypto-insert-encstatus-button) #'ignore))
+ (notmuch-show-insert-body original (plist-get original :body) 0)
+ (buffer-substring-no-properties (point-min) (point-max))))))
(set-mark (point))
(goto-char start)
@@ -272,13 +286,14 @@ mutiple parts get a header."
(define-derived-mode notmuch-message-mode message-mode "Message[Notmuch]"
"Notmuch message composition mode. Mostly like `message-mode'"
- (when notmuch-address-command
- (notmuch-address-setup)))
+ (notmuch-address-setup))
(put 'notmuch-message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
(define-key notmuch-message-mode-map (kbd "C-c C-c") #'notmuch-mua-send-and-exit)
(define-key notmuch-message-mode-map (kbd "C-c C-s") #'notmuch-mua-send)
+(define-key notmuch-message-mode-map (kbd "C-c C-p") #'notmuch-draft-postpone)
+(define-key notmuch-message-mode-map (kbd "C-x C-s") #'notmuch-draft-save)
(defun notmuch-mua-pop-to-buffer (name switch-function)
"Pop to buffer NAME, and warn if it already exists and is
@@ -291,7 +306,7 @@ modified. This function is notmuch addaptation of
(if window
;; Raise the frame already displaying the message buffer.
(progn
- (gnus-select-frame-set-input-focus (window-frame window))
+ (select-frame-set-input-focus (window-frame window))
(select-window window))
(funcall switch-function buffer)
(set-buffer buffer))
@@ -318,8 +333,8 @@ modified. This function is notmuch addaptation of
(push (cons 'User-Agent user-agent) other-headers))))
(unless (assq 'From other-headers)
- (push (cons 'From (concat
- (notmuch-user-name) " <" (notmuch-user-primary-email) ">")) 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)))
@@ -330,11 +345,14 @@ modified. This function is notmuch addaptation of
;; C-h f compose-mail says that headers should be specified as
;; (string . value); however all the rest of message expects
;; headers to be symbols, not strings (eg message-header-format-alist).
- ;; http://lists.gnu.org/archive/html/emacs-devel/2011-01/msg00337.html
+ ;; https://lists.gnu.org/archive/html/emacs-devel/2011-01/msg00337.html
;; We need to convert any string input, eg from rmail-start-mail.
(dolist (h other-headers other-headers)
(if (stringp (car h)) (setcar h (intern (capitalize (car h))))))))
- (args (list yank-action send-actions)))
+ (args (list yank-action send-actions))
+ ;; Cause `message-setup-1' to do things relevant for mail,
+ ;; such as observe `message-default-mail-headers'.
+ (message-this-is-mail t))
;; message-setup-1 in Emacs 23 does not accept return-action
;; argument. Pass it only if it is supplied by the caller. This
;; will never be the case when we're called by `compose-mail' in
@@ -393,7 +411,7 @@ the From: header is already filled in by notmuch."
(ido-completing-read (concat "Sender address for " name ": ") addrs
nil nil nil 'notmuch-mua-sender-history
(car addrs))))
- (concat name " <" address ">"))))
+ (message-make-from name address))))
(put 'notmuch-mua-new-mail 'notmuch-prefix-doc "... and prompt for sender")
(defun notmuch-mua-new-mail (&optional prompt-for-sender)
@@ -481,15 +499,65 @@ will be addressed to all recipients of the source message."
(notmuch-mua-reply query-string sender reply-all)
(deactivate-mark)))
+(defun notmuch-mua-check-no-misplaced-secure-tag ()
+ "Query user if there is a misplaced secure mml tag.
+
+Emacs message-send will (probably) ignore a secure mml tag unless
+it is at the start of the body. Returns t if there is no such
+tag, or the user confirms they mean it."
+ (save-excursion
+ (let ((body-start (progn (message-goto-body) (point))))
+ (goto-char (point-max))
+ (or
+ ;; We are always fine if there is no secure tag.
+ (not (search-backward "<#secure" nil 't))
+ ;; There is a secure tag, so it must be at the start of the
+ ;; body, with no secure tag earlier (i.e., in the headers).
+ (and (= (point) body-start)
+ (not (search-backward "<#secure" nil 't)))
+ ;; The user confirms they means it.
+ (yes-or-no-p "\
+There is a <#secure> tag not at the start of the body. It is
+likely that the message will be sent unsigned and unencrypted.
+Really send? ")))))
+
+(defun notmuch-mua-check-secure-tag-has-newline ()
+ "Query if the secure mml tag has a newline following it.
+
+Emacs message-send will (probably) ignore a correctly placed
+secure mml tag unless it is followed by a newline. Returns t if
+any secure tag is followed by a newline, or the user confirms
+they mean it."
+ (save-excursion
+ (message-goto-body)
+ (or
+ ;; There is no (correctly placed) secure tag.
+ (not (looking-at "<#secure"))
+ ;; The secure tag is followed by a newline.
+ (looking-at "<#secure[^\n>]*>\n")
+ ;; The user confirms they means it.
+ (yes-or-no-p "\
+The <#secure> tag at the start of the body is not followed by a
+newline. It is likely that the message will be sent unsigned and
+unencrypted. Really send? "))))
+
+(defun notmuch-mua-send-common (arg &optional exit)
+ (interactive "P")
+ (run-hooks 'notmuch-mua-send-hook)
+ (when (and (notmuch-mua-check-no-misplaced-secure-tag)
+ (notmuch-mua-check-secure-tag-has-newline))
+ (letf (((symbol-function 'message-do-fcc) #'notmuch-maildir-message-do-fcc))
+ (if exit
+ (message-send-and-exit arg)
+ (message-send arg)))))
+
(defun notmuch-mua-send-and-exit (&optional arg)
(interactive "P")
- (let ((message-fcc-handler-function #'notmuch-fcc-handler))
- (message-send-and-exit arg)))
+ (notmuch-mua-send-common arg 't))
(defun notmuch-mua-send (&optional arg)
(interactive "P")
- (let ((message-fcc-handler-function #'notmuch-fcc-handler))
- (message-send arg)))
+ (notmuch-mua-send-common arg))
(defun notmuch-mua-kill-buffer ()
(interactive)
@@ -513,3 +581,5 @@ simply runs the corresponding `message-mode' hook functions."
;;
(provide 'notmuch-mua)
+
+;;; notmuch-mua.el ends here