]> code.delx.au - gnu-emacs/blobdiff - lisp/mh-e/mh-e.el
* mh-search.el: New file containing contents of mh-index.el and
[gnu-emacs] / lisp / mh-e / mh-e.el
index d75457bd2038d54f12f99e3624c036a10779d04e..551aa21d5cd4b66a44e336e8718679fe16824317 100644 (file)
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1985, 1986, 1987, 1988,
 ;;  1990, 1992, 1993, 1994, 1995, 1997, 1999,
-;;  2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;;  2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Bill Wohler <wohler@newt.com>
 ;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -51,7 +51,9 @@
 
 ;; MH-E is an Emacs interface to the MH mail system.
 
-;; MH-E is supported in GNU Emacs 20 and 21, with MH 6.8.4 and nmh 1.0.4.
+;; MH-E is supported in GNU Emacs 21 and 22 as well as XEmacs 21
+;; (except for versions 21.5.9-21.5.16), with MH 6.8.4 on, nmh 1.0.4
+;; on, and GNU mailutils 0.4 on.
 
 ;; Mailing Lists:
 ;;   mh-e-users@lists.sourceforge.net
 
 (eval-when-compile (require 'mh-acros))
 (mh-require-cl)
-(require 'mh-utils)
-(require 'mh-init)
-(require 'mh-inc)
-(require 'mh-seq)
-(require 'gnus-util)
-(require 'easymenu)
 
-;; Shush the byte-compiler
-(defvar font-lock-auto-fontify)
-(defvar font-lock-defaults)
+(require 'easymenu)
+(require 'gnus-util)
+(require 'mh-buffers)
+(require 'mh-seq)
+(require 'mh-utils)
 
 (defconst mh-version "7.85+cvs" "Version number of MH-E.")
 
@@ -194,7 +192,8 @@ matches the message number as in the default of
   \"^\\\\( *[0-9]+\\\\)[^D^0-9]\".
 
 This expression includes the leading space within the parenthesis
-since it looks better to highlight it as well. This regular
+since it looks better to highlight it as well. The highlighting
+is done with the face `mh-folder-msg-number'. This regular
 expression should be correct as it is needed by non-fontification
 functions.")
 
@@ -209,7 +208,8 @@ matches the message number as in the default of
   \"^\\\\( *[0-9]+\\\\)D\".
 
 This expression includes the leading space within the parenthesis
-since it looks better to highlight it as well. This regular
+since it looks better to highlight it as well. The highlighting
+is done with the face `mh-folder-deleted'. This regular
 expression should be correct as it is needed by non-fontification
 functions. See also `mh-note-deleted'.")
 
@@ -224,7 +224,8 @@ matches the message number as in the default of
   \"^\\\\( *[0-9]+\\\\)\\\\^\".
 
 This expression includes the leading space within the parenthesis
-since it looks better to highlight it as well. This regular
+since it looks better to highlight it as well. The highlighting
+is done with the face `mh-folder-refiled'. This regular
 expression should be correct as it is needed by non-fontification
 functions. See also `mh-note-refiled'.")
 
@@ -246,9 +247,10 @@ matches the message number as in the default of
 
 This expression includes the leading space and current message
 marker \"+\" within the parenthesis since it looks better to
-highlight these items as well. This regular expression should be
-correct as it is needed by non-fontification functions. See also
-`mh-note-cur'.")
+highlight these items as well. The highlighting is done with the
+face `mh-folder-cur-msg-number'. This regular expression should
+be correct as it is needed by non-fontification functions. See
+also `mh-note-cur'.")
 
 (defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)"
   "This regular expression matches a valid date.
@@ -258,8 +260,8 @@ Note that the default setting of `mh-folder-font-lock-keywords'
 expects this expression to contain only one parenthesized
 expression which matches the date field as in the default of
 \"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}. If this regular expression
-is not correct, the date will not be highlighted. See also
-`mh-scan-format-regexp'.")
+is not correct, the date will not be highlighted with the face
+`mh-folder-date'.")
 
 (defvar mh-scan-rcpt-regexp  "\\(To:\\)\\(..............\\)"
   "This regular expression specifies the recipient in messages you sent.
@@ -270,8 +272,9 @@ The first is expected to match the \"To:\" that the default scan
 format file generates. The second is expected to match the
 recipient's name as in the default of
 \"\\\\(To:\\\\)\\\\(..............\\\\)\". If this regular
-expression is not correct, the recipient will not be
-highlighted.")
+expression is not correct, the \"To:\" string will not be
+highlighted with the face `mh-folder-to' and the recipient will
+not be highlighted with the face `mh-folder-address'")
 
 (defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)"
   "This regular expression matches the message body fragment.
@@ -280,7 +283,8 @@ Note that the default setting of `mh-folder-font-lock-keywords'
 expects this expression to contain at least one parenthesized
 expression which matches the body text as in the default of
 \"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is
-not correct, the body fragment will not be highlighted.")
+not correct, the body fragment will not be highlighted with the
+face `mh-folder-body'.")
 
 (defvar mh-scan-subject-regexp
   "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)"
@@ -289,12 +293,13 @@ not correct, the body fragment will not be highlighted.")
 It must match from the beginning of the line. Note that the
 default setting of `mh-folder-font-lock-keywords' expects this
 expression to contain at least three parenthesized expressions.
-The first is expected to match the \"Re:\" string, if any. The
-second matches an optional bracketed number after \"Re:\", such as
-in \"Re[2]:\" (and is thus a sub-expression of the first
-expression) and the third is expected to match the subject line
-itself as in the default of (broken on multiple lines for
-readability):
+The first is expected to match the \"Re:\" string, if any, and is
+highlighted with the face `mh-folder-followup'. The second
+matches an optional bracketed number after \"Re:\", such as in
+\"Re[2]:\" (and is thus a sub-expression of the first expression)
+and the third is expected to match the subject line itself which
+is highlighted with the face `mh-folder-subject'. For example,
+the default (broken on multiple lines for readability) is
 
   ^ *[0-9]+........[ ]*...................
   \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)*
@@ -303,22 +308,22 @@ readability):
 This regular expression should be correct as it is needed by
 non-fontification functions.")
 
-(defvar mh-scan-format-regexp
-  (concat "\\([bct]\\)" mh-scan-date-regexp " *\\(..................\\)")
-  "This regular expression matches the output of scan.
+(defvar mh-scan-sent-to-me-sender-regexp
+  "^ *[0-9]+.\\([bct]\\).....[ ]*\\(..................\\)"
+  "This regular expression matches messages sent to us.
 
 Note that the default setting of `mh-folder-font-lock-keywords'
-expects this expression to contain at least three parenthesized
+expects this expression to contain at least two parenthesized
 expressions. The first should match the fontification hint (see
-`mh-scan-format-nmh'), the second is found in
-`mh-scan-date-regexp', and the third should match the user name
+`mh-scan-format-nmh') and the second should match the user name
 as in the default of
 
-  \"(concat \"\\\\([bct]\\\\)\" mh-scan-date-regexp
-            \"*\\\\(..................\\\\)\")\".
+  ^ *[0-9]+.\\\\([bct]\\\\).....[ ]*\\\\(..................\\\\)
 
-If this regular expression is not correct, the notation hints and
-the sender will not be highlighted.")
+If this regular expression is not correct, the notation hints
+will not be highlighted with the face
+`mh-mh-folder-sent-to-me-hint' and the sender will not be
+highlighted with the face `mh-folder-sent-to-me-sender'.")
 
 \f
 
@@ -326,31 +331,37 @@ the sender will not be highlighted.")
   (list
    ;; Folders when displaying index buffer
    (list "^\\+.*"
-         '(0 mh-index-folder-face))
+         '(0 'mh-index-folder))
    ;; Marked for deletion
    (list (concat mh-scan-deleted-msg-regexp ".*")
-         '(0 mh-folder-deleted-face))
+         '(0 'mh-folder-deleted))
    ;; Marked for refile
    (list (concat mh-scan-refiled-msg-regexp ".*")
-         '(0 mh-folder-refiled-face))
-   ;;after subj
-   (list mh-scan-body-regexp '(1 mh-folder-body-face nil t))
+         '(0 'mh-folder-refiled))
+   ;; After subject
+   (list mh-scan-body-regexp
+         '(1 'mh-folder-body nil t))
+   ;; Subject
    '(mh-folder-font-lock-subject
-     (1 mh-folder-followup-face append t)
-     (2 mh-folder-subject-face append t))
-   ;;current msg
+     (1 'mh-folder-followup append t)
+     (2 'mh-folder-subject append t))
+   ;; Current message number
    (list mh-scan-cur-msg-number-regexp
-         '(1 mh-folder-cur-msg-number-face))
+         '(1 'mh-folder-cur-msg-number))
+   ;; Message number
    (list mh-scan-good-msg-regexp
-         '(1 mh-folder-msg-number-face)) ;; Msg number
-   (list mh-scan-date-regexp '(1 mh-folder-date-face)) ;; Date
+         '(1 'mh-folder-msg-number))
+   ;; Date
+   (list mh-scan-date-regexp
+         '(1 'mh-folder-date))
+   ;; Messages from me (To:)
    (list mh-scan-rcpt-regexp
-         '(1 mh-folder-to-face) ;; To:
-         '(2 mh-folder-address-face)) ;; address
-   ;; scan font-lock name
-   (list mh-scan-format-regexp
-         '(1 mh-folder-date-face)
-         '(3 mh-folder-scan-format-face)))
+         '(1 'mh-folder-to)
+         '(2 'mh-folder-address))
+   ;; Messages to me
+   (list mh-scan-sent-to-me-sender-regexp
+         '(1 'mh-folder-sent-to-me-hint)
+         '(2 'mh-folder-sent-to-me-sender)))
   "Keywords (regular expressions) used to fontify the MH-Folder buffer.")
 
 (defvar mh-scan-cmd-note-width 1
@@ -523,7 +534,7 @@ This variable can be used by
   "Lists which folders were affected by deletes and refiles.
 This list will always include the current folder
 `mh-current-folder'. This variable can be used by
-`mh-before-commands-processed-hook'.")
+`mh-after-commands-processed-hook'.")
 
 (defvar mh-next-direction 'forward
   "Direction to move to next message.")
@@ -697,21 +708,18 @@ Use the command \\[mh-show] to show the message normally again."
       (mh-recenter 0))
     (setq mh-showing-with-headers t)))
 
-(defun mh-inc-folder (&optional maildrop-name folder)
+(defun mh-inc-folder (&optional file folder)
   "Incorporate new mail into a folder.
 
 You can incorporate mail from any file into the current folder by
 specifying a prefix argument; you'll be prompted for the name of
-the file to use as well as the destination folder
+the FILE to use as well as the destination FOLDER
 
 The hook `mh-inc-folder-hook' is run after incorporating new
-mail. Do not call this function from outside MH-E; use
-\\[mh-rmail] instead.
+mail.
 
-In a program optional argument MAILDROP-NAME specifies an
-alternate maildrop from the default. The optional argument FOLDER
-specifies where to incorporate mail instead of the default named
-by `mh-inbox'."
+Do not call this function from outside MH-E; use \\[mh-rmail]
+instead."
   (interactive (list (if current-prefix-arg
                          (expand-file-name
                           (read-file-name "inc mail from file: "
@@ -731,7 +739,7 @@ by `mh-inbox'."
             ((not (eq (current-buffer) (get-buffer folder)))
              (switch-to-buffer folder)
              (setq mh-previous-window-config config))))
-    (mh-get-new-mail maildrop-name)
+    (mh-get-new-mail file)
     (when (and threading-needed-flag
                (save-excursion
                  (goto-char (point-min))
@@ -878,8 +886,10 @@ DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil."
 (defun mh-refile-or-write-again (range &optional interactive-flag)
   "Repeat last output command.
 
-If you are refiling several messages into the same folder, you can use
-this command to repeat the last refile or write. You can use a range.
+If you are refiling several messages into the same folder, you
+can use this command to repeat the last
+refile (\\[mh-refile-msg]) or write (\\[mh-write-msg-to-file]).
+You can use a range.
 
 Check the documentation of `mh-interactive-range' to see how RANGE is
 read in interactive use.
@@ -891,8 +901,7 @@ called interactively."
       (error "No previous refile or write"))
   (cond ((eq (car mh-last-destination) 'refile)
          (mh-refile-msg range (cdr mh-last-destination))
-         (message "%s" (format "Destination folder: %s"
-                               (cdr mh-last-destination))))
+         (message "Destination folder: %s" (cdr mh-last-destination)))
         (t
          (mh-iterate-on-range msg range
            (apply 'mh-write-msg-to-file msg (cdr mh-last-destination)))
@@ -992,7 +1001,7 @@ This command can be given a prefix argument COUNT to specify how
 many unread messages to skip."
   (interactive "p")
   (unless (> count 0)
-    (error "The function mh-previous-unread-msg expects positive argument"))
+    (error "The function `mh-previous-unread-msg' expects positive argument"))
   (setq count (1- count))
   (let ((unread-sequence (cdr (assoc mh-unseen-seq mh-seq-list)))
         (cur-msg (mh-get-msg-num nil)))
@@ -1172,8 +1181,6 @@ if it is available."
   (when (consp part-index) (setq part-index (car part-index)))
   (mh-folder-mime-action part-index #'mh-mime-save-part nil))
 
-(defvar mh-thread-scan-line-map-stack)
-
 (defun mh-reset-threads-and-narrowing ()
   "Reset all variables pertaining to threads and narrowing.
 Also removes all content from the folder buffer."
@@ -1202,8 +1209,13 @@ if DONT-EXEC-PENDING is non-nil."
                                         mh-interpret-number-as-range-flag)
                        nil)))
   (setq mh-next-direction 'forward)
-  (let ((threaded-flag (memq 'unthread mh-view-ops)))
+  (let ((threaded-flag (memq 'unthread mh-view-ops))
+        (msg-num (mh-get-msg-num nil)))
     (mh-scan-folder mh-current-folder (or range "all") dont-exec-pending)
+    ;; If there isn't a cur sequence, mh-scan-folder goes to the first message.
+    ;; Try to stay where we were.
+    (if (null (car (mh-seq-to-msgs 'cur)))
+        (mh-goto-msg msg-num t t))
     (cond (threaded-flag (mh-toggle-threads))
           (mh-index-data (mh-index-insert-folder-headers)))))
 
@@ -1241,7 +1253,14 @@ the command \\[mh-refile-or-write-again]."
       (append-to-file (point) (point-max) output-file))))
 
 (defun mh-toggle-showing ()
-  "Toggle the scanning mode/showing mode of displaying messages."
+  "Toggle between MH-Folder and MH-Folder Show modes.
+
+This command switches between MH-Folder mode and MH-Folder Show
+mode. MH-Folder mode turns off the associated show buffer so that
+you can perform operations on the messages quickly without
+reading them. This is an excellent way to prune out your junk
+mail or to refile a group of messages to another folder for later
+examination."
   (interactive)
   (if mh-showing-mode
       (mh-set-scan-mode)
@@ -1280,7 +1299,6 @@ RANGE is read in interactive use."
   (if (not (mh-outstanding-commands-p))
       (mh-set-folder-modified-p nil)))
 
-
 (defun mh-folder-line-matches-show-buffer-p ()
   "Return t if the message under point in folder-mode is in the show buffer.
 Return nil in any other circumstance (no message under point, no
@@ -1461,7 +1479,6 @@ structures."
       (setq mh-previous-window-config config)))
   nil)
 
-
 (defun mh-update-sequences ()
   "Flush MH-E's state out to MH.
 
@@ -1507,7 +1524,7 @@ once when he kept statistics on his mail usage."
       (beginning-of-line)
       (setq message (mh-get-msg-num t)))
     (if (looking-at mh-scan-refiled-msg-regexp)
-        (error "Message %d is refiled.  Undo refile before deleting" message))
+        (error "Message %d is refiled; undo refile before deleting" message))
     (if (looking-at mh-scan-deleted-msg-regexp)
         nil
       (mh-set-folder-modified-p t)
@@ -1527,10 +1544,10 @@ be refiled."
       (beginning-of-line)
       (setq message (mh-get-msg-num t)))
     (cond ((looking-at mh-scan-deleted-msg-regexp)
-           (error "Message %d is deleted.  Undo delete before moving" message))
+           (error "Message %d is deleted; undo delete before moving" message))
           ((looking-at mh-scan-refiled-msg-regexp)
            (if (y-or-n-p
-                (format "Message %d already refiled.  Copy to %s as well? "
+                (format "Message %d already refiled; copy to %s as well? "
                         message folder))
                (mh-exec-cmd "refile" (mh-get-msg-num t) "-link"
                             "-src" mh-current-folder
@@ -1561,7 +1578,7 @@ This command can be given a prefix argument COUNT to specify how
 many unread messages to skip."
   (interactive "p")
   (unless (> count 0)
-    (error "The function mh-next-unread-msg expects positive argument"))
+    (error "The function `mh-next-unread-msg' expects positive argument"))
   (setq count (1- count))
   (let ((unread-sequence (reverse (cdr (assoc mh-unseen-seq mh-seq-list))))
         (cur-msg (mh-get-msg-num nil)))
@@ -1718,8 +1735,7 @@ Make it the current folder."
     ["List Folders"                     mh-list-folders t]
     ["Visit a Folder..."                mh-visit-folder t]
     ["View New Messages"                mh-index-new-messages t]
-    ["Search a Folder..."               mh-search-folder t]
-    ["Indexed Search..."                mh-index-search t]
+    ["Search..."                        mh-search t]
     "--"
     ["Quit MH-E"                        mh-quit t]))
 
@@ -1740,13 +1756,7 @@ purely for compatibility. The former symbol is used in Emacs 21.4
 onward while the latter is used in previous versions and XEmacs."
   (if (boundp 'write-file-functions)
       ''write-file-functions            ;Emacs 21.4
-    ''local-write-file-hooks))          ;<Emacs 21.4, XEmacs
-
-;; Avoid compiler warnings in non-bleeding edge versions of Emacs.
-(eval-when-compile
-  (defvar tool-bar-mode)
-  (defvar tool-bar-map)
-  (defvar desktop-save-buffer))         ;Emacs 21.4
+    ''local-write-file-hooks))          ;XEmacs
 
 ;; Register mh-folder-mode as supporting which-function-mode...
 (load "which-func" t t)
@@ -1754,6 +1764,11 @@ onward while the latter is used in previous versions and XEmacs."
            (not (member 'mh-folder-mode which-func-modes)))
   (push 'mh-folder-mode which-func-modes))
 
+;; Shush compiler.
+(eval-when-compile
+  (defvar desktop-save-buffer)
+  (defvar font-lock-auto-fontify))
+
 (defvar mh-folder-buttons-init-flag nil)
 
 ;; Autoload cookie needed by desktop.el
@@ -1846,9 +1861,9 @@ perform the operation on all messages in that region.
    'mh-folder-view-stack ()             ; Stack of previous views of the
                                         ; folder.
    'mh-index-data nil                   ; If the folder was created by a call
-                                        ; to mh-index-search this contains info
+                                        ; to mh-search, this contains info
                                         ; about the search results.
-   'mh-index-previous-search nil        ; Previous folder and search-regexp
+   'mh-index-previous-search nil        ; folder, indexer, search-regexp
    'mh-index-msg-checksum-map nil       ; msg -> checksum map
    'mh-index-checksum-origin-map nil    ; checksum -> ( orig-folder, orig-msg )
    'mh-index-sequence-search-flag nil   ; folder resulted from sequence search
@@ -1894,10 +1909,7 @@ perform the operation on all messages in that region.
 (defun mh-colors-available-p ()
   "Check if colors are available in the Emacs being used."
   (or mh-xemacs-flag
-      (let ((color-cells
-             (or (ignore-errors (mh-funcall-if-exists display-color-cells))
-                 (ignore-errors (mh-funcall-if-exists
-                                 x-display-color-cells)))))
+      (let ((color-cells (display-color-cells)))
         (and (numberp color-cells) (>= color-cells 8)))))
 
 (defun mh-colors-in-use-p ()
@@ -1969,8 +1981,8 @@ columns contain the message number, and the column for notations
 comes after that."
   (if (eq mh-scan-format-file t)
       (max (1+ width) 2)
-    (error "%s %s" "Can't call mh-msg-num-width-to-column"
-           "when mh-scan-format-file is not t")))
+    (error "%s %s" "Can't call `mh-msg-num-width-to-column' when"
+           "`mh-scan-format-file' is not set to \"Use MH-E scan Format\"")))
 
 (defun mh-set-cmd-note (column)
   "Set `mh-cmd-note' to COLUMN.
@@ -2253,7 +2265,6 @@ removed."
       (mh-remove-sequence-notation msg nil t))
     (clrhash mh-sequence-notation-history)))
 
-
 (defun mh-goto-cur-msg (&optional minimal-changes-flag)
   "Position the cursor at the current message.
 When optional argument MINIMAL-CHANGES-FLAG is non-nil, the
@@ -2693,7 +2704,6 @@ in list."
   "S"           mh-sort-folder
   "c"           mh-catchup
   "f"           mh-alt-visit-folder
-  "i"           mh-index-search
   "k"           mh-kill-folder
   "l"           mh-list-folders
   "n"           mh-index-new-messages
@@ -2701,7 +2711,7 @@ in list."
   "p"           mh-pack-folder
   "q"           mh-index-sequenced-messages
   "r"           mh-rescan-folder
-  "s"           mh-search-folder
+  "s"           mh-search
   "u"           mh-undo-folder
   "v"           mh-visit-folder)