-;;; rmail.el --- main code of "RMAIL" mail reader for Emacs
+;;; rmail.el --- main code of "RMAIL" mail reader for Emacs -*- lexical-binding:t -*-
;; Copyright (C) 1985-1988, 1993-1998, 2000-2015 Free Software
;; Foundation, Inc.
"Regexp to match Header fields that Rmail should display.
If nil, display all header fields except those matched by
`rmail-ignored-headers'."
- :type '(choice regexp (const :tag "All"))
+ :type '(choice regexp (const :tag "All" nil))
:group 'rmail-headers)
;;;###autoload
(defcustom rmail-highlighted-headers (purecopy "^From:\\|^Subject:")
"Regexp to match Header fields that Rmail should normally highlight.
A value of nil means don't highlight. Uses the face `rmail-highlight'."
- :type 'regexp
+ :type '(choice regexp (const :tag "None" nil))
:group 'rmail-headers)
(defface rmail-highlight
Signal an error and set `rmail-mime-feature' to nil if the feature
isn't provided."
(when rmail-enable-mime
- (condition-case err
+ (condition-case nil
(require rmail-mime-feature)
(error
(display-warning
'rmail
- (format "Although MIME support is requested
+ (format-message "Although MIME support is requested
through `rmail-enable-mime' being non-nil, the required feature
`%s' (the value of `rmail-mime-feature')
is not available in the current session.
(interactive)
;; This let var was called rmail-buffer, but that interfered
;; with the buffer-local var used in summary buffers.
- (let ((buffer-to-bury (current-buffer)))
- (if (rmail-summary-exists)
- (let (window)
- (while (setq window (get-buffer-window rmail-summary-buffer))
- (quit-window nil window))
- (bury-buffer rmail-summary-buffer)))
- (quit-window)))
+ (if (rmail-summary-exists)
+ (let (window)
+ (while (setq window (get-buffer-window rmail-summary-buffer))
+ (quit-window nil window))
+ (bury-buffer rmail-summary-buffer)))
+ (quit-window))
\f
(defun rmail-duplicate-message ()
"Create a duplicated copy of the current message.
;; This loops if any members of the inbox list have the same
;; basename (see "name conflict" below).
(while all-files
- (let ((opoint (point))
- ;; If buffer has not changed yet, and has not been
+ (let (;; If buffer has not changed yet, and has not been
;; saved yet, don't replace the old backup file now.
(make-backup-files (and make-backup-files
(buffer-modified-p)))
(buffer-read-only nil)
;; Don't make undo records while getting mail.
(buffer-undo-list t)
- delete-files success files file-last-names)
+ delete-files files file-last-names)
;; Pull files off all-files onto files as long as there is
;; no name conflict. A conflict happens when two inbox
;; file names have the same last component.
;; Make sure we end with a blank line unless there are
;; no messages, as required by mbox format (Bug#9974).
(unless (bobp)
- (while (not (looking-back "\n\n"))
+ (while (not (looking-back "\n\n" (- (point) 2)))
(insert "\n")))
(setq found (or
(rmail-get-new-mail-1 file-name files delete-files)
((string-match "^po:\\([^:]+\\)\\(:\\(.*\\)\\)?" file)
(let (got-password supplied-password
- (proto "pop")
- (user (match-string 1 file))
- (host (match-string 3 file)))
+ ;; (proto "pop")
+ ;; (user (match-string 1 file))
+ ;; (host (match-string 3 file))
+ )
(when rmail-remote-password-required
(setq got-password (not (rmail-have-password)))
Value is the size of the newly read mail after conversion."
;; Detect previous Babyl format files.
(let ((case-fold-search nil)
- (old-file file)
- new-file)
+ (old-file file))
(cond ((looking-at "BABYL OPTIONS:")
;; The new mail is in Babyl version 5 format. Use unrmail
;; to convert it.
(or (memq (file-locked-p buffer-file-name) '(nil t))
(error "RMAIL file %s is locked"
(file-name-nondirectory buffer-file-name)))
- (let (file tofile delete-files movemail popmail got-password password)
+ (let (file tofile delete-files popmail got-password password)
(while files
;; Handle remote mailbox names specially; don't expand as filenames
;; in case the userid contains a directory separator.
;; Make sure the read-in mbox data properly ends with a
;; blank line unless it is of size 0.
(unless (zerop size)
- (while (not (looking-back "\n\n"))
+ (while (not (looking-back "\n\n" (- (point) 2)))
(insert "\n")))
(if (not (and rmail-preserve-inbox (string= file tofile)))
(setq delete-files (cons tofile delete-files)))))
Call with point at the end of the message."
(unless (bolp)
(insert "\n"))
- (unless (looking-back "\n\n")
+ (unless (looking-back "\n\n" (- (point) 2))
(insert "\n")))
(defun rmail-add-mbox-headers ()
(value "------U-")
(case-fold-search nil)
(delim (concat "\n\n" rmail-unix-mail-delimiter))
- limit stop)
+ stop)
;; Detect an empty inbox file.
(unless (= start (point-max))
;; Scan the new messages to establish a count and to ensure that
"\\>\\)"))
addr))
(y-or-n-p
- (format "Add `%s' to `mail-mailing-lists'? "
- addr)))
+ (format-message "Add `%s' to `mail-mailing-lists'? "
+ addr)))
(customize-save-variable 'mail-mailing-lists
(cons addr mail-mailing-lists)))))))))
(setq blurb (format "Showing message %d...done" msg)))))
blurb))
-(defun rmail-copy-headers (beg end &optional ignored-headers)
+(defun rmail-copy-headers (beg _end &optional ignored-headers)
"Copy displayed header fields to the message viewer buffer.
BEG and END marks the start and end positions of the message in
the mbox buffer. If the optional argument IGNORED-HEADERS is
(1+ (match-beginning 0))
(point-max))))
(if (and (looking-at ignored-headers)
- (not (looking-at rmail-nonignored-headers)))
+ (not (and rmail-nonignored-headers
+ (looking-at rmail-nonignored-headers))))
(goto-char lim)
(append-to-buffer rmail-view-buffer (point) lim)
(goto-char lim))))
(rmail-maybe-set-message-counters)
(rmail-show-message rmail-total-messages))
-(defun rmail-next-error-move (msg-pos bad-marker)
+(defun rmail-next-error-move (msg-pos _bad-marker)
"Move to an error locus (probably grep hit) in an Rmail buffer.
MSG-POS is a marker pointing at the error message in the grep buffer.
BAD-MARKER is a marker that ought to point at where to move to,
"Back up to deleted message, select it, and undelete it."
(interactive "p")
(set-buffer rmail-buffer)
- (let (value)
- (dotimes (i count)
- (let ((msg rmail-current-message))
- (while (and (> msg 0)
- (not (rmail-message-deleted-p msg)))
- (setq msg (1- msg)))
- (if (= msg 0)
- (error "No previous deleted message")
- (if (/= msg rmail-current-message)
- (rmail-show-message msg))
- (rmail-set-attribute rmail-deleted-attr-index nil)
- (if (rmail-summary-exists)
- (with-current-buffer rmail-summary-buffer
- (rmail-summary-mark-undeleted msg))))))
- (rmail-maybe-display-summary)))
+ (dotimes (_ count)
+ (let ((msg rmail-current-message))
+ (while (and (> msg 0)
+ (not (rmail-message-deleted-p msg)))
+ (setq msg (1- msg)))
+ (if (= msg 0)
+ (error "No previous deleted message")
+ (if (/= msg rmail-current-message)
+ (rmail-show-message msg))
+ (rmail-set-attribute rmail-deleted-attr-index nil)
+ (if (rmail-summary-exists)
+ (with-current-buffer rmail-summary-buffer
+ (rmail-summary-mark-undeleted msg))))))
+ (rmail-maybe-display-summary))
(defun rmail-delete-forward (&optional count)
"Delete this message and move to next nondeleted one.
(let (value backward)
(if (< count 0)
(setq count (- count) backward t))
- (dotimes (i count)
+ (dotimes (_ count)
(rmail-set-attribute rmail-deleted-attr-index t)
(run-hooks 'rmail-delete-message-hook)
(let ((del-msg rmail-current-message))
(if (zerop rmail-current-message)
(error "There is no message to reply to"))
(let (from reply-to cc subject date to message-id references
- resent-to resent-cc resent-reply-to
+ ;; resent-to resent-cc resent-reply-to
(msgnum rmail-current-message))
(rmail-apply-in-message
rmail-current-message
date (mail-fetch-field "date")
message-id (mail-fetch-field "message-id")
references (mail-fetch-field "references" nil nil t)
- resent-reply-to (mail-fetch-field "resent-reply-to" nil t)
;; Bug#512. It's inappropriate to reply to these addresses.
-;;; resent-cc (and (not just-sender)
-;;; (mail-fetch-field "resent-cc" nil t))
-;;; resent-to (or (mail-fetch-field "resent-to" nil t) "")
-;;; resent-subject (mail-fetch-field "resent-subject")
-;;; resent-date (mail-fetch-field "resent-date")
-;;; resent-message-id (mail-fetch-field "resent-message-id")
+ ;;resent-reply-to (mail-fetch-field "resent-reply-to" nil t)
+ ;;resent-cc (and (not just-sender)
+ ;; (mail-fetch-field "resent-cc" nil t))
+ ;;resent-to (or (mail-fetch-field "resent-to" nil t) "")
+ ;;resent-subject (mail-fetch-field "resent-subject")
+ ;;resent-date (mail-fetch-field "resent-date")
+ ;;resent-message-id (mail-fetch-field "resent-message-id")
)
(unless just-sender
(if (mail-fetch-field "mail-followup-to" nil t)
to (or (mail-fetch-field "to" nil t) ""))))))
;; Merge the resent-to and resent-cc into the to and cc.
;; Bug#512. It's inappropriate to reply to these addresses.
-;;; (if (and resent-to (not (equal resent-to "")))
-;;; (if (not (equal to ""))
-;;; (setq to (concat to ", " resent-to))
-;;; (setq to resent-to)))
-;;; (if (and resent-cc (not (equal resent-cc "")))
-;;; (if (not (equal cc ""))
-;;; (setq cc (concat cc ", " resent-cc))
-;;; (setq cc resent-cc)))
+ ;;(if (and resent-to (not (equal resent-to "")))
+ ;; (setq to (if (not (equal to ""))
+ ;; (concat to ", " resent-to)
+ ;; resent-to)))
+ ;;(if (and resent-cc (not (equal resent-cc "")))
+ ;; (setq cc (if (not (equal cc ""))
+ ;; (concat cc ", " resent-cc)
+ ;; resent-cc)))
;; Add `Re: ' to subject if not there already.
(and (stringp subject)
- (setq subject
+ (setq subject (rfc2047-decode-string subject)
+ subject
(concat rmail-reply-prefix
(if (let ((case-fold-search t))
(string-match rmail-reply-regexp subject))
(declare-function rmail-mime-toggle-raw "rmailmm" (&optional state))
+(defvar rmail-mime-mbox-buffer)
+(defvar rmail-mime-view-buffer)
+
(defun rmail-retry-failure ()
"Edit a mail message which is based on the contents of the current message.
For a message rejected by the mail system, extract the interesting headers and
(declare-function dframe-select-attached-frame "dframe" (&optional frame))
(declare-function dframe-maybee-jump-to-attached-frame "dframe" ())
-(defun rmail-speedbar-button (text token indent)
+(defun rmail-speedbar-button (_text token _indent)
"Execute an rmail command specified by TEXT.
The command used is TOKEN. INDENT is not used."
(dframe-with-attached-buffer
(funcall token t)))
-(defun rmail-speedbar-find-file (text token indent)
+(defun rmail-speedbar-find-file (text _token _indent)
"Load in the rmail file TEXT.
TOKEN and INDENT are not used."
(dframe-with-attached-buffer
(forward-char -2)
(speedbar-do-function-pointer)))))
-(defun rmail-speedbar-move-message (text token indent)
+(defun rmail-speedbar-move-message (_text token _indent)
"From button TEXT, copy current message to the rmail file specified by TOKEN.
TEXT and INDENT are not used."
(dframe-with-attached-buffer
(setq i (1+ i)))
(concat string-vector)))
+(defun rmail-epa-decrypt-1 (mime)
+ "Decrypt a single GnuPG encrypted text in a message.
+The starting string of the encrypted text should have just been regexp-matched.
+Argument MIME is non-nil if this is a mime message."
+ (let* ((armor-start (match-beginning 0))
+ (armor-prefix (buffer-substring
+ (line-beginning-position)
+ armor-start))
+ (armor-end-regexp)
+ armor-end after-end
+ unquote)
+ (if (string-match "<pre>\\'" armor-prefix)
+ (setq armor-prefix ""))
+
+ (setq armor-end-regexp
+ (concat "^"
+ armor-prefix
+ "-----END PGP MESSAGE-----$"))
+ (setq armor-end (re-search-forward armor-end-regexp
+ nil t))
+
+ (unless armor-end
+ (error "Encryption armor beginning has no matching end"))
+ (goto-char armor-start)
+
+ ;; Because epa--find-coding-system-for-mime-charset not autoloaded.
+ (require 'epa)
+
+ ;; Advance over this armor.
+ (goto-char armor-end)
+ (setq after-end (- (point-max) armor-end))
+
+ (when mime
+ (save-excursion
+ (goto-char armor-start)
+ (re-search-backward "^--" nil t)
+ (save-restriction
+ (narrow-to-region (point) armor-start)
+
+ ;; Use the charset specified in the armor.
+ (unless coding-system-for-read
+ (if (re-search-forward "^[ \t]*Charset[ \t\n]*:[ \t\n]*\\(.*\\)" nil t)
+ (setq coding-system-for-read
+ (epa--find-coding-system-for-mime-charset
+ (intern (downcase (match-string 1)))))))
+
+ (goto-char (point-min))
+ (if (re-search-forward "^[ \t]*Content-transfer-encoding[ \t\n]*:[ \t\n]*quoted-printable[ \t]*$" nil t)
+ (setq unquote t)))))
+
+ (when unquote
+ (let ((inhibit-read-only t))
+ (mail-unquote-printable-region armor-start
+ (- (point-max) after-end))))
+
+ ;; Decrypt it, maybe in place, maybe making new buffer.
+ (epa-decrypt-region
+ armor-start (- (point-max) after-end)
+ ;; Call back this function to prepare the output.
+ (lambda ()
+ (let ((inhibit-read-only t))
+ (delete-region armor-start (- (point-max) after-end))
+ (goto-char armor-start)
+ (current-buffer))))
+
+ (list armor-start (- (point-max) after-end) mime
+ armor-end-regexp)))
+
;; Should this have a key-binding, or be in a menu?
;; There doesn't really seem to be an appropriate menu.
;; Eg the edit command is not in a menu either.
+
(defun rmail-epa-decrypt ()
"Decrypt GnuPG or OpenPGP armors in current message."
(interactive)
;; change it in one of the calls to `epa-decrypt-region'.
(save-excursion
- (let (decrypts (mime (rmail-mime-message-p)))
+ (let (decrypts (mime (rmail-mime-message-p))
+ mime-disabled)
(goto-char (point-min))
;; Turn off mime processing.
(when (and mime
(not (get-text-property (point-min) 'rmail-mime-hidden)))
+ (setq mime-disabled t)
(rmail-mime))
;; Now find all armored messages in the buffer
(goto-char (point-min))
(while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
(let ((coding-system-for-read coding-system-for-read)
- (case-fold-search t)
- unquote
- armor-start armor-prefix armor-end-regexp armor-end after-end)
-
- (setq armor-start (match-beginning 0)
- armor-prefix (buffer-substring
- (line-beginning-position)
- armor-start))
- (if (string-match "<pre>\\'" armor-prefix)
- (setq armor-prefix ""))
-
- (setq armor-end-regexp
- (concat "^"
- armor-prefix
- "-----END PGP MESSAGE-----$"))
- (setq armor-end (re-search-forward armor-end-regexp
- nil t))
-
- (unless armor-end
- (error "Encryption armor beginning has no matching end"))
- (goto-char armor-start)
-
- ;; Because epa--find-coding-system-for-mime-charset not autoloaded.
- (require 'epa)
-
- ;; Advance over this armor.
- (goto-char armor-end)
- (setq after-end (- (point-max) armor-end))
-
- (when mime
- (save-excursion
- (goto-char armor-start)
- (re-search-backward "^--" nil t)
- (save-restriction
- (narrow-to-region (point) armor-start)
-
- ;; Use the charset specified in the armor.
- (unless coding-system-for-read
- (if (re-search-forward "^[ \t]*Charset[ \t\n]*:[ \t\n]*\\(.*\\)" nil t)
- (setq coding-system-for-read
- (epa--find-coding-system-for-mime-charset
- (intern (downcase (match-string 1)))))))
-
- (goto-char (point-min))
- (if (re-search-forward "^[ \t]*Content-transfer-encoding[ \t\n]*:[ \t\n]*quoted-printable[ \t]*$" nil t)
- (setq unquote t)))))
-
- (when unquote
- (let ((inhibit-read-only t))
- (mail-unquote-printable-region armor-start
- (- (point-max) after-end))))
-
- ;; Decrypt it, maybe in place, maybe making new buffer.
- (epa-decrypt-region
- armor-start (- (point-max) after-end)
- ;; Call back this function to prepare the output.
- (lambda ()
- (let ((inhibit-read-only t))
- (delete-region armor-start (- (point-max) after-end))
- (goto-char armor-start)
- (current-buffer))))
-
- (push (list armor-start (- (point-max) after-end) mime
- armor-end-regexp)
- decrypts)))
+ (case-fold-search t))
- (unless decrypts
- (error "Nothing to decrypt"))
+ (push (rmail-epa-decrypt-1 mime) decrypts)))
+
+ (when (and decrypts (eq major-mode 'rmail-mode))
+ (rmail-add-label "decrypt"))
(when (and decrypts (rmail-buffers-swapped-p))
(when (y-or-n-p "Replace the original message? ")
(let ((value (match-string 0)))
(unless (member value '("text/plain" "text/html"))
(replace-match "text/plain"))))))))
- ))))))))))
-
+ )))))))
+
+ (when (and (null decrypts)
+ mime mime-disabled)
+ ;; Re-enable mime processing.
+ (rmail-mime)
+ ;; Find each Show button and show that part.
+ (while (search-forward " Show " nil t)
+ (forward-char -2)
+ (let ((rmail-mime-render-html-function nil)
+ (entity (get-text-property (point) 'rmail-mime-entity)))
+ (unless (and (not (stringp entity))
+ (rmail-mime-entity-truncated entity))
+ (push-button))))
+ (goto-char (point-min))
+ (while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
+ (let ((coding-system-for-read coding-system-for-read)
+ (case-fold-search t))
+ (push (rmail-epa-decrypt-1 mime) decrypts)))
+
+ )
+
+ (unless decrypts
+ (error "Nothing to decrypt")))))
+
\f
;;;; Desktop support
-(defun rmail-restore-desktop-buffer (desktop-buffer-file-name
- desktop-buffer-name
- desktop-buffer-misc)
+(defun rmail-restore-desktop-buffer (file-name
+ _buffer-name
+ _buffer-misc)
"Restore an rmail buffer specified in a desktop file."
- (condition-case error
+ (condition-case nil
(progn
- (rmail-input desktop-buffer-file-name)
+ (rmail-input file-name)
(if (eq major-mode 'rmail-mode)
(current-buffer)
rmail-buffer))
(defvar rmail-message-encoding nil)
;; Used in `write-region-annotate-functions' to write rmail files.
-(defun rmail-write-region-annotate (start end)
+(defun rmail-write-region-annotate (start _end)
(when (and (null start) rmail-buffer-swapped)
(unless (buffer-live-p rmail-view-buffer)
(error "Buffer `%s' with real text of `%s' has disappeared"
\f
;;; Start of automatically extracted autoloads.
\f
-;;;### (autoloads nil "rmailedit" "rmailedit.el" "f6da7267316d02c90b9d314ce95b3c22")
+;;;### (autoloads nil "rmailedit" "rmailedit.el" "1ed1c211e6e9c254ba3e0dd8d546e745")
;;; Generated autoloads from rmailedit.el
(autoload 'rmail-edit-current-message "rmailedit" "\
;;;***
\f
-;;;### (autoloads nil "rmailmm" "rmailmm.el" "a17df5ef8968113c8f6a78cf85c82da4")
+;;;### (autoloads nil "rmailmm" "rmailmm.el" "e5b89eed8afb278cc8881f2208382c7c")
;;; Generated autoloads from rmailmm.el
(autoload 'rmail-mime "rmailmm" "\
;;;***
\f
-;;;### (autoloads nil "rmailsum" "rmailsum.el" "3203e61425330fc20f3154b559f8b539")
+;;;### (autoloads nil "rmailsum" "rmailsum.el" "4bc0d1a65aede332348200e1937c84d4")
;;; Generated autoloads from rmailsum.el
(autoload 'rmail-summary "rmailsum" "\
Normally checks the To, From and Cc fields of headers;
but if PRIMARY-ONLY is non-nil (prefix arg given),
only look in the To and From fields.
-RECIPIENTS is a string of regexps separated by commas.
+RECIPIENTS is a regular expression.
\(fn RECIPIENTS &optional PRIMARY-ONLY)" t nil)
Display a summary of all messages with the given SUBJECT.
Normally checks just the Subject field of headers; but with prefix
argument WHOLE-MESSAGE is non-nil, looks in the whole message.
-SUBJECT is a string of regexps separated by commas.
+SUBJECT is a regular expression.
\(fn SUBJECT &optional WHOLE-MESSAGE)" t nil)
(autoload 'rmail-summary-by-senders "rmailsum" "\
Display a summary of all messages whose \"From\" field matches SENDERS.
-SENDERS is a string of regexps separated by commas.
+SENDERS is a regular expression.
\(fn SENDERS)" t nil)