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.el240
1 files changed, 119 insertions, 121 deletions
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 0eebbe299d2..a0adccef7ad 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -28,8 +28,7 @@
;;; Code:
-(eval-when-compile
- (require 'cl))
+(eval-when-compile (require 'cl-lib))
(require 'mailheader)
(require 'gmm-utils)
@@ -1436,8 +1435,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)
@@ -1450,8 +1447,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)
@@ -1464,8 +1459,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)
@@ -1478,8 +1471,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)
@@ -1492,8 +1483,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)
@@ -1506,8 +1495,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)
@@ -1520,8 +1507,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)
@@ -1534,8 +1519,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)
@@ -1548,8 +1531,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)
@@ -1562,53 +1543,50 @@ 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))
+ `((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)))
,@(if (and mail-header-separator
(not (equal mail-header-separator "")))
`((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
@@ -2434,7 +2412,7 @@ Return the number of headers removed."
(not (looking-at regexp))
(looking-at regexp))
(progn
- (incf number)
+ (cl-incf number)
(when first
(setq last t))
(delete-region
@@ -2459,10 +2437,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."
@@ -2842,8 +2820,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 '(":-)" ":)"
@@ -2950,7 +2927,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
@@ -2958,7 +2935,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)
@@ -3092,17 +3071,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
@@ -3121,12 +3098,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 ()
@@ -3217,13 +3194,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)
@@ -3584,7 +3561,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)
@@ -3752,13 +3729,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?
@@ -4381,7 +4358,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)
@@ -4603,9 +4580,9 @@ This function could be useful in `message-setup-hook'."
(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))))
+ (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)
@@ -4759,7 +4736,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)
@@ -4790,7 +4767,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)
@@ -5313,7 +5290,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? ")
@@ -5840,10 +5819,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 +6171,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
@@ -6717,9 +6696,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
@@ -7901,6 +7880,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\\):"
@@ -8124,11 +8104,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 +8205,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 +8230,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 ,(apply-partially #'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---