summaryrefslogtreecommitdiff
path: root/lisp/gnus/message.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/gnus/message.el')
-rw-r--r--lisp/gnus/message.el685
1 files changed, 346 insertions, 339 deletions
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index d260bdb2a2c..986567faa1f 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -28,9 +28,7 @@
;;; Code:
-(eval-when-compile
- (require 'cl))
-
+(require 'cl-lib)
(require 'mailheader)
(require 'gmm-utils)
(require 'mail-utils)
@@ -158,7 +156,7 @@ If this variable is nil, no such courtesy message will be added."
:group 'message-interface
:type 'regexp)
-(defcustom message-from-style mail-from-style
+(defcustom message-from-style 'angles
"Specifies how \"From\" headers look.
If nil, they contain just the return address like:
@@ -170,12 +168,16 @@ If `angles', they look like:
Otherwise, most addresses look like `angles', but they look like
`parens' if `angles' would need quoting and `parens' would not."
- :version "23.2"
+ :version "27.1"
:type '(choice (const :tag "simple" nil)
(const parens)
(const angles)
(const default))
:group 'message-headers)
+(make-obsolete-variable
+ 'message-from-style
+ "Only the `angles' value is valid according to RFC2822" "27.1")
+
(defcustom message-insert-canlock t
"Whether to insert a Cancel-Lock header in news postings."
@@ -550,10 +552,15 @@ The provided functions are:
(function-item message-forward-subject-name-subject)
(repeat :tag "List of functions" function)))
-(defcustom message-forward-as-mime t
+(defcustom message-forward-as-mime nil
"Non-nil means forward messages as an inline/rfc822 MIME section.
-Otherwise, directly inline the old message in the forwarded message."
- :version "21.1"
+Otherwise, directly inline the old message in the forwarded
+message.
+
+When forwarding as MIME, certain MIME-related headers in the
+forwarded message may be removed/altered to ensure that the
+resulting mail is syntactically valid."
+ :version "27.1"
:group 'message-forwarding
:link '(custom-manual "(message)Forwarding")
:type 'boolean)
@@ -605,6 +612,9 @@ Done before generating the new subject of a forward."
(defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus"
"All headers that match this regexp will be deleted when forwarding a message.
+This variable is only consulted when forwarding \"normally\", not
+when forwarding as MIME or the like.
+
This may also be a list of regexps."
:version "21.1"
:group 'message-forwarding
@@ -615,11 +625,12 @@ This may also be a list of regexps."
(widget-editable-list-match widget value)))
regexp))
-(defcustom message-forward-included-headers nil
+(defcustom message-forward-included-headers
+ '("^From:" "^Subject:" "^Date:")
"If non-nil, delete non-matching headers when forwarding a message.
Only headers that match this regexp will be included. This
variable should be a regexp or a list of regexps."
- :version "25.1"
+ :version "27.1"
:group 'message-forwarding
:type '(repeat :value-to-internal (lambda (widget value)
(custom-split-regexp-maybe value))
@@ -1067,13 +1078,15 @@ point and mark around the citation text as modified."
(defcustom message-signature mail-signature
"String to be inserted at the end of the message buffer.
-If t, the `message-signature-file' file will be inserted instead.
-If a function, the result from the function will be used instead.
-If a form, the result from the form will be used instead."
+If nil, don't insert a signature.
+If t, insert `message-signature-file'.
+If a function or form, insert its result.
+See `mail-signature' for the recommended format of a signature."
:version "23.2"
- :type '(choice string (const :tag "Contents of signature file" t)
- function
- sexp)
+ :type '(choice string
+ (const :tag "None" nil)
+ (const :tag "Contents of signature file" t)
+ function sexp)
:risky t
:link '(custom-manual "(message)Insertion Variables")
:group 'message-insertion)
@@ -1241,13 +1254,13 @@ called and its result is inserted."
;; Ease the transition from mail-mode to message-mode. See bugs#4431, 5555.
(concat (if (and (boundp 'mail-default-reply-to)
(stringp mail-default-reply-to))
- (format "Reply-to: %s\n" mail-default-reply-to))
+ (format "Reply-To: %s\n" mail-default-reply-to))
(if (and (boundp 'mail-self-blind)
mail-self-blind)
- (format "BCC: %s\n" user-mail-address))
+ (format "Bcc: %s\n" user-mail-address))
(if (and (boundp 'mail-archive-file-name)
(stringp mail-archive-file-name))
- (format "FCC: %s\n" mail-archive-file-name))
+ (format "Fcc: %s\n" mail-archive-file-name))
mail-default-headers)
"A string of header lines to be inserted in outgoing mails."
:version "23.2"
@@ -1277,7 +1290,7 @@ called and its result is inserted."
;; According to RFC 822 and its successors, the field name must
;; consist of printable US-ASCII characters other than colon,
;; i.e., decimal 33-56 and 59-126.
- '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))
+ '(looking-at "[ \t]\\|[][!\"#$%&'()*+,./0-9;<=>?@A-Z\\^_`a-z{|}~-]+:"))
"Set this non-nil if the system's mailer runs the header and body together.
\(This problem exists on Sunos 4 when sendmail is run in remote mode.)
The value should be an expression to test whether the problem will
@@ -1340,7 +1353,8 @@ If nil, Message won't auto-save."
:link '(custom-manual "(message)Various Message Variables")
:type '(choice directory (const :tag "Don't auto-save" nil)))
-(defcustom message-default-charset (and (not (mm-multibyte-p)) 'iso-8859-1)
+(defcustom message-default-charset (and (not enable-multibyte-characters)
+ 'iso-8859-1)
"Default charset used in non-MULE Emacsen.
If nil, you might be asked to input the charset."
:version "21.1"
@@ -1435,8 +1449,6 @@ starting with `not' and followed by regexps."
:bold t :italic t))
"Face used for displaying To headers."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-to-face
- 'message-header-to "22.1")
(defface message-header-cc
'((((class color)
@@ -1449,8 +1461,6 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying Cc headers."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-cc-face
- 'message-header-cc "22.1")
(defface message-header-subject
'((((class color)
@@ -1463,8 +1473,6 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying Subject headers."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-subject-face
- 'message-header-subject "22.1")
(defface message-header-newsgroups
'((((class color)
@@ -1477,8 +1485,6 @@ starting with `not' and followed by regexps."
:bold t :italic t))
"Face used for displaying Newsgroups headers."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-newsgroups-face
- 'message-header-newsgroups "22.1")
(defface message-header-other
'((((class color)
@@ -1491,8 +1497,6 @@ starting with `not' and followed by regexps."
:bold t :italic t))
"Face used for displaying other headers."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-other-face
- 'message-header-other "22.1")
(defface message-header-name
'((((class color)
@@ -1505,8 +1509,6 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying header names."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-name-face
- 'message-header-name "22.1")
(defface message-header-xheader
'((((class color)
@@ -1519,8 +1521,6 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying X-Header headers."
:group 'message-faces)
-(define-obsolete-face-alias 'message-header-xheader-face
- 'message-header-xheader "22.1")
(defface message-separator
'((((class color)
@@ -1533,8 +1533,6 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying the separator."
:group 'message-faces)
-(define-obsolete-face-alias 'message-separator-face
- 'message-separator "22.1")
(defface message-cited-text
'((((class color)
@@ -1547,8 +1545,6 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying cited text names."
:group 'message-faces)
-(define-obsolete-face-alias 'message-cited-text-face
- 'message-cited-text "22.1")
(defface message-mml
'((((class color)
@@ -1561,66 +1557,65 @@ starting with `not' and followed by regexps."
:bold t))
"Face used for displaying MML."
:group 'message-faces)
-(define-obsolete-face-alias 'message-mml-face
- 'message-mml "22.1")
-(defun message-font-lock-make-header-matcher (regexp)
- (let ((form
- `(lambda (limit)
- (let ((start (point)))
- (save-restriction
- (widen)
- (goto-char (point-min))
- (if (re-search-forward
- (concat "^" (regexp-quote mail-header-separator) "$")
- nil t)
- (setq limit (min limit (match-beginning 0))))
- (goto-char start))
- (and (< start limit)
- (re-search-forward ,regexp limit t))))))
- (if (featurep 'bytecomp)
- (byte-compile form)
- form)))
+(defun message-match-to-eoh (_limit)
+ (let ((start (point)))
+ (rfc822-goto-eoh)
+ ;; Typical situation: some temporary change causes the header to be
+ ;; incorrect, so EOH comes earlier than intended: the last lines of the
+ ;; intended headers are now not considered part of the header any more,
+ ;; so they don't have the multiline property set. When the change is
+ ;; completed and the header has its correct shape again, the lack of the
+ ;; multiline property means we won't rehighlight the last lines of
+ ;; the header.
+ (if (< (point) start)
+ nil ;No header within start..limit.
+ ;; Here we disregard LIMIT so that we may extend the area again.
+ (set-match-data (list start (point)))
+ (point))))
(defvar message-font-lock-keywords
(let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
- `((,(message-font-lock-make-header-matcher
- (concat "^\\([Tt]o:\\)" content))
- (1 'message-header-name)
- (2 'message-header-to nil t))
- (,(message-font-lock-make-header-matcher
- (concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content))
- (1 'message-header-name)
- (2 'message-header-cc nil t))
- (,(message-font-lock-make-header-matcher
- (concat "^\\([Ss]ubject:\\)" content))
- (1 'message-header-name)
- (2 'message-header-subject nil t))
- (,(message-font-lock-make-header-matcher
- (concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content))
- (1 'message-header-name)
- (2 'message-header-newsgroups nil t))
- (,(message-font-lock-make-header-matcher
- (concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content))
- (1 'message-header-name)
- (2 'message-header-xheader))
- (,(message-font-lock-make-header-matcher
- (concat "^\\([A-Z][^: \n\t]+:\\)" content))
- (1 'message-header-name)
- (2 'message-header-other nil t))
- ,@(if (and mail-header-separator
- (not (equal mail-header-separator "")))
- `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
- 1 'message-separator))
- nil)
- ((lambda (limit)
- (re-search-forward (concat "^\\("
- message-cite-prefix-regexp
- "\\).*")
- limit t))
- (0 'message-cited-text))
- ("<#/?\\(multipart\\|part\\|external\\|mml\\|secure\\)[^>]*>"
- (0 'message-mml))))
+ `((message-match-to-eoh
+ (,(concat "^\\([Tt]o:\\)" content)
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'message-header-name)
+ (2 'message-header-to nil t))
+ (,(concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content)
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'message-header-name)
+ (2 'message-header-cc nil t))
+ (,(concat "^\\([Ss]ubject:\\)" content)
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'message-header-name)
+ (2 'message-header-subject nil t))
+ (,(concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content)
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'message-header-name)
+ (2 'message-header-newsgroups nil t))
+ (,(concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content)
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'message-header-name)
+ (2 'message-header-xheader))
+ (,(concat "^\\([A-Z][^: \n\t]+:\\)" content)
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'message-header-name)
+ (2 'message-header-other nil t)))
+ (,(lambda (limit)
+ (and mail-header-separator
+ (not (equal mail-header-separator ""))
+ (re-search-forward
+ (concat "^" (regexp-quote mail-header-separator) "$")
+ limit t)))
+ 0 'message-separator)
+ (,(lambda (limit)
+ (re-search-forward (concat "^\\(?:"
+ message-cite-prefix-regexp
+ "\\).*")
+ limit t))
+ 0 'message-cited-text)
+ ("<#/?\\(?:multipart\\|part\\|external\\|mml\\|secure\\)[^>]*>"
+ 0 'message-mml)))
"Additional expressions to highlight in Message mode.")
(defvar message-face-alist
@@ -1773,6 +1768,7 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'."
;;; Internal variables.
+(defvar message-inhibit-body-encoding nil)
(defvar message-sending-message "Sending...")
(defvar message-buffer-list nil)
(defvar message-this-is-news nil)
@@ -1861,7 +1857,7 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'."
"Alist of header names/filler functions.")
(defvar message-header-format-alist
- `((From)
+ '((From)
(Newsgroups)
(To)
(Cc)
@@ -2039,8 +2035,7 @@ see `message-narrow-to-headers-or-head'."
(defmacro message-with-reply-buffer (&rest forms)
"Evaluate FORMS in the reply buffer, if it exists."
- `(when (and (bufferp message-reply-buffer)
- (buffer-name message-reply-buffer))
+ `(when (buffer-live-p message-reply-buffer)
(with-current-buffer message-reply-buffer
,@forms)))
@@ -2060,8 +2055,9 @@ see `message-narrow-to-headers-or-head'."
(let ((regexp (if (stringp gnus-list-identifiers)
gnus-list-identifiers
(mapconcat 'identity gnus-list-identifiers " *\\|"))))
- (if (string-match (concat "\\(\\(\\(Re: +\\)?\\(" regexp
- " *\\)\\)+\\(Re: +\\)?\\)") subject)
+ (if (and (not (equal regexp ""))
+ (string-match (concat "\\(\\(\\(Re: +\\)?\\(" regexp
+ " *\\)\\)+\\(Re: +\\)?\\)") subject))
(concat (substring subject 0 (match-beginning 1))
(or (match-string 3 subject)
(match-string 5 subject))
@@ -2435,7 +2431,7 @@ Return the number of headers removed."
(looking-at "[!-9;-~]+:"))
(looking-at regexp))
(progn
- (incf number)
+ (cl-incf number)
(when first
(setq last t))
(delete-region
@@ -2460,10 +2456,10 @@ Return the number of headers removed."
(save-excursion
(goto-char (point-min))
(while (re-search-forward regexp nil t)
- (incf count)))
+ (cl-incf count)))
(while (> count 1)
(message-remove-header header nil t)
- (decf count))))
+ (cl-decf count))))
(defun message-narrow-to-headers ()
"Narrow the buffer to the head of the message."
@@ -2606,6 +2602,36 @@ PGG manual, depending on the value of `mml2015-use'."
(t
'message)))))
+(defun message-all-recipients ()
+ "Return a list of all recipients in the message, looking at TO, Cc and Bcc.
+
+Each recipient is in the format of `mail-extract-address-components'."
+ (mapcan (lambda (header)
+ (let ((header-value (message-fetch-field header)))
+ (and
+ header-value
+ (mail-extract-address-components header-value t))))
+ '("To" "Cc" "Bcc")))
+
+(defun message-all-epg-keys-available-p ()
+ "Return non-nil if the pgp keyring has a public key for each recipient."
+ (require 'epa)
+ (let ((context (epg-make-context epa-protocol)))
+ (catch 'break
+ (dolist (recipient (message-all-recipients))
+ (let ((recipient-email (cadr recipient)))
+ (when (and recipient-email (not (epg-list-keys context recipient-email)))
+ (throw 'break nil))))
+ t)))
+
+(defun message-sign-encrypt-if-all-keys-available ()
+ "Add MML tag to encrypt message when there is a key for each recipient.
+
+Consider adding this function to `message-send-hook' to
+systematically send encrypted emails when possible."
+ (when (message-all-epg-keys-available-p)
+ (mml-secure-message-sign-encrypt)))
+
;;;
@@ -2694,7 +2720,7 @@ PGG manual, depending on the value of `mml2015-use'."
(easy-menu-define
message-mode-menu message-mode-map "Message Menu."
- `("Message"
+ '("Message"
["Yank Original" message-yank-original message-reply-buffer]
["Fill Yanked Message" message-fill-yanked-message t]
["Insert Signature" message-insert-signature t]
@@ -2728,7 +2754,7 @@ PGG manual, depending on the value of `mml2015-use'."
(easy-menu-define
message-mode-field-menu message-mode-map ""
- `("Field"
+ '("Field"
["To" message-goto-to t]
["From" message-goto-from t]
["Subject" message-goto-subject t]
@@ -2843,8 +2869,7 @@ See also `message-forbidden-properties'."
(message-display-abbrev))
(when (and message-strip-special-text-properties
(message-tamago-not-in-use-p begin))
- (let ((buffer-read-only nil)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
(remove-text-properties begin end message-forbidden-properties))))
(defvar message-smileys '(":-)" ":)"
@@ -2874,42 +2899,9 @@ See also `message-forbidden-properties'."
;;;###autoload
(define-derived-mode message-mode text-mode "Message"
"Major mode for editing mail and news to be sent.
-Like Text Mode but with these additional commands:\\<message-mode-map>
-C-c C-s `message-send' (send the message) C-c C-c `message-send-and-exit'
-C-c C-d Postpone sending the message C-c C-k Kill the message
-C-c C-f move to a header field (and create it if there isn't):
- C-c C-f C-t move to To C-c C-f C-s move to Subject
- C-c C-f C-c move to Cc C-c C-f C-b move to Bcc
- C-c C-f C-w move to Fcc C-c C-f C-r move to Reply-To
- C-c C-f C-u move to Summary C-c C-f C-n move to Newsgroups
- C-c C-f C-k move to Keywords C-c C-f C-d move to Distribution
- C-c C-f C-o move to From (\"Originator\")
- C-c C-f C-f move to Followup-To
- C-c C-f C-m move to Mail-Followup-To
- C-c C-f C-e move to Expires
- C-c C-f C-i cycle through Importance values
- C-c C-f s change subject and append \"(was: <Old Subject>)\"
- C-c C-f x crossposting with FollowUp-To header and note in body
- C-c C-f t replace To: header with contents of Cc: or Bcc:
- C-c C-f a Insert X-No-Archive: header and a note in the body
-C-c C-t `message-insert-to' (add a To header to a news followup)
-C-c C-l `message-to-list-only' (removes all but list address in to/cc)
-C-c C-n `message-insert-newsgroups' (add a Newsgroup header to a news reply)
-C-c C-b `message-goto-body' (move to beginning of message text).
-C-c C-i `message-goto-signature' (move to the beginning of the signature).
-C-c C-w `message-insert-signature' (insert `message-signature-file' file).
-C-c C-y `message-yank-original' (insert current message, if any).
-C-c C-q `message-fill-yanked-message' (fill what was yanked).
-C-c C-e `message-elide-region' (elide the text between point and mark).
-C-c C-v `message-delete-not-region' (remove the text outside the region).
-C-c C-z `message-kill-to-signature' (kill the text up to the signature).
-C-c C-r `message-caesar-buffer-body' (rot13 the message body).
-C-c C-a `mml-attach-file' (attach a file as MIME).
-C-c C-u `message-insert-or-toggle-importance' (insert or cycle importance).
-C-c M-n `message-insert-disposition-notification-to' (request receipt).
-C-c M-m `message-mark-inserted-region' (mark region with enclosing tags).
-C-c M-f `message-mark-insert-file' (insert file marked with enclosing tags).
-M-RET `message-newline-and-reformat' (break the line and reformat)."
+Like `text-mode', but with these additional commands:
+
+\\{message-mode-map}"
(set (make-local-variable 'message-reply-buffer) nil)
(set (make-local-variable 'message-inserted-headers) nil)
(set (make-local-variable 'message-send-actions) nil)
@@ -2951,7 +2943,7 @@ M-RET `message-newline-and-reformat' (break the line and reformat)."
(easy-menu-add message-mode-menu message-mode-map)
(easy-menu-add message-mode-field-menu message-mode-map)
;; Mmmm... Forbidden properties...
- (add-hook 'after-change-functions 'message-strip-forbidden-properties
+ (add-hook 'after-change-functions #'message-strip-forbidden-properties
nil 'local)
;; Allow mail alias things.
(cond
@@ -2959,7 +2951,9 @@ M-RET `message-newline-and-reformat' (break the line and reformat)."
(mail-abbrevs-setup))
((message-mail-alias-type-p 'ecomplete)
(ecomplete-setup)))
- (add-hook 'completion-at-point-functions 'message-completion-function nil t)
+ ;; FIXME: merge the completion tables from ecomplete/bbdb/...?
+ ;;(add-hook 'completion-at-point-functions #'message-ecomplete-capf nil t)
+ (add-hook 'completion-at-point-functions #'message-completion-function nil t)
(unless buffer-file-name
(message-set-auto-save-file-name))
(unless (buffer-base-buffer)
@@ -3093,17 +3087,15 @@ M-RET `message-newline-and-reformat' (break the line and reformat)."
(push-mark)
(message-position-on-field "Summary" "Subject"))
-(defun message-goto-body ()
- "Move point to the beginning of the message body."
- (interactive)
- (when (and (called-interactively-p 'any)
- (looking-at "[ \t]*\n"))
+(define-obsolete-function-alias 'message-goto-body-1 'message-goto-body "27.1")
+(defun message-goto-body (&optional interactive)
+ "Move point to the beginning of the message body.
+Returns point."
+ (interactive "p")
+ (when interactive
+ (when (looking-at "[ \t]*\n")
(expand-abbrev))
- (push-mark)
- (message-goto-body-1))
-
-(defun message-goto-body-1 ()
- "Go to the body and return point."
+ (push-mark))
(goto-char (point-min))
(or (search-forward (concat "\n" mail-header-separator "\n") nil t)
;; If the message is mangled, find the end of the headers the
@@ -3122,12 +3114,12 @@ M-RET `message-newline-and-reformat' (break the line and reformat)."
"Return t if point is in the message body."
(>= (point)
(save-excursion
- (message-goto-body-1))))
+ (message-goto-body))))
-(defun message-goto-eoh ()
+(defun message-goto-eoh (&optional interactive)
"Move point to the end of the headers."
- (interactive)
- (message-goto-body)
+ (interactive "p")
+ (message-goto-body interactive)
(forward-line -1))
(defun message-goto-signature ()
@@ -3218,13 +3210,13 @@ or in the synonym headers, defined by `message-header-synonyms'."
(dolist (header headers)
(let* ((header-name (symbol-name (car header)))
(new-header (cdr header))
- (synonyms (loop for synonym in message-header-synonyms
- when (memq (car header) synonym) return synonym))
+ (synonyms (cl-loop for synonym in message-header-synonyms
+ when (memq (car header) synonym) return synonym))
(old-header
- (loop for synonym in synonyms
- for old-header = (mail-fetch-field (symbol-name synonym))
- when (and old-header (string-match new-header old-header))
- return synonym)))
+ (cl-loop for synonym in synonyms
+ for old-header = (mail-fetch-field (symbol-name synonym))
+ when (and old-header (string-match new-header old-header))
+ return synonym)))
(if old-header
(message "already have `%s' in `%s'" new-header old-header)
(when (and (message-position-on-field header-name)
@@ -3237,8 +3229,7 @@ or in the synonym headers, defined by `message-header-synonyms'."
"Widen the reply to include maximum recipients."
(interactive)
(let ((follow-to
- (and (bufferp message-reply-buffer)
- (buffer-name message-reply-buffer)
+ (and (buffer-live-p message-reply-buffer)
(with-current-buffer message-reply-buffer
(message-get-reply-headers t)))))
(save-excursion
@@ -3544,7 +3535,7 @@ Note that this should not be used in newsgroups."
(message-remove-header "Disposition-Notification-To"))
(message-goto-eoh)
(insert (format "Disposition-Notification-To: %s\n"
- (or (message-field-value "Reply-to")
+ (or (message-field-value "Reply-To")
(message-field-value "From")
(message-make-from))))))
@@ -3585,7 +3576,7 @@ text was killed."
"Create a rot table with offset N."
(let ((i -1)
(table (make-string 256 0)))
- (while (< (incf i) 256)
+ (while (< (cl-incf i) 256)
(aset table i i))
(concat
(substring table 0 ?A)
@@ -3753,13 +3744,13 @@ To use this automatically, you may add this function to
(goto-char (mark t))
(insert-before-markers ?\n)
(goto-char pt))))
- (case message-cite-reply-position
- (above
+ (pcase message-cite-reply-position
+ ('above
(message-goto-body)
(insert body-text)
(insert (if (bolp) "\n" "\n\n"))
(message-goto-body))
- (below
+ ('below
(message-goto-signature)))
;; Add a `message-setup-very-last-hook' here?
;; Add `gnus-article-highlight-citation' here?
@@ -3827,13 +3818,14 @@ This function uses `mail-citation-hook' if that is non-nil."
(narrow-to-region start end)
(message-narrow-to-head-1)
(setq x-no-archive (message-fetch-field "x-no-archive"))
- (vector 0
- (or (message-fetch-field "subject") "none")
- (or (message-fetch-field "from") "nobody")
- (message-fetch-field "date")
- (message-fetch-field "message-id" t)
- (message-fetch-field "references")
- 0 0 ""))))
+ (make-full-mail-header
+ 0
+ (or (message-fetch-field "subject") "none")
+ (or (message-fetch-field "from") "nobody")
+ (message-fetch-field "date")
+ (message-fetch-field "message-id" t)
+ (message-fetch-field "references")
+ 0 0 ""))))
(mml-quote-region start end)
(when strip-signature
;; Allow undoing.
@@ -4034,7 +4026,7 @@ It should typically alter the sending method in some way or other."
(let ((buf (current-buffer))
(actions message-exit-actions))
(when (and (message-send arg)
- (buffer-name buf))
+ (buffer-live-p buf))
(message-bury buf)
(if message-kill-buffer-on-exit
(kill-buffer buf))
@@ -4277,7 +4269,7 @@ conformance."
(point-max))))
(setq char (char-after)))
(when (or (< char 128)
- (and (mm-multibyte-p)
+ (and enable-multibyte-characters
(memq (char-charset char)
'(eight-bit-control eight-bit-graphic
;; Emacs 23, Bug#1770:
@@ -4309,7 +4301,7 @@ conformance."
(while (not (eobp))
(when (let ((char (char-after)))
(or (< char 128)
- (and (mm-multibyte-p)
+ (and enable-multibyte-characters
;; FIXME: Wrong for Emacs 23 (unicode) and for
;; things like undecodable utf-8 (in Emacs 21?).
;; Should at least use find-coding-systems-region.
@@ -4382,7 +4374,7 @@ This function could be useful in `message-setup-hook'."
(if (string= encoded bog)
""
(format " (%s)" encoded))))))
- (error "Bogus address"))))))))
+ (user-error "Bogus address"))))))))
(custom-add-option 'message-setup-hook 'message-check-recipients)
@@ -4485,6 +4477,49 @@ This function could be useful in `message-setup-hook'."
(declare-function hashcash-wait-async "hashcash" (&optional buffer))
+(defun message--check-continuation-headers ()
+ (message-check 'continuation-headers
+ (goto-char (point-min))
+ (while (re-search-forward "^[^ \t\n][^ \t\n:]*[ \t\n]" nil t)
+ (goto-char (match-beginning 0))
+ (if (y-or-n-p "Fix continuation lines? ")
+ (insert " ")
+ (forward-line 1)
+ (unless (y-or-n-p "Send anyway? ")
+ (error "Failed to send the message"))))))
+
+(defun message--send-mail-maybe-partially ()
+ (if (or (not message-send-mail-partially-limit)
+ (< (buffer-size) message-send-mail-partially-limit)
+ (not (message-y-or-n-p
+ "The message size is too large, split? "
+ t
+ "\
+The message size, "
+ (/ (buffer-size) 1000) "KB, is too large.
+
+Some mail gateways (MTA's) bounce large messages. To avoid the
+problem, answer `y', and the message will be split into several
+smaller pieces, the size of each is about "
+ (/ message-send-mail-partially-limit 1000)
+ "KB except the last
+one.
+
+However, some mail readers (MUA's) can't read split messages, i.e.,
+mails in message/partially format. Answer `n', and the message will be
+sent in one piece.
+
+The size limit is controlled by `message-send-mail-partially-limit'.
+If you always want Gnus to send messages in one piece, set
+`message-send-mail-partially-limit' to nil.
+")))
+ (progn
+ (message "Sending via mail...")
+ (if message-send-mail-real-function
+ (funcall message-send-mail-real-function)
+ (message-multi-smtp-send-mail)))
+ (message-send-mail-partially)))
+
(defun message-send-mail (&optional _)
(require 'mail-utils)
(let* ((tembuf (message-generate-new-buffer-clone-locals " message temp"))
@@ -4536,17 +4571,7 @@ This function could be useful in `message-setup-hook'."
(if news nil message-deletable-headers)))
(message-generate-headers headers))
;; Check continuation headers.
- (message-check 'continuation-headers
- (goto-char (point-min))
- (while (re-search-forward "^[^ \t\n][^ \t\n:]*[ \t\n]" nil t)
- (goto-char (match-beginning 0))
- (if (y-or-n-p "Fix continuation lines? ")
- (insert " ")
- (forward-line 1)
- (unless (y-or-n-p "Send anyway? ")
- (error "Failed to send the message")))))
- ;; Fold too-long header lines. They should be no longer than
- ;; 998 octets long.
+ (message--check-continuation-headers)
(message--fold-long-headers)
;; Let the user do all of the above.
(run-hooks 'message-header-hook))
@@ -4568,8 +4593,7 @@ This function could be useful in `message-setup-hook'."
(message-generate-headers '(Lines)))
;; Remove some headers.
(message-remove-header message-ignored-mail-headers t)
- (let ((mail-parse-charset message-default-charset))
- (mail-encode-encoded-word-buffer)))
+ (mail-encode-encoded-word-buffer))
(goto-char (point-max))
;; require one newline at the end.
(or (= (preceding-char) ?\n)
@@ -4603,41 +4627,14 @@ This function could be useful in `message-setup-hook'."
(message-insert-courtesy-copy
(with-current-buffer mailbuf
message-courtesy-message)))
- ;; Let's make sure we encoded all the body.
- (assert (save-excursion
- (goto-char (point-min))
- (not (re-search-forward "[^\000-\377]" nil t))))
+ ;; If this was set, `sendmail-program' takes care of encoding.
+ (unless message-inhibit-body-encoding
+ ;; Let's make sure we encoded all the body.
+ (cl-assert (save-excursion
+ (goto-char (point-min))
+ (not (re-search-forward "[^\000-\377]" nil t)))))
(mm-disable-multibyte)
- (if (or (not message-send-mail-partially-limit)
- (< (buffer-size) message-send-mail-partially-limit)
- (not (message-y-or-n-p
- "The message size is too large, split? "
- t
- "\
-The message size, "
- (/ (buffer-size) 1000) "KB, is too large.
-
-Some mail gateways (MTA's) bounce large messages. To avoid the
-problem, answer `y', and the message will be split into several
-smaller pieces, the size of each is about "
- (/ message-send-mail-partially-limit 1000)
- "KB except the last
-one.
-
-However, some mail readers (MUA's) can't read split messages, i.e.,
-mails in message/partially format. Answer `n', and the message will be
-sent in one piece.
-
-The size limit is controlled by `message-send-mail-partially-limit'.
-If you always want Gnus to send messages in one piece, set
-`message-send-mail-partially-limit' to nil.
-")))
- (progn
- (message "Sending via mail...")
- (if message-send-mail-real-function
- (funcall message-send-mail-real-function)
- (message-multi-smtp-send-mail)))
- (message-send-mail-partially))
+ (message--send-mail-maybe-partially)
(setq options message-options))
(kill-buffer tembuf))
(set-buffer mailbuf)
@@ -4645,10 +4642,12 @@ If you always want Gnus to send messages in one piece, set
(push 'mail message-sent-message-via)))
(defun message--fold-long-headers ()
+ "Fold too-long header lines.
+They should be no longer than 998 octets long."
(goto-char (point-min))
(while (not (eobp))
(when (and (looking-at "[^:]+:")
- (> (- (line-end-position) (point)) 998))
+ (> (- (line-end-position) (point)) 998))
(mail-header-fold-field))
(forward-line 1)))
@@ -4671,9 +4670,11 @@ that instead."
(message-send-mail-with-sendmail))
((equal (car method) "smtp")
(require 'smtpmail)
- (let ((smtpmail-smtp-server (nth 1 method))
- (smtpmail-smtp-service (nth 2 method))
- (smtpmail-smtp-user (or (nth 3 method) smtpmail-smtp-user)))
+ (let* ((smtpmail-smtp-server (nth 1 method))
+ (service (nth 2 method))
+ (port (string-to-number service))
+ (smtpmail-smtp-service (if (> port 0) port service))
+ (smtpmail-smtp-user (or (nth 3 method) smtpmail-smtp-user)))
(message-smtpmail-send-it)))
(t
(error "Unknown method %s" method))))))
@@ -4746,7 +4747,7 @@ that instead."
(if (not (zerop (buffer-size)))
(error "Sending...failed to %s"
(buffer-string))))))
- (when (bufferp errbuf)
+ (when (buffer-live-p errbuf)
(kill-buffer errbuf)))))
(defun message-send-mail-with-qmail ()
@@ -4760,7 +4761,7 @@ to find out how to use this."
(replace-match "\n")
(run-hooks 'message-send-mail-hook)
;; send the message
- (case
+ (pcase
(let ((coding-system-for-write message-send-coding-system))
(apply
'call-process-region (point-min) (point-max)
@@ -4791,7 +4792,7 @@ to find out how to use this."
(100 (error "qmail-inject reported permanent failure"))
(111 (error "qmail-inject reported transient failure"))
;; should never happen
- (t (error "qmail-inject reported unknown failure"))))
+ (_ (error "qmail-inject reported unknown failure"))))
(defvar mh-previous-window-config)
@@ -4940,8 +4941,7 @@ Otherwise, generate and save a value for `canlock-password' first."
(message-generate-headers '(Lines)))
;; Remove some headers.
(message-remove-header message-ignored-news-headers t)
- (let ((mail-parse-charset message-default-charset))
- (mail-encode-encoded-word-buffer)))
+ (mail-encode-encoded-word-buffer))
(goto-char (point-max))
;; require one newline at the end.
(or (= (preceding-char) ?\n)
@@ -5165,19 +5165,8 @@ Otherwise, generate and save a value for `canlock-password' first."
"Really post to %s unknown group%s: %s? "
(if (= (length errors) 1) "this" "these")
(if (= (length errors) 1) "" "s")
- (mapconcat 'identity errors ", ")))))))
- ;; Check continuation headers.
- (message-check 'continuation-headers
- (goto-char (point-min))
- (let ((do-posting t))
- (while (re-search-forward "^[^ \t\n][^ \t\n:]*[ \t\n]" nil t)
- (goto-char (match-beginning 0))
- (if (y-or-n-p "Fix continuation lines? ")
- (insert " ")
- (forward-line 1)
- (unless (y-or-n-p "Send anyway? ")
- (setq do-posting nil))))
- do-posting))
+ (mapconcat #'identity errors ", ")))))))
+ (progn (message--check-continuation-headers) t)
;; Check the Newsgroups & Followup-To headers for syntax errors.
(message-check 'valid-newsgroups
(let ((case-fold-search t)
@@ -5314,7 +5303,9 @@ Otherwise, generate and save a value for `canlock-password' first."
;; Check for control characters.
(message-check 'control-chars
(if (re-search-forward
- (string-to-multibyte "[\000-\007\013\015-\032\034-\037\200-\237]")
+ (eval-when-compile
+ (decode-coding-string "[\000-\007\013\015-\032\034-\037\200-\237]"
+ 'binary))
nil t)
(y-or-n-p
"The article contains control characters. Really post? ")
@@ -5375,6 +5366,17 @@ Otherwise, generate and save a value for `canlock-password' first."
(message "Denied posting -- only quoted text.")
nil)))))))
+(defun message--rotate-fixnum-left (n)
+ "Rotate the fixnum N left by one bit in a fixnum word.
+The result is a fixnum."
+ (logior (if (natnump n) 0 1)
+ (ash (cond ((< (ash most-positive-fixnum -1) n)
+ (logior n most-negative-fixnum))
+ ((< n (ash most-negative-fixnum -1))
+ (logand n most-positive-fixnum))
+ (n))
+ 1)))
+
(defun message-checksum ()
"Return a \"checksum\" for the current buffer."
(let ((sum 0))
@@ -5384,7 +5386,7 @@ Otherwise, generate and save a value for `canlock-password' first."
(concat "^" (regexp-quote mail-header-separator) "$"))
(while (not (eobp))
(when (not (looking-at "[ \t\n]"))
- (setq sum (logxor (ash sum 1) (if (natnump sum) 0 1)
+ (setq sum (logxor (message--rotate-fixnum-left sum)
(char-after))))
(forward-char 1)))
sum))
@@ -5406,8 +5408,7 @@ Otherwise, generate and save a value for `canlock-password' first."
(while (setq file (message-fetch-field "fcc" t))
(push file list)
(message-remove-header "fcc" nil t))
- (let ((mail-parse-charset message-default-charset)
- (rfc2047-header-encoding-alist
+ (let ((rfc2047-header-encoding-alist
(cons '("Newsgroups" . default)
rfc2047-header-encoding-alist)))
(mail-encode-encoded-word-buffer)))
@@ -5416,7 +5417,7 @@ Otherwise, generate and save a value for `canlock-password' first."
(concat "^" (regexp-quote mail-header-separator) "$")
nil t)
(replace-match "" t t ))
- ;; Process FCC operations.
+ ;; Process Fcc operations.
(while list
(setq file (pop list))
(if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file)
@@ -5506,7 +5507,7 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'."
(let* ((cur (decode-time))
(nday (+ days (nth 3 cur))))
(setf (nth 3 cur) nday)
- (message-make-date (apply 'encode-time cur))))
+ (message-make-date (encode-time cur))))
(defun message-make-message-id ()
"Make a unique Message-ID."
@@ -5539,7 +5540,7 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'."
;; Instead we use this randomly inited counter.
(setq message-unique-id-char
(% (1+ (or message-unique-id-char
- (logand (random most-positive-fixnum) (1- (lsh 1 20)))))
+ (random (ash 1 20))))
;; (current-time) returns 16-bit ints,
;; and 2^16*25 just fits into 4 digits i base 36.
(* 25 25)))
@@ -5554,9 +5555,9 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'."
user)
(message-number-base36 (user-uid) -1))
(message-number-base36 (+ (car tm)
- (lsh (% message-unique-id-char 25) 16)) 4)
+ (ash (% message-unique-id-char 25) 16)) 4)
(message-number-base36 (+ (nth 1 tm)
- (lsh (/ message-unique-id-char 25) 16)) 4)
+ (ash (/ message-unique-id-char 25) 16)) 4)
;; Append a given name, because while the generated ID is unique
;; to this newsreader, other newsreaders might otherwise generate
;; the same ID via another algorithm.
@@ -5840,10 +5841,10 @@ subscribed address (and not the additional To and Cc header contents)."
message-subscribed-address-functions))))
(save-match-data
(let ((list
- (loop for recipient in recipients
- when (loop for regexp in mft-regexps
- thereis (string-match regexp recipient))
- return recipient)))
+ (cl-loop for recipient in recipients
+ when (cl-loop for regexp in mft-regexps
+ thereis (string-match regexp recipient))
+ return recipient)))
(when list
(if only-show-subscribed
list
@@ -6192,7 +6193,7 @@ they are."
(when (> count maxcount)
(let ((surplus (- count maxcount)))
(message-shorten-1 refs cut surplus)
- (decf count surplus)))
+ (cl-decf count surplus)))
;; When sending via news, make sure the total folded length will
;; be less than 998 characters. This is to cater to broken INN
@@ -6372,8 +6373,7 @@ moved to the beginning "
(defun message-pop-to-buffer (name &optional switch-function)
"Pop to buffer NAME, and warn if it already exists and is modified."
(let ((buffer (get-buffer name)))
- (if (and buffer
- (buffer-name buffer))
+ (if (buffer-live-p buffer)
(let ((window (get-buffer-window buffer 0)))
(if window
;; Raise the frame already displaying the message buffer.
@@ -6404,7 +6404,7 @@ moved to the beginning "
(>= (length message-buffer-list) message-max-buffers))
;; Kill the oldest buffer -- unless it has been changed.
(let ((buffer (pop message-buffer-list)))
- (when (and (buffer-name buffer)
+ (when (and (buffer-live-p buffer)
(not (buffer-modified-p buffer)))
(kill-buffer buffer))))
;; Rename the buffer.
@@ -6717,9 +6717,9 @@ The function is called with one parameter, a cons cell ..."
;; Gmane renames "To". Look at "Original-To", too, if it is present in
;; message-header-synonyms.
(setq to (or (message-fetch-field "to")
- (and (loop for synonym in message-header-synonyms
- when (memq 'Original-To synonym)
- return t)
+ (and (cl-loop for synonym in message-header-synonyms
+ when (memq 'Original-To synonym)
+ return t)
(message-fetch-field "original-to")))
cc (message-fetch-field "cc")
extra (when message-extra-wide-headers
@@ -6857,6 +6857,9 @@ want to get rid of this query permanently.")))
(setq recipients (delq recip recipients))))))))
(setq recipients (message-prune-recipients recipients))
+ (setq recipients
+ (cl-loop for (id . address) in recipients
+ collect (cons id (message--alter-repeat-address address))))
;; Build the header alist. Allow the user to be asked whether
;; or not to reply to all recipients in a wide reply.
@@ -6887,6 +6890,15 @@ want to get rid of this query permanently.")))
(setq recipients (delq recipient recipients))))))))
recipients)
+(defun message--alter-repeat-address (address)
+ "Transform an address on the form \"\"foo@bar.com\"\" <foo@bar.com>\".
+The first bit will be elided if a match is made."
+ (let ((bits (gnus-extract-address-components address)))
+ (if (equal (car bits) (cadr bits))
+ (car bits)
+ ;; Return the original address if we don't have repetition.
+ address)))
+
(defcustom message-simplify-subject-functions
'(message-strip-list-identifiers
message-strip-subject-re
@@ -6904,21 +6916,12 @@ Useful functions to put in this list include:
:type '(repeat function))
(defun message-simplify-subject (subject &optional functions)
- "Return simplified SUBJECT."
- (unless functions
- ;; Simplify fully:
- (setq functions message-simplify-subject-functions))
- (when (and (memq 'message-strip-list-identifiers functions)
- gnus-list-identifiers)
- (setq subject (message-strip-list-identifiers subject)))
- (when (memq 'message-strip-subject-re functions)
- (setq subject (concat "Re: " (message-strip-subject-re subject))))
- (when (and (memq 'message-strip-subject-trailing-was functions)
- message-subject-trailing-was-query)
- (setq subject (message-strip-subject-trailing-was subject)))
- (when (memq 'message-strip-subject-encoded-words functions)
- (setq subject (message-strip-subject-encoded-words subject)))
- subject)
+ "Return simplified SUBJECT.
+Do so by calling each one-argument function in the list of functions
+specified by FUNCTIONS, if non-nil, or by the variable
+`message-simplify-subject-functions' otherwise."
+ (dolist (fun (or functions message-simplify-subject-functions) subject)
+ (setq subject (funcall fun subject))))
;;;###autoload
(defun message-reply (&optional to-address wide switch-function)
@@ -6951,7 +6954,7 @@ Useful functions to put in this list include:
subject (or (message-fetch-field "subject") "none"))
;; Strip list identifiers, "Re: ", and "was:"
- (setq subject (message-simplify-subject subject))
+ (setq subject (concat "Re: " (message-simplify-subject subject)))
(when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
(string-match "<[^>]+>" gnus-warning))
@@ -6970,8 +6973,8 @@ Useful functions to put in this list include:
(if wide to-address nil))
switch-function))
(setq message-reply-headers
- (vector 0 (cdr (assq 'Subject headers))
- from date message-id references 0 0 ""))
+ (make-full-mail-header 0 (cdr (assq 'Subject headers))
+ from date message-id references 0 0 ""))
(message-setup headers cur))))
;;;###autoload
@@ -7022,13 +7025,14 @@ If TO-NEWSGROUPS, use that as the new Newsgroups line."
(string-match "world" distribution)))
(setq distribution nil))
;; Strip list identifiers, "Re: ", and "was:"
- (setq subject (message-simplify-subject subject))
+ (setq subject (concat "Re: " (message-simplify-subject subject)))
(widen))
(message-pop-to-buffer (message-buffer-name "followup" from newsgroups))
(setq message-reply-headers
- (vector 0 subject from date message-id references 0 0 ""))
+ (make-full-mail-header
+ 0 subject from date message-id references 0 0 ""))
(message-setup
`((Subject . ,subject)
@@ -7367,9 +7371,7 @@ Optional DIGEST will use digest to forward."
(unless (multibyte-string-p contents)
(error "Attempt to insert unibyte string from the buffer \"%s\"\
to the multibyte buffer \"%s\""
- (if (bufferp forward-buffer)
- (buffer-name forward-buffer)
- forward-buffer)
+ forward-buffer
(buffer-name)))
(insert (mm-with-multibyte-buffer
(insert contents)
@@ -7401,7 +7403,8 @@ Optional DIGEST will use digest to forward."
(when message-forward-included-headers
(message-remove-header
(if (listp message-forward-included-headers)
- (regexp-opt message-forward-included-headers)
+ (mapconcat #'identity (cons "^$" message-forward-included-headers)
+ "\\|")
message-forward-included-headers)
t nil t)))))
@@ -7420,7 +7423,7 @@ Optional DIGEST will use digest to forward."
;; Consider there is no illegible text.
(add-text-properties
b (point)
- `(no-illegible-text t rear-nonsticky t start-open t))))
+ '(no-illegible-text t rear-nonsticky t start-open t))))
(defun message-forward-make-body-mml (forward-buffer)
(insert "\n\n<#mml type=message/rfc822 disposition=inline>\n")
@@ -7430,9 +7433,7 @@ Optional DIGEST will use digest to forward."
(unless (multibyte-string-p contents)
(error "Attempt to insert unibyte string from the buffer \"%s\"\
to the multibyte buffer \"%s\""
- (if (bufferp forward-buffer)
- (buffer-name forward-buffer)
- forward-buffer)
+ forward-buffer
(buffer-name)))
(insert (mm-with-multibyte-buffer
(insert contents)
@@ -7578,8 +7579,6 @@ is for the internal use."
(setq rmail-insert-mime-forwarded-message-function
'message-forward-rmail-make-body))
-(defvar message-inhibit-body-encoding nil)
-
;;;###autoload
(defun message-resend (address)
"Resend the current article to ADDRESS."
@@ -7875,6 +7874,8 @@ See `gmm-tool-bar-from-list' for the format of the list."
:group 'message)
(defvar image-load-path)
+(declare-function image-load-path-for-library "image"
+ (library image &optional path no-error))
(defun message-make-tool-bar (&optional force)
"Make a message mode tool bar from `message-tool-bar-list'.
@@ -7901,6 +7902,7 @@ When FORCE, rebuild the tool bar."
:type 'regexp)
(defcustom message-completion-alist
+ ;; FIXME: Make it possible to use the standard completion UI.
(list (cons message-newgroups-header-regexp 'message-expand-group)
'("^\\(Resent-\\)?\\(To\\|B?Cc\\):" . message-expand-name)
'("^\\(Reply-To\\|From\\|Mail-Followup-To\\|Mail-Copies-To\\):"
@@ -7973,18 +7975,11 @@ regular text mode tabbing command."
(skip-chars-backward "^, \t\n") (point))))
(completion-ignore-case t)
(e (progn (skip-chars-forward "^,\t\n ") (point)))
- group collection)
- (when (and (boundp 'gnus-active-hashtb)
- gnus-active-hashtb)
- (mapatoms
- (lambda (symbol)
- (setq group (symbol-name symbol))
- (push (if (string-match "[^\000-\177]" group)
- (gnus-group-decoded-name group)
- group)
- collection))
- gnus-active-hashtb))
- (completion-in-region b e collection)))
+ (collection (when (and (boundp 'gnus-active-hashtb)
+ gnus-active-hashtb)
+ (hash-table-keys gnus-active-hashtb))))
+ (when collection
+ (completion-in-region b e collection))))
(defun message-expand-name ()
(cond ((and (memq 'eudc message-expand-name-databases)
@@ -8009,7 +8004,7 @@ regular text mode tabbing command."
If SHOW is non-nil, the arguments TEXT... are displayed in a temp buffer.
The following arguments may contain lists of values."
(if (and show
- (setq text (message-flatten-list text)))
+ (setq text (flatten-tree text)))
(save-window-excursion
(with-output-to-temp-buffer " *MESSAGE information message*"
(with-current-buffer " *MESSAGE information message*"
@@ -8019,15 +8014,7 @@ The following arguments may contain lists of values."
(funcall ask question))
(funcall ask question)))
-(defun message-flatten-list (list)
- "Return a new, flat list that contains all elements of LIST.
-
-\(message-flatten-list \\='(1 (2 3 (4 5 (6))) 7))
-=> (1 2 3 4 5 6 7)"
- (cond ((consp list)
- (apply 'append (mapcar 'message-flatten-list list)))
- (list
- (list list))))
+(define-obsolete-function-alias 'message-flatten-list #'flatten-tree "27.1")
(defun message-generate-new-buffer-clone-locals (name &optional varstr)
"Create and return a buffer with name based on NAME using `generate-new-buffer'.
@@ -8065,9 +8052,7 @@ regexp VARSTR."
(defun message-encode-message-body ()
(unless message-inhibit-body-encoding
- (let ((mail-parse-charset (or mail-parse-charset
- message-default-charset))
- (case-fold-search t)
+ (let ((case-fold-search t)
lines content-type-p)
(message-goto-body)
(save-restriction
@@ -8124,11 +8109,12 @@ From headers in the original article."
(message-tokenize-header
(mail-strip-quoted-names
(mapconcat 'message-fetch-reply-field fields ","))))
- (email (cond ((functionp message-alternative-emails)
- (car (cl-remove-if-not message-alternative-emails emails)))
- (t (loop for email in emails
- if (string-match-p message-alternative-emails email)
- return email)))))
+ (email
+ (cond ((functionp message-alternative-emails)
+ (car (cl-remove-if-not message-alternative-emails emails)))
+ (t (cl-loop for email in emails
+ if (string-match-p message-alternative-emails email)
+ return email)))))
(unless (or (not email) (equal email user-mail-address))
(message-remove-header "From")
(goto-char (point-max))
@@ -8224,16 +8210,19 @@ From headers in the original article."
(autoload 'ecomplete-display-matches "ecomplete")
+(defun message--in-tocc-p ()
+ (and (memq (char-after (point-at-bol)) '(?C ?T ?\t ? ))
+ (message-point-in-header-p)
+ (save-excursion
+ (beginning-of-line)
+ (while (and (memq (char-after) '(?\t ? ))
+ (zerop (forward-line -1))))
+ (looking-at "To:\\|Cc:"))))
+
(defun message-display-abbrev (&optional choose)
"Display the next possible abbrev for the text before point."
(interactive (list t))
- (when (and (memq (char-after (point-at-bol)) '(?C ?T ?\t ? ))
- (message-point-in-header-p)
- (save-excursion
- (beginning-of-line)
- (while (and (memq (char-after) '(?\t ? ))
- (zerop (forward-line -1))))
- (looking-at "To:\\|Cc:")))
+ (when (message--in-tocc-p)
(let* ((end (point))
(start (save-excursion
(and (re-search-backward "[\n\t ]" nil t)
@@ -8246,6 +8235,20 @@ From headers in the original article."
(delete-region start end)
(insert match)))))
+(defun message-ecomplete-capf ()
+ "Return completion data for email addresses in Ecomplete.
+Meant for use on `completion-at-point-functions'."
+ (when (and (bound-and-true-p ecomplete-database)
+ (fboundp 'ecomplete-completion-table)
+ (message--in-tocc-p))
+ (let ((end (save-excursion
+ (skip-chars-forward "^, \t\n")
+ (point)))
+ (start (save-excursion
+ (skip-chars-backward "^, \t\n")
+ (point))))
+ `(,start ,end ,(ecomplete-completion-table 'mail)))))
+
;; To send pre-formatted letters like the example below, you can use
;; `message-send-form-letter':
;; --8<---------------cut here---------------start------------->8---
@@ -8353,6 +8356,9 @@ even if NEW-VALUE is empty."
(message-position-on-field header))
(insert new-value))))
+(make-obsolete-variable
+ 'message-recipients-without-full-name
+ "Recipients are simplified by default" "27.1")
(defcustom message-recipients-without-full-name
(list "ding@gnus.org"
"bugs@gnus.org"
@@ -8368,6 +8374,7 @@ Used in `message-simplify-recipients'."
:version "23.1" ;; No Gnus
:group 'message-headers)
+(make-obsolete 'message-simplify-recipients nil "27.1")
(defun message-simplify-recipients ()
(interactive)
(dolist (hdr '("Cc" "To"))