[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lisp/mail/pmailsum.el,v
From: |
Paul Michael Reilly |
Subject: |
[Emacs-diffs] Changes to emacs/lisp/mail/pmailsum.el,v |
Date: |
Sun, 05 Oct 2008 14:08:22 +0000 |
CVSROOT: /cvsroot/emacs
Module name: emacs
Changes by: Paul Michael Reilly <pmr> 08/10/05 14:08:22
Index: pmailsum.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/mail/pmailsum.el,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- pmailsum.el 6 Sep 2008 02:55:29 -0000 1.6
+++ pmailsum.el 5 Oct 2008 14:08:21 -0000 1.7
@@ -23,19 +23,10 @@
;;; Commentary:
-;; All commands run from the summary buffer update the buffer local
-;; variable `pmail-current-message'. As part of the post command
-;; processing point is moved to the beginning of the line describing
-;; the current message.
-
-;;; History:
-
;; Extended by Bob Weiner of Motorola
;; Provided all commands from pmail-mode in pmail-summary-mode and made key
;; bindings in both modes wholly compatible.
-;; Overhauled by Paul Reilly to support mbox format.
-
;;; Code:
(defvar msgnum)
@@ -51,175 +42,28 @@
;;;###autoload
(defcustom pmail-summary-line-count-flag t
- "*Non-nil if Pmail summary should show the number of lines in each message."
+ "*Non-nil means Pmail summary should show the number of lines in each
message."
:type 'boolean
:group 'pmail-summary)
+(defconst pmail-summary-header "X-BABYL-V6-SUMMARY"
+ "The header that stores the Pmail summary line.")
+
(defvar pmail-summary-font-lock-keywords
'(("^.....D.*" . font-lock-string-face) ; Deleted.
("^.....-.*" . font-lock-type-face) ;
Unread.
;; Neither of the below will be highlighted if either of the above are:
- ("^.....[^D-]....\\(......\\)" 1 font-lock-keyword-face) ; Date.
+ ("^.....[^D-] \\(......\\)" 1 font-lock-keyword-face) ; Date.
("{ \\([^\n}]+\\) }" 1 font-lock-comment-face)) ; Labels.
"Additional expressions to highlight in Pmail Summary mode.")
-(defvar pmail-summary-redo nil
- "Private storage for Pmail summary history.")
+(defvar pmail-summary-redo
+ "(FUNCTION . ARGS) to regenerate this Pmail summary buffer.")
-(defvar pmail-summary-overlay nil
- "Private storage for an Pmail summary overlay cache")
+(defvar pmail-summary-overlay nil)
(put 'pmail-summary-overlay 'permanent-local t)
-(defvar pmail-summary-mode-map
- (let ((map (make-keymap)))
- (suppress-keymap map)
- (define-key map [mouse-2] 'pmail-summary-mouse-goto-message)
- (define-key map "a" 'pmail-summary-add-label)
- (define-key map "b" 'pmail-summary-bury)
- (define-key map "B" 'pmail-summary-browse-body)
- (define-key map "c" 'pmail-summary-continue)
- (define-key map "d" 'pmail-summary-delete-forward)
- (define-key map "\C-d" 'pmail-summary-delete-backward)
- (define-key map "e" 'pmail-summary-edit-current-message)
- (define-key map "f" 'pmail-summary-forward)
- (define-key map "g" 'pmail-summary-get-new-mail)
- (define-key map "h" 'pmail-summary)
- (define-key map "i" 'pmail-summary-input)
- (define-key map "j" 'pmail-summary-goto-msg)
- (define-key map "\C-m" 'pmail-summary-goto-msg)
- (define-key map "k" 'pmail-summary-kill-label)
- (define-key map "l" 'pmail-summary-by-labels)
- (define-key map "\e\C-h" 'pmail-summary)
- (define-key map "\e\C-l" 'pmail-summary-by-labels)
- (define-key map "\e\C-r" 'pmail-summary-by-recipients)
- (define-key map "\e\C-f" 'pmail-summary-by-senders)
- (define-key map "\e\C-s" 'pmail-summary-by-regexp)
- (define-key map "\e\C-t" 'pmail-summary-by-topic)
- (define-key map "m" 'pmail-summary-mail)
- (define-key map "\M-m" 'pmail-summary-retry-failure)
- (define-key map "n" 'pmail-summary-next-msg)
- (define-key map "\en" 'pmail-summary-next-all)
- (define-key map "\e\C-n" 'pmail-summary-next-labeled-message)
- (define-key map "o" 'pmail-summary-output)
- (define-key map "\C-o" 'pmail-summary-output)
- (define-key map "p" 'pmail-summary-previous-msg)
- (define-key map "\ep" 'pmail-summary-previous-all)
- (define-key map "\e\C-p" 'pmail-summary-previous-labeled-message)
- (define-key map "q" 'pmail-summary-quit)
- (define-key map "Q" 'pmail-summary-wipe)
- (define-key map "r" 'pmail-summary-reply)
- (define-key map "s" 'pmail-summary-expunge-and-save)
- (define-key map "\es" 'pmail-summary-search)
- (define-key map "t" 'pmail-summary-toggle-header)
- (define-key map "u" 'pmail-summary-undelete)
- (define-key map "\M-u" 'pmail-summary-undelete-many)
- (define-key map "x" 'pmail-summary-expunge)
- (define-key map "w" 'pmail-summary-output-body)
- (define-key map "." 'pmail-summary-beginning-of-message)
- (define-key map "/" 'pmail-summary-end-of-message)
- (define-key map "<" 'pmail-summary-first-message)
- (define-key map ">" 'pmail-summary-last-message)
- (define-key map " " 'pmail-summary-scroll-msg-up)
- (define-key map "\177" 'pmail-summary-scroll-msg-down)
- (define-key map "?" 'describe-mode)
- (define-key map "\C-c\C-n" 'pmail-summary-next-same-subject)
- (define-key map "\C-c\C-p" 'pmail-summary-previous-same-subject)
- (define-key map "\C-c\C-s\C-d" 'pmail-summary-sort-by-date)
- (define-key map "\C-c\C-s\C-s" 'pmail-summary-sort-by-subject)
- (define-key map "\C-c\C-s\C-a" 'pmail-summary-sort-by-author)
- (define-key map "\C-c\C-s\C-r" 'pmail-summary-sort-by-recipient)
- (define-key map "\C-c\C-s\C-c" 'pmail-summary-sort-by-correspondent)
- (define-key map "\C-c\C-s\C-l" 'pmail-summary-sort-by-lines)
- (define-key map "\C-c\C-s\C-k" 'pmail-summary-sort-by-labels)
- (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 (Pmail Menu)..." . pmail-summary-output-menu))
- (define-key map [menu-bar classify input-menu]
- '("Input Pmail File (menu)..." . pmail-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)..." . pmail-summary-output-body))
- (define-key map [menu-bar classify output-inbox]
- '("Output (inbox)..." . pmail-summary-output))
- (define-key map [menu-bar classify output]
- '("Output (Pmail)..." . pmail-summary-output))
- (define-key map [menu-bar classify kill-label]
- '("Kill Label..." . pmail-summary-kill-label))
- (define-key map [menu-bar classify add-label]
- '("Add Label..." . pmail-summary-add-label))
- (define-key map [menu-bar summary]
- (cons "Summary" (make-sparse-keymap "Summary")))
- (define-key map [menu-bar summary senders]
- '("By Senders..." . pmail-summary-by-senders))
- (define-key map [menu-bar summary labels]
- '("By Labels..." . pmail-summary-by-labels))
- (define-key map [menu-bar summary recipients]
- '("By Recipients..." . pmail-summary-by-recipients))
- (define-key map [menu-bar summary topic]
- '("By Topic..." . pmail-summary-by-topic))
- (define-key map [menu-bar summary regexp]
- '("By Regexp..." . pmail-summary-by-regexp))
- (define-key map [menu-bar summary all]
- '("All" . pmail-summary))
- (define-key map [menu-bar mail]
- (cons "Mail" (make-sparse-keymap "Mail")))
- (define-key map [menu-bar mail pmail-summary-get-new-mail]
- '("Get New Mail" . pmail-summary-get-new-mail))
- (define-key map [menu-bar mail lambda]
- '("----"))
- (define-key map [menu-bar mail continue]
- '("Continue" . pmail-summary-continue))
- (define-key map [menu-bar mail resend]
- '("Re-send..." . pmail-summary-resend))
- (define-key map [menu-bar mail forward]
- '("Forward" . pmail-summary-forward))
- (define-key map [menu-bar mail retry]
- '("Retry" . pmail-summary-retry-failure))
- (define-key map [menu-bar mail reply]
- '("Reply" . pmail-summary-reply))
- (define-key map [menu-bar mail mail]
- '("Mail" . pmail-summary-mail))
- (define-key map [menu-bar delete]
- (cons "Delete" (make-sparse-keymap "Delete")))
- (define-key map [menu-bar delete expunge/save]
- '("Expunge/Save" . pmail-summary-expunge-and-save))
- (define-key map [menu-bar delete expunge]
- '("Expunge" . pmail-summary-expunge))
- (define-key map [menu-bar delete undelete]
- '("Undelete" . pmail-summary-undelete))
- (define-key map [menu-bar delete delete]
- '("Delete" . pmail-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..." . pmail-summary-search-backward))
- (define-key map [menu-bar move search]
- '("Search..." . pmail-summary-search))
- (define-key map [menu-bar move previous]
- '("Previous Nondeleted" . pmail-summary-previous-msg))
- (define-key map [menu-bar move next]
- '("Next Nondeleted" . pmail-summary-next-msg))
- (define-key map [menu-bar move last]
- '("Last" . pmail-summary-last-message))
- (define-key map [menu-bar move first]
- '("First" . pmail-summary-first-message))
- (define-key map [menu-bar move previous]
- '("Previous" . pmail-summary-previous-all))
- (define-key map [menu-bar move next]
- '("Next" . pmail-summary-next-all))
- map)
- "Keymap for `pmail-summary-mode'.")
-
-(declare-function pmail-abort-edit "pmailedit" ())
-(declare-function pmail-cease-edit "pmailedit"())
-(declare-function pmail-set-label "pmailkwd" (l state &optional n))
-(declare-function pmail-output-read-file-name "pmailout" ())
-(declare-function mail-comma-list-regexp "mail-utils" (labels))
-(declare-function mail-send-and-exit "sendmail" (&optional arg))
-(declare-function mail-strip-quoted-names "mail-utils" (address))
+(defvar pmail-summary-mode-map nil)
;; Entry points for making a summary buffer.
@@ -247,7 +91,7 @@
(pmail-new-summary (concat "labels " labels)
(list 'pmail-summary-by-labels labels)
'pmail-message-labels-p
- (mail-comma-list-regexp labels)))
+ (concat ", \\(" (mail-comma-list-regexp labels) "\\),")))
;;;###autoload
(defun pmail-summary-by-recipients (recipients &optional primary-only)
@@ -279,6 +123,9 @@
'pmail-message-regexp-p
regexp))
+;; pmail-summary-by-topic
+;; 1989 R.A. Schnitzler
+
;;;###autoload
(defun pmail-summary-by-topic (subject &optional whole-message)
"Display a summary of all messages with the given SUBJECT.
@@ -289,6 +136,8 @@
(interactive
(let* ((subject (with-current-buffer pmail-buffer
(pmail-current-subject)))
+ (subject-re (with-current-buffer pmail-buffer
+ (pmail-current-subject-regexp)))
(prompt (concat "Topics to summarize by (regexp"
(if subject ", default current subject" "")
"): ")))
@@ -300,95 +149,132 @@
(mail-comma-list-regexp subject) whole-message))
(defun pmail-message-subject-p (msg subject &optional whole-message)
- "Return non-nil if SUBJECT is found in MSG.
-If WHOLE-MESSAGE is nil only the subject header will be searched,
-otherwise the whole message will be searched for text matching
-SUBJECT. Return nil to indicate that SUBJECT is not found,
-non-nil otherwise."
(save-restriction
+ (goto-char (pmail-msgbeg msg))
+ (search-forward "\n*** EOOH ***\n" (pmail-msgend msg) 'move)
(narrow-to-region
- (pmail-desc-get-start msg)
- (pmail-desc-get-end msg))
+ (point)
+ (progn (search-forward (if whole-message "\^_" "\n\n")) (point)))
(goto-char (point-min))
- (if whole-message
- (re-search-forward subject nil t))
- (string-match subject
- (let ((subj (pmail-header-get-header "subject")))
+ (if whole-message (re-search-forward subject nil t)
+ (string-match subject (let ((subj (mail-fetch-field "Subject")))
(if subj
(funcall pmail-summary-line-decoder subj)
- "")))))
+ ""))))))
;;;###autoload
(defun pmail-summary-by-senders (senders)
"Display a summary of all messages with the given SENDERS.
SENDERS is a string of names separated by commas."
- (interactive
- (let* ((sender (when pmail-current-message
- (pmail-desc-get-sender pmail-current-message)))
- (sender-re (with-current-buffer pmail-buffer
- (regexp-quote sender)))
- (prompt (concat "Senders to summarize by (regexp"
- (if sender ", default current sender" "")
- "): ")))
- (list (read-string prompt nil nil sender))))
+ (interactive "sSenders to summarize by: ")
(pmail-new-summary
(concat "senders " senders)
(list 'pmail-summary-by-senders senders)
'pmail-message-senders-p
(mail-comma-list-regexp senders)))
-(defun pmail-message-senders-p (msg sender)
- "Return non-nil if SENDER is found in MSG.
-The From header is tested."
+(defun pmail-message-senders-p (msg senders)
(save-restriction
- (narrow-to-region
- (pmail-desc-get-start msg)
- (pmail-desc-get-end msg))
- (goto-char (point-min))
- (string-match sender (or (mail-fetch-field "From") ""))))
+ (goto-char (pmail-msgbeg msg))
+ (search-forward "\n*** EOOH ***\n")
+ (narrow-to-region (point) (progn (search-forward "\n\n") (point)))
+ (string-match senders (or (mail-fetch-field "From") ""))))
-;;;; General making of a summary buffer.
+;; General making of a summary buffer.
(defvar pmail-summary-symbol-number 0)
-(defun pmail-new-summary (description redo-form function &rest args)
+(defvar pmail-new-summary-line-count)
+
+(defun pmail-new-summary (desc redo func &rest args)
"Create a summary of selected messages.
-DESCRIPTION makes part of the mode line of the summary buffer.
-For each message, FUNCTION is applied to the message number and ARGS...
+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."
(message "Computing summary lines...")
- (let ((summary-msgs ())
- (new-summary-line-count 0)
- (msgnum 1)
- current-message sumbuf was-in-summary)
- (save-excursion
- ;; Go to the Pmail buffer.
+ (let (mesg was-in-summary)
+ (with-current-buffer pmail-buffer
(if (eq major-mode 'pmail-summary-mode)
(setq was-in-summary t))
+ (setq mesg pmail-current-message
+ pmail-summary-buffer (pmail-new-summary-1 desc redo func args)))
+ ;; Now display the summary buffer and go to the right place in it.
+ (or was-in-summary
+ (progn
+ (if (and (one-window-p)
+ pop-up-windows (not pop-up-frames))
+ ;; If there is just one window, put the summary on the top.
+ (progn
+ (split-window (selected-window) pmail-summary-window-size)
+ (select-window (next-window (frame-first-window)))
+ (pop-to-buffer pmail-summary-buffer)
+ ;; If pop-to-buffer did not use that window, delete that
+ ;; window. (This can happen if it uses another frame.)
+ (if (not (eq pmail-summary-buffer (window-buffer
(frame-first-window))))
+ (delete-other-windows)))
+ (pop-to-buffer pmail-summary-buffer))
(set-buffer pmail-buffer)
- ;; Find its summary buffer, or make one.
- (setq current-message pmail-current-message
- sumbuf
- (if (and pmail-summary-buffer
- (buffer-name pmail-summary-buffer))
- pmail-summary-buffer
- (generate-new-buffer (concat (buffer-name) "-summary"))))
- ;; Collect the message summaries based on the filtering
- ;; argument (FUNCTION).
+ ;; This is how pmail makes the summary buffer reappear.
+ ;; We do this here to make the window the proper size.
+ (pmail-select-summary nil)
+ (set-buffer pmail-summary-buffer)))
+ (pmail-summary-goto-msg mesg t t)
+ (pmail-summary-construct-io-menu)
+ (message "Computing summary lines...done")))
+
+(defun pmail-new-summary-1 (description form function &rest 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...
+
+REDO is a form ...
+
+The current buffer must be a Pmail buffer either containing a
+collection of mbox formatted messages or displaying a single
+message."
+ (let ((summary-msgs ())
+ (pmail-new-summary-line-count 0)
+ (sumbuf (pmail-get-create-summary-buffer)))
+ (let ((swap (pmail-use-collection-buffer))
+ (msgnum 1)
+ (buffer-read-only nil)
+ (old-min (point-min-marker))
+ (old-max (point-max-marker)))
+ ;; Can't use save-restriction here; that doesn't work if we
+ ;; plan to modify text outside the original restriction.
+ (save-excursion
+ (widen)
+ (goto-char (point-min))
(while (>= pmail-total-messages msgnum)
(if (or (null function)
(apply function (cons msgnum args)))
(setq summary-msgs
- (cons (cons msgnum (pmail-summary-get-summary-line msgnum))
+ (cons (cons msgnum (pmail-get-summary msgnum))
summary-msgs)))
- (setq msgnum (1+ msgnum)))
- (setq summary-msgs (nreverse summary-msgs))
- ;; Place the collected summaries into the summary buffer.
+ (setq msgnum (1+ msgnum))
+ ;; Provide a periodic User progress message.
+ (if (zerop (% pmail-new-summary-line-count 10))
+ (message "Computing summary lines...%d"
+ pmail-new-summary-line-count)))
+ (setq summary-msgs (nreverse summary-msgs)))
+ (narrow-to-region old-min old-max))
+
+ ;; Temporarily, while summary buffer is unfinished,
+ ;; we "don't have" a summary.
+ ;;
+ ;; 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
+ ;; address@hidden
(setq pmail-summary-buffer nil)
+ (if pmail-enable-mime
+ (with-current-buffer pmail-buffer
+ (setq pmail-summary-buffer nil)))
+
(save-excursion
(let ((rbuf (current-buffer))
- (vbuf pmail-view-buffer)
(total pmail-total-messages))
(set-buffer sumbuf)
;; Set up the summary buffer's contents.
@@ -404,36 +290,36 @@
(make-local-variable 'minor-mode-alist)
(setq minor-mode-alist (list (list t (concat ": " description))))
(setq pmail-buffer rbuf
- pmail-view-buffer vbuf
- pmail-summary-redo redo-form
- pmail-total-messages total
- pmail-current-message current-message)))
- (setq pmail-summary-buffer sumbuf))
- ;; Now display the summary buffer and go to the right place in it.
- (or was-in-summary
- (progn
- (if (and (one-window-p)
- pop-up-windows (not pop-up-frames))
- ;; If there is just one window, put the summary on the top.
- (progn
- (split-window (selected-window) pmail-summary-window-size)
- (select-window (next-window (frame-first-window)))
- (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 sumbuf (window-buffer (frame-first-window))))
- (delete-other-windows)))
- (pop-to-buffer sumbuf))
- (set-buffer pmail-buffer)
- ;; This is how pmail makes the summary buffer reappear.
- ;; We do this here to make the window the proper size.
- (pmail-select-summary nil)
- (set-buffer pmail-summary-buffer)))
- (pmail-summary-goto-msg current-message nil t)
- (pmail-summary-construct-io-menu)
- (message "Computing summary lines...done")))
+ pmail-summary-redo form
+ pmail-total-messages total)))
+ sumbuf))
+
+(defun pmail-get-create-summary-buffer ()
+ "Obtain a summary buffer by re-using an existing summary
+buffer, or by creating a new summary buffer."
+ (if (and pmail-summary-buffer (buffer-name pmail-summary-buffer))
+ pmail-summary-buffer
+ (generate-new-buffer (concat (buffer-name) "-summary"))))
+
+
+;; Low levels of generating a summary.
-;;;; Low levels of generating a summary.
+(defun pmail-get-summary (msgnum)
+ "Return the summary line for message MSGNUM.
+If the message has a summary line already, it will be stored in
+the message as a header and simply returned, otherwise the
+summary line is created, saved in the message header, cached and
+returned.
+
+The current buffer contains the unrestricted message collection."
+ (let ((line (aref pmail-summary-vector (1- msgnum))))
+ (unless line
+ ;; Register a summary line for MSGNUM.
+ (setq pmail-new-summary-line-count (1+ pmail-new-summary-line-count)
+ line (pmail-get-create-summary-line msgnum))
+ ;; Cache the summary line for use during this Pmail session.
+ (aset pmail-summary-vector (1- msgnum) line))
+ line))
;;;###autoload
(defcustom pmail-summary-line-decoder (function identity)
@@ -443,41 +329,205 @@
:type 'function
:group 'pmail-summary)
+(defun pmail-get-create-summary-line (msgnum)
+ "Return the summary line for message MSGNUM.
+Obtain the message summary from the header if it is available
+otherwise create it and store it in the message header.
+
+The current buffer contains the unrestricted message collection."
+ (let ((beg (pmail-msgbeg msgnum))
+ (end (pmail-msgend msgnum))
+ result)
+ (goto-char beg)
+ (if (search-forward "\n\n" end t)
+ (save-restriction
+ (narrow-to-region beg (point))
+ ;; Generate a status line from the message and put it in the
+ ;; message.
+ (setq result (mail-fetch-field pmail-summary-header))
+ (unless result
+ (setq result (pmail-create-summary msgnum))
+ (pmail-add-header pmail-summary-header result)))
+ (pmail-error-bad-format msgnum))
+ result))
+
+(defun pmail-get-summary-labels ()
+ "Return a coded string wrapped in curly braces denoting the status labels.
+
+The current buffer is narrowed to the message headers for
+the message being processed."
+ (let ((status (mail-fetch-field pmail-attribute-header))
+ (index 0)
+ (result "")
+ char)
+ ;; Strip off the read/unread and the deleted attribute which are
+ ;; handled separately.
+ (setq status (concat (substring status 0 1) (substring status 2 6)))
+ (while (< index (length status))
+ (unless (string= "-" (setq char (substring status index (1+ index))))
+ (setq result (concat result char)))
+ (setq index (1+ index)))
+ (when (> (length result) 0)
+ (setq result (concat "{" result "}")))
+ result))
+
+(defun pmail-create-summary (msgnum)
+ "Return the summary line for message MSGNUM.
+The current buffer is narrowed to the header for message MSGNUM."
+ (goto-char (point-min))
+ (let ((line (pmail-make-basic-summary-line))
+ (labels (pmail-get-summary-labels))
+ pos prefix status suffix)
+ (setq pos (string-match "#" line)
+ status (cond
+ ((pmail-message-deleted-p msgnum) ?D)
+ ((pmail-message-unseen-p msgnum) ?-)
+ (t ? ))
+ prefix (format "%5d%c %s" msgnum status (substring line 0 pos))
+ suffix (substring line (1+ pos)))
+ (funcall pmail-summary-line-decoder (concat prefix labels suffix))))
+
;;;###autoload
-(defcustom pmail-user-mail-address-regexp
- (concat "^\\("
- (regexp-quote (user-login-name))
- "\\($\\|@\\)\\|"
- (regexp-quote
- (or user-mail-address
- (concat (user-login-name) "@"
- (or mail-host-address
- (system-name)))))
- "\\>\\)")
+(defcustom pmail-user-mail-address-regexp nil
"*Regexp matching user mail addresses.
If non-nil, this variable is used to identify the correspondent
-when receiving new mail. If it matches the address of the
-sender, the recipient is taken as correspondent of a mail. It is
-initialized based on your `user-login-name' and
-`user-mail-address'.
-
-Usually you don't have to set this variable, except if you
-collect mails sent by you under different user names. Then it
-should be a regexp matching your mail addresses.
+when receiving new mail. If it matches the address of the sender,
+the recipient is taken as correspondent of a mail.
+If nil \(default value\), your `user-login-name' and `user-mail-address'
+are used to exclude yourself as correspondent.
+
+Usually you don't have to set this variable, except if you collect mails
+sent by you under different user names.
+Then it should be a regexp matching your mail addresses.
Setting this variable has an effect only before reading a mail."
:type '(choice (const :tag "None" nil) regexp)
:group 'pmail-retrieve
:version "21.1")
+(defun pmail-make-basic-summary-line ()
+ (goto-char (point-min))
+ (concat (save-excursion
+ (if (not (re-search-forward "^Date:" nil t))
+ " "
+ (cond ((re-search-forward "\\([^0-9:]\\)\\([0-3]?[0-9]\\)\\([-
\t_]+\\)\\([adfjmnos][aceopu][bcglnprtvy]\\)"
+ (save-excursion (end-of-line) (point)) t)
+ (format "%2d-%3s"
+ (string-to-number (buffer-substring
+ (match-beginning 2)
+ (match-end 2)))
+ (buffer-substring
+ (match-beginning 4) (match-end 4))))
+ ((re-search-forward
"\\([^a-z]\\)\\([adfjmnos][acepou][bcglnprtvy]\\)\\([-a-z
\t_]*\\)\\([0-9][0-9]?\\)"
+ (save-excursion (end-of-line) (point)) t)
+ (format "%2d-%3s"
+ (string-to-number (buffer-substring
+ (match-beginning 4)
+ (match-end 4)))
+ (buffer-substring
+ (match-beginning 2) (match-end 2))))
+ ((re-search-forward
"\\(19\\|20\\)\\([0-9][0-9]\\)-\\([01][0-9]\\)-\\([0-3][0-9]\\)"
+ (save-excursion (end-of-line) (point)) t)
+ (format "%2s%2s%2s"
+ (buffer-substring
+ (match-beginning 2) (match-end 2))
+ (buffer-substring
+ (match-beginning 3) (match-end 3))
+ (buffer-substring
+ (match-beginning 4) (match-end 4))))
+ (t "??????"))))
+ " "
+ (save-excursion
+ (let* ((from (and (re-search-forward "^From:[ \t]*" nil t)
+ (mail-strip-quoted-names
+ (buffer-substring
+ (1- (point))
+ ;; Get all the lines of the From field
+ ;; so that we get a whole comment if there is
one,
+ ;; so that mail-strip-quoted-names can discard
it.
+ (let ((opoint (point)))
+ (while (progn (forward-line 1)
+ (looking-at "[ \t]")))
+ ;; Back up over newline, then trailing spaces
or tabs
+ (forward-char -1)
+ (skip-chars-backward " \t")
+ (point))))))
+ len mch lo)
+ (if (or (null from)
+ (string-match
+ (or pmail-user-mail-address-regexp
+ (concat "^\\("
+ (regexp-quote (user-login-name))
+ "\\($\\|@\\)\\|"
+ (regexp-quote
+ ;; Don't lose if run from init file
+ ;; where user-mail-address is not
+ ;; set yet.
+ (or user-mail-address
+ (concat (user-login-name) "@"
+ (or mail-host-address
+ (system-name)))))
+ "\\>\\)"))
+ from))
+ ;; No From field, or it's this user.
+ (save-excursion
+ (goto-char (point-min))
+ (if (not (re-search-forward "^To:[ \t]*" nil t))
+ nil
+ (setq from
+ (concat "to: "
+ (mail-strip-quoted-names
+ (buffer-substring
+ (point)
+ (progn (end-of-line)
+ (skip-chars-backward " \t")
+ (point)))))))))
+ (if (null from)
+ " "
+ (setq len (length from))
+ (setq mch (string-match "address@hidden" from))
+ (format "%25s"
+ (if (or (not mch) (<= len 25))
+ (substring from (max 0 (- len 25)))
+ (substring from
+ (setq lo (cond ((< (- mch 14) 0) 0)
+ ((< len (+ mch 11))
+ (- len 25))
+ (t (- mch 14))))
+ (min len (+ lo 25))))))))
+ (if pmail-summary-line-count-flag
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((beg (pmail-msgbeg msgnum))
+ (end (pmail-msgend msgnum))
+ lines)
+ (save-excursion
+ (goto-char beg)
+ ;; Count only lines in the reformatted header,
+ ;; if we have reformatted it.
+ (search-forward "\n*** EOOH ***\n" end t)
+ (setq lines (count-lines (point) end)))
+ (format (cond
+ ((<= lines 9) " [%d]")
+ ((<= lines 99) " [%d]")
+ ((<= lines 999) " [%3d]")
+ (t "[%d]"))
+ lines))))
+ " ")
+ " #" ;The # is part of the format.
+ (if (re-search-forward "^Subject:" nil t)
+ (progn (skip-chars-forward " \t")
+ (buffer-substring (point)
+ (progn (end-of-line)
+ (point))))
+ (re-search-forward "[\n][\n]+" nil t)
+ (buffer-substring (point) (progn (end-of-line) (point))))
+ "\n"))
-;;;; Simple motion in a summary buffer.
+;; Simple motion in a summary buffer.
(defun pmail-summary-next-all (&optional number)
- "Move to an nearby message.
-If NUMBER is positive then move forward NUMBER messages. If NUMBER is
-negative then move backwards NUMBER messages. If NUMBER is nil then
-move forward one message."
(interactive "p")
(forward-line (if number number 1))
;; It doesn't look nice to move forward past the last message line.
@@ -495,14 +545,20 @@
(defun pmail-summary-next-msg (&optional number)
"Display next non-deleted msg from pmail file.
-With optional prefix argument NUMBER, moves forward this number of
-non-deleted messages, or backward if NUMBER is negative."
+With optional prefix argument NUMBER, moves forward this number of non-deleted
+messages, or backward if NUMBER is negative."
(interactive "p")
- (let (msg)
- (with-current-buffer pmail-buffer
- (pmail-next-undeleted-message number)
- (setq msg pmail-current-message))
- (pmail-summary-goto-msg msg)))
+ (forward-line 0)
+ (and (> number 0) (end-of-line))
+ (let ((count (if (< number 0) (- number) number))
+ (search (if (> number 0) 're-search-forward 're-search-backward))
+ (non-del-msg-found nil))
+ (while (and (> count 0) (setq non-del-msg-found
+ (or (funcall search "^.....[^D]" nil t)
+ non-del-msg-found)))
+ (setq count (1- count))))
+ (beginning-of-line)
+ (display-buffer pmail-buffer))
(defun pmail-summary-previous-msg (&optional number)
"Display previous non-deleted msg from pmail file.
@@ -512,7 +568,7 @@
(pmail-summary-next-msg (- (if number number 1))))
(defun pmail-summary-next-labeled-message (n labels)
- "Show next message with LABEL. Defaults to last labels used.
+ "Show next message with LABELS. Defaults to last labels used.
With prefix argument N moves forward N messages with these labels."
(interactive "p\nsMove to next msg with labels: ")
(let (msg)
@@ -520,10 +576,10 @@
(set-buffer pmail-buffer)
(pmail-next-labeled-message n labels)
(setq msg pmail-current-message))
- (setq pmail-current-message msg)))
+ (pmail-summary-goto-msg msg)))
(defun pmail-summary-previous-labeled-message (n labels)
- "Show previous message with LABEL. Defaults to last labels used.
+ "Show previous message with LABELS. Defaults to last labels used.
With prefix argument N moves backward N messages with these labels."
(interactive "p\nsMove to previous msg with labels: ")
(let (msg)
@@ -531,15 +587,52 @@
(set-buffer pmail-buffer)
(pmail-previous-labeled-message n labels)
(setq msg pmail-current-message))
- (setq pmail-current-message msg)))
+ (pmail-summary-goto-msg msg)))
(defun pmail-summary-next-same-subject (n)
"Go to the next message in the summary having the same subject.
With prefix argument N, do this N times.
If N is negative, go backwards."
(interactive "p")
+ (let ((forward (> n 0))
+ search-regexp i found)
(with-current-buffer pmail-buffer
- (pmail-next-same-subject n)))
+ (setq search-regexp (pmail-current-subject-regexp)
+ i pmail-current-message))
+ (save-excursion
+ (while (and (/= n 0)
+ (if forward
+ (not (eobp))
+ (not (bobp))))
+ (let (done)
+ (while (and (not done)
+ (if forward
+ (not (eobp))
+ (not (bobp))))
+ ;; Advance thru summary.
+ (forward-line (if forward 1 -1))
+ ;; Get msg number of this line.
+ (setq i (string-to-number
+ (buffer-substring (point)
+ (min (point-max) (+ 6 (point))))))
+ ;; See if that msg has desired subject.
+ (save-excursion
+ (set-buffer pmail-buffer)
+ (save-restriction
+ (widen)
+ (goto-char (pmail-msgbeg i))
+ (search-forward "\n*** EOOH ***\n")
+ (let ((beg (point)) end)
+ (search-forward "\n\n")
+ (setq end (point))
+ (goto-char beg)
+ (setq done (re-search-forward search-regexp end t))))))
+ (if done (setq found i)))
+ (setq n (if forward (1- n) (1+ n)))))
+ (if found
+ (pmail-summary-goto-msg found)
+ (error "No %s message with same subject"
+ (if forward "following" "previous")))))
(defun pmail-summary-previous-same-subject (n)
"Go to the previous message in the summary having the same subject.
@@ -548,7 +641,6 @@
(interactive "p")
(pmail-summary-next-same-subject (- n)))
-
;; Delete and undelete summary commands.
(defun pmail-summary-delete-forward (&optional count)
@@ -570,11 +662,11 @@
(save-excursion (beginning-of-line)
(looking-at " *[0-9]+D")))
(forward-line (if backward -1 1)))
+ ;; It looks ugly to move to the empty line at end of buffer.
+ (and (eobp) (not backward)
+ (forward-line -1))
(setq count
- (if (> count 0) (1- count) (1+ count))))
- ;; Update the summary buffer current message counter and show the
- ;; message in the Pmail buffer.
- (pmail-summary-goto-msg (pmail-summary-get-message-at-point))))
+ (if (> count 0) (1- count) (1+ count))))))
(defun pmail-summary-delete-backward (&optional count)
"Delete this message and move to previous nondeleted one.
@@ -586,7 +678,7 @@
(defun pmail-summary-mark-deleted (&optional n undel)
;; Since third arg is t, this only alters the summary, not the Pmail buf.
- (and n (pmail-summary-goto-msg n t))
+ (and n (pmail-summary-goto-msg n t t))
(or (eobp)
(not (overlay-get pmail-summary-overlay 'face))
(let ((buffer-read-only nil))
@@ -603,9 +695,11 @@
(pmail-summary-mark-deleted n t))
(defun pmail-summary-deleted-p (&optional n)
- (unless n (setq n pmail-current-message))
- (with-current-buffer pmail-buffer
- (pmail-desc-deleted-p n)))
+ (save-excursion
+ (and n (pmail-summary-goto-msg n nil t))
+ (skip-chars-forward " ")
+ (skip-chars-forward "[0-9]")
+ (looking-at "D")))
(defun pmail-summary-undelete (&optional arg)
"Undelete current message.
@@ -615,40 +709,44 @@
(pmail-summary-undelete-many arg)
(let ((buffer-read-only nil)
(opoint (point)))
- (goto-char (line-end-position))
- (if (not (re-search-backward "\\(^ *[0-9]*\\)\\(D\\)" nil t))
- (goto-char opoint)
+ (end-of-line)
+ (cond ((re-search-backward "\\(^ *[0-9]*\\)\\(D\\)" nil t)
(replace-match "\\1 ")
(pmail-summary-goto-msg)
(if pmail-enable-mime
(set-buffer pmail-buffer)
(pop-to-buffer pmail-buffer))
- (when (pmail-message-deleted-p pmail-current-message)
+ (and (pmail-message-deleted-p pmail-current-message)
(pmail-undelete-previous-message))
- (when pmail-enable-mime
- (pop-to-buffer pmail-view-buffer))
- (pop-to-buffer pmail-summary-buffer)))))
+ (if pmail-enable-mime
+ (pop-to-buffer pmail-buffer))
+ (pop-to-buffer pmail-summary-buffer))
+ (t (goto-char opoint))))))
(defun pmail-summary-undelete-many (&optional n)
"Undelete all deleted msgs, optional prefix arg N means undelete N prev
msgs."
(interactive "P")
- (with-current-buffer pmail-buffer
+ (save-excursion
+ (set-buffer pmail-buffer)
(let* ((init-msg (if n pmail-current-message pmail-total-messages))
(pmail-current-message init-msg)
(n (or n pmail-total-messages))
(msgs-undeled 0))
- (while (and (> pmail-current-message 0) (< msgs-undeled n))
- (when (pmail-message-deleted-p pmail-current-message)
- (pmail-set-attribute "deleted" nil)
- (setq msgs-undeled (1+ msgs-undeled)))
+ (while (and (> pmail-current-message 0)
+ (< msgs-undeled n))
+ (if (pmail-message-deleted-p pmail-current-message)
+ (progn (pmail-set-attribute "deleted" nil)
+ (setq msgs-undeled (1+ msgs-undeled))))
(setq pmail-current-message (1- pmail-current-message)))
- (with-current-buffer pmail-summary-buffer
+ (set-buffer pmail-summary-buffer)
(setq pmail-current-message init-msg msgs-undeled 0)
- (while (and (> pmail-current-message 0) (< msgs-undeled n))
- (when (pmail-summary-deleted-p pmail-current-message)
- (pmail-summary-mark-undeleted pmail-current-message)
- (setq msgs-undeled (1+ msgs-undeled)))
- (setq pmail-current-message (1- pmail-current-message)))))))
+ (while (and (> pmail-current-message 0)
+ (< msgs-undeled n))
+ (if (pmail-summary-deleted-p pmail-current-message)
+ (progn (pmail-summary-mark-undeleted pmail-current-message)
+ (setq msgs-undeled (1+ msgs-undeled))))
+ (setq pmail-current-message (1- pmail-current-message))))
+ (pmail-summary-goto-msg)))
;; Pmail Summary mode is suitable only for specially formatted data.
(put 'pmail-summary-mode 'mode-class 'special)
@@ -667,22 +765,6 @@
\\[pmail-summary-undelete-many] Undelete all or prefix arg deleted
messages.
\\[pmail-summary-wipe] Delete the summary and go to the Pmail buffer.
-Commands for filtering the summary:
-
-\\[pmail-summary-by-labels] Filter by label.
-\\[pmail-summary-by-topic] Filter by Subject.
- Filter by the entire message (header and body) if given a
- prefix argument.
-\\[pmail-summary-by-senders] Filter by From field.
-\\[pmail-summary-by-recipients] Filter by To, From, and Cc fields.
- Filter by To and From only if given a prefix argument.
-
-The commands listed above take comma-separated lists of regular
-expressions.
-
-\\[pmail-summary-by-regexp] Filter by any header line.
-\\[pmail-summary] Restore the default summary.
-
Commands for sorting the summary:
\\[pmail-summary-sort-by-date] Sort by date.
@@ -700,7 +782,6 @@
(setq buffer-read-only t)
(set-syntax-table text-mode-syntax-table)
(make-local-variable 'pmail-buffer)
- (make-local-variable 'pmail-view-buffer)
(make-local-variable 'pmail-total-messages)
(make-local-variable 'pmail-current-message)
(setq pmail-current-message nil)
@@ -730,101 +811,289 @@
so that if the next motion between messages is in the same Incremental
Search, the `unseen' attribute is restored.")
+;; Show in Pmail the message described by the summary line that point is on,
+;; but only if the Pmail buffer is already visible.
+;; This is a post-command-hook in summary buffers.
(defun pmail-summary-pmail-update ()
- "Update the Pmail summary buffer.
-Put the cursor on the beginning of the line containing the
-current message and highlight the buffer. Show in Pmail the
-message described by the summary line that point is on, but only
-if the Pmail buffer is already visible. This is on
-`post-command-hook' in summary buffers."
(let (buffer-read-only)
(save-excursion
;; If at end of buffer, pretend we are on the last text line.
- (when (eobp)
+ (if (eobp)
(forward-line -1))
- ;; Determine the message number corresponding to line point is on.
(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 `unseen'.
- (when (not isearch-mode)
+ ;; 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 pmail-summary-put-back-unseen nil))
+
(or (eq pmail-current-message msg-num)
- (let ((window (get-buffer-window pmail-view-buffer t))
+ (let ((window (get-buffer-window pmail-buffer t))
(owin (selected-window)))
(if isearch-mode
(save-excursion
(set-buffer pmail-buffer)
- ;; 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.
+ ;; 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.
(if pmail-summary-put-back-unseen
(pmail-set-attribute "unseen" t
pmail-current-message))
;; Arrange to do that later, for the new current message,
;; if it still has `unseen'.
(setq pmail-summary-put-back-unseen
- (member "unseen" (pmail-desc-get-keywords msg-num))))
+ (pmail-message-attr-p msg-num
pmail-unseen-attr-index)))
(setq pmail-summary-put-back-unseen nil))
+
;; Go to the desired message.
(setq pmail-current-message msg-num)
+
;; Update the summary to show the message has been seen.
- (when (= (following-char) ?-)
+ (if (= (following-char) ?-)
+ (progn
(delete-char 1)
- (insert " "))
+ (insert " ")))
+
(if window
;; Using save-window-excursion would cause the new value
;; of point to get lost.
(unwind-protect
(progn
(select-window window)
- (pmail-show-message msg-num t))
+ (pmail-show-message-maybe msg-num t))
(select-window owin))
- (when (buffer-name pmail-buffer)
+ (if (buffer-name pmail-buffer)
(save-excursion
(set-buffer pmail-buffer)
- (pmail-show-message msg-num t))))))
+ (pmail-show-message-maybe msg-num t))))))
(pmail-summary-update-highlight nil)))))
+(defun pmail-summary-save-buffer ()
+ "Save the buffer associated with this PMAIL summary."
+ (interactive)
+ (save-window-excursion
+ (save-excursion
+ (switch-to-buffer pmail-buffer)
+ (save-buffer))))
+
+
+(if pmail-summary-mode-map
+ nil
+ (setq pmail-summary-mode-map (make-keymap))
+ (suppress-keymap pmail-summary-mode-map)
+
+ (define-key pmail-summary-mode-map [mouse-2]
'pmail-summary-mouse-goto-message)
+ (define-key pmail-summary-mode-map "a" 'pmail-summary-add-label)
+ (define-key pmail-summary-mode-map "b" 'pmail-summary-bury)
+ (define-key pmail-summary-mode-map "c" 'pmail-summary-continue)
+ (define-key pmail-summary-mode-map "d" 'pmail-summary-delete-forward)
+ (define-key pmail-summary-mode-map "\C-d" 'pmail-summary-delete-backward)
+ (define-key pmail-summary-mode-map "e"
'pmail-summary-edit-current-message)
+ (define-key pmail-summary-mode-map "f" 'pmail-summary-forward)
+ (define-key pmail-summary-mode-map "g" 'pmail-summary-get-new-mail)
+ (define-key pmail-summary-mode-map "h" 'pmail-summary)
+ (define-key pmail-summary-mode-map "i" 'pmail-summary-input)
+ (define-key pmail-summary-mode-map "j" 'pmail-summary-goto-msg)
+ (define-key pmail-summary-mode-map "\C-m" 'pmail-summary-goto-msg)
+ (define-key pmail-summary-mode-map "k" 'pmail-summary-kill-label)
+ (define-key pmail-summary-mode-map "l" 'pmail-summary-by-labels)
+ (define-key pmail-summary-mode-map "\e\C-h" 'pmail-summary)
+ (define-key pmail-summary-mode-map "\e\C-l" 'pmail-summary-by-labels)
+ (define-key pmail-summary-mode-map "\e\C-r" 'pmail-summary-by-recipients)
+ (define-key pmail-summary-mode-map "\e\C-s" 'pmail-summary-by-regexp)
+ (define-key pmail-summary-mode-map "\e\C-t" 'pmail-summary-by-topic)
+ (define-key pmail-summary-mode-map "m" 'pmail-summary-mail)
+ (define-key pmail-summary-mode-map "\M-m" 'pmail-summary-retry-failure)
+ (define-key pmail-summary-mode-map "n" 'pmail-summary-next-msg)
+ (define-key pmail-summary-mode-map "\en" 'pmail-summary-next-all)
+ (define-key pmail-summary-mode-map "\e\C-n"
'pmail-summary-next-labeled-message)
+ (define-key pmail-summary-mode-map "o"
'pmail-summary-output-to-pmail-file)
+ (define-key pmail-summary-mode-map "\C-o" 'pmail-summary-output)
+ (define-key pmail-summary-mode-map "p" 'pmail-summary-previous-msg)
+ (define-key pmail-summary-mode-map "\ep" 'pmail-summary-previous-all)
+ (define-key pmail-summary-mode-map "\e\C-p"
'pmail-summary-previous-labeled-message)
+ (define-key pmail-summary-mode-map "q" 'pmail-summary-quit)
+ (define-key pmail-summary-mode-map "Q" 'pmail-summary-wipe)
+ (define-key pmail-summary-mode-map "r" 'pmail-summary-reply)
+ (define-key pmail-summary-mode-map "s" 'pmail-summary-expunge-and-save)
+ (define-key pmail-summary-mode-map "\es" 'pmail-summary-search)
+ (define-key pmail-summary-mode-map "t" 'pmail-summary-toggle-header)
+ (define-key pmail-summary-mode-map "u" 'pmail-summary-undelete)
+ (define-key pmail-summary-mode-map "\M-u" 'pmail-summary-undelete-many)
+ (define-key pmail-summary-mode-map "x" 'pmail-summary-expunge)
+ (define-key pmail-summary-mode-map "w" 'pmail-summary-output-body)
+ (define-key pmail-summary-mode-map "."
'pmail-summary-beginning-of-message)
+ (define-key pmail-summary-mode-map "/" 'pmail-summary-end-of-message)
+ (define-key pmail-summary-mode-map "<" 'pmail-summary-first-message)
+ (define-key pmail-summary-mode-map ">" 'pmail-summary-last-message)
+ (define-key pmail-summary-mode-map " " 'pmail-summary-scroll-msg-up)
+ (define-key pmail-summary-mode-map "\177" 'pmail-summary-scroll-msg-down)
+ (define-key pmail-summary-mode-map "?" 'describe-mode)
+ (define-key pmail-summary-mode-map "\C-c\C-n"
'pmail-summary-next-same-subject)
+ (define-key pmail-summary-mode-map "\C-c\C-p"
'pmail-summary-previous-same-subject)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-d"
+ 'pmail-summary-sort-by-date)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-s"
+ 'pmail-summary-sort-by-subject)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-a"
+ 'pmail-summary-sort-by-author)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-r"
+ 'pmail-summary-sort-by-recipient)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-c"
+ 'pmail-summary-sort-by-correspondent)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-l"
+ 'pmail-summary-sort-by-lines)
+ (define-key pmail-summary-mode-map "\C-c\C-s\C-k"
+ 'pmail-summary-sort-by-labels)
+ (define-key pmail-summary-mode-map "\C-x\C-s" 'pmail-summary-save-buffer)
+ )
+
+;;; Menu bar bindings.
+
+(define-key pmail-summary-mode-map [menu-bar] (make-sparse-keymap))
+
+(define-key pmail-summary-mode-map [menu-bar classify]
+ (cons "Classify" (make-sparse-keymap "Classify")))
+
+(define-key pmail-summary-mode-map [menu-bar classify output-menu]
+ '("Output (Pmail Menu)..." . pmail-summary-output-menu))
+
+(define-key pmail-summary-mode-map [menu-bar classify input-menu]
+ '("Input Pmail File (menu)..." . pmail-input-menu))
+
+(define-key pmail-summary-mode-map [menu-bar classify input-menu]
+ '(nil))
+
+(define-key pmail-summary-mode-map [menu-bar classify output-menu]
+ '(nil))
+
+(define-key pmail-summary-mode-map [menu-bar classify output-body]
+ '("Output (body)..." . pmail-summary-output-body))
+
+(define-key pmail-summary-mode-map [menu-bar classify output-inbox]
+ '("Output (inbox)..." . pmail-summary-output))
+
+(define-key pmail-summary-mode-map [menu-bar classify output]
+ '("Output (Pmail)..." . pmail-summary-output-to-pmail-file))
+
+(define-key pmail-summary-mode-map [menu-bar classify kill-label]
+ '("Kill Label..." . pmail-summary-kill-label))
+
+(define-key pmail-summary-mode-map [menu-bar classify add-label]
+ '("Add Label..." . pmail-summary-add-label))
+
+(define-key pmail-summary-mode-map [menu-bar summary]
+ (cons "Summary" (make-sparse-keymap "Summary")))
+
+(define-key pmail-summary-mode-map [menu-bar summary senders]
+ '("By Senders..." . pmail-summary-by-senders))
+
+(define-key pmail-summary-mode-map [menu-bar summary labels]
+ '("By Labels..." . pmail-summary-by-labels))
+
+(define-key pmail-summary-mode-map [menu-bar summary recipients]
+ '("By Recipients..." . pmail-summary-by-recipients))
+
+(define-key pmail-summary-mode-map [menu-bar summary topic]
+ '("By Topic..." . pmail-summary-by-topic))
+
+(define-key pmail-summary-mode-map [menu-bar summary regexp]
+ '("By Regexp..." . pmail-summary-by-regexp))
+
+(define-key pmail-summary-mode-map [menu-bar summary all]
+ '("All" . pmail-summary))
+
+(define-key pmail-summary-mode-map [menu-bar mail]
+ (cons "Mail" (make-sparse-keymap "Mail")))
+
+(define-key pmail-summary-mode-map [menu-bar mail pmail-summary-get-new-mail]
+ '("Get New Mail" . pmail-summary-get-new-mail))
+
+(define-key pmail-summary-mode-map [menu-bar mail lambda]
+ '("----"))
+
+(define-key pmail-summary-mode-map [menu-bar mail continue]
+ '("Continue" . pmail-summary-continue))
+
+(define-key pmail-summary-mode-map [menu-bar mail resend]
+ '("Re-send..." . pmail-summary-resend))
+
+(define-key pmail-summary-mode-map [menu-bar mail forward]
+ '("Forward" . pmail-summary-forward))
+
+(define-key pmail-summary-mode-map [menu-bar mail retry]
+ '("Retry" . pmail-summary-retry-failure))
+
+(define-key pmail-summary-mode-map [menu-bar mail reply]
+ '("Reply" . pmail-summary-reply))
+
+(define-key pmail-summary-mode-map [menu-bar mail mail]
+ '("Mail" . pmail-summary-mail))
+
+(define-key pmail-summary-mode-map [menu-bar delete]
+ (cons "Delete" (make-sparse-keymap "Delete")))
+
+(define-key pmail-summary-mode-map [menu-bar delete expunge/save]
+ '("Expunge/Save" . pmail-summary-expunge-and-save))
+
+(define-key pmail-summary-mode-map [menu-bar delete expunge]
+ '("Expunge" . pmail-summary-expunge))
+
+(define-key pmail-summary-mode-map [menu-bar delete undelete]
+ '("Undelete" . pmail-summary-undelete))
+
+(define-key pmail-summary-mode-map [menu-bar delete delete]
+ '("Delete" . pmail-summary-delete-forward))
+
+(define-key pmail-summary-mode-map [menu-bar move]
+ (cons "Move" (make-sparse-keymap "Move")))
+
+(define-key pmail-summary-mode-map [menu-bar move search-back]
+ '("Search Back..." . pmail-summary-search-backward))
+
+(define-key pmail-summary-mode-map [menu-bar move search]
+ '("Search..." . pmail-summary-search))
+
+(define-key pmail-summary-mode-map [menu-bar move previous]
+ '("Previous Nondeleted" . pmail-summary-previous-msg))
+
+(define-key pmail-summary-mode-map [menu-bar move next]
+ '("Next Nondeleted" . pmail-summary-next-msg))
+
+(define-key pmail-summary-mode-map [menu-bar move last]
+ '("Last" . pmail-summary-last-message))
+
+(define-key pmail-summary-mode-map [menu-bar move first]
+ '("First" . pmail-summary-first-message))
+
+(define-key pmail-summary-mode-map [menu-bar move previous]
+ '("Previous" . pmail-summary-previous-all))
+
+(define-key pmail-summary-mode-map [menu-bar move next]
+ '("Next" . pmail-summary-next-all))
+
(defun pmail-summary-mouse-goto-message (event)
"Select the message whose summary line you click on."
(interactive "@e")
(goto-char (posn-point (event-end event)))
- (setq pmail-current-message (pmail-summary-get-message-at-point))
- (pmail-summary-pmail-update))
-
-(defun pmail-summary-get-message-at-point ()
- "Return the message number corresponding to the line containing point.
-If the summary buffer contains no messages, nil is returned."
- (save-excursion
- ;; Position point at the beginning of a line.
- (if (eobp)
- (forward-line -1)
- (forward-line 0))
- ;; Parse the message number.
- (string-to-number
- (buffer-substring (point) (min (point-max) (+ 6 (point)))))))
+ (pmail-summary-goto-msg))
(defun pmail-summary-goto-msg (&optional n nowarn skip-pmail)
"Go to message N in the summary buffer and the Pmail buffer.
If N is nil, use the message corresponding to point in the summary
-buffer and move to that message in the Pmail buffer.
+and move to that message in the Pmail buffer.
If NOWARN, don't say anything if N is out of range.
If SKIP-PMAIL, don't do anything to the Pmail buffer."
(interactive "P")
(if (consp n) (setq n (prefix-numeric-value n)))
- ;; Do the end of buffer adjustment.
(if (eobp) (forward-line -1))
(beginning-of-line)
- ;; Set N to the current message unless it was already set by the
- ;; caller.
- (unless n (setq n (pmail-summary-get-message-at-point)))
(let* ((obuf (current-buffer))
(buf pmail-buffer)
(cur (point))
@@ -832,11 +1101,13 @@
(curmsg (string-to-number
(buffer-substring (point)
(min (point-max) (+ 6 (point))))))
- (total (with-current-buffer buf
- pmail-total-messages)))
- ;; Do a validity check on N. If it is valid then set the current
- ;; summary message to N. `pmail-summary-pmail-update' will then
- ;; actually move point to the selected message.
+ (total (save-excursion (set-buffer buf) pmail-total-messages)))
+ ;; 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.
+ ;; set N by default.
+ (if (not n)
+ (setq n curmsg)
(if (< n 1)
(progn (message "No preceding message")
(setq n 1)))
@@ -850,7 +1121,7 @@
(progn (or nowarn (message "Message %d not found" n))
(setq n curmsg)
(setq message-not-found t)
- (goto-char cur)))
+ (goto-char cur))))
(beginning-of-line)
(skip-chars-forward " ")
(skip-chars-forward "0-9")
@@ -860,10 +1131,8 @@
(insert " "))))
(pmail-summary-update-highlight message-not-found)
(beginning-of-line)
- ;; Determine if the Pmail buffer needs to be processed.
(if skip-pmail
nil
- ;; It does.
(let ((selwin (selected-window)))
(unwind-protect
(progn (pop-to-buffer buf)
@@ -899,7 +1168,7 @@
(interactive "P")
(if (eq dist '-)
(pmail-summary-scroll-msg-down nil)
- (let ((pmail-buffer-window (get-buffer-window pmail-view-buffer)))
+ (let ((pmail-buffer-window (get-buffer-window pmail-buffer)))
(if pmail-buffer-window
(if (let ((pmail-summary-window (selected-window)))
(select-window pmail-buffer-window)
@@ -914,7 +1183,7 @@
(if (not pmail-summary-scroll-between-messages)
(error "End of buffer")
(pmail-summary-next-msg (or dist 1)))
- (let ((other-window-scroll-buffer pmail-view-buffer))
+ (let ((other-window-scroll-buffer pmail-buffer))
(scroll-other-window dist)))
;; If it isn't visible at all, show the beginning.
(pmail-summary-beginning-of-message)))))
@@ -926,7 +1195,7 @@
(interactive "P")
(if (eq dist '-)
(pmail-summary-scroll-msg-up nil)
- (let ((pmail-buffer-window (get-buffer-window pmail-view-buffer)))
+ (let ((pmail-buffer-window (get-buffer-window pmail-buffer)))
(if pmail-buffer-window
(if (let ((pmail-summary-window (selected-window)))
(select-window pmail-buffer-window)
@@ -940,7 +1209,7 @@
(if (not pmail-summary-scroll-between-messages)
(error "Beginning of buffer")
(pmail-summary-previous-msg (or dist 1)))
- (let ((other-window-scroll-buffer pmail-view-buffer))
+ (let ((other-window-scroll-buffer pmail-buffer))
(scroll-other-window-down dist)))
;; If it isn't visible at all, show the beginning.
(pmail-summary-beginning-of-message)))))
@@ -960,21 +1229,23 @@
Position it according to WHERE which can be BEG or END"
(if (and (one-window-p) (not pop-up-frames))
;; If there is just one window, put the summary on the top.
- (let ((buffer pmail-view-buffer))
+ (let ((buffer pmail-buffer))
(split-window (selected-window) pmail-summary-window-size)
(select-window (frame-first-window))
- (pop-to-buffer pmail-view-buffer)
+ (pop-to-buffer pmail-buffer)
;; If pop-to-buffer did not use that window, delete that
;; window. (This can happen if it uses another frame.)
(or (eq buffer (window-buffer (next-window (frame-first-window))))
(delete-other-windows)))
- (pop-to-buffer pmail-view-buffer))
- (cond ((eq where 'BEG)
+ (pop-to-buffer pmail-buffer))
+ (cond
+ ((eq where 'BEG)
(goto-char (point-min))
(search-forward "\n\n"))
((eq where 'END)
(goto-char (point-max))
- (recenter (1- (window-height)))))
+ (recenter (1- (window-height))))
+ )
(pop-to-buffer pmail-summary-buffer))
(defun pmail-summary-bury ()
@@ -998,7 +1269,7 @@
"Kill and wipe away Pmail summary, remaining within Pmail."
(interactive)
(save-excursion (set-buffer pmail-buffer) (setq pmail-summary-buffer nil))
- (let ((local-pmail-buffer pmail-view-buffer))
+ (let ((local-pmail-buffer pmail-buffer))
(kill-buffer (current-buffer))
;; Delete window if not only one.
(if (not (eq (selected-window) (next-window nil 'no-minibuf)))
@@ -1009,17 +1280,23 @@
(defun pmail-summary-expunge ()
"Actually erase all deleted messages and recompute summary headers."
(interactive)
+ (save-excursion
(set-buffer pmail-buffer)
- (pmail-expunge)
- (set-buffer pmail-summary-buffer))
+ (when (pmail-expunge-confirmed)
+ (pmail-only-expunge)))
+ (pmail-update-summary))
(defun pmail-summary-expunge-and-save ()
"Expunge and save PMAIL file."
(interactive)
+ (save-excursion
(set-buffer pmail-buffer)
- (pmail-expunge)
- (save-buffer)
- (set-buffer pmail-summary-buffer)
+ (when (pmail-expunge-confirmed)
+ (pmail-only-expunge)))
+ (pmail-update-summary)
+ (save-excursion
+ (set-buffer pmail-buffer)
+ (save-buffer))
(set-buffer-modified-p nil))
(defun pmail-summary-get-new-mail (&optional file-name)
@@ -1032,14 +1309,15 @@
(interactive
(list (if current-prefix-arg
(read-file-name "Get new mail from file: "))))
- (let (current-message new-mail)
- (with-current-buffer pmail-buffer
- (setq new-mail (pmail-get-new-mail file-name)
- current-message pmail-current-message))
- ;; If new mail was found, display of the correct message was
- ;; done elsewhere.
- (unless new-mail
- (pmail-summary-goto-msg current-message nil t))))
+ (let (msg)
+ (save-excursion
+ (set-buffer pmail-buffer)
+ (pmail-get-new-mail file-name)
+ ;; Get the proper new message number.
+ (setq msg pmail-current-message))
+ ;; Make sure that message is displayed.
+ (or (zerop msg)
+ (pmail-summary-goto-msg msg))))
(defun pmail-summary-input (filename)
"Run Pmail on file FILENAME."
@@ -1061,12 +1339,20 @@
(end-of-buffer))
(forward-line -1))
-(defvar pmail-summary-edit-map
- (let ((map (nconc (make-sparse-keymap) text-mode-map)))
- (define-key map "\C-c\C-c" 'pmail-cease-edit)
- (define-key map "\C-c\C-]" 'pmail-abort-edit)
- map)
- "Mode map to use when editing the pmail summary.")
+(declare-function pmail-abort-edit "pmailedit" ())
+(declare-function pmail-cease-edit "pmailedit"())
+(declare-function pmail-set-label "pmailkwd" (l state &optional n))
+(declare-function pmail-output-read-file-name "pmailout" ())
+(declare-function pmail-output-read-pmail-file-name "pmailout" ())
+(declare-function mail-send-and-exit "sendmail" (&optional arg))
+
+(defvar pmail-summary-edit-map nil)
+(if pmail-summary-edit-map
+ nil
+ (setq pmail-summary-edit-map
+ (nconc (make-sparse-keymap) text-mode-map))
+ (define-key pmail-summary-edit-map "\C-c\C-c" 'pmail-cease-edit)
+ (define-key pmail-summary-edit-map "\C-c\C-]" 'pmail-abort-edit))
(defun pmail-summary-edit-current-message ()
"Edit the contents of this message."
@@ -1155,29 +1441,46 @@
(defun pmail-summary-toggle-header ()
"Show original message header if pruned header currently shown, or vice
versa."
(interactive)
- (with-current-buffer pmail-buffer
- (pmail-toggle-header)))
+ (save-window-excursion
+ (set-buffer pmail-buffer)
+ (pmail-toggle-header))
+ ;; Inside save-excursion, some changes to point in the PMAIL buffer are lost.
+ ;; Set point to point-min in the PMAIL buffer, if it is visible.
+ (let ((window (get-buffer-window pmail-buffer)))
+ (if window
+ ;; Using save-window-excursion would lose the new value of point.
+ (let ((owin (selected-window)))
+ (unwind-protect
+ (progn
+ (select-window window)
+ (goto-char (point-min)))
+ (select-window owin))))))
+
(defun pmail-summary-add-label (label)
"Add LABEL to labels associated with current Pmail message.
Completion is performed over known labels when reading."
- (interactive (list (with-current-buffer pmail-buffer
+ (interactive (list (save-excursion
+ (set-buffer pmail-buffer)
(pmail-read-label "Add label"))))
- (with-current-buffer pmail-buffer
+ (save-excursion
+ (set-buffer pmail-buffer)
(pmail-add-label label)))
(defun pmail-summary-kill-label (label)
"Remove LABEL from labels associated with current Pmail message.
Completion is performed over known labels when reading."
- (interactive (list (with-current-buffer pmail-buffer
- (pmail-read-label "Kill label" t))))
- (with-current-buffer pmail-buffer
- (pmail-kill-label label)))
+ (interactive (list (save-excursion
+ (set-buffer pmail-buffer)
+ (pmail-read-label "Kill label"))))
+ (save-excursion
+ (set-buffer pmail-buffer)
+ (pmail-set-label label nil)))
;;;; *** Pmail Summary Mailing Commands ***
(defun pmail-summary-override-mail-send-and-exit ()
- "Replace bindings to 'mail-send-and-exit with 'pmail-summary-send-and-exit"
+ "Replace bindings to `mail-send-and-exit' with
`pmail-summary-send-and-exit'."
(use-local-map (copy-keymap (current-local-map)))
(dolist (key (where-is-internal 'mail-send-and-exit))
(define-key (current-local-map) key 'pmail-summary-send-and-exit)))
@@ -1209,10 +1512,10 @@
prefix argument means ignore them. While composing the reply,
use \\[mail-yank-original] to yank the original message into it."
(interactive "P")
- (let ((window (get-buffer-window pmail-view-buffer)))
+ (let ((window (get-buffer-window pmail-buffer)))
(if window
(select-window window)
- (set-buffer pmail-view-buffer)))
+ (set-buffer pmail-buffer)))
(pmail-reply just-sender)
(pmail-summary-override-mail-send-and-exit))
@@ -1256,7 +1559,7 @@
(set-buffer pmail-buffer)))
(call-interactively 'pmail-resend)))
-;;;; Summary output commands.
+;; Summary output commands.
(defun pmail-summary-output-to-pmail-file (&optional file-name n)
"Append the current message to an Pmail file named FILE-NAME.
@@ -1268,7 +1571,7 @@
starting with the current one. Deleted messages are skipped and don't count."
(interactive
(progn (require 'pmailout)
- (list (pmail-output-read-file-name)
+ (list (pmail-output-read-pmail-file-name)
(prefix-numeric-value current-prefix-arg))))
(let ((i 0) prev-msg)
(while
@@ -1415,88 +1718,7 @@
(funcall sortfun reverse))
(select-window selwin))))
-(defun pmail-summary-get-sender (n)
- "Return the sender for message N.
-If sender matches `pmail-user-mail-address-regexp' or
-`user-mail-address', return the to-address instead."
- (let ((sender (pmail-desc-get-sender n)))
- (if (or (null sender)
- (and pmail-user-mail-address-regexp
- (string-match pmail-user-mail-address-regexp sender)))
- ;; Either no sender known, or it's this user.
- (save-restriction
- (narrow-to-region (pmail-desc-get-start n)
- (pmail-desc-get-end n))
- (concat "to: " (mail-strip-quoted-names
- (pmail-header-get-header "to"))))
- sender)))
-
-(defun pmail-summary-get-line-count (n)
- "Return a string containing the number of lines in message N.
-If `pmail-summary-line-count-flag' is nil, return the empty string."
- (if pmail-summary-line-count-flag
- (let ((lines (pmail-desc-get-line-count n)))
- (format (cond ((<= lines 9) " [%d]")
- ((<= lines 99) " [%d]")
- ((<= lines 999) " [%3d]")
- (t "[%d]"))
- lines))
- ""))
-
-(defun pmail-summary-get-summary-attributes (n)
- "Return the attribute character codes for message N.
-`-' means an unseen message, `D' means marked for deletion."
- (format "%s%s%s%s%s"
- (cond ((pmail-desc-attr-p pmail-desc-unseen-index n) "-")
- ((pmail-desc-attr-p pmail-desc-deleted-index n) "D")
- (t " "))
- (or (pmail-desc-get-attr-code pmail-desc-answered-index n) " ")
- (or (pmail-desc-get-attr-code pmail-desc-filed-index n) " ")
- (or (pmail-desc-get-attr-code pmail-desc-edited-index n) " ")
- (or (pmail-desc-get-attr-code pmail-desc-stored-index n) " ")))
-
-(defun pmail-summary-get-summary-line (n)
- "Return a summary line for message N."
- (let (keywords str subj)
- (dolist (keyword (pmail-desc-get-keywords n))
- (when (and (pmail-keyword-p keyword)
- (not (pmail-attribute-p keyword)))
- (setq keywords (cons keyword keywords))))
- (setq keywords (nreverse keywords)
- str (if keywords
- (concat "{ " (mapconcat 'identity keywords " ") " } ")
- "")
- subj (replace-regexp-in-string "\\s-+" " "
- (pmail-desc-get-subject n)))
- (funcall pmail-summary-line-decoder
- (format "%5s%s%6s %25.25s%s %s\n"
- n
- (pmail-summary-get-summary-attributes n)
- (concat (pmail-desc-get-day-number n) "-"
- (pmail-desc-get-month n))
- (pmail-summary-get-sender n)
- (pmail-summary-get-line-count n)
- (concat str subj)))))
-
-(defun pmail-summary-update (n)
- "Rewrite the summary line for message N."
- (with-current-buffer pmail-buffer
- ;; we need to do this in the pmail-buffer lest the keywords are
- ;; not recognized
- (let ((summary (pmail-summary-get-summary-line n)))
- (with-current-buffer pmail-summary-buffer
- (save-excursion
- (let ((buffer-read-only nil))
- (pmail-summary-goto-msg n)
- ;; summary line includes newline at the end
- (delete-region (point) (1+ (line-end-position)))
- (insert summary)))))))
-
(provide 'pmailsum)
-;; Local Variables:
-;; change-log-default-name: "ChangeLog.pmail"
-;; End:
-
;; arch-tag: 80b0a27a-a50d-4f37-9466-83d32d1e0ca8
;;; pmailsum.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] Changes to emacs/lisp/mail/pmailsum.el,v,
Paul Michael Reilly <=