Mercurial > emacs
diff lisp/mh-e/mh-index.el @ 50702:7dd3d5eae9c7
Upgraded to MH-E version 7.3.
See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Fri, 25 Apr 2003 05:52:00 +0000 |
parents | 0d8b17d428b5 |
children | 695cf19ef79e |
line wrap: on
line diff
--- a/lisp/mh-e/mh-index.el Fri Apr 25 04:32:25 2003 +0000 +++ b/lisp/mh-e/mh-index.el Fri Apr 25 05:52:00 2003 +0000 @@ -1,6 +1,6 @@ ;;; mh-index -- MH-E interface to indexing programs -;; Copyright (C) 2002 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. ;; Author: Satyaki Das <satyaki@theforce.stanford.edu> ;; Maintainer: Bill Wohler <wohler@newt.com> @@ -29,6 +29,7 @@ ;;; (1) The following search engines are supported: ;;; swish++ ;;; swish-e +;;; mairix ;;; namazu ;;; glimpse ;;; grep @@ -40,8 +41,6 @@ ;;; Change Log: -;; $Id: mh-index.el,v 1.2 2003/02/03 20:55:30 wohler Exp $ - ;;; Code: (require 'cl) @@ -165,21 +164,22 @@ will execute CMD with ARGS and pass the first `mh-index-max-cmdline-args' strings to it. This is repeated till all the strings have been used." (goto-char (point-min)) - (let ((out (get-buffer-create " *mh-xargs-output*"))) - (save-excursion - (set-buffer out) - (erase-buffer)) - (while (not (eobp)) - (let ((arg-list (reverse args)) - (count 0)) - (while (and (not (eobp)) (< count mh-index-max-cmdline-args)) - (push (buffer-substring-no-properties (point) (line-end-position)) - arg-list) - (incf count) - (forward-line)) - (apply #'call-process cmd nil (list out nil) nil (nreverse arg-list)))) - (erase-buffer) - (insert-buffer-substring out))) + (let ((current-buffer (current-buffer))) + (with-temp-buffer + (let ((out (current-buffer))) + (set-buffer current-buffer) + (while (not (eobp)) + (let ((arg-list (reverse args)) + (count 0)) + (while (and (not (eobp)) (< count mh-index-max-cmdline-args)) + (push (buffer-substring-no-properties (point) (line-end-position)) + arg-list) + (incf count) + (forward-line)) + (apply #'call-process cmd nil (list out nil) nil + (nreverse arg-list)))) + (erase-buffer) + (insert-buffer-substring out))))) @@ -230,7 +230,8 @@ (point) (line-end-position))) (forward-line) (save-excursion - (cond ((eolp) + (cond ((not (string-match "^[0-9]*$" msg))) + ((eolp) ;; need to compute checksum (set-buffer mh-checksum-buffer) (insert mh-user-path (substring folder 1) "/" msg "\n")) @@ -260,6 +261,9 @@ (mh-index-update-single-msg msg checksum origin-map))) (forward-line)))))) +(defvar mh-flists-results-folder "new" + "Subfolder for `mh-index-folder' where flists output is placed.") + (defun mh-index-generate-pretty-name (string) "Given STRING generate a name which is suitable for use as a folder name. White space from the beginning and end are removed. All spaces in the name are @@ -288,19 +292,24 @@ (subst-char-in-region (point-min) (point-max) ?\n ?_ t) (subst-char-in-region (point-min) (point-max) ?\r ?_ t) (subst-char-in-region (point-min) (point-max) ?/ ?$ t) - (truncate-string-to-width (buffer-substring (point-min) (point-max)) 20))) + (let ((out (truncate-string-to-width (buffer-string) 20))) + (cond ((eq mh-indexer 'flists) mh-flists-results-folder) + ((equal out mh-flists-results-folder) (concat out "1")) + (t out))))) ;;;###mh-autoload (defun* mh-index-search (redo-search-flag folder search-regexp - &optional window-config) + &optional window-config unseen-flag) "Perform an indexed search in an MH mail folder. +Use a prefix argument to repeat the search, as in REDO-SEARCH-FLAG below. If REDO-SEARCH-FLAG is non-nil and the current folder buffer was generated by a index search, then the search is repeated. Otherwise, FOLDER is searched with SEARCH-REGEXP and the results are presented in an MH-E folder. If FOLDER is \"+\" then mail in all folders are searched. Optional argument WINDOW-CONFIG stores the window configuration that will be restored after the user quits the -folder containing the index search results. +folder containing the index search results. If optional argument UNSEEN-FLAG +is non-nil, then all the messages are marked as unseen. Four indexing programs are supported; if none of these are present, then grep is used. This function picks the first program that is available on your @@ -381,7 +390,7 @@ (message "Processing %s output... " mh-indexer) (goto-char (point-min)) (loop for next-result = (funcall mh-index-next-result-function) - when (null next-result) return nil + while next-result do (unless (eq next-result 'error) (unless (gethash (car next-result) folder-results-map) (setf (gethash (car next-result) folder-results-map) @@ -403,9 +412,13 @@ (cons folder msg))))) folder-results-map) + ;; Mark messages as unseen (if needed) + (when (and unseen-flag (> result-count 0)) + (mh-exec-cmd "mark" index-folder "all" + "-sequence" (symbol-name mh-unseen-seq) "-add")) + ;; Generate scan lines for the hits. - (let ((mh-show-threads-flag nil)) - (mh-visit-folder index-folder () (list folder-results-map origin-map))) + (mh-visit-folder index-folder () (list folder-results-map origin-map)) (goto-char (point-min)) (forward-line) @@ -548,9 +561,8 @@ With non-nil optional argument BACKWARD-FLAG, jump to the previous group of results." (interactive "P") - (if (or (null mh-index-data) - (memq 'unthread mh-view-ops)) - (message "Only applicable in an unthreaded MH-E index search buffer") + (if (null mh-index-data) + (message "Only applicable in an MH-E index search buffer") (let ((point (point))) (forward-line (if backward-flag -1 1)) (cond ((if backward-flag @@ -628,6 +640,22 @@ (set-buffer-modified-p old-buffer-modified-flag))) ;;;###mh-autoload +(defun mh-index-group-by-folder () + "Partition the messages based on source folder. +Returns an alist with the the folder names in the car and the cdr being the +list of messages originally from that folder." + (save-excursion + (goto-char (point-min)) + (let ((result-table (make-hash-table))) + (loop for msg being hash-keys of mh-index-msg-checksum-map + do (push msg (gethash (car (gethash + (gethash msg mh-index-msg-checksum-map) + mh-index-checksum-origin-map)) + result-table))) + (loop for x being the hash-keys of result-table + collect (cons x (nreverse (gethash x result-table))))))) + +;;;###mh-autoload (defun mh-index-delete-folder-headers () "Delete the folder headers." (let ((cur-msg (mh-get-msg-num nil)) @@ -662,9 +690,28 @@ (when (not folder) (setq folder (car (gethash (gethash msg mh-index-msg-checksum-map) mh-index-checksum-origin-map)))) - (mh-visit-folder - folder (loop for x being the hash-keys of (gethash folder mh-index-data) - when (mh-msg-exists-p x folder) collect x)))) + (when (or (not (get-buffer folder)) + (y-or-n-p (format "Reuse buffer displaying %s? " folder))) + (mh-visit-folder + folder (loop for x being the hash-keys of (gethash folder mh-index-data) + when (mh-msg-exists-p x folder) collect x))))) + +;;;###mh-autoload +(defun mh-index-update-unseen (msg) + "Remove counterpart of MSG in source folder from `mh-unseen-seq'. +Also `mh-update-unseen' is called in the original folder, if we have it open." + (let* ((checksum (gethash msg mh-index-msg-checksum-map)) + (folder-msg-pair (gethash checksum mh-index-checksum-origin-map)) + (orig-folder (car folder-msg-pair)) + (orig-msg (cdr folder-msg-pair))) + (when (mh-index-match-checksum orig-msg orig-folder checksum) + (when (get-buffer orig-folder) + (save-excursion + (set-buffer orig-folder) + (unless (member orig-msg mh-seen-list) (push orig-msg mh-seen-list)) + (mh-update-unseen))) + (mh-exec-cmd-daemon "mark" #'ignore orig-folder (format "%s" orig-msg) + "-sequence" (symbol-name mh-unseen-seq) "-del")))) (defun mh-index-match-checksum (msg folder checksum) "Check if MSG in FOLDER has X-MHE-Checksum header value of CHECKSUM." @@ -918,7 +965,7 @@ (when (or (eobp) (and (bolp) (eolp))) (return nil)) (unless (eq (char-after) ?/) - (return error)) + (return 'error)) (let ((start (point)) end msg-start) (setq end (line-end-position)) @@ -1000,6 +1047,68 @@ +;; Interface to unseen messages script + +(defvar mh-flists-search-folders) + +(defun mh-flists-execute (&rest args) + "Search for unseen messages in `mh-flists-search-folders'. +If `mh-recursive-folders-flag' is t, then the folders are searched +recursively. All parameters ARGS are ignored." + (set-buffer (get-buffer-create mh-index-temp-buffer)) + (erase-buffer) + (unless (executable-find "sh") + (error "Didn't find sh")) + (with-temp-buffer + (let ((unseen (symbol-name mh-unseen-seq))) + (insert "for folder in `flists " + (cond ((eq mh-flists-search-folders t) mh-inbox) + ((eq mh-flists-search-folders nil) "") + ((listp mh-flists-search-folders) + (loop for folder in mh-flists-search-folders + concat (concat " " folder)))) + (if mh-recursive-folders-flag " -recurse" "") + " -sequence " unseen " -noshowzero -fast` ; do\n" + "mhpath \"+$folder\" " unseen "\n" "done\n")) + (call-process-region + (point-min) (point-max) "sh" nil (get-buffer mh-index-temp-buffer)))) + +;;;###mh-autoload +(defun mh-index-new-messages (folders) + "Display new messages. +All messages in the `mh-unseen-seq' sequence from FOLDERS are displayed. +By default the folders specified by `mh-index-new-messages-folders' are +searched. With a prefix argument, enter a space-separated list of folders, or +nothing to search all folders." + (interactive + (list (if current-prefix-arg + (split-string (read-string "Folders to search: ")) + mh-index-new-messages-folders))) + (let* ((mh-flists-search-folders folders) + (mh-indexer 'flists) + (mh-index-execute-search-function 'mh-flists-execute) + (mh-index-next-result-function 'mh-mairix-next-result) + (mh-mairix-folder mh-user-path) + (mh-index-regexp-builder nil) + (new-folder (format "%s/%s" mh-index-folder mh-flists-results-folder)) + (window-config (if (equal new-folder mh-current-folder) + mh-previous-window-config + (current-window-configuration))) + (redo-flag nil)) + (cond ((buffer-live-p (get-buffer new-folder)) + ;; The destination folder is being visited. Trick `mh-index-search' + ;; into thinking that the folder was the result of a previous search. + (set-buffer new-folder) + (setq mh-index-previous-search (list "+" mh-flists-results-folder)) + (setq redo-flag t)) + ((mh-folder-exists-p new-folder) + ;; Folder exists but we don't have it open. That means they are + ;; stale results from a old flists search. Clear it out. + (mh-exec-cmd-quiet nil "rmf" new-folder))) + (mh-index-search redo-flag "+" mh-flists-results-folder window-config t))) + + + ;; Swish interface (defvar mh-swish-binary (executable-find "swish-e")) @@ -1163,7 +1272,7 @@ (defun mh-swish++-regexp-builder (regexp-list) "Generate query for swish++. REGEXP-LIST is an alist of fields and values." - (let ((regexp "") meta) + (let ((regexp "")) (dolist (elem regexp-list) (when (cdr elem) (setq regexp (concat regexp " and " @@ -1264,6 +1373,7 @@ +;;;###mh-autoload (defun mh-index-choose () "Choose an indexing function. The side-effects of this function are that the variables `mh-indexer',