summaryrefslogtreecommitdiff
path: root/lisp/mail
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/mail')
-rw-r--r--lisp/mail/emacsbug.el11
-rw-r--r--lisp/mail/hashcash.el4
-rw-r--r--lisp/mail/rmail.el164
-rw-r--r--lisp/mail/rmailmm.el139
-rw-r--r--lisp/mail/rmailsum.el80
-rw-r--r--lisp/mail/smtpmail.el3
6 files changed, 283 insertions, 118 deletions
diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el
index 4cfd3e2051e..5dde90b9fe4 100644
--- a/lisp/mail/emacsbug.el
+++ b/lisp/mail/emacsbug.el
@@ -1,7 +1,7 @@
;;; emacsbug.el --- command to report Emacs bugs to appropriate mailing list
-;; Copyright (C) 1985, 1994, 1997-1998, 2000-2014 Free Software
-;; Foundation, Inc.
+;; Copyright (C) 1985, 1994, 1997-1998, 2000-2014
+;; Free Software Foundation, Inc.
;; Author: K. Shane Hartman
;; Maintainer: emacs-devel@gnu.org
@@ -43,11 +43,6 @@
(define-obsolete-variable-alias 'report-emacs-bug-pretest-address
'report-emacs-bug-address "24.1")
-(defcustom report-emacs-bug-address "bug-gnu-emacs@gnu.org"
- "Address of mailing list for GNU Emacs bugs."
- :group 'emacsbug
- :type 'string)
-
(defcustom report-emacs-bug-no-confirmation nil
"If non-nil, suppress the confirmations asked for the sake of novice users."
:group 'emacsbug
@@ -261,6 +256,8 @@ usually do not have translators for other languages.\n\n")))
(insert "Configured using:\n `configure "
system-configuration-options "'\n\n")
(fill-region (line-beginning-position -1) (point)))
+ (insert "Configured features:\n" system-configuration-features "\n\n")
+ (fill-region (line-beginning-position -1) (point))
(insert "Important settings:\n")
(mapc
(lambda (var)
diff --git a/lisp/mail/hashcash.el b/lisp/mail/hashcash.el
index 2224884eede..fb8dfba8554 100644
--- a/lisp/mail/hashcash.el
+++ b/lisp/mail/hashcash.el
@@ -47,10 +47,6 @@
;;; Code:
-;; For Emacs <22.2 and XEmacs.
-(eval-and-compile
- (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
-
(eval-when-compile (require 'cl)) ; for case
(defgroup hashcash nil
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index 52f4845eecb..8c43e090d63 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -1507,8 +1507,7 @@ If so restore the actual mbox message collection."
'(rmail-font-lock-keywords
t t nil nil
(font-lock-maximum-size . nil)
- (font-lock-fontify-buffer-function . rmail-fontify-buffer-function)
- (font-lock-unfontify-buffer-function . rmail-unfontify-buffer-function)
+ (font-lock-dont-widen . t)
(font-lock-inhibit-thing-lock . (lazy-lock-mode fast-lock-mode))))
(make-local-variable 'require-final-newline)
(setq require-final-newline nil)
@@ -3448,47 +3447,66 @@ STATE non-nil means mark as deleted."
"Delete this message and stay on it."
(interactive)
(rmail-set-attribute rmail-deleted-attr-index t)
- (run-hooks 'rmail-delete-message-hook))
+ (run-hooks 'rmail-delete-message-hook)
+ (let ((del-msg rmail-current-message))
+ (if (rmail-summary-exists)
+ (rmail-select-summary
+ (rmail-summary-mark-deleted del-msg)))))
-(defun rmail-undelete-previous-message ()
+(defun rmail-undelete-previous-message (count)
"Back up to deleted message, select it, and undelete it."
- (interactive)
+ (interactive "p")
(set-buffer rmail-buffer)
- (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 backward)
+ (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)))
+
+(defun rmail-delete-forward (&optional count)
"Delete this message and move to next nondeleted one.
Deleted messages stay in the file until the \\[rmail-expunge] command is given.
-With prefix argument, delete and move backward.
+Optional argument COUNT (interactively, prefix argument) is a repeat count;
+negative argument means move backwards instead of forwards.
Returns t if a new message is displayed after the delete, or nil otherwise."
- (interactive "P")
- (rmail-set-attribute rmail-deleted-attr-index t)
- (run-hooks 'rmail-delete-message-hook)
- (let ((del-msg rmail-current-message))
- (if (rmail-summary-exists)
- (rmail-select-summary
- (rmail-summary-mark-deleted del-msg)))
- (prog1 (rmail-next-undeleted-message (if backward -1 1))
- (rmail-maybe-display-summary))))
+ (interactive "p")
+ (if (not count) (setq count 1))
+ (let (value backward)
+ (if (< count 0)
+ (setq count (- count) backward t))
+ (dotimes (i count)
+ (rmail-set-attribute rmail-deleted-attr-index t)
+ (run-hooks 'rmail-delete-message-hook)
+ (let ((del-msg rmail-current-message))
+ (if (rmail-summary-exists)
+ (rmail-select-summary
+ (rmail-summary-mark-deleted del-msg)))
+ (setq value (rmail-next-undeleted-message (if backward -1 1)))))
+ (rmail-maybe-display-summary)
+ value))
-(defun rmail-delete-backward ()
+(defun rmail-delete-backward (&optional count)
"Delete this message and move to previous nondeleted one.
-Deleted messages stay in the file until the \\[rmail-expunge] command is given."
- (interactive)
- (rmail-delete-forward t))
+Deleted messages stay in the file until the \\[rmail-expunge] command is given.
+Optional argument COUNT (interactively, prefix argument) is a repeat count;
+negative argument means move forwards instead of backwards.
+
+Returns t if a new message is displayed after the delete, or nil otherwise."
+
+ (interactive "p")
+ (if (not count) (setq count 1))
+ (rmail-delete-forward (- count)))
;; Expunging.
@@ -4297,31 +4315,21 @@ This has an effect only if a summary buffer exists."
(defun rmail-unfontify-buffer-function ()
;; This function's symbol is bound to font-lock-fontify-unbuffer-function.
- (let ((modified (buffer-modified-p))
- (buffer-undo-list t) (inhibit-read-only t)
- before-change-functions after-change-functions
- buffer-file-name buffer-file-truename)
+ (with-silent-modifications
(save-restriction
(widen)
(remove-hook 'rmail-show-message-hook 'rmail-fontify-message t)
(remove-text-properties (point-min) (point-max) '(rmail-fontified nil))
- (font-lock-default-unfontify-buffer)
- (and (not modified) (buffer-modified-p)
- (restore-buffer-modified-p nil)))))
+ (font-lock-default-unfontify-buffer))))
(defun rmail-fontify-message ()
;; Fontify the current message if it is not already fontified.
(if (text-property-any (point-min) (point-max) 'rmail-fontified nil)
- (let ((modified (buffer-modified-p))
- (buffer-undo-list t) (inhibit-read-only t)
- before-change-functions after-change-functions
- buffer-file-name buffer-file-truename)
+ (with-silent-modifications
(save-excursion
(save-match-data
(add-text-properties (point-min) (point-max) '(rmail-fontified t))
- (font-lock-fontify-region (point-min) (point-max))
- (and (not modified) (buffer-modified-p)
- (restore-buffer-modified-p nil)))))))
+ (font-lock-fontify-region (point-min) (point-max)))))))
;;; Speedbar support for RMAIL files.
(defcustom rmail-speedbar-match-folder-regexp "^[A-Z0-9]+\\(\\.[A-Z0-9]+\\)?$"
@@ -4504,11 +4512,11 @@ encoded string (and the same mask) will decode the string."
;; change it in one of the calls to `epa-decrypt-region'.
(save-excursion
- (let (decrypts)
+ (let (decrypts (mime (rmail-mime-message-p)))
(goto-char (point-min))
;; Turn off mime processing.
- (when (and (rmail-mime-message-p)
+ (when (and mime
(not (get-text-property (point-min) 'rmail-mime-hidden)))
(rmail-mime))
@@ -4517,10 +4525,19 @@ encoded string (and the same mask) will decode the string."
(goto-char (point-min))
(while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
(let ((coding-system-for-read coding-system-for-read)
- armor-start armor-end after-end)
+ (case-fold-search t)
+ unquote
+ armor-start armor-prefix armor-end after-end)
+
(setq armor-start (match-beginning 0)
- armor-end (re-search-forward "^-----END PGP MESSAGE-----$"
- nil t))
+ armor-prefix (buffer-substring
+ (line-beginning-position)
+ armor-start)
+ armor-end (re-search-forward
+ (concat "^"
+ armor-prefix
+ "-----END PGP MESSAGE-----$")
+ nil t))
(unless armor-end
(error "Encryption armor beginning has no matching end"))
(goto-char armor-start)
@@ -4528,30 +4545,49 @@ encoded string (and the same mask) will decode the string."
;; Because epa--find-coding-system-for-mime-charset not autoloaded.
(require 'epa)
- ;; Use the charset specified in the armor.
- (unless coding-system-for-read
- (if (re-search-forward "^Charset: \\(.*\\)" armor-end t)
- (setq coding-system-for-read
- (epa--find-coding-system-for-mime-charset
- (intern (downcase (match-string 1)))))))
-
;; 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 "^Charset: \\(.*\\)" 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]*:[ \t]*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 armor-end
+ armor-start (- (point-max) after-end)
;; Call back this function to prepare the output.
(lambda ()
(let ((inhibit-read-only t))
- (delete-region armor-start armor-end)
+ (delete-region armor-start (- (point-max) after-end))
(goto-char armor-start)
(current-buffer))))
(push (list armor-start (- (point-max) after-end))
decrypts)))
+ (unless decrypts
+ (error "Nothing to decrypt"))
+
(when (and decrypts (rmail-buffers-swapped-p))
(when (y-or-n-p "Replace the original message? ")
(setq decrypts (nreverse decrypts))
@@ -4676,7 +4712,7 @@ With prefix argument N moves forward N messages with these labels.
;;;***
-;;;### (autoloads nil "rmailmm" "rmailmm.el" "4904dafb4e3b7b456c14e63d2dc9163d")
+;;;### (autoloads nil "rmailmm" "rmailmm.el" "6446c799d49a6df8519b11bfe2e3cbea")
;;; Generated autoloads from rmailmm.el
(autoload 'rmail-mime "rmailmm" "\
@@ -4773,7 +4809,7 @@ If prefix argument REVERSE is non-nil, sorts in reverse order.
;;;***
-;;;### (autoloads nil "rmailsum" "rmailsum.el" "1278ff9911aa307f30dd57c20adbcdc6")
+;;;### (autoloads nil "rmailsum" "rmailsum.el" "ee1fa556cd65d7ef457a97ab560e15da")
;;; Generated autoloads from rmailsum.el
(autoload 'rmail-summary "rmailsum" "\
diff --git a/lisp/mail/rmailmm.el b/lisp/mail/rmailmm.el
index 2c625f67e38..29f7d449a8b 100644
--- a/lisp/mail/rmailmm.el
+++ b/lisp/mail/rmailmm.el
@@ -131,6 +131,26 @@ automatically display the image in the buffer."
:version "23.2"
:group 'rmail-mime)
+(defcustom rmail-mime-render-html-function
+ (cond ((fboundp 'libxml-parse-html-region) 'rmail-mime-render-html-shr)
+ ((executable-find "lynx") 'rmail-mime-render-html-lynx)
+ (t nil))
+ "Function to convert HTML to text. Called with buffer containing HTML
+extracted from message in a temporary buffer. Converts to text in current
+buffer. If NIL, display HTML source."
+ :group 'rmail
+ :version "25.1"
+ :type '(choice function (const nil)))
+
+(defcustom rmail-mime-prefer-html
+ ;; Default to preferring HTML parts, but only if we have a renderer
+ (if rmail-mime-render-html-function t nil)
+ "If non-nil, default to showing HTML part rather than text part
+when both are available"
+ :group 'rmail
+ :version "25.1"
+ :type 'boolean)
+
;;; End of user options.
;;; Global variables that always have let-binding when referred.
@@ -150,6 +170,10 @@ processing MIME.")
The value is usually nil, and bound to non-nil while inserting
MIME entities.")
+(defvar rmail-mime-searching nil
+ "Bound to T inside `rmail-search-mime-message' to suppress expensive
+operations such as HTML decoding")
+
;;; MIME-entity object
(defun rmail-mime-entity (type disposition transfer-encoding
@@ -631,6 +655,72 @@ HEADER is a header component of a MIME-entity object (see
(insert-image (create-image data (cdr bulk-data) t))
(insert "\n")))
+(defun rmail-mime-insert-html (entity)
+ "Decode, render, and insert html from MIME-entity ENTITY."
+ (let ((body (rmail-mime-entity-body entity))
+ (transfer-encoding (rmail-mime-entity-transfer-encoding entity))
+ (charset (cdr (assq 'charset (cdr (rmail-mime-entity-type entity)))))
+ (buffer (current-buffer))
+ coding-system)
+ (if charset (setq coding-system (coding-system-from-name charset)))
+ (or (and coding-system (coding-system-p coding-system))
+ (setq coding-system 'undecided))
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (setq buffer-undo-list t)
+ (insert-buffer-substring rmail-mime-mbox-buffer
+ (aref body 0) (aref body 1))
+ (cond ((string= transfer-encoding "base64")
+ (ignore-errors (base64-decode-region (point-min) (point-max))))
+ ((string= transfer-encoding "quoted-printable")
+ (quoted-printable-decode-region (point-min) (point-max))))
+ (decode-coding-region (point-min) (point) coding-system)
+ (if (and
+ (or (not rmail-mime-coding-system) (consp rmail-mime-coding-system))
+ (not (eq (coding-system-base coding-system) 'us-ascii)))
+ (setq rmail-mime-coding-system coding-system))
+ ;; Convert html in temporary buffer to text and insert in original buffer
+ (let ((source-buffer (current-buffer)))
+ (with-current-buffer buffer
+ (let ((start (point)))
+ (if rmail-mime-render-html-function
+ (funcall rmail-mime-render-html-function source-buffer)
+ (insert-buffer-substring source-buffer))
+ (rmail-mime-fix-inserted-faces start)))))))
+
+(defun rmail-mime-render-html-shr (source-buffer)
+ (let ((dom (with-current-buffer source-buffer
+ (libxml-parse-html-region (point-min) (point-max))))
+ ;; Image retrieval happens asynchronously, but meanwhile
+ ;; `rmail-swap-buffers' may have been run, leaving
+ ;; `shr-image-fetched' trying to insert the image in the wrong buffer.
+ (shr-inhibit-images t)
+ ;; Bind shr-width to nil to force shr-insert-document break
+ ;; the lines at the window margin. The default is
+ ;; fill-column, whose default value is too small, and screws
+ ;; up display of the quoted messages.
+ shr-width)
+ (shr-insert-document dom)))
+
+(defun rmail-mime-render-html-lynx (source-buffer)
+ (let ((destination-buffer (current-buffer)))
+ (with-current-buffer source-buffer
+ (call-process-region (point-min) (point-max)
+ "lynx" nil destination-buffer nil
+ "-stdin" "-dump" "-force_html"
+ "-dont_wrap_pre" "-width=70"))))
+
+;; Put font-lock-face properties matching face properties on text
+;; inserted, e.g., by shr, in text from START to point.
+(defun rmail-mime-fix-inserted-faces (start)
+ (while (< start (point))
+ (let ((face (get-text-property start 'face))
+ (next (next-single-property-change
+ start 'face (current-buffer) (point))))
+ (if face ; anything to do?
+ (put-text-property start next 'font-lock-face face))
+ (setq start next))))
+
(defun rmail-mime-toggle-button (button)
"Hide or show the body of the MIME-entity associated with BUTTON."
(save-excursion
@@ -675,6 +765,8 @@ directly."
(setq size (/ (* size 7) 3)))))))
(cond
+ ((string-match "text/html" content-type)
+ (setq type 'html))
((string-match "text/" content-type)
(setq type 'text))
((string-match "image/\\(.*\\)" content-type)
@@ -784,6 +876,12 @@ directly."
(if (rmail-mime-display-body new)
(cond ((eq (cdr bulk-data) 'text)
(rmail-mime-insert-decoded-text entity))
+ ((eq (cdr bulk-data) 'html)
+ ;; Render HTML if display single message, but if searching
+ ;; don't render but just search HTML itself.
+ (if rmail-mime-searching
+ (rmail-mime-insert-decoded-text entity)
+ (rmail-mime-insert-html entity)))
((cdr bulk-data)
(rmail-mime-insert-image entity))
(t
@@ -918,18 +1016,28 @@ The other arguments are the same as `rmail-mime-multipart-handler'."
(setq entities (nreverse entities))
(if (string-match "alternative" subtype)
;; Find the best entity to show, and hide all the others.
- (let (best second)
+ ;; If rmail-mime-prefer-html is set, html is best, then plain.
+ ;; If not, plain is best, then html.
+ ;; Then comes any other text part.
+ ;; If thereto of the same type, earlier entities in the message (later
+ ;; in the reverse list) are preferred.
+ (let (best best-priority)
(dolist (child entities)
(if (string= (or (car (rmail-mime-entity-disposition child))
(car content-disposition))
"inline")
- (if (string-match "text/plain"
- (car (rmail-mime-entity-type child)))
- (setq best child)
- (if (string-match "text/.*"
- (car (rmail-mime-entity-type child)))
- (setq second child)))))
- (or best (not second) (setq best second))
+ (let ((type (car (rmail-mime-entity-type child))))
+ (if (string-match "text/" type)
+ ;; Consider all inline text parts
+ (let ((priority
+ (cond ((string-match "text/html" type)
+ (if rmail-mime-prefer-html 1 2))
+ ((string-match "text/plain" type)
+ (if rmail-mime-prefer-html 2 1))
+ (t 3))))
+ (if (or (null best) (<= priority best-priority))
+ (setq best child
+ best-priority priority)))))))
(dolist (child entities)
(unless (eq best child)
(aset (rmail-mime-entity-body child) 2 nil)
@@ -1114,6 +1222,8 @@ modified."
(cond ((string-match "multipart/.*" (car content-type))
(save-restriction
(narrow-to-region (1- end) (point-max))
+ (if (zerop (length parse-tag)) ; top level of message
+ (aset new 1 (aset tagline 2 nil))) ; don't show tagline
(setq children (rmail-mime-process-multipart
content-type
content-disposition
@@ -1134,6 +1244,12 @@ modified."
(aset (rmail-mime-entity-tagline msg) 2 nil)
(setq children (list msg)
handler 'rmail-mime-insert-multipart))))
+ ((and is-inline (string-match "text/html" (car content-type)))
+ ;; Display tagline, so part can be detached
+ (aset new 1 (aset tagline 2 t))
+ (aset new 2 (aset body 2 t)) ; display body also.
+ (setq handler 'rmail-mime-insert-bulk))
+ ;; Inline non-HTML text
((and is-inline (string-match "text/" (car content-type)))
;; Don't need a tagline.
(aset new 1 (aset tagline 2 nil))
@@ -1186,10 +1302,6 @@ If an error occurs, return an error message string."
(new (aref (rmail-mime-entity-display entity) 1)))
;; Show header.
(aset new 0 (aset (rmail-mime-entity-header entity) 2 t))
- ;; Show tagline if and only if body is not shown.
- (if (aref new 2)
- (aset new 1 (aset (rmail-mime-entity-tagline entity) 2 nil))
- (aset new 1 (aset (rmail-mime-entity-tagline entity) 2 t)))
entity)))
(error (format "%s" err)))))
@@ -1390,7 +1502,8 @@ This is the usual value of `rmail-insert-mime-forwarded-message-function'."
"Function to set in `rmail-search-mime-message-function' (which see)."
(save-restriction
(narrow-to-region (rmail-msgbeg msg) (rmail-msgend msg))
- (let* ((rmail-mime-mbox-buffer (current-buffer))
+ (let* ((rmail-mime-searching t) ; mark inside search
+ (rmail-mime-mbox-buffer (current-buffer))
(rmail-mime-view-buffer rmail-view-buffer)
(header-end (save-excursion
(re-search-forward "^$" nil 'move) (point)))
diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el
index ca884136a34..af08d0f3d3a 100644
--- a/lisp/mail/rmailsum.el
+++ b/lisp/mail/rmailsum.el
@@ -914,7 +914,10 @@ a negative argument means to delete and move backward."
(unless (numberp count) (setq count 1))
(let (end del-msg
(backward (< count 0)))
- (while (/= count 0)
+ (while (and (/= count 0)
+ ;; Don't waste time if we are at the beginning
+ ;; and trying to go backward.
+ (not (and backward (bobp))))
(rmail-summary-goto-msg)
(with-current-buffer rmail-buffer
(rmail-delete-message)
@@ -924,11 +927,13 @@ a negative argument means to delete and move backward."
(save-excursion (beginning-of-line)
(looking-at " *[0-9]+D")))
(forward-line (if backward -1 1)))
+ (setq count
+ (if (> count 0) (1- count) (1+ count)))
;; It looks ugly to move to the empty line at end of buffer.
+ ;; And don't waste time after hitting the end.
(and (eobp) (not backward)
- (forward-line -1))
- (setq count
- (if (> count 0) (1- count) (1+ count))))))
+ (progn (setq count 0)
+ (forward-line -1))))))
(defun rmail-summary-delete-backward (&optional count)
"Delete this message and move to previous nondeleted one.
@@ -939,8 +944,9 @@ a negative argument means to delete and move forward."
(rmail-summary-delete-forward (- count)))
(defun rmail-summary-mark-deleted (&optional n undel)
- ;; Since third arg is t, this only alters the summary, not the Rmail buf.
- (and n (rmail-summary-goto-msg n t t))
+ (and n (not (eq n (rmail-summary-msg-number)))
+ ;; Since third arg is t, this only alters summary, not the Rmail buf.
+ (rmail-summary-goto-msg n t t))
(or (eobp)
(not (overlay-get rmail-summary-overlay 'face))
(let ((buffer-read-only nil))
@@ -951,9 +957,9 @@ a negative argument means to delete and move forward."
(progn (delete-char 1) (insert " ")))
(delete-char 1)
(insert "D"))
- ;; Register a new summary line.
+ ;; Discard cached new summary line.
(with-current-buffer rmail-buffer
- (aset rmail-summary-vector (1- n) (rmail-create-summary-line n)))))
+ (aset rmail-summary-vector (1- n) nil))))
(beginning-of-line))
(defun rmail-summary-update-line (n)
@@ -1002,7 +1008,7 @@ Optional prefix ARG means undelete ARG previous messages."
(set-buffer rmail-buffer)
(rmail-pop-to-buffer rmail-buffer))
(and (rmail-message-deleted-p rmail-current-message)
- (rmail-undelete-previous-message))
+ (rmail-undelete-previous-message 1))
(if rmail-enable-mime
(rmail-pop-to-buffer rmail-buffer))
(rmail-pop-to-buffer rmail-summary-buffer))
@@ -1011,26 +1017,35 @@ Optional prefix ARG means undelete ARG previous messages."
(defun rmail-summary-undelete-many (&optional n)
"Undelete all deleted msgs, optional prefix arg N means undelete N prev msgs."
(interactive "P")
- (with-current-buffer rmail-buffer
- (let* ((init-msg (if n rmail-current-message rmail-total-messages))
- (rmail-current-message init-msg)
- (n (or n rmail-total-messages))
- (msgs-undeled 0))
- (while (and (> rmail-current-message 0)
- (< msgs-undeled n))
- (if (rmail-message-deleted-p rmail-current-message)
- (progn (rmail-set-attribute rmail-deleted-attr-index nil)
- (setq msgs-undeled (1+ msgs-undeled))))
- (setq rmail-current-message (1- rmail-current-message)))
- (set-buffer rmail-summary-buffer)
- (setq rmail-current-message init-msg msgs-undeled 0)
- (while (and (> rmail-current-message 0)
- (< msgs-undeled n))
- (if (rmail-summary-deleted-p rmail-current-message)
- (progn (rmail-summary-mark-undeleted rmail-current-message)
- (setq msgs-undeled (1+ msgs-undeled))))
- (setq rmail-current-message (1- rmail-current-message))))
- (rmail-summary-goto-msg)))
+ (if n
+ (while (and (> n 0) (not (eobp)))
+ (rmail-summary-goto-msg)
+ (let (del-msg)
+ (when (rmail-summary-deleted-p)
+ (with-current-buffer rmail-buffer
+ (rmail-undelete-previous-message 1)
+ (setq del-msg rmail-current-message))
+ (rmail-summary-mark-undeleted del-msg)))
+ (while (and (not (eobp))
+ (save-excursion (beginning-of-line)
+ (looking-at " *[0-9]+ ")))
+ (forward-line 1))
+ (setq n (1- n)))
+ (rmail-summary-goto-msg 1)
+ (dotimes (i rmail-total-messages)
+ (rmail-summary-goto-msg)
+ (let (del-msg)
+ (when (rmail-summary-deleted-p)
+ (with-current-buffer rmail-buffer
+ (rmail-undelete-previous-message 1)
+ (setq del-msg rmail-current-message))
+ (rmail-summary-mark-undeleted del-msg)))
+ (if (not (eobp))
+ (forward-line 1))))
+
+ ;; It looks ugly to move to the empty line at end of buffer.
+ (and (eobp)
+ (forward-line -1)))
;; Rmail Summary mode is suitable only for specially formatted data.
(put 'rmail-summary-mode 'mode-class 'special)
@@ -1188,6 +1203,13 @@ Search, the `unseen' attribute is restored.")
(goto-char (posn-point (event-end event)))
(rmail-summary-goto-msg))
+(defun rmail-summary-msg-number ()
+ (save-excursion
+ (beginning-of-line)
+ (string-to-number
+ (buffer-substring (point)
+ (min (point-max) (+ 6 (point)))))))
+
(defun rmail-summary-goto-msg (&optional n nowarn skip-rmail)
"Go to message N in the summary buffer and the Rmail buffer.
If N is nil, use the message corresponding to point in the summary
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index 54f4664e6db..e70499f222a 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -687,6 +687,7 @@ Returns an error if the server cannot be contacted."
"smtpmail" process-buffer host port
:type smtpmail-stream-type
:return-list t
+ :warn-unless-encrypted ask-for-password
:capability-command (format "EHLO %s\r\n" (smtpmail-fqdn))
:end-of-command "^[0-9]+ .*\r\n"
:success "^2.*\n"
@@ -733,7 +734,7 @@ Returns an error if the server cannot be contacted."
(plist-get (cdr result) :capabilities)
"\r\n")))
(let ((name
- (with-case-table ascii-case-table
+ (with-case-table ascii-case-table ;FIXME: Why?
(mapcar (lambda (s) (intern (downcase s)))
(split-string (substring line 4) "[ ]")))))
(when (= (length name) 1)