6365
|
1 ;;; mh-seq --- mh-e sequences support
|
13387
|
2 ;; Time-stamp: <95/08/19 16:45:15 gildea>
|
6365
|
3
|
11332
|
4 ;; Copyright (C) 1993, 1995 Free Software Foundation, Inc.
|
6365
|
5
|
13387
|
6 ;; This file is part of mh-e, part of GNU Emacs.
|
6365
|
7
|
11333
|
8 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
6365
|
9 ;; it under the terms of the GNU General Public License as published by
|
|
10 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
11 ;; any later version.
|
|
12
|
11333
|
13 ;; GNU Emacs is distributed in the hope that it will be useful,
|
6365
|
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 ;; GNU General Public License for more details.
|
|
17
|
|
18 ;; You should have received a copy of the GNU General Public License
|
11333
|
19 ;; along with GNU Emacs; see the file COPYING. If not, write to
|
6365
|
20 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
21
|
|
22 ;;; Commentary:
|
|
23
|
|
24 ;; Internal support for mh-e package.
|
|
25
|
11332
|
26 ;;; Change Log:
|
|
27
|
13387
|
28 ;; $Id: mh-seq.el,v 1.3 1995/04/10 00:19:48 kwzh Exp kwzh $
|
11332
|
29
|
6365
|
30 ;;; Code:
|
|
31
|
|
32 (provide 'mh-seq)
|
|
33 (require 'mh-e)
|
|
34
|
11332
|
35 ;;; Internal variables:
|
|
36
|
|
37 (defvar mh-last-seq-used nil) ;Name of seq to which a msg was last added.
|
|
38
|
|
39 (defvar mh-non-seq-mode-line-annotation nil) ;Saved value of mh-mode-line-annotation when narrowed to a seq.
|
6365
|
40
|
|
41
|
11332
|
42 (defun mh-delete-seq (sequence)
|
6365
|
43 "Delete the SEQUENCE."
|
|
44 (interactive (list (mh-read-seq-default "Delete" t)))
|
11332
|
45 (mh-map-to-seq-msgs 'mh-notate-if-in-one-seq sequence ? (1+ mh-cmd-note)
|
|
46 sequence)
|
|
47 (mh-undefine-sequence sequence '("all"))
|
|
48 (mh-delete-seq-locally sequence))
|
6365
|
49
|
|
50
|
|
51 (defun mh-list-sequences (folder)
|
|
52 "List the sequences defined in FOLDER."
|
|
53 (interactive (list (mh-prompt-for-folder "List sequences in"
|
|
54 mh-current-folder t)))
|
11332
|
55 (let ((temp-buffer mh-temp-buffer)
|
6365
|
56 (seq-list mh-seq-list))
|
|
57 (with-output-to-temp-buffer temp-buffer
|
|
58 (save-excursion
|
|
59 (set-buffer temp-buffer)
|
|
60 (erase-buffer)
|
|
61 (message "Listing sequences ...")
|
|
62 (insert "Sequences in folder " folder ":\n")
|
|
63 (while seq-list
|
|
64 (let ((name (mh-seq-name (car seq-list)))
|
|
65 (sorted-seq-msgs
|
|
66 (sort (copy-sequence (mh-seq-msgs (car seq-list))) '<))
|
|
67 (last-col (- (window-width) 4))
|
|
68 name-spec)
|
|
69 (insert (setq name-spec (format "%20s:" name)))
|
|
70 (while sorted-seq-msgs
|
|
71 (if (> (current-column) last-col)
|
|
72 (progn
|
|
73 (insert "\n")
|
|
74 (move-to-column (length name-spec))))
|
|
75 (insert (format " %s" (car sorted-seq-msgs)))
|
|
76 (setq sorted-seq-msgs (cdr sorted-seq-msgs)))
|
|
77 (insert "\n"))
|
|
78 (setq seq-list (cdr seq-list)))
|
|
79 (goto-char (point-min))
|
|
80 (message "Listing sequences...done")))))
|
|
81
|
|
82
|
11332
|
83 (defun mh-msg-is-in-seq (message)
|
|
84 "Display the sequences that contain MESSAGE (default: current message)."
|
6365
|
85 (interactive (list (mh-get-msg-num t)))
|
|
86 (message "Message %d is in sequences: %s"
|
11332
|
87 message
|
6365
|
88 (mapconcat 'concat
|
11332
|
89 (mh-list-to-string (mh-seq-containing-msg message t))
|
6365
|
90 " ")))
|
|
91
|
|
92
|
11332
|
93 (defun mh-narrow-to-seq (sequence)
|
|
94 "Restrict display of this folder to just messages in SEQUENCE.
|
|
95 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
|
6365
|
96 (interactive (list (mh-read-seq "Narrow to" t)))
|
11332
|
97 (with-mh-folder-updating (t)
|
|
98 (cond ((mh-seq-to-msgs sequence)
|
|
99 (mh-widen)
|
|
100 (let ((eob (point-max)))
|
|
101 (mh-copy-seq-to-point sequence eob)
|
6365
|
102 (narrow-to-region eob (point-max))
|
11332
|
103 (make-variable-buffer-local 'mh-non-seq-mode-line-annotation)
|
|
104 (setq mh-non-seq-mode-line-annotation mh-mode-line-annotation)
|
|
105 (setq mh-mode-line-annotation (symbol-name sequence))
|
|
106 (mh-make-folder-mode-line)
|
6365
|
107 (mh-recenter nil)
|
11332
|
108 (setq mh-narrowed-to-seq sequence)))
|
|
109 (t
|
|
110 (error "No messages in sequence `%s'" (symbol-name sequence))))))
|
6365
|
111
|
|
112
|
11332
|
113 (defun mh-put-msg-in-seq (msg-or-seq sequence)
|
6365
|
114 "Add MESSAGE(s) (default: displayed message) to SEQUENCE.
|
|
115 If optional prefix argument provided, then prompt for the message sequence."
|
|
116 (interactive (list (if current-prefix-arg
|
|
117 (mh-read-seq-default "Add messages from" t)
|
|
118 (mh-get-msg-num t))
|
|
119 (mh-read-seq-default "Add to" nil)))
|
11332
|
120 (if (not (mh-internal-seq sequence))
|
|
121 (setq mh-last-seq-used sequence))
|
6365
|
122 (mh-add-msgs-to-seq (if (numberp msg-or-seq)
|
|
123 msg-or-seq
|
|
124 (mh-seq-to-msgs msg-or-seq))
|
11332
|
125 sequence))
|
6365
|
126
|
|
127
|
|
128 (defun mh-widen ()
|
|
129 "Remove restrictions from current folder, thereby showing all messages."
|
|
130 (interactive)
|
|
131 (if mh-narrowed-to-seq
|
|
132 (with-mh-folder-updating (t)
|
|
133 (delete-region (point-min) (point-max))
|
|
134 (widen)
|
11332
|
135 (setq mh-mode-line-annotation mh-non-seq-mode-line-annotation)
|
6365
|
136 (mh-make-folder-mode-line)))
|
|
137 (setq mh-narrowed-to-seq nil))
|
|
138
|
|
139
|
|
140
|
|
141 ;;; Commands to manipulate sequences. Sequences are stored in an alist
|
|
142 ;;; of the form:
|
|
143 ;;; ((seq-name msgs ...) (seq-name msgs ...) ...)
|
|
144
|
|
145
|
|
146 (defun mh-read-seq-default (prompt not-empty)
|
|
147 ;; Read and return sequence name with default narrowed or previous sequence.
|
11332
|
148 (mh-read-seq prompt not-empty
|
|
149 (or mh-narrowed-to-seq
|
|
150 mh-last-seq-used
|
|
151 (car (mh-seq-containing-msg (mh-get-msg-num nil) nil)))))
|
6365
|
152
|
|
153
|
|
154 (defun mh-read-seq (prompt not-empty &optional default)
|
|
155 ;; Read and return a sequence name. Prompt with PROMPT, raise an error
|
|
156 ;; if the sequence is empty and the NOT-EMPTY flag is non-nil, and supply
|
|
157 ;; an optional DEFAULT sequence.
|
|
158 ;; A reply of '%' defaults to the first sequence containing the current
|
|
159 ;; message.
|
|
160 (let* ((input (completing-read (format "%s %s %s" prompt "sequence:"
|
|
161 (if default
|
|
162 (format "[%s] " default)
|
|
163 ""))
|
|
164 (mh-seq-names mh-seq-list)))
|
11332
|
165 (seq (cond ((equal input "%")
|
|
166 (car (mh-seq-containing-msg (mh-get-msg-num t) nil)))
|
6365
|
167 ((equal input "") default)
|
|
168 (t (intern input))))
|
|
169 (msgs (mh-seq-to-msgs seq)))
|
|
170 (if (and (null msgs) not-empty)
|
|
171 (error (format "No messages in sequence `%s'" seq)))
|
|
172 seq))
|
|
173
|
|
174
|
|
175 (defun mh-seq-names (seq-list)
|
|
176 ;; Return an alist containing the names of the SEQUENCES.
|
|
177 (mapcar (function (lambda (entry) (list (symbol-name (mh-seq-name entry)))))
|
|
178 seq-list))
|
|
179
|
|
180
|
11332
|
181 (defun mh-rename-seq (sequence new-name)
|
|
182 "Rename SEQUENCE to have NEW-NAME."
|
6365
|
183 (interactive (list (mh-read-seq "Old" t)
|
|
184 (intern (read-string "New sequence name: "))))
|
11332
|
185 (let ((old-seq (mh-find-seq sequence)))
|
6365
|
186 (or old-seq
|
11332
|
187 (error "Sequence %s does not exist" sequence))
|
|
188 ;; create new sequence first, since it might raise an error.
|
6365
|
189 (mh-define-sequence new-name (mh-seq-msgs old-seq))
|
11332
|
190 (mh-undefine-sequence sequence (mh-seq-msgs old-seq))
|
6365
|
191 (rplaca old-seq new-name)))
|
|
192
|
|
193
|
|
194 (defun mh-map-to-seq-msgs (func seq &rest args)
|
|
195 ;; Invoke the FUNCTION at each message in the SEQUENCE, passing the
|
|
196 ;; remaining ARGS as arguments.
|
|
197 (save-excursion
|
|
198 (let ((msgs (mh-seq-to-msgs seq)))
|
|
199 (while msgs
|
|
200 (if (mh-goto-msg (car msgs) t t)
|
|
201 (apply func (car msgs) args))
|
|
202 (setq msgs (cdr msgs))))))
|
|
203
|
|
204
|
|
205 (defun mh-notate-seq (seq notation offset)
|
|
206 ;; Mark the scan listing of all messages in the SEQUENCE with the CHARACTER
|
|
207 ;; at the given OFFSET from the beginning of the listing line.
|
|
208 (mh-map-to-seq-msgs 'mh-notate seq notation offset))
|
|
209
|
|
210
|
|
211 (defun mh-add-to-sequence (seq msgs)
|
|
212 ;; Add to a SEQUENCE each message the list of MSGS.
|
|
213 (if (not (mh-folder-name-p seq))
|
|
214 (if msgs
|
|
215 (apply 'mh-exec-cmd "mark" mh-current-folder "-add"
|
|
216 "-sequence" (symbol-name seq)
|
11332
|
217 (mh-coalesce-msg-list msgs)))))
|
6365
|
218
|
|
219
|
|
220 (defun mh-copy-seq-to-point (seq location)
|
|
221 ;; Copy the scan listing of the messages in SEQUENCE to after the point
|
|
222 ;; LOCATION in the current buffer.
|
|
223 (mh-map-to-seq-msgs 'mh-copy-line-to-point seq location))
|
|
224
|
|
225
|
|
226 (defun mh-copy-line-to-point (msg location)
|
|
227 ;; Copy the current line to the LOCATION in the current buffer.
|
|
228 (beginning-of-line)
|
11332
|
229 (save-excursion
|
|
230 (let ((beginning-of-line (point))
|
|
231 end)
|
|
232 (forward-line 1)
|
|
233 (setq end (point))
|
|
234 (goto-char location)
|
|
235 (insert-buffer-substring (current-buffer) beginning-of-line end))))
|
6365
|
236
|