232
225
(setq iter (lambda () (mew-summary-search-regexp-visible regex))))
233
226
(mew-summary-thread-region (point-min) (point-max) nil nil iter)))
228
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
233
(defun mew-thread-get-iter (mark iter)
236
(mark (lambda () (re-search-forward mew-regex-msg-review nil t)))
237
(t (lambda () (not (eobp))))))
239
(defun mew-thread-create-db (size)
243
((<= size 1511) 1511)
244
((<= size 7211) 7211)
246
(make-vector dbsize 0))) ;; hash
248
(defun mew-thread-pass-1 (db func)
249
(let (start msg my-id prnt-id prnt-cld me top line prnt)
251
(goto-char (point-min))
252
(while (funcall func)
255
(if (not (mew-sumsyn-match mew-regex-sumsyn-long))
257
(setq msg (mew-sumsyn-message-number))
258
(setq my-id (mew-sumsyn-my-id))
259
(setq prnt-id (mew-sumsyn-parent-id))
261
;; Throw away properties here and give properties later.
262
;; This is faster than inheriting properties.
263
(setq line (mew-buffer-substring start (point)))
264
(setq me (mew-thread-make-entry))
265
(mew-thread-set-msg me msg)
266
(mew-thread-set-line me line)
267
(if (string= my-id "")
268
(setq top (cons me top))
269
;; some broken messages refer themselves
270
;; don't register me here so that his parent
271
;; will not be found.
272
(if (or (string= prnt-id "") (string= my-id prnt-id))
273
(setq top (cons me top))
274
(mew-thread-set-prntid me prnt-id)
275
(setq prnt (symbol-value (intern-soft prnt-id db)))
277
(setq top (cons me top))
278
(setq prnt-cld (mew-thread-get-child prnt))
280
(nconc prnt-cld (list me))
281
(mew-thread-set-child prnt (list me)))))
282
(mew-thread-set-myid me my-id)
283
(set (intern my-id db) me)))))
286
(defun mew-summary-setup-vfolder (db top column)
287
(let* ((ofolder (mew-summary-folder-name 'ext))
288
(vfolder (mew-folder-to-thread ofolder))
289
(pfolder (mew-summary-physical-folder))
290
(disp (mew-sinfo-get-disp-msg))
291
(ctime (mew-sinfo-get-cache-time))
292
(case (mew-sinfo-get-case)))
293
(mew-summary-switch-to-folder vfolder)
294
(mew-vinfo-set-mode 'thread)
295
(mew-vinfo-set-physical-folder pfolder)
296
(mew-vinfo-set-original-folder ofolder)
299
(mew-summary-toggle-disp-msg (if disp 'on 'off))
300
(mew-sinfo-set-cache-time ctime)
301
(mew-sinfo-set-case case)
302
(setq mew-summary-buffer-raw t)
303
(mew-vinfo-set-db db)
304
(mew-vinfo-set-top top)
305
(mew-vinfo-set-column column)))
307
(defun mew-thread-pass-2 (db top)
308
(if (null mew-use-complete-thread)
310
;; This may create looped thread.
311
;; See mew-use-complete-thread for more information.
312
(let (prnt prnt-id prnt-cld ret)
314
(if (not (and (mew-thread-get-myid me)
315
(setq prnt-id (mew-thread-get-prntid me))))
316
(setq ret (cons me ret))
317
(setq prnt (symbol-value (intern-soft prnt-id db)))
319
(setq ret (cons me ret))
320
(setq prnt-cld (mew-thread-get-child prnt))
322
(setq prnt-cld (nconc prnt-cld (list me)))
323
(mew-thread-set-child prnt (list me))))))
326
(defun mew-thread-postscript (mark disp-msg)
327
(when mark (mew-mark-undo-mark mew-mark-review))
328
(jit-lock-register 'mew-summary-cook-region)
329
(mew-summary-set-count-line)
330
(set-buffer-modified-p nil)
332
(mew-summary-move-and-display disp-msg)
333
(goto-char (point-max)))
334
(mew-thread-move-cursor))
336
(defun mew-thread-debug-info (tm1 tm2 tm3 tm4 tm5 tm6)
337
(when (mew-debug 'thread)
338
(let* ((t1 (mew-time-calc tm2 tm1))
339
(t2 (mew-time-calc tm4 tm3))
340
(t3 (mew-time-calc tm6 tm5)))
341
(message "pass1 %f, pass2 %f, visual %f" t1 t2 t3))))
235
343
(defun mew-summary-thread-region (beg end &optional mark disp-msg iter)
236
344
"Make threads for messages in a region. If you want to know how
237
345
threads are created, see 'mew-use-complete-thread'."
238
346
(interactive "r")
240
(when (mew-summary-exclusive-p)
241
(let* ((ofolder (mew-summary-folder-name 'ext))
242
(vfolder (mew-folder-to-thread (mew-physical-folder ofolder)))
243
(folder (mew-summary-physical-folder))
244
(disp (mew-sinfo-get-disp-msg))
245
(ctime (mew-sinfo-get-cache-time))
246
(case (mew-sinfo-get-case))
247
(column (mew-get-summary-form folder 'column))
248
db size top start me prnt prnt-cld my-id prnt-id func msg line
249
tm1 tm2 tm3 tm4 tm5 tm6)
250
(message "Making thread (first pass)...")
252
(narrow-to-region beg end)
253
(setq size (count-lines beg end))
263
(setq db (make-vector size 0)) ;; hash
265
(goto-char (point-min))
267
(setq func (lambda ()
268
(re-search-forward mew-regex-msg-review nil t)))
269
(setq func (lambda () (not (eobp)))))
272
(setq tm1 (current-time))
273
(while (funcall func)
276
(if (not (mew-sumsyn-match mew-regex-sumsyn-long))
278
(setq msg (mew-sumsyn-message-number))
279
(setq my-id (mew-sumsyn-my-id))
280
(setq prnt-id (mew-sumsyn-parent-id))
282
;; Throw away properties here and give properties later.
283
;; This is faster than inheriting properties.
284
(setq line (mew-buffer-substring start (point)))
285
(setq me (mew-thread-make-entry))
286
(mew-thread-set-msg me msg)
287
(mew-thread-set-line me line)
288
(if (string= my-id "")
289
(setq top (cons me top))
290
;; some broken messages refer themselves
291
;; don't register me here so that his parent
292
;; will not be found.
293
(if (or (string= prnt-id "") (string= my-id prnt-id))
294
(setq top (cons me top))
295
(mew-thread-set-prntid me prnt-id)
296
(setq prnt (symbol-value (intern-soft prnt-id db)))
298
(setq top (cons me top))
299
(setq prnt-cld (mew-thread-get-child prnt))
301
(nconc prnt-cld (list me))
302
(mew-thread-set-child prnt (list me)))))
303
(mew-thread-set-myid me my-id)
304
(set (intern my-id db) me))))))
307
(message "No target messages")
308
(setq tm2 (current-time))
309
(mew-summary-switch-to-folder vfolder ofolder)
312
(mew-summary-toggle-disp-msg (if disp 'on 'off))
313
(mew-sinfo-set-cache-time ctime)
314
(mew-sinfo-set-case case)
315
(setq mew-summary-buffer-raw t)
316
(mew-vinfo-set-top nil)
317
(mew-vinfo-set-db db)
318
(mew-vinfo-set-column column)
320
(message "Making thread (second pass)...")
321
(setq tm3 (current-time))
322
(if (null mew-use-complete-thread)
323
(mew-vinfo-set-top (nreverse top))
324
;; This may create looped thread.
325
;; See mew-use-complete-thread for more information.
328
(if (not (and (mew-thread-get-myid me)
329
(setq prnt-id (mew-thread-get-prntid me))))
330
(mew-vinfo-set-top (cons me (mew-vinfo-get-top)))
331
(setq prnt (symbol-value (intern-soft prnt-id db)))
333
(mew-vinfo-set-top (cons me (mew-vinfo-get-top)))
334
(setq prnt-cld (mew-thread-get-child prnt))
336
(nconc prnt-cld (list me))
337
(mew-thread-set-child prnt (list me)))))
338
(setq top (cdr top))))
340
(setq tm4 (current-time))
341
(message "Displaying thread...")
342
(setq tm5 (current-time))
343
(mew-summary-thread-print-top
344
(mew-vinfo-get-top) folder column)
346
;; Unmarking in both Summary and Thread
347
(when mark (mew-mark-undo-mark mew-mark-review))
348
(setq tm6 (current-time))
350
(jit-lock-register 'mew-summary-cook-region))
351
(mew-summary-set-count-line)
352
(set-buffer-modified-p nil)
354
(mew-summary-move-and-display disp-msg)
355
(goto-char (point-max)))
356
(mew-thread-move-cursor)
357
(message "Displaying thread...done")
358
(run-hooks 'mew-thread-display-hook)
359
(when (mew-debug 'thread)
360
(let* ((t1 (mew-time-calc tm2 tm1))
361
(t2 (mew-time-calc tm4 tm3))
362
(t3 (mew-time-calc tm6 tm5)))
363
(message "pass1 %f, pass2 %f, visual %f" t1 t2 t3))))))))
347
(when (mew-summary-exclusive-p)
348
(let* ((column (or (mew-sinfo-get-summary-column) ;; scanned
350
(mew-get-summary-column (mew-summary-folder-name 'ext))))
351
db top tm1 tm2 tm3 tm4 tm5 tm6)
353
(narrow-to-region beg end)
354
(setq db (mew-thread-create-db (count-lines beg end)))
356
(message "Making thread (first pass)...")
357
(setq tm1 (current-time))
358
(setq top (mew-thread-pass-1 db (mew-thread-get-iter mark iter)))
359
(setq tm2 (current-time)))
362
(message "No target messages")
363
(message "Making thread (second pass)...")
364
(setq tm3 (current-time))
365
(setq top (mew-thread-pass-2 db top))
366
(setq tm4 (current-time))
368
(mew-summary-setup-vfolder db top column)
370
(message "Displaying thread...")
371
(setq tm5 (current-time))
372
(mew-summary-thread-print-top (mew-vinfo-get-top) column)
373
(setq tm6 (current-time))
375
(mew-thread-postscript mark disp-msg)
377
(message "Displaying thread...done")
378
(run-hooks 'mew-thread-display-hook)
379
(mew-thread-debug-info tm1 tm2 tm3 tm4 tm5 tm6)))))
365
381
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
680
687
(mew-thread-move-cursor)
681
688
(mew-summary-display)))))
683
(defun mew-summary-thread-parent ()
690
(defun mew-summary-parent ()
684
691
"Move onto the parent message of the current message."
686
693
(mew-summary-goto-message)
687
694
(mew-decode-syntax-delete)
695
(let ((par-id (mew-summary-parent-id)) result)
697
((or (null par-id) (string= par-id ""))
698
(message "No parent"))
699
((mew-summary-parent-local par-id)
700
(message "Parent found"))
701
((and (y-or-n-p "No parent in this folder. Find in others? ")
702
(setq result (mew-summary-parent-global par-id)))
704
(message "Parent found")
705
(message "%s" result)))
707
(message "Parent not found")))))
709
(defun mew-summary-parent-local (par-id)
688
710
(let ((pos (point))
689
(par-id (mew-summary-parent-id))
691
(if (or (null par-id) (string= par-id ""))
692
(message "No required info")
693
(setq key (mew-regex-sumsyn-my-id par-id))
694
(if (or (re-search-backward key nil t)
696
(goto-char (point-max))
697
(re-search-backward key nil t)))
699
(mew-thread-move-cursor)
700
(mew-summary-display)
701
(message "Parent found"))
703
(message "No parent")))))
711
(key (mew-regex-sumsyn-my-id par-id)))
712
(if (or (re-search-backward key nil t)
713
(re-search-forward key nil t))
715
(mew-thread-move-cursor)
716
(mew-summary-display)
721
(defun mew-summary-parent-global (par-id)
723
(let ((db (mew-expand-file "+" mew-id-db-file))
724
(regex (format "\\(.*\\)/\\([0-9]+\\)\\(%s\\)?$" (regexp-quote mew-suffix)))
727
(mew-piolet mew-cs-text-for-read mew-cs-text-for-write
728
(call-process mew-prog-smew nil t nil "-p" db par-id "")
729
(goto-char (point-min))
730
(when (looking-at regex)
731
(setq path (mew-match-string 1))
732
(setq msg (mew-match-string 2)))))
735
(setq folder (mew-folder-path-to-folder path))
737
(mew-summary-visit-folder folder nil 'no-ls)
738
(if (mew-summary-search-msg msg)
740
(mew-summary-display)
742
"Parent not found. Scan 'update would be necessary"))))))
705
744
(defun mew-summary-thread-child ()
706
"Move onto the child message of the current message."
745
"Move onto the first child message of the current message."
708
747
(mew-summary-goto-message)
709
748
(mew-decode-syntax-delete)