;;; rmailsum.el --- make summary buffers for the mail reader
-;; Copyright (C) 1985, 1993, 1994, 1995, 1996, 2000, 2001, 2002, 2003,
-;; 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1993-1996, 2000-2014 Free Software Foundation,
+;; Inc.
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: mail
+;; Package: rmail
;; This file is part of GNU Emacs.
"Overlay used to highlight the current message in the Rmail summary.")
(put 'rmail-summary-overlay 'permanent-local t)
-(defvar rmail-summary-mode-map nil
+(defvar rmail-summary-mode-map
+ (let ((map (make-keymap)))
+ (suppress-keymap map)
+ (define-key map [mouse-2] 'rmail-summary-mouse-goto-message)
+ (define-key map "a" 'rmail-summary-add-label)
+ (define-key map "b" 'rmail-summary-bury)
+ (define-key map "c" 'rmail-summary-continue)
+ (define-key map "d" 'rmail-summary-delete-forward)
+ (define-key map "\C-d" 'rmail-summary-delete-backward)
+ (define-key map "e" 'rmail-summary-edit-current-message)
+ (define-key map "f" 'rmail-summary-forward)
+ (define-key map "g" 'rmail-summary-get-new-mail)
+ (define-key map "h" 'rmail-summary)
+ (define-key map "i" 'rmail-summary-input)
+ (define-key map "j" 'rmail-summary-goto-msg)
+ (define-key map "\C-m" 'rmail-summary-goto-msg)
+ (define-key map "k" 'rmail-summary-kill-label)
+ (define-key map "l" 'rmail-summary-by-labels)
+ (define-key map "\e\C-h" 'rmail-summary)
+ (define-key map "\e\C-l" 'rmail-summary-by-labels)
+ (define-key map "\e\C-r" 'rmail-summary-by-recipients)
+ (define-key map "\e\C-s" 'rmail-summary-by-regexp)
+ ;; `f' for "from".
+ (define-key map "\e\C-f" 'rmail-summary-by-senders)
+ (define-key map "\e\C-t" 'rmail-summary-by-topic)
+ (define-key map "m" 'rmail-summary-mail)
+ (define-key map "\M-m" 'rmail-summary-retry-failure)
+ (define-key map "n" 'rmail-summary-next-msg)
+ (define-key map "\en" 'rmail-summary-next-all)
+ (define-key map "\e\C-n" 'rmail-summary-next-labeled-message)
+ (define-key map "o" 'rmail-summary-output)
+ (define-key map "\C-o" 'rmail-summary-output-as-seen)
+ (define-key map "p" 'rmail-summary-previous-msg)
+ (define-key map "\ep" 'rmail-summary-previous-all)
+ (define-key map "\e\C-p" 'rmail-summary-previous-labeled-message)
+ (define-key map "q" 'rmail-summary-quit)
+ (define-key map "Q" 'rmail-summary-wipe)
+ (define-key map "r" 'rmail-summary-reply)
+ (define-key map "s" 'rmail-summary-expunge-and-save)
+ ;; See rms's comment in rmail.el
+ ;; (define-key map "\er" 'rmail-summary-search-backward)
+ (define-key map "\es" 'rmail-summary-search)
+ (define-key map "t" 'rmail-summary-toggle-header)
+ (define-key map "u" 'rmail-summary-undelete)
+ (define-key map "\M-u" 'rmail-summary-undelete-many)
+ (define-key map "x" 'rmail-summary-expunge)
+ (define-key map "w" 'rmail-summary-output-body)
+ (define-key map "v" 'rmail-mime)
+ (define-key map "." 'rmail-summary-beginning-of-message)
+ (define-key map "/" 'rmail-summary-end-of-message)
+ (define-key map "<" 'rmail-summary-first-message)
+ (define-key map ">" 'rmail-summary-last-message)
+ (define-key map " " 'rmail-summary-scroll-msg-up)
+ (define-key map [?\S-\ ] 'rmail-summary-scroll-msg-down)
+ (define-key map "\177" 'rmail-summary-scroll-msg-down)
+ (define-key map "?" 'describe-mode)
+ (define-key map "\C-c\C-n" 'rmail-summary-next-same-subject)
+ (define-key map "\C-c\C-p" 'rmail-summary-previous-same-subject)
+ (define-key map "\C-c\C-s\C-d" 'rmail-summary-sort-by-date)
+ (define-key map "\C-c\C-s\C-s" 'rmail-summary-sort-by-subject)
+ (define-key map "\C-c\C-s\C-a" 'rmail-summary-sort-by-author)
+ (define-key map "\C-c\C-s\C-r" 'rmail-summary-sort-by-recipient)
+ (define-key map "\C-c\C-s\C-c" 'rmail-summary-sort-by-correspondent)
+ (define-key map "\C-c\C-s\C-l" 'rmail-summary-sort-by-lines)
+ (define-key map "\C-c\C-s\C-k" 'rmail-summary-sort-by-labels)
+ (define-key map "\C-x\C-s" 'rmail-summary-save-buffer)
+
+ ;; Menu bar bindings.
+
+ (define-key map [menu-bar] (make-sparse-keymap))
+
+ (define-key map [menu-bar classify]
+ (cons "Classify" (make-sparse-keymap "Classify")))
+
+ (define-key map [menu-bar classify output-menu]
+ '("Output (Rmail Menu)..." . rmail-summary-output-menu))
+
+ (define-key map [menu-bar classify input-menu]
+ '("Input Rmail File (menu)..." . rmail-input-menu))
+
+ (define-key map [menu-bar classify input-menu]
+ '(nil))
+
+ (define-key map [menu-bar classify output-menu]
+ '(nil))
+
+ (define-key map [menu-bar classify output-body]
+ '("Output body..." . rmail-summary-output-body))
+
+ (define-key map [menu-bar classify output-inbox]
+ '("Output..." . rmail-summary-output))
+
+ (define-key map [menu-bar classify output]
+ '("Output as seen..." . rmail-summary-output-as-seen))
+
+ (define-key map [menu-bar classify kill-label]
+ '("Kill Label..." . rmail-summary-kill-label))
+
+ (define-key map [menu-bar classify add-label]
+ '("Add Label..." . rmail-summary-add-label))
+
+ (define-key map [menu-bar summary]
+ (cons "Summary" (make-sparse-keymap "Summary")))
+
+ (define-key map [menu-bar summary senders]
+ '("By Senders..." . rmail-summary-by-senders))
+
+ (define-key map [menu-bar summary labels]
+ '("By Labels..." . rmail-summary-by-labels))
+
+ (define-key map [menu-bar summary recipients]
+ '("By Recipients..." . rmail-summary-by-recipients))
+
+ (define-key map [menu-bar summary topic]
+ '("By Topic..." . rmail-summary-by-topic))
+
+ (define-key map [menu-bar summary regexp]
+ '("By Regexp..." . rmail-summary-by-regexp))
+
+ (define-key map [menu-bar summary all]
+ '("All" . rmail-summary))
+
+ (define-key map [menu-bar mail]
+ (cons "Mail" (make-sparse-keymap "Mail")))
+
+ (define-key map [menu-bar mail rmail-summary-get-new-mail]
+ '("Get New Mail" . rmail-summary-get-new-mail))
+
+ (define-key map [menu-bar mail lambda]
+ '("----"))
+
+ (define-key map [menu-bar mail continue]
+ '("Continue" . rmail-summary-continue))
+
+ (define-key map [menu-bar mail resend]
+ '("Re-send..." . rmail-summary-resend))
+
+ (define-key map [menu-bar mail forward]
+ '("Forward" . rmail-summary-forward))
+
+ (define-key map [menu-bar mail retry]
+ '("Retry" . rmail-summary-retry-failure))
+
+ (define-key map [menu-bar mail reply]
+ '("Reply" . rmail-summary-reply))
+
+ (define-key map [menu-bar mail mail]
+ '("Mail" . rmail-summary-mail))
+
+ (define-key map [menu-bar delete]
+ (cons "Delete" (make-sparse-keymap "Delete")))
+
+ (define-key map [menu-bar delete expunge/save]
+ '("Expunge/Save" . rmail-summary-expunge-and-save))
+
+ (define-key map [menu-bar delete expunge]
+ '("Expunge" . rmail-summary-expunge))
+
+ (define-key map [menu-bar delete undelete]
+ '("Undelete" . rmail-summary-undelete))
+
+ (define-key map [menu-bar delete delete]
+ '("Delete" . rmail-summary-delete-forward))
+
+ (define-key map [menu-bar move]
+ (cons "Move" (make-sparse-keymap "Move")))
+
+ (define-key map [menu-bar move search-back]
+ '("Search Back..." . rmail-summary-search-backward))
+
+ (define-key map [menu-bar move search]
+ '("Search..." . rmail-summary-search))
+
+ (define-key map [menu-bar move previous]
+ '("Previous Nondeleted" . rmail-summary-previous-msg))
+
+ (define-key map [menu-bar move next]
+ '("Next Nondeleted" . rmail-summary-next-msg))
+
+ (define-key map [menu-bar move last]
+ '("Last" . rmail-summary-last-message))
+
+ (define-key map [menu-bar move first]
+ '("First" . rmail-summary-first-message))
+
+ (define-key map [menu-bar move previous]
+ '("Previous" . rmail-summary-previous-all))
+
+ (define-key map [menu-bar move next]
+ '("Next" . rmail-summary-next-all))
+ map)
"Keymap used in Rmail summary mode.")
;; Entry points for making a summary buffer.
(defun rmail-summary ()
"Display a summary of all messages, one line per message."
(interactive)
- (rmail-new-summary "All" '(rmail-summary) nil)
- (unless (get-buffer-window rmail-buffer)
- (rmail-summary-beginning-of-message)))
+ (rmail-new-summary "All" '(rmail-summary) nil))
;;;###autoload
(defun rmail-summary-by-labels (labels)
(defun rmail-message-regexp-p-1 (msg regexp)
;; Search functions can expect to start from the beginning.
(narrow-to-region (point) (save-excursion (search-forward "\n\n") (point)))
- (if rmail-enable-mime
- (if rmail-search-mime-header-function
- (funcall rmail-search-mime-header-function msg regexp (point))
- (error "You must set `rmail-search-mime-header-function'"))
+ (if (and rmail-enable-mime
+ rmail-search-mime-header-function)
+ (funcall rmail-search-mime-header-function msg regexp (point))
(re-search-forward regexp nil t)))
;;;###autoload
(defvar rmail-new-summary-line-count)
-(defun rmail-new-summary (desc redo func &rest args)
+(defun rmail-new-summary (desc redo function &rest args)
"Create a summary of selected messages.
-DESC makes part of the mode line of the summary buffer. REDO is form ...
-For each message, FUNC is applied to the message number and ARGS...
-and if the result is non-nil, that message is included.
-nil for FUNCTION means all messages."
+DESC makes part of the mode line of the summary buffer.
+REDO is what to put in `rmail-summary-redo'; usually
+its car is the function that called `rmail-new-summary'
+and its cdr is the arguments passed to that function.
+
+For each message, applies FUNCTION to the message number and ARGS...,
+and if the result is non-nil, it includes that message in the summary.
+If FUNCTION is nil, includes all messages."
(message "Computing summary lines...")
(unless rmail-buffer
(error "No RMAIL buffer found"))
- (let (mesg was-in-summary)
- (if (eq major-mode 'rmail-summary-mode)
+ (let (mesg was-in-summary sumbuf)
+ (if (derived-mode-p 'rmail-summary-mode)
(setq was-in-summary t))
(with-current-buffer rmail-buffer
- (if (zerop (setq mesg rmail-current-message))
- (error "No messages to summarize"))
- (setq rmail-summary-buffer (rmail-new-summary-1 desc redo func args)))
+ (setq rmail-summary-buffer (rmail-new-summary-1 desc redo function args)
+ ;; r-s-b is buffer-local.
+ sumbuf rmail-summary-buffer
+ mesg rmail-current-message))
;; Now display the summary buffer and go to the right place in it.
(unless was-in-summary
(if (and (one-window-p)
(progn
(split-window (selected-window) rmail-summary-window-size)
(select-window (next-window (frame-first-window)))
- (rmail-pop-to-buffer rmail-summary-buffer)
+ (rmail-pop-to-buffer sumbuf)
;; If pop-to-buffer did not use that window, delete that
;; window. (This can happen if it uses another frame.)
- (if (not (eq rmail-summary-buffer
- (window-buffer (frame-first-window))))
+ (if (not (eq sumbuf (window-buffer (frame-first-window))))
(delete-other-windows)))
- (rmail-pop-to-buffer rmail-summary-buffer))
+ (rmail-pop-to-buffer sumbuf))
(set-buffer rmail-buffer)
;; This is how rmail makes the summary buffer reappear.
;; We do this here to make the window the proper size.
(rmail-select-summary nil)
- (set-buffer rmail-summary-buffer))
+ (set-buffer sumbuf))
(rmail-summary-goto-msg mesg t t)
(rmail-summary-construct-io-menu)
(message "Computing summary lines...done")))
-(defun rmail-new-summary-1 (description form function args)
+(defun rmail-new-summary-1 (description redo function args)
"Filter messages to obtain summary lines.
DESCRIPTION is added to the mode line.
Return the summary buffer by invoking FUNCTION on each message
-passing the message number and ARGS...
+passing the message number and ARGS.
-REDO is a form ...
+REDO is what to put in `rmail-summary-redo'.
The current buffer must be a Rmail buffer either containing a
collection of mbox formatted messages or displaying a single
(widen)
(goto-char (point-min))
(while (>= total msgnum)
- ;; Go back to the Rmail buffer so
- ;; so FUNCTION and rmail-get-summary can see its local vars.
+ ;; Go back to the Rmail buffer so FUNCTION and
+ ;; rmail-get-summary can see its local vars.
(with-current-buffer main-buffer
;; First test whether to include this message.
(if (or (null function)
;; Temporarily, while summary buffer is unfinished,
;; we "don't have" a summary.
(setq rmail-summary-buffer nil)
- (unless summary-msgs
- (kill-buffer sumbuf)
- (error "Nothing to summarize"))
;; I have not a clue what this clause is doing. If you read this
- ;; chunk of code and have a clue, then please email that clue to
- ;; pmr@pajato.com
+ ;; chunk of code and have a clue, then please write it here.
(if rmail-enable-mime
(with-current-buffer rmail-buffer
(setq rmail-summary-buffer nil)))
(make-local-variable 'minor-mode-alist)
(setq minor-mode-alist (list (list t (concat ": " description))))
(setq rmail-buffer rbuf
- rmail-summary-redo form
+ rmail-summary-redo redo
rmail-total-messages total)))
sumbuf))
(point)))))))))
(if (null from)
" "
+ ;; We are going to return only 25 characters of the
+ ;; address, so make sure it is RFC2047 decoded before
+ ;; taking its substring. This is important when the address is not on the same line as the name, e.g.:
+ ;; To: =?UTF-8?Q?=C5=A0t=C4=9Bp=C3=A1n_?= =?UTF-8?Q?N=C4=9Bmec?=
+ ;; <stepnem@gmail.com>
+ (setq from (rfc2047-decode-string from))
(setq len (length from))
(setq mch (string-match "[@%]" from))
(format "%25s"
(setq pos (point))
(forward-line 1)
(setq str (buffer-substring pos (1- (point))))
- (while (looking-at "\\s ")
+ (while (looking-at "[ \t]")
(setq str (concat str " "
(buffer-substring (match-end 0)
(line-end-position))))
(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)
(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.
(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))
(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)
(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))
(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)))
\f
;; Rmail Summary mode is suitable only for specially formatted data.
(put 'rmail-summary-mode 'mode-class 'special)
-(defun rmail-summary-mode ()
+(define-derived-mode rmail-summary-mode special-mode "RMAIL Summary"
"Rmail Summary Mode is invoked from Rmail Mode by using \\<rmail-mode-map>\\[rmail-summary].
As commands are issued in the summary buffer, they are applied to the
corresponding mail messages in the rmail buffer.
\\[rmail-summary-sort-by-correspondent] Sort by correspondent.
\\[rmail-summary-sort-by-lines] Sort by lines.
\\[rmail-summary-sort-by-labels] Sort by labels."
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'rmail-summary-mode)
- (setq mode-name "RMAIL Summary")
(setq truncate-lines t)
(setq buffer-read-only t)
(set-syntax-table text-mode-syntax-table)
(make-local-variable 'revert-buffer-function)
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults '(rmail-summary-font-lock-keywords t))
- (rmail-summary-enable)
- (run-mode-hooks 'rmail-summary-mode-hook))
+ (rmail-summary-enable))
;; Summary features need to be disabled during edit mode.
(defun rmail-summary-disable ()
(forward-line -1))
(beginning-of-line)
(skip-chars-forward " ")
- (let ((msg-num (string-to-number (buffer-substring
- (point)
- (progn (skip-chars-forward "0-9")
- (point))))))
- ;; Always leave `unseen' removed
- ;; if we get out of isearch mode.
- ;; Don't let a subsequent isearch restore that `unseen'.
- (if (not isearch-mode)
- (setq rmail-summary-put-back-unseen nil))
-
- (or (eq rmail-current-message msg-num)
- (let ((window (get-buffer-window rmail-buffer t))
- (owin (selected-window)))
- (if isearch-mode
- (progn
- ;; If we first saw the previous message in this search,
- ;; and we have gone to a different message while searching,
- ;; put back `unseen' on the former one.
- (when rmail-summary-put-back-unseen
- (rmail-set-attribute rmail-unseen-attr-index t
- rmail-current-message)
- (save-excursion
- (goto-char rmail-summary-put-back-unseen)
- (rmail-summary-mark-seen rmail-current-message t t)))
- ;; Arrange to do that later, for the new current message,
- ;; if it still has `unseen'.
- (setq rmail-summary-put-back-unseen
- (if (rmail-message-unseen-p msg-num)
- (point))))
- (setq rmail-summary-put-back-unseen nil))
- ;; Go to the desired message.
- (setq rmail-current-message msg-num)
- ;; Update the summary to show the message has been seen.
- (rmail-summary-mark-seen msg-num t)
- (if window
- ;; Using save-window-excursion would cause the new value
- ;; of point to get lost.
- (unwind-protect
- (progn
- (select-window window)
- (rmail-show-message msg-num t))
- (select-window owin))
- (if (buffer-name rmail-buffer)
- (with-current-buffer rmail-buffer
- (rmail-show-message msg-num t))))
- ;; In linum mode, the message buffer must be specially
- ;; updated (Bug#4878).
- (and (fboundp 'linum-update)
- (buffer-name rmail-buffer)
- (linum-update rmail-buffer))))
- (rmail-summary-update-highlight nil)))))
+ ;; If the summary is empty, don't do anything.
+ (unless (eobp)
+ (let ((msg-num (string-to-number (buffer-substring
+ (point)
+ (progn (skip-chars-forward "0-9")
+ (point))))))
+ ;; Always leave `unseen' removed
+ ;; if we get out of isearch mode.
+ ;; Don't let a subsequent isearch restore that `unseen'.
+ (if (not isearch-mode)
+ (setq rmail-summary-put-back-unseen nil))
+
+ (or (eq rmail-current-message msg-num)
+ (let ((window (get-buffer-window rmail-buffer t))
+ (owin (selected-window)))
+ (if isearch-mode
+ (progn
+ ;; If we first saw the previous message in this search,
+ ;; and we have gone to a different message while searching,
+ ;; put back `unseen' on the former one.
+ (when rmail-summary-put-back-unseen
+ (rmail-set-attribute rmail-unseen-attr-index t
+ rmail-current-message)
+ (save-excursion
+ (goto-char rmail-summary-put-back-unseen)
+ (rmail-summary-mark-seen rmail-current-message t t)))
+ ;; Arrange to do that later, for the new current message,
+ ;; if it still has `unseen'.
+ (setq rmail-summary-put-back-unseen
+ (if (rmail-message-unseen-p msg-num)
+ (point))))
+ (setq rmail-summary-put-back-unseen nil))
+ ;; Go to the desired message.
+ (setq rmail-current-message msg-num)
+ ;; Update the summary to show the message has been seen.
+ (rmail-summary-mark-seen msg-num t)
+ (if window
+ ;; Using save-window-excursion would cause the new value
+ ;; of point to get lost.
+ (unwind-protect
+ (progn
+ (select-window window)
+ (rmail-show-message msg-num t))
+ (select-window owin))
+ (if (buffer-name rmail-buffer)
+ (with-current-buffer rmail-buffer
+ (rmail-show-message msg-num t))))
+ ;; In linum mode, the message buffer must be specially
+ ;; updated (Bug#4878).
+ (and (fboundp 'linum-update)
+ (buffer-name rmail-buffer)
+ (linum-update rmail-buffer))))
+ (rmail-summary-update-highlight nil))))))
(defun rmail-summary-save-buffer ()
"Save the buffer associated with this RMAIL summary."
(save-excursion
(switch-to-buffer rmail-buffer)
(save-buffer))))
-
-\f
-(if rmail-summary-mode-map
- nil
- (setq rmail-summary-mode-map (make-keymap))
- (suppress-keymap rmail-summary-mode-map)
-
- (define-key rmail-summary-mode-map [mouse-2] 'rmail-summary-mouse-goto-message)
- (define-key rmail-summary-mode-map "a" 'rmail-summary-add-label)
- (define-key rmail-summary-mode-map "b" 'rmail-summary-bury)
- (define-key rmail-summary-mode-map "c" 'rmail-summary-continue)
- (define-key rmail-summary-mode-map "d" 'rmail-summary-delete-forward)
- (define-key rmail-summary-mode-map "\C-d" 'rmail-summary-delete-backward)
- (define-key rmail-summary-mode-map "e" 'rmail-summary-edit-current-message)
- (define-key rmail-summary-mode-map "f" 'rmail-summary-forward)
- (define-key rmail-summary-mode-map "g" 'rmail-summary-get-new-mail)
- (define-key rmail-summary-mode-map "h" 'rmail-summary)
- (define-key rmail-summary-mode-map "i" 'rmail-summary-input)
- (define-key rmail-summary-mode-map "j" 'rmail-summary-goto-msg)
- (define-key rmail-summary-mode-map "\C-m" 'rmail-summary-goto-msg)
- (define-key rmail-summary-mode-map "k" 'rmail-summary-kill-label)
- (define-key rmail-summary-mode-map "l" 'rmail-summary-by-labels)
- (define-key rmail-summary-mode-map "\e\C-h" 'rmail-summary)
- (define-key rmail-summary-mode-map "\e\C-l" 'rmail-summary-by-labels)
- (define-key rmail-summary-mode-map "\e\C-r" 'rmail-summary-by-recipients)
- (define-key rmail-summary-mode-map "\e\C-s" 'rmail-summary-by-regexp)
- ;; `f' for "from".
- (define-key rmail-summary-mode-map "\e\C-f" 'rmail-summary-by-senders)
- (define-key rmail-summary-mode-map "\e\C-t" 'rmail-summary-by-topic)
- (define-key rmail-summary-mode-map "m" 'rmail-summary-mail)
- (define-key rmail-summary-mode-map "\M-m" 'rmail-summary-retry-failure)
- (define-key rmail-summary-mode-map "n" 'rmail-summary-next-msg)
- (define-key rmail-summary-mode-map "\en" 'rmail-summary-next-all)
- (define-key rmail-summary-mode-map "\e\C-n" 'rmail-summary-next-labeled-message)
- (define-key rmail-summary-mode-map "o" 'rmail-summary-output)
- (define-key rmail-summary-mode-map "\C-o" 'rmail-summary-output-as-seen)
- (define-key rmail-summary-mode-map "p" 'rmail-summary-previous-msg)
- (define-key rmail-summary-mode-map "\ep" 'rmail-summary-previous-all)
- (define-key rmail-summary-mode-map "\e\C-p" 'rmail-summary-previous-labeled-message)
- (define-key rmail-summary-mode-map "q" 'rmail-summary-quit)
- (define-key rmail-summary-mode-map "Q" 'rmail-summary-wipe)
- (define-key rmail-summary-mode-map "r" 'rmail-summary-reply)
- (define-key rmail-summary-mode-map "s" 'rmail-summary-expunge-and-save)
- ;; See rms's comment in rmail.el
-;;; (define-key rmail-summary-mode-map "\er" 'rmail-summary-search-backward)
- (define-key rmail-summary-mode-map "\es" 'rmail-summary-search)
- (define-key rmail-summary-mode-map "t" 'rmail-summary-toggle-header)
- (define-key rmail-summary-mode-map "u" 'rmail-summary-undelete)
- (define-key rmail-summary-mode-map "\M-u" 'rmail-summary-undelete-many)
- (define-key rmail-summary-mode-map "x" 'rmail-summary-expunge)
- (define-key rmail-summary-mode-map "w" 'rmail-summary-output-body)
- (define-key rmail-summary-mode-map "v" 'rmail-mime)
- (define-key rmail-summary-mode-map "." 'rmail-summary-beginning-of-message)
- (define-key rmail-summary-mode-map "/" 'rmail-summary-end-of-message)
- (define-key rmail-summary-mode-map "<" 'rmail-summary-first-message)
- (define-key rmail-summary-mode-map ">" 'rmail-summary-last-message)
- (define-key rmail-summary-mode-map " " 'rmail-summary-scroll-msg-up)
- (define-key rmail-summary-mode-map "\177" 'rmail-summary-scroll-msg-down)
- (define-key rmail-summary-mode-map "?" 'describe-mode)
- (define-key rmail-summary-mode-map "\C-c\C-n" 'rmail-summary-next-same-subject)
- (define-key rmail-summary-mode-map "\C-c\C-p" 'rmail-summary-previous-same-subject)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-d"
- 'rmail-summary-sort-by-date)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-s"
- 'rmail-summary-sort-by-subject)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-a"
- 'rmail-summary-sort-by-author)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-r"
- 'rmail-summary-sort-by-recipient)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-c"
- 'rmail-summary-sort-by-correspondent)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-l"
- 'rmail-summary-sort-by-lines)
- (define-key rmail-summary-mode-map "\C-c\C-s\C-k"
- 'rmail-summary-sort-by-labels)
- (define-key rmail-summary-mode-map "\C-x\C-s" 'rmail-summary-save-buffer)
- )
-\f
-;;; Menu bar bindings.
-
-(define-key rmail-summary-mode-map [menu-bar] (make-sparse-keymap))
-
-(define-key rmail-summary-mode-map [menu-bar classify]
- (cons "Classify" (make-sparse-keymap "Classify")))
-
-(define-key rmail-summary-mode-map [menu-bar classify output-menu]
- '("Output (Rmail Menu)..." . rmail-summary-output-menu))
-
-(define-key rmail-summary-mode-map [menu-bar classify input-menu]
- '("Input Rmail File (menu)..." . rmail-input-menu))
-
-(define-key rmail-summary-mode-map [menu-bar classify input-menu]
- '(nil))
-
-(define-key rmail-summary-mode-map [menu-bar classify output-menu]
- '(nil))
-
-(define-key rmail-summary-mode-map [menu-bar classify output-body]
- '("Output body..." . rmail-summary-output-body))
-
-(define-key rmail-summary-mode-map [menu-bar classify output-inbox]
- '("Output..." . rmail-summary-output))
-
-(define-key rmail-summary-mode-map [menu-bar classify output]
- '("Output as seen..." . rmail-summary-output-as-seen))
-
-(define-key rmail-summary-mode-map [menu-bar classify kill-label]
- '("Kill Label..." . rmail-summary-kill-label))
-
-(define-key rmail-summary-mode-map [menu-bar classify add-label]
- '("Add Label..." . rmail-summary-add-label))
-
-(define-key rmail-summary-mode-map [menu-bar summary]
- (cons "Summary" (make-sparse-keymap "Summary")))
-
-(define-key rmail-summary-mode-map [menu-bar summary senders]
- '("By Senders..." . rmail-summary-by-senders))
-
-(define-key rmail-summary-mode-map [menu-bar summary labels]
- '("By Labels..." . rmail-summary-by-labels))
-
-(define-key rmail-summary-mode-map [menu-bar summary recipients]
- '("By Recipients..." . rmail-summary-by-recipients))
-
-(define-key rmail-summary-mode-map [menu-bar summary topic]
- '("By Topic..." . rmail-summary-by-topic))
-
-(define-key rmail-summary-mode-map [menu-bar summary regexp]
- '("By Regexp..." . rmail-summary-by-regexp))
-
-(define-key rmail-summary-mode-map [menu-bar summary all]
- '("All" . rmail-summary))
-
-(define-key rmail-summary-mode-map [menu-bar mail]
- (cons "Mail" (make-sparse-keymap "Mail")))
-
-(define-key rmail-summary-mode-map [menu-bar mail rmail-summary-get-new-mail]
- '("Get New Mail" . rmail-summary-get-new-mail))
-
-(define-key rmail-summary-mode-map [menu-bar mail lambda]
- '("----"))
-
-(define-key rmail-summary-mode-map [menu-bar mail continue]
- '("Continue" . rmail-summary-continue))
-
-(define-key rmail-summary-mode-map [menu-bar mail resend]
- '("Re-send..." . rmail-summary-resend))
-
-(define-key rmail-summary-mode-map [menu-bar mail forward]
- '("Forward" . rmail-summary-forward))
-
-(define-key rmail-summary-mode-map [menu-bar mail retry]
- '("Retry" . rmail-summary-retry-failure))
-
-(define-key rmail-summary-mode-map [menu-bar mail reply]
- '("Reply" . rmail-summary-reply))
-
-(define-key rmail-summary-mode-map [menu-bar mail mail]
- '("Mail" . rmail-summary-mail))
-
-(define-key rmail-summary-mode-map [menu-bar delete]
- (cons "Delete" (make-sparse-keymap "Delete")))
-
-(define-key rmail-summary-mode-map [menu-bar delete expunge/save]
- '("Expunge/Save" . rmail-summary-expunge-and-save))
-
-(define-key rmail-summary-mode-map [menu-bar delete expunge]
- '("Expunge" . rmail-summary-expunge))
-
-(define-key rmail-summary-mode-map [menu-bar delete undelete]
- '("Undelete" . rmail-summary-undelete))
-
-(define-key rmail-summary-mode-map [menu-bar delete delete]
- '("Delete" . rmail-summary-delete-forward))
-
-(define-key rmail-summary-mode-map [menu-bar move]
- (cons "Move" (make-sparse-keymap "Move")))
-
-(define-key rmail-summary-mode-map [menu-bar move search-back]
- '("Search Back..." . rmail-summary-search-backward))
-
-(define-key rmail-summary-mode-map [menu-bar move search]
- '("Search..." . rmail-summary-search))
-
-(define-key rmail-summary-mode-map [menu-bar move previous]
- '("Previous Nondeleted" . rmail-summary-previous-msg))
-
-(define-key rmail-summary-mode-map [menu-bar move next]
- '("Next Nondeleted" . rmail-summary-next-msg))
-
-(define-key rmail-summary-mode-map [menu-bar move last]
- '("Last" . rmail-summary-last-message))
-
-(define-key rmail-summary-mode-map [menu-bar move first]
- '("First" . rmail-summary-first-message))
-
-(define-key rmail-summary-mode-map [menu-bar move previous]
- '("Previous" . rmail-summary-previous-all))
-
-(define-key rmail-summary-mode-map [menu-bar move next]
- '("Next" . rmail-summary-next-all))
\f
(defun rmail-summary-mouse-goto-message (event)
"Select the message whose summary line you click on."
(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
(buffer-substring (point)
(min (point-max) (+ 6 (point))))))
(total (with-current-buffer buf rmail-total-messages)))
+ ;; CURMSG should be nil when there's no current summary message
+ ;; (for instance, if the summary is empty).
+ (if (= curmsg 0)
+ (setq curmsg nil))
;; If message number N was specified, find that message's line
;; or set message-not-found.
;; If N wasn't specified or that message can't be found.
(setq n curmsg)
(setq message-not-found t)
(goto-char cur))))
- (rmail-summary-mark-seen n)
- (rmail-summary-update-highlight message-not-found)
- (beginning-of-line)
- (unless skip-rmail
- (let ((selwin (selected-window)))
- (unwind-protect
- (progn (rmail-pop-to-buffer buf)
- (rmail-show-message n))
- (select-window selwin)
- ;; The actions above can alter the current buffer. Preserve it.
- (set-buffer obuf))))
+ ;; N can be nil now, along with CURMSG,
+ ;; if the summary is empty.
+ (when n
+ (rmail-summary-mark-seen n)
+ (rmail-summary-update-highlight message-not-found)
+ (beginning-of-line)
+ (unless skip-rmail
+ (let ((selwin (selected-window)))
+ (unwind-protect
+ (progn (rmail-pop-to-buffer buf)
+ (rmail-show-message n))
+ (select-window selwin)
+ ;; The actions above can alter the current buffer. Preserve it.
+ (set-buffer obuf)))))
(not message-not-found)))
;; Update the highlighted line in an rmail summary buffer.
(prog1
;; Is EOB visible in the buffer?
(save-excursion
- (let ((ht (window-height (selected-window))))
+ (let ((ht (window-height)))
(move-to-window-line (- ht 2))
(end-of-line)
(eobp)))
"Sort messages of current Rmail summary by other correspondent.
This uses either the \"From\", \"Sender\", \"To\", or
\"Apparently-To\" header, downcased. Uses the first header not
-excluded by `rmail-dont-reply-to-names'. If prefix argument
+excluded by `mail-dont-reply-to-names'. If prefix argument
REVERSE is non-nil, sorts in reverse order."
(interactive "P")
(rmail-sort-from-summary (function rmail-sort-by-correspondent) reverse))
;; generated-autoload-file: "rmail.el"
;; End:
-;; arch-tag: 80b0a27a-a50d-4f37-9466-83d32d1e0ca8
;;; rmailsum.el ends here