Mercurial > hg > xemacs-beta
comparison lisp/vm/vm-thread.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 05472e90ae02 |
children | 0d2f883870bc |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
40 ;; Just for laughs, make the update interval vary. | 40 ;; Just for laughs, make the update interval vary. |
41 (modulus (+ (% (vm-abs (random)) 11) 40)) | 41 (modulus (+ (% (vm-abs (random)) 11) 40)) |
42 ;; no need to schedule reindents of reparented messages | 42 ;; no need to schedule reindents of reparented messages |
43 ;; unless there were already messages present. | 43 ;; unless there were already messages present. |
44 (schedule-reindents message-list) | 44 (schedule-reindents message-list) |
45 m parent parent-sym id id-sym date refs old-parent-sym) | 45 parent parent-sym id id-sym date) |
46 (while mp | 46 (while mp |
47 (setq m (car mp) | 47 (setq parent (vm-th-parent (car mp)) |
48 parent (vm-th-parent m) | 48 id (vm-su-message-id (car mp)) |
49 id (vm-su-message-id m) | |
50 id-sym (intern id vm-thread-obarray) | 49 id-sym (intern id vm-thread-obarray) |
51 date (vm-so-sortable-datestring m)) | 50 date (vm-so-sortable-datestring (car mp))) |
52 (put id-sym 'messages (cons m (get id-sym 'messages))) | 51 (put id-sym 'messages (cons (car mp) (get id-sym 'messages))) |
53 (if (and (null (cdr (get id-sym 'messages))) | 52 (if (and (null (cdr (get id-sym 'messages))) |
54 schedule-reindents) | 53 schedule-reindents) |
55 (vm-thread-mark-for-summary-update (get id-sym 'children))) | 54 (vm-thread-mark-for-summary-update (get id-sym 'children))) |
56 (if parent | 55 (if parent |
57 (progn | 56 (progn |
58 (setq parent-sym (intern parent vm-thread-obarray)) | 57 (setq parent-sym (intern parent vm-thread-obarray)) |
59 (cond ((or (not (boundp id-sym)) | 58 (if (not (boundp id-sym)) |
60 (null (symbol-value id-sym)) | 59 (set id-sym parent-sym)) |
61 (eq (symbol-value id-sym) parent-sym)) | |
62 (set id-sym parent-sym)) | |
63 (t | |
64 (setq old-parent-sym (symbol-value id-sym)) | |
65 (put old-parent-sym 'children | |
66 (let ((kids (get old-parent-sym 'children)) | |
67 (msgs (get id-sym 'messages))) | |
68 (while msgs | |
69 (setq kids (delq m kids) | |
70 msgs (cdr msgs))) | |
71 kids )) | |
72 (set id-sym parent-sym) | |
73 (if schedule-reindents | |
74 (vm-thread-mark-for-summary-update | |
75 (get id-sym 'messages))))) | |
76 (put parent-sym 'children | 60 (put parent-sym 'children |
77 (cons m (get parent-sym 'children)))) | 61 (cons (car mp) (get parent-sym 'children)))) |
78 (if (not (boundp id-sym)) | 62 (set id-sym nil)) |
79 (set id-sym nil))) | 63 ;; we need to make sure the asets below are an atomic group. |
80 ;; use the references header to set parenting information | |
81 ;; for ancestors of this message. This does not override | |
82 ;; a parent pointer for a message if it already exists. | |
83 (if (cdr (setq refs (vm-th-references m))) | |
84 (let (parent-sym id-sym msgs) | |
85 (setq parent-sym (intern (car refs) vm-thread-obarray) | |
86 refs (cdr refs)) | |
87 (while refs | |
88 (setq id-sym (intern (car refs) vm-thread-obarray)) | |
89 (if (and (boundp id-sym) (symbol-value id-sym)) | |
90 nil | |
91 (set id-sym parent-sym) | |
92 (if (setq msgs (get id-sym 'messages)) | |
93 (put parent-sym 'children | |
94 (append msgs (get parent-sym 'children)))) | |
95 (if schedule-reindents | |
96 (vm-thread-mark-for-summary-update msgs))) | |
97 (setq parent-sym id-sym | |
98 refs (cdr refs))))) | |
99 (if vm-thread-using-subject | 64 (if vm-thread-using-subject |
100 ;; inhibit-quit because we need to make sure the asets | |
101 ;; below are an atomic group. | |
102 (let* ((inhibit-quit t) | 65 (let* ((inhibit-quit t) |
103 (subject (vm-so-sortable-subject m)) | 66 (subject (vm-so-sortable-subject (car mp))) |
104 (subject-sym (intern subject vm-thread-subject-obarray))) | 67 (subject-sym (intern subject vm-thread-subject-obarray))) |
105 ;; if this subject never seen before create the | |
106 ;; information vector. | |
107 (if (not (boundp subject-sym)) | 68 (if (not (boundp subject-sym)) |
108 (set subject-sym | 69 (set subject-sym |
109 (vector id-sym (vm-so-sortable-datestring m) | 70 (vector id-sym (vm-so-sortable-datestring (car mp)) |
110 nil (list m))) | 71 nil (list (car mp)))) |
111 ;; this subject seen before | |
112 (aset (symbol-value subject-sym) 3 | 72 (aset (symbol-value subject-sym) 3 |
113 (cons m (aref (symbol-value subject-sym) 3))) | 73 (cons (car mp) (aref (symbol-value subject-sym) 3))) |
114 (if (string< date (aref (symbol-value subject-sym) 1)) | 74 (if (string< date (aref (symbol-value subject-sym) 1)) |
115 (let* ((vect (symbol-value subject-sym)) | 75 (let* ((vect (symbol-value subject-sym)) |
116 (i-sym (aref vect 0))) | 76 (i-sym (aref vect 0))) |
117 ;; optimization: if we know that this message | |
118 ;; already has a parent, then don't bother | |
119 ;; adding it to the list of child messages | |
120 ;; since we know that it will be threaded and | |
121 ;; unthreaded using the parent information. | |
122 (if (or (not (boundp i-sym)) | 77 (if (or (not (boundp i-sym)) |
123 (null (symbol-value i-sym))) | 78 (null (symbol-value i-sym))) |
124 (aset vect 2 (append (get i-sym 'messages) | 79 (aset vect 2 (append (get i-sym 'messages) |
125 (aref vect 2)))) | 80 (aref vect 2)))) |
126 (aset vect 0 id-sym) | 81 (aset vect 0 id-sym) |
131 ;; that it finish... the summary will just be out | 86 ;; that it finish... the summary will just be out |
132 ;; of sync. | 87 ;; of sync. |
133 (if schedule-reindents | 88 (if schedule-reindents |
134 (let ((inhibit-quit nil)) | 89 (let ((inhibit-quit nil)) |
135 (vm-thread-mark-for-summary-update (aref vect 2))))) | 90 (vm-thread-mark-for-summary-update (aref vect 2))))) |
136 ;; optimization: if we know that this message | |
137 ;; already has a parent, then don't bother adding | |
138 ;; it to the list of child messages, since we | |
139 ;; know that it will be threaded and unthreaded | |
140 ;; using the parent information. | |
141 (if (null parent) | 91 (if (null parent) |
142 (aset (symbol-value subject-sym) 2 | 92 (aset (symbol-value subject-sym) 2 |
143 (cons m (aref (symbol-value subject-sym) 2)))))))) | 93 (cons (car mp) |
94 (aref (symbol-value subject-sym) 2)))))))) | |
144 (setq mp (cdr mp) n (1+ n)) | 95 (setq mp (cdr mp) n (1+ n)) |
145 (if (zerop (% n modulus)) | 96 (if (zerop (% n modulus)) |
146 (message "Building threads... %d" n))) | 97 (vm-unsaved-message "Building threads... %d" n))) |
147 (if (> n modulus) | 98 (if (> n modulus) |
148 (message "Building threads... done")))) | 99 (vm-unsaved-message "Building threads... done")))) |
149 | 100 |
150 (defun vm-thread-mark-for-summary-update (message-list) | 101 (defun vm-thread-mark-for-summary-update (message-list) |
151 (let (m) | 102 (while message-list |
152 (while message-list | 103 (vm-mark-for-summary-update (car message-list) t) |
153 (setq m (car message-list)) | 104 (vm-set-thread-list-of (car message-list) nil) |
154 ;; if thread-list is null then we've already marked this | 105 (vm-set-thread-indentation-of (car message-list) nil) |
155 ;; message, or it doesn't need marking. | 106 (vm-thread-mark-for-summary-update |
156 (if (null (vm-thread-list-of m)) | 107 (get (intern (vm-su-message-id (car message-list)) |
157 nil | 108 vm-thread-obarray) |
158 (vm-mark-for-summary-update m t) | 109 'children)) |
159 (vm-set-thread-list-of m nil) | 110 (setq message-list (cdr message-list)))) |
160 (vm-set-thread-indentation-of m nil) | |
161 (vm-thread-mark-for-summary-update | |
162 (get (intern (vm-su-message-id m) vm-thread-obarray) | |
163 'children))) | |
164 (setq message-list (cdr message-list))))) | |
165 | 111 |
166 (defun vm-thread-list (message) | 112 (defun vm-thread-list (message) |
167 (let ((done nil) | 113 (let ((done nil) |
168 (m message) | 114 (m message) |
169 thread-list id-sym subject-sym loop-sym root-date) | 115 thread-list id-sym subject-sym loop-sym root-date) |
174 (fillarray vm-thread-loop-obarray 0) | 120 (fillarray vm-thread-loop-obarray 0) |
175 (while (not done) | 121 (while (not done) |
176 (setq loop-sym (intern (symbol-name id-sym) vm-thread-loop-obarray)) | 122 (setq loop-sym (intern (symbol-name id-sym) vm-thread-loop-obarray)) |
177 (if (boundp loop-sym) | 123 (if (boundp loop-sym) |
178 ;; loop detected, bail... | 124 ;; loop detected, bail... |
179 (setq done t) | 125 (setq done t |
126 thread-list (cdr thread-list)) | |
180 (set loop-sym t) | 127 (set loop-sym t) |
181 (if (and (boundp id-sym) (symbol-value id-sym)) | 128 (if (and (boundp id-sym) (symbol-value id-sym)) |
182 (progn | 129 (progn |
183 (setq id-sym (symbol-value id-sym) | 130 (setq id-sym (symbol-value id-sym) |
184 thread-list (cons id-sym thread-list) | 131 thread-list (cons id-sym thread-list) |
204 thread-list ))) | 151 thread-list ))) |
205 | 152 |
206 ;; remove message struct from thread data. | 153 ;; remove message struct from thread data. |
207 ;; | 154 ;; |
208 ;; optional second arg non-nil means forget information that | 155 ;; optional second arg non-nil means forget information that |
209 ;; might be different if the message contents changed. | 156 ;; might be different if the mesage contents changed. |
210 ;; | 157 ;; |
211 ;; message must be a real (non-virtual) message | 158 ;; message must be a real message |
212 (defun vm-unthread-message (message &optional message-changing) | 159 (defun vm-unthread-message (message &optional message-changing) |
213 (save-excursion | 160 (save-excursion |
214 (let ((mp (cons message (vm-virtual-messages-of message))) | 161 (let ((mp (cons message (vm-virtual-messages-of message))) |
215 m id-sym subject-sym vect p-sym) | 162 id-sym subject-sym vect p-sym) |
216 (while mp | 163 (while mp |
217 (setq m (car mp)) | |
218 (let ((inhibit-quit t)) | 164 (let ((inhibit-quit t)) |
219 (vm-set-thread-list-of m nil) | 165 (vm-set-thread-list-of (car mp) nil) |
220 (vm-set-thread-indentation-of m nil) | 166 (vm-set-thread-indentation-of (car mp) nil) |
221 (set-buffer (vm-buffer-of m)) | 167 (set-buffer (vm-buffer-of (car mp))) |
222 (setq id-sym (intern (vm-su-message-id m) vm-thread-obarray) | 168 (setq id-sym (intern (vm-su-message-id (car mp)) vm-thread-obarray) |
223 subject-sym (intern (vm-so-sortable-subject m) | 169 subject-sym (intern (vm-so-sortable-subject (car mp)) |
224 vm-thread-subject-obarray)) | 170 vm-thread-subject-obarray)) |
225 (if (boundp id-sym) | 171 (if (boundp id-sym) |
226 (progn | 172 (progn |
227 (put id-sym 'messages (delq m (get id-sym 'messages))) | 173 (put id-sym 'messages (delq (car mp) (get id-sym 'messages))) |
228 (vm-thread-mark-for-summary-update (get id-sym 'children)) | 174 (vm-thread-mark-for-summary-update (get id-sym 'children)) |
229 (setq p-sym (symbol-value id-sym)) | 175 (setq p-sym (symbol-value id-sym)) |
230 (and p-sym (put p-sym 'children | 176 (and p-sym (put p-sym 'children |
231 (delq m (get p-sym 'children)))) | 177 (delq (car mp) (get p-sym 'children)))) |
232 (if message-changing | 178 (if message-changing |
233 (set id-sym nil)))) | 179 (set id-sym nil)))) |
234 (if (and (boundp subject-sym) (setq vect (symbol-value subject-sym))) | 180 (if (and (boundp subject-sym) (setq vect (symbol-value subject-sym))) |
235 (if (not (eq id-sym (aref vect 0))) | 181 (if (not (eq id-sym (aref vect 0))) |
236 (aset vect 2 (delq m (aref vect 2))) | 182 (aset vect 2 (delq (car mp) (aref vect 2))) |
237 (if message-changing | 183 (if message-changing |
238 (if (null (cdr (aref vect 3))) | 184 (if (null (cdr (aref vect 3))) |
239 (makunbound subject-sym) | 185 (makunbound subject-sym) |
240 (let ((p (aref vect 3)) | 186 (let ((p (aref vect 3)) |
241 oldest-msg oldest-date children) | 187 oldest-msg oldest-date children) |
243 oldest-date (vm-so-sortable-datestring (car p)) | 189 oldest-date (vm-so-sortable-datestring (car p)) |
244 p (cdr p)) | 190 p (cdr p)) |
245 (while p | 191 (while p |
246 (if (and (string-lessp (vm-so-sortable-datestring (car p)) | 192 (if (and (string-lessp (vm-so-sortable-datestring (car p)) |
247 oldest-date) | 193 oldest-date) |
248 (not (eq m (car p)))) | 194 (not (eq (car mp) (car p)))) |
249 (setq oldest-msg (car p) | 195 (setq oldest-msg (car p) |
250 oldest-date (vm-so-sortable-datestring (car p)))) | 196 oldest-date (vm-so-sortable-datestring (car p)))) |
251 (setq p (cdr p))) | 197 (setq p (cdr p))) |
252 (aset vect 0 (intern (vm-su-message-id oldest-msg) | 198 (aset vect 0 (intern (vm-su-message-id oldest-msg) |
253 vm-thread-obarray)) | 199 vm-thread-obarray)) |
254 (aset vect 1 oldest-date) | 200 (aset vect 1 oldest-date) |
255 (setq children (delq oldest-msg (aref vect 2))) | 201 (setq children (delq oldest-msg (aref vect 2))) |
256 (aset vect 2 children) | 202 (aset vect 2 children) |
257 (aset vect 3 (delq m (aref vect 3))) | 203 (aset vect 3 (delq (car mp) (aref vect 3))) |
258 ;; I'm not sure there aren't situations | 204 ;; I'm not sure there aren't situations |
259 ;; where this might loop forever. | 205 ;; where this might loop forever. |
260 (let ((inhibit-quit nil)) | 206 (let ((inhibit-quit nil)) |
261 (vm-thread-mark-for-summary-update children)))))))) | 207 (vm-thread-mark-for-summary-update children)))))))) |
262 (setq mp (cdr mp)))))) | 208 (setq mp (cdr mp)))))) |
263 | 209 |
264 (defun vm-th-references (m) | |
265 (or (vm-references-of m) | |
266 (vm-set-references-of | |
267 m | |
268 (let (references) | |
269 (setq references (vm-get-header-contents m "References:" " ")) | |
270 (and references (vm-parse references "[^<]*\\(<[^>]+>\\)")))))) | |
271 | |
272 (defun vm-th-parent (m) | 210 (defun vm-th-parent (m) |
273 (or (vm-parent-of m) | 211 (or (vm-parent-of m) |
274 (vm-set-parent-of | 212 (vm-set-parent-of |
275 m | 213 m |
276 (or (car (vm-last (vm-th-references m))) | 214 (or (let (references) |
215 (setq references (vm-get-header-contents m "References:")) | |
216 (and references | |
217 (car (vm-last | |
218 (vm-parse references "[^<]*\\(<[^>]+>\\)"))))) | |
277 (let (in-reply-to) | 219 (let (in-reply-to) |
278 (setq in-reply-to (vm-get-header-contents m "In-Reply-To:" " ")) | 220 (setq in-reply-to (vm-get-header-contents m "In-Reply-To:")) |
279 (and in-reply-to | 221 (and in-reply-to |
280 (car (vm-parse in-reply-to "[^<]*\\(<[^>]+>\\)")))))))) | 222 (car (vm-parse in-reply-to "[^<]*\\(<[^>]+>\\)")))))))) |
281 | 223 |
282 (defun vm-th-thread-indentation (m) | 224 (defun vm-th-thread-indentation (m) |
283 (or (vm-thread-indentation-of m) | 225 (or (vm-thread-indentation-of m) |