update nadvice
[bpt/emacs.git] / lisp / epa-mail.el
index b63890e..d1ed679 100644 (file)
@@ -1,5 +1,5 @@
 ;;; epa-mail.el --- the EasyPG Assistant, minor-mode for mail composer -*- lexical-binding: t -*-
-;; Copyright (C) 2006-2012 Free Software Foundation, Inc.
+;; Copyright (C) 2006-2014 Free Software Foundation, Inc.
 
 ;; Author: Daiki Ueno <ueno@unixuser.org>
 ;; Keywords: PGP, GnuPG, mail, message
 
 ;;;###autoload
 (define-minor-mode epa-mail-mode
-  "A minor-mode for composing encrypted/clearsigned mails."
+  "A minor-mode for composing encrypted/clearsigned mails.
+With a prefix argument ARG, enable the mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil."
   nil " epa-mail" epa-mail-mode-map)
 
 (defun epa-mail--find-usable-key (keys usage)
@@ -67,27 +70,24 @@ USAGE would be `sign' or `encrypt'."
 ;;;###autoload
 (defun epa-mail-decrypt ()
   "Decrypt OpenPGP armors in the current buffer.
-The buffer is expected to contain a mail message.
-
-Don't use this command in Lisp programs!"
+The buffer is expected to contain a mail message."
+  (declare (interactive-only t))
   (interactive)
   (epa-decrypt-armor-in-region (point-min) (point-max)))
 
 ;;;###autoload
 (defun epa-mail-verify ()
   "Verify OpenPGP cleartext signed messages in the current buffer.
-The buffer is expected to contain a mail message.
-
-Don't use this command in Lisp programs!"
+The buffer is expected to contain a mail message."
+  (declare (interactive-only t))
   (interactive)
   (epa-verify-cleartext-in-region (point-min) (point-max)))
 
 ;;;###autoload
 (defun epa-mail-sign (start end signers mode)
   "Sign the current buffer.
-The buffer is expected to contain a mail message.
-
-Don't use this command in Lisp programs!"
+The buffer is expected to contain a mail message."
+  (declare (interactive-only t))
   (interactive
    (save-excursion
      (goto-char (point-min))
@@ -106,103 +106,142 @@ If no one is selected, default secret key is used.  "
             (if verbose
                 (epa--read-signature-type)
               'clear)))))
-  (epa-sign-region start end signers mode))
+  (let ((inhibit-read-only t))
+    (epa-sign-region start end signers mode)))
+
+(defun epa-mail-default-recipients ()
+  "Return the default list of encryption recipients for a mail buffer."
+  (let ((config (epg-configuration))
+       recipients-string real-recipients)
+    (save-excursion
+      (goto-char (point-min))
+      (save-restriction
+       (narrow-to-region (point)
+                         (if (search-forward mail-header-separator nil 0)
+                             (match-beginning 0)
+                           (point)))
+       (setq recipients-string
+             (mapconcat #'identity
+                        (nconc (mail-fetch-field "to" nil nil t)
+                               (mail-fetch-field "cc" nil nil t)
+                               (mail-fetch-field "bcc" nil nil t))
+                        ","))
+       (setq recipients-string
+             (mail-strip-quoted-names
+              (with-temp-buffer
+                (insert "to: " recipients-string "\n")
+                (expand-mail-aliases (point-min) (point-max))
+                (car (mail-fetch-field "to" nil nil t))))))
+
+      (setq real-recipients
+           (split-string recipients-string "," t "[ \t\n]*"))
+
+      ;; Process all the recipients thru the list of GnuPG groups.
+      ;; Expand GnuPG group names to what they stand for.
+      (setq real-recipients
+           (apply #'nconc
+                  (mapcar
+                   (lambda (recipient)
+                     (or (epg-expand-group config recipient)
+                         (list recipient)))
+                   real-recipients)))
+
+      ;; Process all the recipients thru the user's list
+      ;; of encryption aliases.
+      (setq real-recipients
+           (apply #'nconc
+                  (mapcar
+                   (lambda (recipient)
+                     (let ((tem (assoc recipient epa-mail-aliases)))
+                       (if tem (cdr tem)
+                         (list recipient))))
+                   real-recipients)))
+      )))
 
 ;;;###autoload
-(defun epa-mail-encrypt (start end recipients sign signers)
-  "Encrypt the current buffer.
-The buffer is expected to contain a mail message.
-
-Don't use this command in Lisp programs!"
+(defun epa-mail-encrypt (&optional recipients signers)
+  "Encrypt the outgoing mail message in the current buffer.
+Takes the recipients from the text in the header in the buffer
+and translates them through `epa-mail-aliases'.
+With prefix argument, asks you to select among them interactively
+and also whether and how to sign.
+
+Called from Lisp, the optional argument RECIPIENTS is a list
+of recipient addresses, t to perform symmetric encryption,
+or nil meaning use the defaults.
+
+SIGNERS is a list of keys to sign the message with."
   (interactive
-   (save-excursion
-     (let ((verbose current-prefix-arg)
-          (config (epg-configuration))
-          (context (epg-make-context epa-protocol))
-          recipients-string recipients recipient-key sign)
-       (goto-char (point-min))
-       (save-restriction
-        (narrow-to-region (point)
-                          (if (search-forward mail-header-separator nil 0)
-                              (match-beginning 0)
-                            (point)))
-        (setq recipients-string
-              (mapconcat #'identity
-                         (nconc (mail-fetch-field "to" nil nil t)
-                                (mail-fetch-field "cc" nil nil t)
-                                (mail-fetch-field "bcc" nil nil t))
-                         ","))
-        (setq recipients
-              (mail-strip-quoted-names
-               (with-temp-buffer
-                 (insert "to: " recipients-string "\n")
-                 (expand-mail-aliases (point-min) (point-max))
-                 (car (mail-fetch-field "to" nil nil t))))))
-       (if recipients
-          (setq recipients (delete ""
-                                   (split-string recipients
-                                                 "[ \t\n]*,[ \t\n]*"))))
-
-       ;; Process all the recipients thru the list of GnuPG groups.
-       ;; Expand GnuPG group names to what they stand for.
-       (setq recipients
-            (apply #'nconc
+   (let ((verbose current-prefix-arg)
+        (context (epg-make-context epa-protocol)))
+     (list (if verbose
+              (or (epa-select-keys
+                   context
+                   "Select recipients for encryption.
+If no one is selected, symmetric encryption will be performed.  "
+                   (epa-mail-default-recipients))
+                  t))
+          (and verbose (y-or-n-p "Sign? ")
+               (epa-select-keys context
+                                "Select keys for signing.  ")))))
+  (let (start recipient-keys default-recipients)
+    (save-excursion
+      (setq recipient-keys
+           (cond ((eq recipients t)
+                  nil)
+                 (recipients recipients)
+                 (t
+                  (setq default-recipients
+                        (epa-mail-default-recipients))
+                  ;; Convert recipients to keys.
+                  (apply
+                   'nconc
                    (mapcar
                     (lambda (recipient)
-                      (or (epg-expand-group config recipient)
-                          (list recipient)))
-                    recipients)))
-
-       (goto-char (point-min))
-       (if (search-forward mail-header-separator nil t)
-          (forward-line))
-       (setq epa-last-coding-system-specified
-            (or coding-system-for-write
-                (epa--select-safe-coding-system (point) (point-max))))
-       (list (point) (point-max)
-            (if verbose
-                (epa-select-keys
-                 context
-                 "Select recipients for encryption.
-If no one is selected, symmetric encryption will be performed.  "
-                 recipients)
-              (if recipients
-                  (mapcar
-                   (lambda (recipient)
-                     (setq recipient-key
-                           (epa-mail--find-usable-key
-                            (epg-list-keys
-                             (epg-make-context epa-protocol)
-                             (if (string-match "@" recipient)
-                                 (concat "<" recipient ">")
-                               recipient))
-                            'encrypt))
-                     (unless (or recipient-key
-                                 (y-or-n-p
-                                  (format
-                                   "No public key for %s; skip it? "
-                                   recipient)))
-                       (error "No public key for %s" recipient))
-                     recipient-key)
-                   recipients)))
-            (setq sign (if verbose (y-or-n-p "Sign? ")))
-            (if sign
-                (epa-select-keys context
-                                 "Select keys for signing.  "))))))
-  (epa-encrypt-region start end recipients sign signers))
+                      (let ((recipient-key
+                             (epa-mail--find-usable-key
+                              (epg-list-keys
+                               (epg-make-context epa-protocol)
+                               (if (string-match "@" recipient)
+                                   (concat "<" recipient ">")
+                                 recipient))
+                              'encrypt)))
+                        (unless (or recipient-key
+                                    (y-or-n-p
+                                     (format
+                                      "No public key for %s; skip it? "
+                                      recipient)))
+                          (error "No public key for %s" recipient))
+                        (if recipient-key (list recipient-key))))
+                      default-recipients)))))
+
+      (goto-char (point-min))
+      (if (search-forward mail-header-separator nil t)
+         (forward-line))
+      (setq start (point))
+
+      (setq epa-last-coding-system-specified
+           (or coding-system-for-write
+               (epa--select-safe-coding-system (point) (point-max)))))
+
+    ;; Don't let some read-only text stop us from encrypting.
+    (let ((inhibit-read-only t))
+      (epa-encrypt-region start (point-max) recipient-keys signers signers))))
 
 ;;;###autoload
 (defun epa-mail-import-keys ()
   "Import keys in the OpenPGP armor format in the current buffer.
-The buffer is expected to contain a mail message.
-
-Don't use this command in Lisp programs!"
+The buffer is expected to contain a mail message."
+  (declare (interactive-only t))
   (interactive)
   (epa-import-armor-in-region (point-min) (point-max)))
 
 ;;;###autoload
 (define-minor-mode epa-global-mail-mode
-  "Minor mode to hook EasyPG into Mail mode."
+  "Minor mode to hook EasyPG into Mail mode.
+With a prefix argument ARG, enable the mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil."
   :global t :init-value nil :group 'epa-mail :version "23.1"
   (remove-hook 'mail-mode-hook 'epa-mail-mode)
   (if epa-global-mail-mode