Mercurial > emacs
comparison lisp/mh-e/mh-search.el @ 68192:2cfa649fa39d
* mh-customize.el (mh-index): Rename group to mh-search and sort group
definition and options accordingly.
(mh-index-program): Rename to mh-search-program.
(mh-kill-folder-suppress-prompt-hooks): Rename mh-index-p to
mh-search-p.
(mh-search-mode-hook): Change group from mh-index to mh-search.
(mh-index-folder): Rename to mh-search-folder. Change group from
mh-index to mh-search.
* mh-e.el (mh-folder-font-lock-keywords): Rename mh-index-folder to
mh-search-folder.
* mh-search.el (mh-indexer) Rename to mh-searcher. The commands pick
and grep are searchers too but aren't indexed.
(mh-index-execute-search-function): Rename to mh-search-function.
(mh-index-next-result-function): Rename to
mh-search-next-result-function.
(mh-index-regexp-builder): Rename to mh-search-regexp-builder.
(mh-search): Since redo-search-flag defaults to nil and is of lesser
importance, make it an optional argument and place it after the folder
and search-regexp arguments. Sync docstring with manual.
(mh-search-mode-map): Autoload so that keys are shown in help even
before mh-search is loaded.
(mh-search-mode): Sync docstring with manual.
(mh-index-do-search): Rename argument indexer to searcher. Sync
docstring with manual.
(mh-pick-do-search): Sync docstring with manual.
(mh-index-p): Rename to mh-search-p.
(mh-indexer-choices): Rename to mh-search-choices.
(mh-index-choose): Rename to mh-search-choose. Rename argument indexer
to searcher.
(mh-swish++-execute-search, mh-swish-execute-search)
(mh-mairix-execute-search, mh-namazu-execute-search): Drop "and read
the results" from docstring since these functions don't.
(mh-pick-execute-search, mh-grep-execute-search): Sync docstring with
manual.
(mh-index-generate-pretty-name): Prune -search from string so that
folder names for pick searches are the same as those of other
searches.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Sat, 14 Jan 2006 21:17:37 +0000 |
parents | dcf226991252 |
children | 5012e59a73c7 |
comparison
equal
deleted
inserted
replaced
68191:80bda70f9d68 | 68192:2cfa649fa39d |
---|---|
1 ;;; mh-search -- MH-E search | 1 ;;; mh-search --- MH-E search |
2 | 2 |
3 ;; Copyright (C) 1993, 1995, | 3 ;; Copyright (C) 1993, 1995, |
4 ;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. | 4 ;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. |
5 | 5 |
6 ;; Author: Indexed search by Satyaki Das <satyaki@theforce.stanford.edu> | 6 ;; Author: Indexed search by Satyaki Das <satyaki@theforce.stanford.edu> |
36 ;; grep | 36 ;; grep |
37 ;; | 37 ;; |
38 ;; (2) To use this package, you first have to build an index. Please | 38 ;; (2) To use this package, you first have to build an index. Please |
39 ;; read the documentation for `mh-search' to get started. That | 39 ;; read the documentation for `mh-search' to get started. That |
40 ;; documentation will direct you to the specific instructions for | 40 ;; documentation will direct you to the specific instructions for |
41 ;; your particular indexer. | 41 ;; your particular searcher. |
42 | 42 |
43 ;;; Change Log: | 43 ;;; Change Log: |
44 | 44 |
45 ;;; Code: | 45 ;;; Code: |
46 | 46 |
49 | 49 |
50 (require 'gnus-util) | 50 (require 'gnus-util) |
51 (require 'mh-buffers) | 51 (require 'mh-buffers) |
52 (require 'mh-e) | 52 (require 'mh-e) |
53 | 53 |
54 (defvar mh-indexer nil | 54 (defvar mh-searcher nil |
55 "Cached value of chosen index program.") | 55 "Cached value of chosen search program.") |
56 | 56 |
57 (defvar mh-index-execute-search-function nil | 57 (defvar mh-search-function nil |
58 "Function which executes the search program.") | 58 "Function which executes the search program.") |
59 | 59 |
60 (defvar mh-index-next-result-function nil | 60 (defvar mh-search-next-result-function nil |
61 "Function to parse the next line of output. | 61 "Function to parse the next line of output. |
62 Expected to return a list of three strings: name of the folder, | 62 Expected to return a list of three strings: name of the folder, |
63 message number, and optionally the match.") | 63 message number, and optionally the match.") |
64 | 64 |
65 (defvar mh-index-regexp-builder nil | 65 (defvar mh-search-regexp-builder nil |
66 "Function used to construct search regexp.") | 66 "Function used to construct search regexp.") |
67 | 67 |
68 (defvar mh-index-folder "+mhe-index" | 68 (defvar mh-index-folder "+mhe-index" |
69 "Folder that contains the folders resulting from the index searches.") | 69 "Folder that contains the folders resulting from the index searches.") |
70 | 70 |
78 | 78 |
79 | 79 |
80 ;;; MH-Search mode | 80 ;;; MH-Search mode |
81 | 81 |
82 ;;;###mh-autoload | 82 ;;;###mh-autoload |
83 (defun* mh-search (redo-search-flag folder search-regexp | 83 (defun* mh-search (folder search-regexp |
84 &optional window-config) | 84 &optional redo-search-flag window-config) |
85 "Search your MH mail. | 85 "Search your MH mail. |
86 | 86 |
87 With this command, you can search for messages to or from a | 87 This command helps you find messages in your entire corpus of |
88 particular person or about a particular subject. In fact, you can | 88 mail. You can search for messages to or from a particular person |
89 also search for messages containing selected strings in any | 89 or about a particular subject. In fact, you can also search for |
90 arbitrary header field or any string found within the messages. | 90 messages containing selected strings in any arbitrary header |
91 | 91 field or any string found within the messages. |
92 Use a prefix argument REDO-SEARCH-FLAG to repeat the last search. | 92 |
93 Out of the box, MH-E uses \"pick\" to find messages. With a | |
94 little extra effort, you can set an indexing program which | |
95 rewards you with extremely quick results. The drawback is that | |
96 sometimes the index does not contain the words you're looking | |
97 for. You can still use \"pick\" in these situations. | |
93 | 98 |
94 You are prompted for the FOLDER to search. This can be \"all\" to | 99 You are prompted for the FOLDER to search. This can be \"all\" to |
95 search all folders. For most search methods, the search works | 100 search all folders. Note that the search works recursively on the |
96 recursively on the listed folder. | 101 listed folder. |
97 | 102 |
98 Next, an MH-Search buffer appears where you can enter search | 103 Next, an MH-Search buffer appears where you can enter search |
99 criteria. | 104 criteria SEARCH-REGEXP. |
100 | 105 |
101 From: | 106 From: |
102 To: | 107 To: |
103 Cc: | 108 Cc: |
104 Date: | 109 Date: |
109 appropriate header field that is already there, or create a new | 114 appropriate header field that is already there, or create a new |
110 field yourself. If the string you're looking for could be | 115 field yourself. If the string you're looking for could be |
111 anywhere in a message, then place the string underneath the row | 116 anywhere in a message, then place the string underneath the row |
112 of dashes. | 117 of dashes. |
113 | 118 |
114 It is all right to specify several search criteria. What happens | |
115 then is that a logical _and_ of the various fields is performed. | |
116 If you prefer a logical _or_ operation, run \\[mh-search] | |
117 multiple times. | |
118 | |
119 As an example, let's say that we want to find messages from | 119 As an example, let's say that we want to find messages from |
120 Ginnean about horseback riding in the Kosciusko National | 120 Ginnean about horseback riding in the Kosciusko National |
121 Park (Australia) during January, 1994. Normally we would start | 121 Park (Australia) during January, 1994. Normally we would start |
122 with a broad search and narrow it down if necessary to produce a | 122 with a broad search and narrow it down if necessary to produce a |
123 manageable amount of data, but we'll cut to the chase and create | 123 manageable amount of data, but we'll cut to the chase and create |
124 a fairly restrictive set of criteria as follows: | 124 a fairly restrictive set of criteria as follows:\\<mh-search-mode-map> |
125 | 125 |
126 From: ginnean | 126 From: ginnean |
127 To: | 127 To: |
128 Cc: | 128 Cc: |
129 Date: Jan 1994 | 129 Date: Jan 1994 |
131 -------- | 131 -------- |
132 horse | 132 horse |
133 kosciusko | 133 kosciusko |
134 | 134 |
135 As with MH-Letter mode, MH-Search provides commands like | 135 As with MH-Letter mode, MH-Search provides commands like |
136 \\<mh-search-mode-map>\\[mh-to-field] to help you fill in the | 136 \\[mh-to-field] to help you fill in the blanks.\\<mh-folder-mode-map> |
137 blanks. | |
138 | 137 |
139 If you find that you do the same thing over and over when editing | 138 If you find that you do the same thing over and over when editing |
140 the search template, you may wish to bind some shortcuts to keys. | 139 the search template, you may wish to bind some shortcuts to keys. |
141 This can be done with the variable `mh-search-mode-hook', which is | 140 This can be done with the variable `mh-search-mode-hook', which is |
142 called when \\[mh-search] is run on a new pattern. | 141 called when \\[mh-search] is run on a new pattern.\\<mh-search-mode-map> |
143 | 142 |
144 To perform the search, type \\[mh-index-do-search]. | 143 To perform the search, type \\[mh-index-do-search]. |
145 | 144 |
146 Sometimes you're searching for text that is either not indexed, | 145 Sometimes you're searching for text that is either not indexed, |
147 or hasn't been indexed yet. In this case you can override the | 146 or hasn't been indexed yet. In this case you can override the |
153 buffer is special because it displays messages from multiple | 152 buffer is special because it displays messages from multiple |
154 folders; each set of messages from a given folder has a heading | 153 folders; each set of messages from a given folder has a heading |
155 with the folder name.\\<mh-folder-mode-map> | 154 with the folder name.\\<mh-folder-mode-map> |
156 | 155 |
157 The appearance of the heading can be modified by customizing the | 156 The appearance of the heading can be modified by customizing the |
158 face `mh-index-folder'. You can jump back and forth between the | 157 face `mh-search-folder'. You can jump back and forth between the |
159 headings using the commands \\[mh-index-next-folder] and | 158 headings using the commands \\[mh-index-next-folder] and |
160 \\[mh-index-previous-folder]. | 159 \\[mh-index-previous-folder]. |
161 | 160 |
162 In addition, the command \\[mh-index-visit-folder] can be used to | 161 In addition, the command \\[mh-index-visit-folder] can be used to |
163 visit the folder of the message at point. Initially, only the | 162 visit the folder of the message at point. Initially, only the |
167 folder. Thus, the command \\[mh-index-visit-folder] is useful to | 166 folder. Thus, the command \\[mh-index-visit-folder] is useful to |
168 find the actual message number of an interesting message, or to | 167 find the actual message number of an interesting message, or to |
169 view surrounding messages with the command \\[mh-rescan-folder]. | 168 view surrounding messages with the command \\[mh-rescan-folder]. |
170 | 169 |
171 Because this folder is temporary, you'll probably get in the | 170 Because this folder is temporary, you'll probably get in the |
172 habit of killing it when you're done with | 171 habit of killing it when you're done with \\[mh-kill-folder]. |
173 \\[mh-kill-folder]. | 172 |
174 | 173 You can regenerate the results by running this command with a |
175 SEARCH METHODS | 174 prefix argument REDO-SEARCH-FLAG. |
175 | |
176 Note: This command uses an \"X-MHE-Checksum:\" header field to | |
177 cache the MD5 checksum of a message. This means that if an | |
178 incoming message already contains an \"X-MHE-Checksum:\" field, | |
179 that message might not be found by this command. The following | |
180 \"procmail\" recipe avoids this problem by renaming the existing | |
181 header field: | |
182 | |
183 :0 wf | |
184 | formail -R \"X-MHE-Checksum\" \"X-Old-MHE-Checksum\" | |
185 | |
186 Configuring Indexed Searches | |
176 | 187 |
177 The command \\[mh-search] runs the command defined by the option | 188 The command \\[mh-search] runs the command defined by the option |
178 `mh-index-program'. The default value is \"Auto-detect\" which | 189 `mh-search-program'. The default value is \"Auto-detect\" which |
179 means that MH-E will automatically choose one of \"swish++\", | 190 means that MH-E will automatically choose one of \"swish++\", |
180 \"swish-e\", \"mairix\", \"namazu\", \"pick\" and \"grep\" in | 191 \"swish-e\", \"mairix\", \"namazu\", \"pick\" and \"grep\" in |
181 that order. If, for example, you have both \"swish++\" and | 192 that order. If, for example, you have both \"swish++\" and |
182 \"mairix\" installed and you want to use \"mairix\", then you can | 193 \"mairix\" installed and you want to use \"mairix\", then you can |
183 set this option to \"mairix\". | 194 set this option to \"mairix\". |
184 | 195 |
185 *NOTE* | |
186 | |
187 The \"pick\" and \"grep\" commands do not perform a | |
188 recursive search on the given folder. | |
189 | |
190 This command uses an \"X-MHE-Checksum:\" header field to cache | |
191 the MD5 checksum of a message. This means that if an incoming | |
192 message already contains an \"X-MHE-Checksum:\" field, that | |
193 message might not be found by this command. The following | |
194 \"procmail\" recipe avoids this problem by renaming the existing | |
195 header field: | |
196 | |
197 :0 wf | |
198 | formail -R \"X-MHE-Checksum\" \"X-Old-MHE-Checksum\" | |
199 | |
200 The documentation for the following commands describe how to set | 196 The documentation for the following commands describe how to set |
201 up the various indexing programs to use with MH-E. The \"pick\" | 197 up the various indexing programs to use with MH-E. |
202 and \"grep\" commands do not require additional configuration. | |
203 | 198 |
204 - `mh-swish++-execute-search' | 199 - `mh-swish++-execute-search' |
205 - `mh-swish-execute-search' | 200 - `mh-swish-execute-search' |
206 - `mh-mairix-execute-search' | 201 - `mh-mairix-execute-search' |
207 - `mh-namazu-execute-search' | 202 - `mh-namazu-execute-search' |
208 - `mh-pick-execute-search' | 203 - `mh-pick-execute-search' |
209 - `mh-grep-execute-search' | 204 - `mh-grep-execute-search' |
210 | 205 |
211 In a program, the folder is searched with SEARCH-REGEXP. If | 206 In a program, if FOLDER is \"+\" or nil, then mail in all folders |
212 FOLDER is \"+\" then mail in all folders are searched. Optional | 207 are searched. Optional argument WINDOW-CONFIG stores the window |
213 argument WINDOW-CONFIG stores the window configuration that will | 208 configuration that will be restored after the user quits the |
214 be restored after the user quits the folder containing the index | 209 folder containing the index search results." |
215 search results." | |
216 (interactive | 210 (interactive |
217 (list current-prefix-arg | 211 (list (progn |
218 (progn | |
219 (mh-find-path) | 212 (mh-find-path) |
220 ;; Yes, we do want to call mh-index-choose every time in case the | 213 ;; Yes, we do want to call mh-search-choose every time in case the |
221 ;; user has switched the indexer manually. | 214 ;; user has switched the searcher manually. |
222 (unless (mh-index-choose (and current-prefix-arg | 215 (unless (mh-search-choose (and current-prefix-arg |
223 mh-index-previous-search | 216 mh-index-previous-search |
224 (cadr mh-index-previous-search))) | 217 (cadr mh-index-previous-search))) |
225 (error "No indexing program found")) | 218 (error "No search program found")) |
226 (or (and current-prefix-arg mh-index-sequence-search-flag) | 219 (or (and current-prefix-arg mh-index-sequence-search-flag) |
227 (and current-prefix-arg (car mh-index-previous-search)) | 220 (and current-prefix-arg (car mh-index-previous-search)) |
228 (mh-prompt-for-folder "Search" "+" nil "all" t))) | 221 (mh-prompt-for-folder "Search" "+" nil "all" t))) |
229 (or (and current-prefix-arg (caddr mh-index-previous-search)) | 222 (or (and current-prefix-arg (caddr mh-index-previous-search)) |
230 mh-index-regexp-builder | 223 mh-search-regexp-builder |
231 (read-string (format "%s regexp: " | 224 (read-string (format "%s regexp: " |
232 (upcase-initials (symbol-name mh-indexer))))) | 225 (upcase-initials (symbol-name mh-searcher))))) |
226 current-prefix-arg | |
233 (if (and (not (and current-prefix-arg | 227 (if (and (not (and current-prefix-arg |
234 (caddr mh-index-previous-search))) | 228 (caddr mh-index-previous-search))) |
235 mh-index-regexp-builder) | 229 mh-search-regexp-builder) |
236 (current-window-configuration) | 230 (current-window-configuration) |
237 nil))) | 231 nil))) |
238 ;; Redoing a sequence search? | 232 ;; Redoing a sequence search? |
239 (when (and redo-search-flag mh-index-data mh-index-sequence-search-flag | 233 (when (and redo-search-flag mh-index-data mh-index-sequence-search-flag |
240 (not mh-flists-called-flag)) | 234 (not mh-flists-called-flag)) |
263 | 257 |
264 (let ((folder-path (format "%s%s" mh-user-path (substring folder 1))) | 258 (let ((folder-path (format "%s%s" mh-user-path (substring folder 1))) |
265 (folder-results-map (make-hash-table :test #'equal)) | 259 (folder-results-map (make-hash-table :test #'equal)) |
266 (origin-map (make-hash-table :test #'equal))) | 260 (origin-map (make-hash-table :test #'equal))) |
267 ;; Run search program... | 261 ;; Run search program... |
268 (message "Executing %s... " mh-indexer) | 262 (message "Executing %s... " mh-searcher) |
269 (funcall mh-index-execute-search-function folder-path search-regexp) | 263 (funcall mh-search-function folder-path search-regexp) |
270 | 264 |
271 ;; Parse indexer output. | 265 ;; Parse searcher output. |
272 (message "Processing %s output... " mh-indexer) | 266 (message "Processing %s output... " mh-searcher) |
273 (goto-char (point-min)) | 267 (goto-char (point-min)) |
274 (loop for next-result = (funcall mh-index-next-result-function) | 268 (loop for next-result = (funcall mh-search-next-result-function) |
275 while next-result | 269 while next-result |
276 do (unless (eq next-result 'error) | 270 do (unless (eq next-result 'error) |
277 (unless (gethash (car next-result) folder-results-map) | 271 (unless (gethash (car next-result) folder-results-map) |
278 (setf (gethash (car next-result) folder-results-map) | 272 (setf (gethash (car next-result) folder-results-map) |
279 (make-hash-table :test #'equal))) | 273 (make-hash-table :test #'equal))) |
312 (mh-speed-flists t mh-current-folder)) | 306 (mh-speed-flists t mh-current-folder)) |
313 | 307 |
314 ;; Maintain history. | 308 ;; Maintain history. |
315 (when (or (and redo-search-flag previous-search) window-config) | 309 (when (or (and redo-search-flag previous-search) window-config) |
316 (setq mh-previous-window-config old-window-config)) | 310 (setq mh-previous-window-config old-window-config)) |
317 (setq mh-index-previous-search (list folder mh-indexer search-regexp)) | 311 (setq mh-index-previous-search (list folder mh-searcher search-regexp)) |
318 | 312 |
319 ;; Write out data to disk. | 313 ;; Write out data to disk. |
320 (unless mh-flists-called-flag (mh-index-write-data)) | 314 (unless mh-flists-called-flag (mh-index-write-data)) |
321 | 315 |
322 (message "%s found %s matches in %s folders" | 316 (message "%s found %s matches in %s folders" |
323 (upcase-initials (symbol-name mh-indexer)) | 317 (upcase-initials (symbol-name mh-searcher)) |
324 (loop for msg-hash being hash-values of mh-index-data | 318 (loop for msg-hash being hash-values of mh-index-data |
325 sum (hash-table-count msg-hash)) | 319 sum (hash-table-count msg-hash)) |
326 (loop for msg-hash being hash-values of mh-index-data | 320 (loop for msg-hash being hash-values of mh-index-data |
327 count (> (hash-table-count msg-hash) 0)))))) | 321 count (> (hash-table-count msg-hash) 0)))))) |
328 | 322 |
365 (forward-line)) | 359 (forward-line)) |
366 (add-text-properties (point) (1+ (point)) '(front-sticky t)) | 360 (add-text-properties (point) (1+ (point)) '(front-sticky t)) |
367 (add-text-properties (point) (1- (line-end-position)) '(read-only t)) | 361 (add-text-properties (point) (1- (line-end-position)) '(read-only t)) |
368 (goto-char (point-max))) | 362 (goto-char (point-max))) |
369 | 363 |
364 ;;;###mh-autoload | |
370 (defvar mh-search-mode-map (make-sparse-keymap) | 365 (defvar mh-search-mode-map (make-sparse-keymap) |
371 "Keymap for searching folder.") | 366 "Keymap for searching folder.") |
372 | 367 |
368 ;;;###mh-autoload | |
373 ;; If this changes, modify mh-search-mode-help-messages accordingly, below. | 369 ;; If this changes, modify mh-search-mode-help-messages accordingly, below. |
374 (gnus-define-keys mh-search-mode-map | 370 (gnus-define-keys mh-search-mode-map |
375 "\C-c?" mh-help | 371 "\C-c?" mh-help |
376 "\C-c\C-c" mh-index-do-search | 372 "\C-c\C-c" mh-index-do-search |
377 "\C-c\C-p" mh-pick-do-search | 373 "\C-c\C-p" mh-pick-do-search |
418 (put 'mh-search-mode 'mode-class 'special) | 414 (put 'mh-search-mode 'mode-class 'special) |
419 | 415 |
420 (define-derived-mode mh-search-mode fundamental-mode "MH-Search" | 416 (define-derived-mode mh-search-mode fundamental-mode "MH-Search" |
421 "Mode for creating search templates in MH-E.\\<mh-search-mode-map> | 417 "Mode for creating search templates in MH-E.\\<mh-search-mode-map> |
422 | 418 |
423 After each field name, enter the pattern to search for. If a field's | 419 Edit this template by entering your search criteria in an |
424 value does not matter for the search, leave it empty. To search the | 420 appropriate header field that is already there, or create a new |
425 entire message, supply the pattern in the \"body\" of the template. | 421 field yourself. If the string you're looking for could be |
426 Each non-empty field must be matched for a message to be selected. To | 422 anywhere in a message, then place the string underneath the row |
427 effect a logical \"or\", use \\[mh-search-folder] multiple times. When | 423 of dashes. |
428 you have finished, type \\[mh-pick-do-search] to do the search. | 424 |
425 To perform the search, type \\[mh-index-do-search]. | |
426 | |
427 Sometimes you're searching for text that is either not indexed, | |
428 or hasn't been indexed yet. In this case you can override the | |
429 default method with the pick method by running the command | |
430 \\[mh-pick-do-search]. | |
429 | 431 |
430 The hook `mh-search-mode-hook' is called upon entry to this mode. | 432 The hook `mh-search-mode-hook' is called upon entry to this mode. |
431 | 433 |
432 \\{mh-search-mode-map}" | 434 \\{mh-search-mode-map}" |
433 | 435 |
434 (make-local-variable 'mh-help-messages) | 436 (make-local-variable 'mh-help-messages) |
435 (easy-menu-add mh-pick-menu) | 437 (easy-menu-add mh-pick-menu) |
436 (setq mh-help-messages mh-search-mode-help-messages)) | 438 (setq mh-help-messages mh-search-mode-help-messages)) |
437 | 439 |
438 ;;;###mh-autoload | 440 ;;;###mh-autoload |
439 (defun mh-index-do-search (&optional indexer) | 441 (defun mh-index-do-search (&optional searcher) |
440 "Find messages that match the qualifications in the current pattern buffer. | 442 "Find messages using `mh-search-program'. |
441 If optional argument INDEXER is present, use it instead of | 443 If optional argument SEARCHER is present, use it instead of |
442 `mh-index-program'." | 444 `mh-search-program'." |
443 (interactive) | 445 (interactive) |
444 (unless (mh-index-choose indexer) (error "No indexing program found")) | 446 (unless (mh-search-choose searcher) (error "No search program found")) |
445 (let* ((regexp-list (mh-pick-parse-search-buffer)) | 447 (let* ((regexp-list (mh-pick-parse-search-buffer)) |
446 (pattern (funcall mh-index-regexp-builder regexp-list))) | 448 (pattern (funcall mh-search-regexp-builder regexp-list))) |
447 (if pattern | 449 (if pattern |
448 (mh-search nil mh-current-folder pattern mh-previous-window-config) | 450 (mh-search mh-current-folder pattern nil mh-previous-window-config) |
449 (error "No search terms")))) | 451 (error "No search terms")))) |
450 | 452 |
451 ;;;###mh-autoload | 453 ;;;###mh-autoload |
452 (defun mh-pick-do-search () | 454 (defun mh-pick-do-search () |
453 "Find messages that match the qualifications in the current pattern buffer. | 455 "Find messages using \"pick\". |
454 | 456 |
455 Uses the pick method described in `mh-pick-execute-search'." | 457 Uses the pick method described in `mh-pick-execute-search'." |
456 (interactive) | 458 (interactive) |
457 (mh-index-do-search 'pick)) | 459 (mh-index-do-search 'pick)) |
458 | 460 |
640 (mh-read-seq-default "Search" nil))) | 642 (mh-read-seq-default "Search" nil))) |
641 (unless sequence (setq sequence mh-unseen-seq)) | 643 (unless sequence (setq sequence mh-unseen-seq)) |
642 (let* ((mh-flists-search-folders folders) | 644 (let* ((mh-flists-search-folders folders) |
643 (mh-flists-sequence sequence) | 645 (mh-flists-sequence sequence) |
644 (mh-flists-called-flag t) | 646 (mh-flists-called-flag t) |
645 (mh-indexer 'flists) | 647 (mh-searcher 'flists) |
646 (mh-index-execute-search-function 'mh-flists-execute) | 648 (mh-search-function 'mh-flists-execute) |
647 (mh-index-next-result-function 'mh-mairix-next-result) | 649 (mh-search-next-result-function 'mh-mairix-next-result) |
648 (mh-mairix-folder mh-user-path) | 650 (mh-mairix-folder mh-user-path) |
649 (mh-index-regexp-builder nil) | 651 (mh-search-regexp-builder nil) |
650 (new-folder (format "%s/%s/%s" mh-index-folder | 652 (new-folder (format "%s/%s/%s" mh-index-folder |
651 mh-flists-results-folder sequence)) | 653 mh-flists-results-folder sequence)) |
652 (window-config (if (equal new-folder mh-current-folder) | 654 (window-config (if (equal new-folder mh-current-folder) |
653 mh-previous-window-config | 655 mh-previous-window-config |
654 (current-window-configuration))) | 656 (current-window-configuration))) |
656 message) | 658 message) |
657 (cond ((buffer-live-p (get-buffer new-folder)) | 659 (cond ((buffer-live-p (get-buffer new-folder)) |
658 ;; The destination folder is being visited. Trick `mh-search' | 660 ;; The destination folder is being visited. Trick `mh-search' |
659 ;; into thinking that the folder resulted from a previous search. | 661 ;; into thinking that the folder resulted from a previous search. |
660 (set-buffer new-folder) | 662 (set-buffer new-folder) |
661 (setq mh-index-previous-search (list folders mh-indexer sequence)) | 663 (setq mh-index-previous-search (list folders mh-searcher sequence)) |
662 (setq redo-flag t)) | 664 (setq redo-flag t)) |
663 ((mh-folder-exists-p new-folder) | 665 ((mh-folder-exists-p new-folder) |
664 ;; Folder exists but we don't have it open. That means they are | 666 ;; Folder exists but we don't have it open. That means they are |
665 ;; stale results from a old flists search. Clear it out. | 667 ;; stale results from a old flists search. Clear it out. |
666 (mh-exec-cmd-quiet nil "rmf" new-folder))) | 668 (mh-exec-cmd-quiet nil "rmf" new-folder))) |
667 (setq message (mh-search redo-flag "+" mh-flists-results-folder | 669 (setq message (mh-search "+" mh-flists-results-folder |
668 window-config) | 670 redo-flag window-config) |
669 mh-index-sequence-search-flag t | 671 mh-index-sequence-search-flag t |
670 mh-index-previous-search (list folders mh-indexer sequence)) | 672 mh-index-previous-search (list folders mh-searcher sequence)) |
671 (mh-index-write-data) | 673 (mh-index-write-data) |
672 (when (stringp message) (message "%s" message)))) | 674 (when (stringp message) (message "%s" message)))) |
673 | 675 |
674 (defvar mh-flists-search-folders) | 676 (defvar mh-flists-search-folders) |
675 | 677 |
829 (mh-visit-folder | 831 (mh-visit-folder |
830 folder (loop for x being the hash-keys of (gethash folder mh-index-data) | 832 folder (loop for x being the hash-keys of (gethash folder mh-index-data) |
831 when (mh-msg-exists-p x folder) collect x))))) | 833 when (mh-msg-exists-p x folder) collect x))))) |
832 | 834 |
833 ;;;###mh-autoload | 835 ;;;###mh-autoload |
834 (defun mh-index-p () | 836 (defun mh-search-p () |
835 "Non-nil means that this folder was generated by an index search." | 837 "Non-nil means that this folder was generated by searching." |
836 mh-index-data) | 838 mh-index-data) |
837 | 839 |
838 ;;;###mh-autoload | 840 ;;;###mh-autoload |
839 (defun mh-index-execute-commands () | 841 (defun mh-index-execute-commands () |
840 "Delete/refile the actual messages. | 842 "Delete/refile the actual messages. |
879 | 881 |
880 | 882 |
881 | 883 |
882 ;;; Indexing functions | 884 ;;; Indexing functions |
883 | 885 |
884 ;; Support different indexing programs | 886 ;; Support different search programs |
885 (defvar mh-indexer-choices | 887 (defvar mh-search-choices |
886 '((swish++ | 888 '((swish++ |
887 mh-swish++-binary mh-swish++-execute-search mh-swish++-next-result | 889 mh-swish++-binary mh-swish++-execute-search mh-swish++-next-result |
888 mh-swish++-regexp-builder) | 890 mh-swish++-regexp-builder) |
889 (swish | 891 (swish |
890 mh-swish-binary mh-swish-execute-search mh-swish-next-result nil) | 892 mh-swish-binary mh-swish-execute-search mh-swish-next-result nil) |
896 (pick | 898 (pick |
897 mh-pick-binary mh-pick-execute-search mh-pick-next-result | 899 mh-pick-binary mh-pick-execute-search mh-pick-next-result |
898 mh-pick-regexp-builder) | 900 mh-pick-regexp-builder) |
899 (grep | 901 (grep |
900 mh-grep-binary mh-grep-execute-search mh-grep-next-result nil)) | 902 mh-grep-binary mh-grep-execute-search mh-grep-next-result nil)) |
901 "List of possible indexer choices.") | 903 "List of possible searcher choices.") |
902 | 904 |
903 (defun mh-index-choose (&optional indexer) | 905 (defun mh-search-choose (&optional searcher) |
904 "Choose an indexing function. | 906 "Choose a searching function. |
905 The side-effects of this function are that the variables | 907 The side-effects of this function are that the variables |
906 `mh-indexer', `mh-index-execute-search-function', and | 908 `mh-searcher', `mh-search-function', and |
907 `mh-index-next-result-function' are set according to the first | 909 `mh-search-next-result-function' are set according to the first |
908 indexer in `mh-indexer-choices' present on the system. | 910 searcher in `mh-search-choices' present on the system. If |
909 If optional argument INDEXER is present, use it instead of | 911 optional argument SEARCHER is present, use it instead of |
910 `mh-index-program'." | 912 `mh-search-program'." |
911 (block nil | 913 (block nil |
912 (let ((program-alist (cond (indexer | 914 (let ((program-alist (cond (searcher |
913 (list (assoc indexer mh-indexer-choices))) | 915 (list (assoc searcher mh-search-choices))) |
914 (mh-index-program | 916 (mh-search-program |
915 (list | 917 (list |
916 (assoc mh-index-program mh-indexer-choices))) | 918 (assoc mh-search-program mh-search-choices))) |
917 (t mh-indexer-choices)))) | 919 (t mh-search-choices)))) |
918 (while program-alist | 920 (while program-alist |
919 (let* ((current (pop program-alist)) | 921 (let* ((current (pop program-alist)) |
920 (executable (symbol-value (cadr current)))) | 922 (executable (symbol-value (cadr current)))) |
921 (when executable | 923 (when executable |
922 (setq mh-indexer (car current)) | 924 (setq mh-searcher (car current)) |
923 (setq mh-index-execute-search-function (nth 2 current)) | 925 (setq mh-search-function (nth 2 current)) |
924 (setq mh-index-next-result-function (nth 3 current)) | 926 (setq mh-search-next-result-function (nth 3 current)) |
925 (setq mh-index-regexp-builder (nth 4 current)) | 927 (setq mh-search-regexp-builder (nth 4 current)) |
926 (return mh-indexer)))) | 928 (return mh-searcher)))) |
927 nil))) | 929 nil))) |
928 | 930 |
929 ;;; Swish++ interface | 931 ;;; Swish++ interface |
930 | 932 |
931 (defvar mh-swish++-binary (or (executable-find "search++") | 933 (defvar mh-swish++-binary (or (executable-find "search++") |
933 (defvar mh-swish++-directory ".swish++") | 935 (defvar mh-swish++-directory ".swish++") |
934 (defvar mh-swish-folder nil) | 936 (defvar mh-swish-folder nil) |
935 | 937 |
936 ;;;###mh-autoload | 938 ;;;###mh-autoload |
937 (defun mh-swish++-execute-search (folder-path search-regexp) | 939 (defun mh-swish++-execute-search (folder-path search-regexp) |
938 "Execute swish++ and read the results. | 940 "Execute swish++. |
939 | 941 |
940 In the examples below, replace \"/home/user/Mail\" with the path to | 942 In the examples below, replace \"/home/user/Mail\" with the path to |
941 your MH directory. | 943 your MH directory. |
942 | 944 |
943 First create the directory \"/home/user/Mail/.swish++\". Then create | 945 First create the directory \"/home/user/Mail/.swish++\". Then create |
1013 (defvar mh-swish-binary (executable-find "swish-e")) | 1015 (defvar mh-swish-binary (executable-find "swish-e")) |
1014 (defvar mh-swish-directory ".swish") | 1016 (defvar mh-swish-directory ".swish") |
1015 | 1017 |
1016 ;;;###mh-autoload | 1018 ;;;###mh-autoload |
1017 (defun mh-swish-execute-search (folder-path search-regexp) | 1019 (defun mh-swish-execute-search (folder-path search-regexp) |
1018 "Execute swish-e and read the results. | 1020 "Execute swish-e. |
1019 | 1021 |
1020 In the examples below, replace \"/home/user/Mail\" with the path | 1022 In the examples below, replace \"/home/user/Mail\" with the path |
1021 to your MH directory. | 1023 to your MH directory. |
1022 | 1024 |
1023 First create the directory \"/home/user/Mail/.swish\". Then | 1025 First create the directory \"/home/user/Mail/.swish\". Then |
1114 (defvar mh-mairix-directory ".mairix") | 1116 (defvar mh-mairix-directory ".mairix") |
1115 (defvar mh-mairix-folder nil) | 1117 (defvar mh-mairix-folder nil) |
1116 | 1118 |
1117 ;;;###mh-autoload | 1119 ;;;###mh-autoload |
1118 (defun mh-mairix-execute-search (folder-path search-regexp-list) | 1120 (defun mh-mairix-execute-search (folder-path search-regexp-list) |
1119 "Execute mairix and read the results. | 1121 "Execute mairix. |
1120 | 1122 |
1121 In the examples below, replace \"/home/user/Mail\" with the path | 1123 In the examples below, replace \"/home/user/Mail\" with the path |
1122 to your MH directory. | 1124 to your MH directory. |
1123 | 1125 |
1124 First create the directory \"/home/user/Mail/.mairix\". Then | 1126 First create the directory \"/home/user/Mail/.mairix\". Then |
1248 (defvar mh-namazu-directory ".namazu") | 1250 (defvar mh-namazu-directory ".namazu") |
1249 (defvar mh-namazu-folder nil) | 1251 (defvar mh-namazu-folder nil) |
1250 | 1252 |
1251 ;;;###mh-autoload | 1253 ;;;###mh-autoload |
1252 (defun mh-namazu-execute-search (folder-path search-regexp) | 1254 (defun mh-namazu-execute-search (folder-path search-regexp) |
1253 "Execute namazu and read the results. | 1255 "Execute namazu. |
1254 | 1256 |
1255 In the examples below, replace \"/home/user/Mail\" with the path to | 1257 In the examples below, replace \"/home/user/Mail\" with the path to |
1256 your MH directory. | 1258 your MH directory. |
1257 | 1259 |
1258 First create the directory \"/home/user/Mail/.namazu\". Then create | 1260 First create the directory \"/home/user/Mail/.namazu\". Then create |
1326 | 1328 |
1327 ;;;###mh-autoload | 1329 ;;;###mh-autoload |
1328 (defun mh-pick-execute-search (folder-path search-regexp) | 1330 (defun mh-pick-execute-search (folder-path search-regexp) |
1329 "Execute pick. | 1331 "Execute pick. |
1330 | 1332 |
1331 There are no semantics associated with the search criteria--they | 1333 Read \"pick(1)\" or the section Finding Messages with pick in the |
1332 are simply treated as strings. Case is ignored when all lowercase | 1334 MH book to find out more about how to enter the criteria (see URL |
1333 is used, and regular expressions (a la \"ed\") are available. | 1335 `http://www.ics.uci.edu/~mh/book/mh/finpic.htm'). |
1334 | 1336 |
1335 In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP | 1337 In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP |
1336 is used to search." | 1338 is used to search." |
1337 (set-buffer (get-buffer-create mh-temp-index-buffer)) | 1339 (set-buffer (get-buffer-create mh-temp-index-buffer)) |
1338 (erase-buffer) | 1340 (erase-buffer) |
1412 | 1414 |
1413 (defvar mh-grep-binary (executable-find "grep")) | 1415 (defvar mh-grep-binary (executable-find "grep")) |
1414 | 1416 |
1415 ;;;###mh-autoload | 1417 ;;;###mh-autoload |
1416 (defun mh-grep-execute-search (folder-path search-regexp) | 1418 (defun mh-grep-execute-search (folder-path search-regexp) |
1417 "Execute grep and read the results. | 1419 "Execute grep. |
1420 | |
1421 Unlike the other search methods, this method does not use the | |
1422 MH-Search buffer. Instead, you simply enter a regular expression | |
1423 in the minibuffer. For help in constructing regular expressions, | |
1424 see your man page for \"grep\". | |
1418 | 1425 |
1419 In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP | 1426 In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP |
1420 is used to search." | 1427 is used to search." |
1421 (set-buffer (get-buffer-create mh-temp-index-buffer)) | 1428 (set-buffer (get-buffer-create mh-temp-index-buffer)) |
1422 (erase-buffer) | 1429 (erase-buffer) |
1475 (when (car string) (insert (car string))) | 1482 (when (car string) (insert (car string))) |
1476 (dolist (s (cdr string)) | 1483 (dolist (s (cdr string)) |
1477 (insert "_" s))) | 1484 (insert "_" s))) |
1478 (setq string (mh-replace-string "-lbrace" " ")) | 1485 (setq string (mh-replace-string "-lbrace" " ")) |
1479 (setq string (mh-replace-string "-rbrace" " ")) | 1486 (setq string (mh-replace-string "-rbrace" " ")) |
1487 (setq string (mh-replace-string "-search" " ")) | |
1480 (subst-char-in-region (point-min) (point-max) ?( ? t) | 1488 (subst-char-in-region (point-min) (point-max) ?( ? t) |
1481 (subst-char-in-region (point-min) (point-max) ?) ? t) | 1489 (subst-char-in-region (point-min) (point-max) ?) ? t) |
1482 (subst-char-in-region (point-min) (point-max) ?- ? t) | 1490 (subst-char-in-region (point-min) (point-max) ?- ? t) |
1483 (goto-char (point-min)) | 1491 (goto-char (point-min)) |
1484 (while (and (not (eobp)) (memq (char-after) '(? ?\t ?\n ?\r ?_))) | 1492 (while (and (not (eobp)) (memq (char-after) '(? ?\t ?\n ?\r ?_))) |
1490 (subst-char-in-region (point-min) (point-max) ?\t ?_ t) | 1498 (subst-char-in-region (point-min) (point-max) ?\t ?_ t) |
1491 (subst-char-in-region (point-min) (point-max) ?\n ?_ t) | 1499 (subst-char-in-region (point-min) (point-max) ?\n ?_ t) |
1492 (subst-char-in-region (point-min) (point-max) ?\r ?_ t) | 1500 (subst-char-in-region (point-min) (point-max) ?\r ?_ t) |
1493 (subst-char-in-region (point-min) (point-max) ?/ ?$ t) | 1501 (subst-char-in-region (point-min) (point-max) ?/ ?$ t) |
1494 (let ((out (truncate-string-to-width (buffer-string) 20))) | 1502 (let ((out (truncate-string-to-width (buffer-string) 20))) |
1495 (cond ((eq mh-indexer 'flists) | 1503 (cond ((eq mh-searcher 'flists) |
1496 (format "%s/%s" mh-flists-results-folder mh-flists-sequence)) | 1504 (format "%s/%s" mh-flists-results-folder mh-flists-sequence)) |
1497 ((equal out mh-flists-results-folder) (concat out "1")) | 1505 ((equal out mh-flists-results-folder) (concat out "1")) |
1498 (t out))))) | 1506 (t out))))) |
1499 | 1507 |
1500 (defun mh-folder-exists-p (folder) | 1508 (defun mh-folder-exists-p (folder) |