annotate lisp/mh-e/mh-thread.el @ 69478:e8bb5df2ba7a

Add index entries around each paragraph rather than depend on entries from beginning of node. Doing so ensures that index entries are less likely to be forgotten if text is cut and pasted, and are necessary anyway if the references are on a separate page. It seems that makeinfo is now (v. 4.8) only producing one index entry per node, so there is no longer any excuse not to. Use subheading instead of heading. The incorrect use of heading produced very large fonts in Info--as large as the main heading. (From Bill Wohler): MH-E never did appear in Emacs 21--MH-E versions 6 and 7 appeared *around* the time of these Emacs releases.
author Bill Wohler <wohler@newt.com>
date Wed, 15 Mar 2006 00:26:12 +0000
parents 7daec5f4a289
children e3694f1cb928
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
1 ;;; mh-thread.el --- MH-E threading support
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
2
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
3 ;; Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
4
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
5 ;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
6 ;; Maintainer: Bill Wohler <wohler@newt.com>
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
7 ;; Keywords: mail
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
8 ;; See: mh-e.el
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
9
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
10 ;; This file is part of GNU Emacs.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
11
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
13 ;; it under the terms of the GNU General Public License as published by
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
14 ;; the Free Software Foundation; either version 2, or (at your option)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
15 ;; any later version.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
16
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
17 ;; GNU Emacs is distributed in the hope that it will be useful,
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
20 ;; GNU General Public License for more details.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
21
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
22 ;; You should have received a copy of the GNU General Public License
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
25 ;; Boston, MA 02110-1301, USA.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
26
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
27 ;;; Commentary:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
28
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
29 ;; The threading portion of this files tries to implement the
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
30 ;; algorithm described at:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
31 ;; http://www.jwz.org/doc/threading.html
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
32 ;; It also begins to implement the IMAP Threading extension RFC. The
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
33 ;; implementation lacks the reference and subject canonicalization of
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
34 ;; the RFC.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
35
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
36 ;; In the presentation buffer, children messages are shown indented
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
37 ;; with either [ ] or < > around them. Square brackets ([ ]) denote
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
38 ;; that the algorithm can point out some headers which when taken
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
39 ;; together implies that the unindented message is an ancestor of the
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
40 ;; indented message. If no such proof exists then angles (< >) are
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
41 ;; used.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
42
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
43 ;; If threading is slow on your machine, compile this file. Of all the
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
44 ;; files in MH-E, this one really benefits from compilation.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
45
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
46 ;; Some issues and problems are as follows:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
47
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
48 ;; (1) Scan truncates the fields at length 512. So longer
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
49 ;; references: headers get mutilated. The same kind of MH
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
50 ;; format string works when composing messages. Is there a way
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
51 ;; to avoid this? My scan command is as follows:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
52 ;; scan +folder -width 10000 \
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
53 ;; -format "%(msg)\n%{message-id}\n%{references}\n%{subject}\n"
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
54 ;; I would really appreciate it if someone would help me with this.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
55
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
56 ;; (2) Implement heuristics to recognize message identifiers in
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
57 ;; In-Reply-To: header. Right now it just assumes that the last
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
58 ;; text between angles (< and >) is the message identifier.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
59 ;; There is the chance that this will incorrectly use an email
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
60 ;; address like a message identifier.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
61
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
62 ;; (3) Error checking of found message identifiers should be done.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
63
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
64 ;; (4) Since this breaks the assumption that message indices
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
65 ;; increase as one goes down the buffer, the binary search
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
66 ;; based mh-goto-msg doesn't work. I have a simpler replacement
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
67 ;; which may be less efficient.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
68
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
69 ;; (5) Better canonicalizing for message identifier and subject
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
70 ;; strings.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
71
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
72 ;;; Change Log:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
73
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
74 ;;; Code:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
75
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
76 (require 'mh-e)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
77 (require 'mh-scan)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
78
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
79 (mh-defstruct (mh-thread-message (:conc-name mh-message-)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
80 (:constructor mh-thread-make-message))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
81 (id nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
82 (references ())
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
83 (subject "")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
84 (subject-re-p nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
85
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
86 (mh-defstruct (mh-thread-container (:conc-name mh-container-)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
87 (:constructor mh-thread-make-container))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
88 message parent children
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
89 (real-child-p t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
90
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
91 (defvar mh-thread-id-hash nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
92 "Hashtable used to canonicalize message identifiers.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
93 (make-variable-buffer-local 'mh-thread-id-hash)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
94
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
95 (defvar mh-thread-subject-hash nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
96 "Hashtable used to canonicalize subject strings.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
97 (make-variable-buffer-local 'mh-thread-subject-hash)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
98
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
99 (defvar mh-thread-id-table nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
100 "Thread ID table maps from message identifiers to message containers.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
101 (make-variable-buffer-local 'mh-thread-id-table)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
102
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
103 (defvar mh-thread-index-id-map nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
104 "Table to look up message identifier from message index.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
105 (make-variable-buffer-local 'mh-thread-index-id-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
106
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
107 (defvar mh-thread-id-index-map nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
108 "Table to look up message index number from message identifier.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
109 (make-variable-buffer-local 'mh-thread-id-index-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
110
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
111 (defvar mh-thread-subject-container-hash nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
112 "Hashtable used to group messages by subject.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
113 (make-variable-buffer-local 'mh-thread-subject-container-hash)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
114
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
115 (defvar mh-thread-duplicates nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
116 "Hashtable used to associate messages with the same message identifier.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
117 (make-variable-buffer-local 'mh-thread-duplicates)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
118
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
119 (defvar mh-thread-history ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
120 "Variable to remember the transformations to the thread tree.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
121 When new messages are added, these transformations are rewound,
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
122 then the links are added from the newly seen messages. Finally
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
123 the transformations are redone to get the new thread tree. This
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
124 makes incremental threading easier.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
125 (make-variable-buffer-local 'mh-thread-history)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
126
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
127 (defvar mh-thread-body-width nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
128 "Width of scan substring that contains subject and body of message.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
129
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
130
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
131
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
132 ;;; MH-Folder Commands
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
133
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
134 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
135 (defun mh-thread-ancestor (&optional thread-root-flag)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
136 "Display ancestor of current message.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
137
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
138 If you do not care for the way a particular thread has turned,
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
139 you can move up the chain of messages with this command. This
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
140 command can also take a prefix argument THREAD-ROOT-FLAG to jump
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
141 to the message that started everything."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
142 (interactive "P")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
143 (beginning-of-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
144 (cond ((not (memq 'unthread mh-view-ops))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
145 (error "Folder isn't threaded"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
146 ((eobp)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
147 (error "No message at point")))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
148 (let ((current-level (mh-thread-current-indentation-level)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
149 (cond (thread-root-flag
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
150 (while (mh-thread-immediate-ancestor))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
151 (mh-maybe-show))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
152 ((equal current-level 1)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
153 (message "Message has no ancestor"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
154 (t (mh-thread-immediate-ancestor)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
155 (mh-maybe-show)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
156
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
157 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
158 (defun mh-thread-delete ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
159 "Delete thread."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
160 (interactive)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
161 (cond ((not (memq 'unthread mh-view-ops))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
162 (error "Folder isn't threaded"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
163 ((eobp)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
164 (error "No message at point"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
165 (t (let ((region (mh-thread-find-children)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
166 (mh-iterate-on-messages-in-region () (car region) (cadr region)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
167 (mh-delete-a-msg nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
168 (mh-next-msg)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
169
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
170 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
171 (defun mh-thread-next-sibling (&optional previous-flag)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
172 "Display next sibling.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
173
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
174 With non-nil optional argument PREVIOUS-FLAG jump to the previous
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
175 sibling."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
176 (interactive)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
177 (cond ((not (memq 'unthread mh-view-ops))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
178 (error "Folder isn't threaded"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
179 ((eobp)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
180 (error "No message at point")))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
181 (beginning-of-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
182 (let ((point (point))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
183 (done nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
184 (my-level (mh-thread-current-indentation-level)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
185 (while (and (not done)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
186 (equal (forward-line (if previous-flag -1 1)) 0)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
187 (not (eobp)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
188 (let ((level (mh-thread-current-indentation-level)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
189 (cond ((equal level my-level)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
190 (setq done 'success))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
191 ((< level my-level)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
192 (message "No %s sibling" (if previous-flag "previous" "next"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
193 (setq done 'failure)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
194 (cond ((eq done 'success) (mh-maybe-show))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
195 ((eq done 'failure) (goto-char point))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
196 (t (message "No %s sibling" (if previous-flag "previous" "next"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
197 (goto-char point)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
198
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
199 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
200 (defun mh-thread-previous-sibling ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
201 "Display previous sibling."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
202 (interactive)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
203 (mh-thread-next-sibling t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
204
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
205 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
206 (defun mh-thread-refile (folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
207 "Refile (output) thread into FOLDER."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
208 (interactive (list (intern (mh-prompt-for-refile-folder))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
209 (cond ((not (memq 'unthread mh-view-ops))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
210 (error "Folder isn't threaded"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
211 ((eobp)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
212 (error "No message at point"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
213 (t (let ((region (mh-thread-find-children)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
214 (mh-iterate-on-messages-in-region () (car region) (cadr region)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
215 (mh-refile-a-msg nil folder))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
216 (mh-next-msg)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
217
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
218 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
219 (defun mh-toggle-threads ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
220 "Toggle threaded view of folder."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
221 (interactive)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
222 (let ((msg-at-point (mh-get-msg-num nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
223 (old-buffer-modified-flag (buffer-modified-p))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
224 (buffer-read-only nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
225 (cond ((memq 'unthread mh-view-ops)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
226 (unless (mh-valid-view-change-operation-p 'unthread)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
227 (error "Can't unthread folder"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
228 (let ((msg-list ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
229 (goto-char (point-min))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
230 (while (not (eobp))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
231 (let ((index (mh-get-msg-num nil)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
232 (when index
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
233 (push index msg-list)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
234 (forward-line))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
235 (mh-scan-folder mh-current-folder
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
236 (mapcar #'(lambda (x) (format "%s" x))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
237 (mh-coalesce-msg-list msg-list))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
238 t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
239 (when mh-index-data
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
240 (mh-index-insert-folder-headers)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
241 (mh-notate-cur)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
242 (t (mh-thread-folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
243 (push 'unthread mh-view-ops)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
244 (when msg-at-point (mh-goto-msg msg-at-point t t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
245 (set-buffer-modified-p old-buffer-modified-flag)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
246 (mh-recenter nil)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
247
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
248
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
249
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
250 ;;; Support Routines
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
251
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
252 (defun mh-thread-current-indentation-level ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
253 "Find the number of spaces by which current message is indented."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
254 (save-excursion
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
255 (let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
256 mh-scan-date-width 1))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
257 (level 0))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
258 (beginning-of-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
259 (forward-char address-start-offset)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
260 (while (char-equal (char-after) ? )
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
261 (incf level)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
262 (forward-char))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
263 level)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
264
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
265 (defun mh-thread-immediate-ancestor ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
266 "Jump to immediate ancestor in thread tree."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
267 (beginning-of-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
268 (let ((point (point))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
269 (ancestor-level (- (mh-thread-current-indentation-level) 2))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
270 (done nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
271 (if (< ancestor-level 0)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
272 nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
273 (while (and (not done) (equal (forward-line -1) 0))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
274 (when (equal ancestor-level (mh-thread-current-indentation-level))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
275 (setq done t)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
276 (unless done
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
277 (goto-char point))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
278 done)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
279
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
280 (defun mh-thread-find-children ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
281 "Return a region containing the current message and its children.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
282 The result is returned as a list of two elements. The first is
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
283 the point at the start of the region and the second is the point
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
284 at the end."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
285 (beginning-of-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
286 (if (eobp)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
287 nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
288 (let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
289 mh-scan-date-width 1))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
290 (level (mh-thread-current-indentation-level))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
291 spaces begin)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
292 (setq begin (point))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
293 (setq spaces (format (format "%%%ss" (1+ level)) ""))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
294 (forward-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
295 (block nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
296 (while (not (eobp))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
297 (forward-char address-start-offset)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
298 (unless (equal (string-match spaces (buffer-substring-no-properties
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
299 (point) (mh-line-end-position)))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
300 0)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
301 (beginning-of-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
302 (backward-char)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
303 (return))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
304 (forward-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
305 (list begin (point)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
306
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
307
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
308
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
309 ;;; Thread Creation
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
310
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
311 (defun mh-thread-folder ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
312 "Generate thread view of folder."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
313 (message "Threading %s..." (buffer-name))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
314 (mh-thread-initialize)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
315 (goto-char (point-min))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
316 (mh-remove-all-notation)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
317 (let ((msg-list ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
318 (mh-iterate-on-range msg (cons (point-min) (point-max))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
319 (setf (gethash msg mh-thread-scan-line-map) (mh-thread-parse-scan-line))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
320 (push msg msg-list))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
321 (let* ((range (mh-coalesce-msg-list msg-list))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
322 (thread-tree (mh-thread-generate (buffer-name) range)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
323 (delete-region (point-min) (point-max))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
324 (mh-thread-print-scan-lines thread-tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
325 (mh-notate-user-sequences)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
326 (mh-notate-deleted-and-refiled)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
327 (mh-notate-cur)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
328 (message "Threading %s...done" (buffer-name)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
329
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
330 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
331 (defun mh-thread-inc (folder start-point)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
332 "Update thread tree for FOLDER.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
333 All messages after START-POINT are added to the thread tree."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
334 (mh-thread-rewind-pruning)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
335 (mh-remove-all-notation)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
336 (goto-char start-point)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
337 (let ((msg-list ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
338 (while (not (eobp))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
339 (let ((index (mh-get-msg-num nil)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
340 (when (numberp index)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
341 (push index msg-list)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
342 (setf (gethash index mh-thread-scan-line-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
343 (mh-thread-parse-scan-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
344 (forward-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
345 (let ((thread-tree (mh-thread-generate folder msg-list))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
346 (buffer-read-only nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
347 (old-buffer-modified-flag (buffer-modified-p)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
348 (delete-region (point-min) (point-max))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
349 (mh-thread-print-scan-lines thread-tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
350 (mh-notate-user-sequences)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
351 (mh-notate-deleted-and-refiled)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
352 (mh-notate-cur)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
353 (set-buffer-modified-p old-buffer-modified-flag))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
354
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
355 (defmacro mh-thread-initialize-hash (var test)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
356 "Initialize the hash table in VAR.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
357 TEST is the test to use when creating a new hash table."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
358 (unless (symbolp var) (error "Expected a symbol: %s" var))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
359 `(if ,var (clrhash ,var) (setq ,var (make-hash-table :test ,test))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
360
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
361 (defun mh-thread-initialize ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
362 "Make new hash tables, or clear them if already present."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
363 (mh-thread-initialize-hash mh-thread-id-hash #'equal)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
364 (mh-thread-initialize-hash mh-thread-subject-hash #'equal)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
365 (mh-thread-initialize-hash mh-thread-id-table #'eq)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
366 (mh-thread-initialize-hash mh-thread-id-index-map #'eq)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
367 (mh-thread-initialize-hash mh-thread-index-id-map #'eql)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
368 (mh-thread-initialize-hash mh-thread-scan-line-map #'eql)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
369 (mh-thread-initialize-hash mh-thread-subject-container-hash #'eq)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
370 (mh-thread-initialize-hash mh-thread-duplicates #'eq)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
371 (setq mh-thread-history ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
372
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
373 (defsubst mh-thread-id-container (id)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
374 "Given ID, return the corresponding container in `mh-thread-id-table'.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
375 If no container exists then a suitable container is created and
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
376 the id-table is updated."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
377 (when (not id)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
378 (error "1"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
379 (or (gethash id mh-thread-id-table)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
380 (setf (gethash id mh-thread-id-table)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
381 (let ((message (mh-thread-make-message :id id)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
382 (mh-thread-make-container :message message)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
383
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
384 (defsubst mh-thread-remove-parent-link (child)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
385 "Remove parent link of CHILD if it exists."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
386 (let* ((child-container (if (mh-thread-container-p child)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
387 child (mh-thread-id-container child)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
388 (parent-container (mh-container-parent child-container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
389 (when parent-container
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
390 (setf (mh-container-children parent-container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
391 (loop for elem in (mh-container-children parent-container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
392 unless (eq child-container elem) collect elem))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
393 (setf (mh-container-parent child-container) nil))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
394
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
395 (defsubst mh-thread-add-link (parent child &optional at-end-p)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
396 "Add links so that PARENT becomes a parent of CHILD.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
397 Doesn't make any changes if CHILD is already an ancestor of
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
398 PARENT. If optional argument AT-END-P is non-nil, the CHILD is
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
399 added to the end of the children list of PARENT."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
400 (let ((parent-container (cond ((null parent) nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
401 ((mh-thread-container-p parent) parent)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
402 (t (mh-thread-id-container parent))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
403 (child-container (if (mh-thread-container-p child)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
404 child (mh-thread-id-container child))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
405 (when (and parent-container
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
406 (not (mh-thread-ancestor-p child-container parent-container))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
407 (not (mh-thread-ancestor-p parent-container child-container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
408 (mh-thread-remove-parent-link child-container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
409 (cond ((not at-end-p)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
410 (push child-container (mh-container-children parent-container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
411 ((null (mh-container-children parent-container))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
412 (push child-container (mh-container-children parent-container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
413 (t (let ((last-child (mh-container-children parent-container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
414 (while (cdr last-child)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
415 (setq last-child (cdr last-child)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
416 (setcdr last-child (cons child-container nil)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
417 (setf (mh-container-parent child-container) parent-container))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
418 (unless parent-container
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
419 (mh-thread-remove-parent-link child-container))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
420
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
421 (defun mh-thread-rewind-pruning ()
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
422 "Restore the thread tree to its state before pruning."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
423 (while mh-thread-history
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
424 (let ((action (pop mh-thread-history)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
425 (cond ((eq (car action) 'DROP)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
426 (mh-thread-remove-parent-link (cadr action))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
427 (mh-thread-add-link (caddr action) (cadr action)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
428 ((eq (car action) 'PROMOTE)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
429 (let ((node (cadr action))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
430 (parent (caddr action))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
431 (children (cdddr action)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
432 (dolist (child children)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
433 (mh-thread-remove-parent-link child)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
434 (mh-thread-add-link node child))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
435 (mh-thread-add-link parent node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
436 ((eq (car action) 'SUBJECT)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
437 (let ((node (cadr action)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
438 (mh-thread-remove-parent-link node)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
439 (setf (mh-container-real-child-p node) t)))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
440
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
441 (defun mh-thread-ancestor-p (ancestor successor)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
442 "Return t if ANCESTOR is really an ancestor of SUCCESSOR and nil otherwise.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
443 In the limit, the function returns t if ANCESTOR and SUCCESSOR
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
444 are the same containers."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
445 (block nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
446 (while successor
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
447 (when (eq ancestor successor) (return t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
448 (setq successor (mh-container-parent successor)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
449 nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
450
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
451 ;; Another and may be better approach would be to generate all the info from
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
452 ;; the scan which generates the threading info. For now this will have to do.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
453 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
454 (defun mh-thread-parse-scan-line (&optional string)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
455 "Parse a scan line.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
456 If optional argument STRING is given then that is assumed to be
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
457 the scan line. Otherwise uses the line at point as the scan line
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
458 to parse."
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
459 (let* ((string (or string (buffer-substring-no-properties
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
460 (mh-line-beginning-position)
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
461 (mh-line-end-position))))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
462 (address-start (+ mh-cmd-note mh-scan-field-from-start-offset))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
463 (body-start (+ mh-cmd-note mh-scan-field-from-end-offset))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
464 (first-string (substring string 0 address-start)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
465 (list first-string
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
466 (substring string address-start (- body-start 2))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
467 (substring string body-start)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
468 string)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
469
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
470 (defsubst mh-thread-canonicalize-id (id)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
471 "Produce canonical string representation for ID.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
472 This allows cheap string comparison with EQ."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
473 (or (and (equal id "") (copy-sequence ""))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
474 (gethash id mh-thread-id-hash)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
475 (setf (gethash id mh-thread-id-hash) id)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
476
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
477 (defsubst mh-thread-prune-subject (subject)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
478 "Prune leading Re:'s, Fwd:'s etc. and trailing (fwd)'s from SUBJECT.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
479 If the result after pruning is not the empty string then it is
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
480 canonicalized so that subjects can be tested for equality with
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
481 eq. This is done so that all the messages without a subject are
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
482 not put into a single thread."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
483 (let ((case-fold-search t)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
484 (subject-pruned-flag nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
485 ;; Prune subject leader
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
486 (while (or (string-match "^[ \t]*\\(re\\|fwd?\\)\\(\\[[0-9]*\\]\\)?:[ \t]*"
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
487 subject)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
488 (string-match "^[ \t]*\\[[^\\]][ \t]*" subject))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
489 (setq subject-pruned-flag t)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
490 (setq subject (substring subject (match-end 0))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
491 ;; Prune subject trailer
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
492 (while (or (string-match "(fwd)$" subject)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
493 (string-match "[ \t]+$" subject))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
494 (setq subject-pruned-flag t)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
495 (setq subject (substring subject 0 (match-beginning 0))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
496 ;; Canonicalize subject only if it is non-empty
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
497 (cond ((equal subject "") (values subject subject-pruned-flag))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
498 (t (values
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
499 (or (gethash subject mh-thread-subject-hash)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
500 (setf (gethash subject mh-thread-subject-hash) subject))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
501 subject-pruned-flag)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
502
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
503 (defsubst mh-thread-group-by-subject (roots)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
504 "Group the set of message containers, ROOTS based on subject.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
505 Bug: Check for and make sure that something without Re: is made
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
506 the parent in preference to something that has it."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
507 (clrhash mh-thread-subject-container-hash)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
508 (let ((results ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
509 (dolist (root roots)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
510 (let* ((subject (mh-thread-container-subject root))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
511 (parent (gethash subject mh-thread-subject-container-hash)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
512 (cond (parent (mh-thread-remove-parent-link root)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
513 (mh-thread-add-link parent root t)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
514 (setf (mh-container-real-child-p root) nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
515 (push `(SUBJECT ,root) mh-thread-history))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
516 (t
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
517 (setf (gethash subject mh-thread-subject-container-hash) root)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
518 (push root results)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
519 (nreverse results)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
520
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
521 (defun mh-thread-container-subject (container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
522 "Return the subject of CONTAINER.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
523 If CONTAINER is empty return the subject info of one of its
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
524 children."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
525 (cond ((and (mh-container-message container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
526 (mh-message-id (mh-container-message container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
527 (mh-message-subject (mh-container-message container)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
528 (t (block nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
529 (dolist (kid (mh-container-children container))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
530 (when (and (mh-container-message kid)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
531 (mh-message-id (mh-container-message kid)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
532 (let ((kid-message (mh-container-message kid)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
533 (return (mh-message-subject kid-message)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
534 (error "This can't happen")))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
535
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
536 (defsubst mh-thread-update-id-index-maps (id index)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
537 "Message with id, ID is the message in INDEX.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
538 The function also checks for duplicate messages (that is multiple
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
539 messages with the same ID). These messages are put in the
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
540 `mh-thread-duplicates' hash table."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
541 (let ((old-index (gethash id mh-thread-id-index-map)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
542 (when old-index (push old-index (gethash id mh-thread-duplicates)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
543 (setf (gethash id mh-thread-id-index-map) index)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
544 (setf (gethash index mh-thread-index-id-map) id)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
545
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
546 (defsubst mh-thread-get-message-container (message)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
547 "Return container which has MESSAGE in it.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
548 If there is no container present then a new container is
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
549 allocated."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
550 (let* ((id (mh-message-id message))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
551 (container (gethash id mh-thread-id-table)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
552 (cond (container (setf (mh-container-message container) message)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
553 container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
554 (t (setf (gethash id mh-thread-id-table)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
555 (mh-thread-make-container :message message))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
556
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
557 (defsubst mh-thread-get-message (id subject-re-p subject refs)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
558 "Return appropriate message.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
559 Otherwise update message already present to have the proper ID,
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
560 SUBJECT-RE-P, SUBJECT and REFS fields."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
561 (let* ((container (gethash id mh-thread-id-table))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
562 (message (if container (mh-container-message container) nil)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
563 (cond (message
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
564 (setf (mh-message-subject-re-p message) subject-re-p)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
565 (setf (mh-message-subject message) subject)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
566 (setf (mh-message-id message) id)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
567 (setf (mh-message-references message) refs)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
568 message)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
569 (container
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
570 (setf (mh-container-message container)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
571 (mh-thread-make-message :id id :references refs
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
572 :subject subject
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
573 :subject-re-p subject-re-p)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
574 (t (let ((message (mh-thread-make-message :id id :references refs
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
575 :subject-re-p subject-re-p
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
576 :subject subject)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
577 (prog1 message
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
578 (mh-thread-get-message-container message)))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
579
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
580 (defvar mh-message-id-regexp "^<.*@.*>$"
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
581 "Regexp to recognize whether a string is a message identifier.")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
582
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
583 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
584 (defun mh-thread-generate (folder msg-list)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
585 "Scan FOLDER to get info for threading.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
586 Only information about messages in MSG-LIST are added to the tree."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
587 (with-temp-buffer
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
588 (mh-thread-set-tables folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
589 (when msg-list
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
590 (apply
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
591 #'call-process (expand-file-name mh-scan-prog mh-progs) nil '(t nil) nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
592 "-width" "10000" "-format"
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
593 "%(msg)\n%{message-id}\n%{references}\n%{in-reply-to}\n%{subject}\n"
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
594 folder (mapcar #'(lambda (x) (format "%s" x)) msg-list)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
595 (goto-char (point-min))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
596 (let ((roots ())
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
597 (case-fold-search t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
598 (block nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
599 (while (not (eobp))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
600 (block process-message
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
601 (let* ((index-line
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
602 (prog1 (buffer-substring (point) (mh-line-end-position))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
603 (forward-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
604 (index (string-to-number index-line))
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
605 (id (prog1 (buffer-substring (point) (mh-line-end-position))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
606 (forward-line)))
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
607 (refs (prog1
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
608 (buffer-substring (point) (mh-line-end-position))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
609 (forward-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
610 (in-reply-to (prog1 (buffer-substring (point)
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
611 (mh-line-end-position))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
612 (forward-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
613 (subject (prog1
68529
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
614 (buffer-substring
7daec5f4a289 * mh-alias.el (mh-alias-gecos-name): Use mh-replace-regexp-in-string
Bill Wohler <wohler@newt.com>
parents: 68470
diff changeset
615 (point) (mh-line-end-position))
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
616 (forward-line)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
617 (subject-re-p nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
618 (unless (gethash index mh-thread-scan-line-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
619 (return-from process-message))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
620 (unless (integerp index) (return)) ;Error message here
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
621 (multiple-value-setq (subject subject-re-p)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
622 (mh-thread-prune-subject subject))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
623 (setq in-reply-to (mh-thread-process-in-reply-to in-reply-to))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
624 (setq refs (loop for x in (append (split-string refs) in-reply-to)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
625 when (string-match mh-message-id-regexp x)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
626 collect x))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
627 (setq id (mh-thread-canonicalize-id id))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
628 (mh-thread-update-id-index-maps id index)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
629 (setq refs (mapcar #'mh-thread-canonicalize-id refs))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
630 (mh-thread-get-message id subject-re-p subject refs)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
631 (do ((ancestors refs (cdr ancestors)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
632 ((null (cdr ancestors))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
633 (when (car ancestors)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
634 (mh-thread-remove-parent-link id)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
635 (mh-thread-add-link (car ancestors) id)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
636 (mh-thread-add-link (car ancestors) (cadr ancestors)))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
637 (maphash #'(lambda (k v)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
638 (declare (ignore k))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
639 (when (null (mh-container-parent v))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
640 (push v roots)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
641 mh-thread-id-table)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
642 (setq roots (mh-thread-prune-containers roots))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
643 (prog1 (setq roots (mh-thread-group-by-subject roots))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
644 (let ((history mh-thread-history))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
645 (set-buffer folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
646 (setq mh-thread-history history))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
647
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
648 (defun mh-thread-set-tables (folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
649 "Use the tables of FOLDER in current buffer."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
650 (flet ((mh-get-table (symbol)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
651 (save-excursion
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
652 (set-buffer folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
653 (symbol-value symbol))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
654 (setq mh-thread-id-hash (mh-get-table 'mh-thread-id-hash))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
655 (setq mh-thread-subject-hash (mh-get-table 'mh-thread-subject-hash))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
656 (setq mh-thread-id-table (mh-get-table 'mh-thread-id-table))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
657 (setq mh-thread-id-index-map (mh-get-table 'mh-thread-id-index-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
658 (setq mh-thread-index-id-map (mh-get-table 'mh-thread-index-id-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
659 (setq mh-thread-scan-line-map (mh-get-table 'mh-thread-scan-line-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
660 (setq mh-thread-subject-container-hash
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
661 (mh-get-table 'mh-thread-subject-container-hash))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
662 (setq mh-thread-duplicates (mh-get-table 'mh-thread-duplicates))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
663 (setq mh-thread-history (mh-get-table 'mh-thread-history))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
664
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
665 (defun mh-thread-process-in-reply-to (reply-to-header)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
666 "Extract message id's from REPLY-TO-HEADER.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
667 Ideally this should have some regexp which will try to guess if a
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
668 string between < and > is a message id and not an email address.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
669 For now it will take the last string inside angles."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
670 (let ((end (mh-search-from-end ?> reply-to-header)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
671 (when (numberp end)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
672 (let ((begin (mh-search-from-end ?< (substring reply-to-header 0 end))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
673 (when (numberp begin)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
674 (list (substring reply-to-header begin (1+ end))))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
675
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
676 (defun mh-thread-prune-containers (roots)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
677 "Prune empty containers in the containers ROOTS."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
678 (let ((dfs-ordered-nodes ())
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
679 (work-list roots))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
680 (while work-list
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
681 (let ((node (pop work-list)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
682 (dolist (child (mh-container-children node))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
683 (push child work-list))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
684 (push node dfs-ordered-nodes)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
685 (while dfs-ordered-nodes
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
686 (let ((node (pop dfs-ordered-nodes)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
687 (cond ((gethash (mh-message-id (mh-container-message node))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
688 mh-thread-id-index-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
689 ;; Keep it
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
690 (setf (mh-container-children node)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
691 (mh-thread-sort-containers (mh-container-children node))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
692 ((and (mh-container-children node)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
693 (or (null (cdr (mh-container-children node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
694 (mh-container-parent node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
695 ;; Promote kids
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
696 (let ((children ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
697 (dolist (kid (mh-container-children node))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
698 (mh-thread-remove-parent-link kid)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
699 (mh-thread-add-link (mh-container-parent node) kid)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
700 (push kid children))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
701 (push `(PROMOTE ,node ,(mh-container-parent node) ,@children)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
702 mh-thread-history)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
703 (mh-thread-remove-parent-link node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
704 ((mh-container-children node)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
705 ;; Promote the first orphan to parent and add the other kids as
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
706 ;; his children
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
707 (setf (mh-container-children node)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
708 (mh-thread-sort-containers (mh-container-children node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
709 (let ((new-parent (car (mh-container-children node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
710 (other-kids (cdr (mh-container-children node))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
711 (mh-thread-remove-parent-link new-parent)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
712 (dolist (kid other-kids)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
713 (mh-thread-remove-parent-link kid)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
714 (setf (mh-container-real-child-p kid) nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
715 (mh-thread-add-link new-parent kid t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
716 (push `(PROMOTE ,node ,(mh-container-parent node)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
717 ,new-parent ,@other-kids)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
718 mh-thread-history)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
719 (mh-thread-remove-parent-link node)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
720 (t
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
721 ;; Drop it
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
722 (push `(DROP ,node ,(mh-container-parent node))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
723 mh-thread-history)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
724 (mh-thread-remove-parent-link node)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
725 (let ((results ()))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
726 (maphash #'(lambda (k v)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
727 (declare (ignore k))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
728 (when (and (null (mh-container-parent v))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
729 (gethash (mh-message-id (mh-container-message v))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
730 mh-thread-id-index-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
731 (push v results)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
732 mh-thread-id-table)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
733 (mh-thread-sort-containers results))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
734
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
735 (defun mh-thread-sort-containers (containers)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
736 "Sort a list of message CONTAINERS to be in ascending order wrt index."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
737 (sort containers
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
738 #'(lambda (x y)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
739 (when (and (mh-container-message x) (mh-container-message y))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
740 (let* ((id-x (mh-message-id (mh-container-message x)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
741 (id-y (mh-message-id (mh-container-message y)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
742 (index-x (gethash id-x mh-thread-id-index-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
743 (index-y (gethash id-y mh-thread-id-index-map)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
744 (and (integerp index-x) (integerp index-y)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
745 (< index-x index-y)))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
746
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
747 (defvar mh-thread-last-ancestor)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
748
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
749 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
750 (defun mh-thread-print-scan-lines (thread-tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
751 "Print scan lines in THREAD-TREE in threaded mode."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
752 (let ((mh-thread-body-width (- (window-width) mh-cmd-note
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
753 (1- mh-scan-field-subject-start-offset)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
754 (mh-thread-last-ancestor nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
755 (if (null mh-index-data)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
756 (mh-thread-generate-scan-lines thread-tree -2)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
757 (loop for x in (mh-index-group-by-folder)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
758 do (let* ((old-map mh-thread-scan-line-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
759 (mh-thread-scan-line-map (make-hash-table)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
760 (setq mh-thread-last-ancestor nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
761 (loop for msg in (cdr x)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
762 do (let ((v (gethash msg old-map)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
763 (when v
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
764 (setf (gethash msg mh-thread-scan-line-map) v))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
765 (when (> (hash-table-count mh-thread-scan-line-map) 0)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
766 (insert (if (bobp) "" "\n") (car x) "\n")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
767 (mh-thread-generate-scan-lines thread-tree -2))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
768 (mh-index-create-imenu-index))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
769
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
770 (defun mh-thread-generate-scan-lines (tree level)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
771 "Generate scan lines.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
772 TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
773 message indices to the corresponding scan lines and LEVEL used to
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
774 determine indentation of the message."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
775 (cond ((null tree) nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
776 ((mh-thread-container-p tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
777 (let* ((message (mh-container-message tree))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
778 (id (mh-message-id message))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
779 (index (gethash id mh-thread-id-index-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
780 (duplicates (gethash id mh-thread-duplicates))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
781 (new-level (+ level 2))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
782 (dupl-flag t)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
783 (force-angle-flag nil)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
784 (increment-level-flag nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
785 (dolist (scan-line (mapcar (lambda (x)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
786 (gethash x mh-thread-scan-line-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
787 (reverse (cons index duplicates))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
788 (when scan-line
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
789 (when (and dupl-flag (equal level 0)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
790 (mh-thread-ancestor-p mh-thread-last-ancestor tree))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
791 (setq level (+ level 2)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
792 new-level (+ new-level 2)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
793 force-angle-flag t))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
794 (when (equal level 0)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
795 (setq mh-thread-last-ancestor tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
796 (while (mh-container-parent mh-thread-last-ancestor)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
797 (setq mh-thread-last-ancestor
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
798 (mh-container-parent mh-thread-last-ancestor))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
799 (let* ((lev (if dupl-flag level new-level))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
800 (square-flag (or (and (mh-container-real-child-p tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
801 (not force-angle-flag)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
802 dupl-flag)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
803 (equal lev 0))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
804 (insert (car scan-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
805 (format (format "%%%ss" lev) "")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
806 (if square-flag "[" "<")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
807 (cadr scan-line)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
808 (if square-flag "]" ">")
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
809 (truncate-string-to-width
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
810 (caddr scan-line) (- mh-thread-body-width lev))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
811 "\n"))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
812 (setq increment-level-flag t)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
813 (setq dupl-flag nil)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
814 (unless increment-level-flag (setq new-level level))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
815 (dolist (child (mh-container-children tree))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
816 (mh-thread-generate-scan-lines child new-level))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
817 (t (let ((nlevel (+ level 2)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
818 (dolist (ch tree)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
819 (mh-thread-generate-scan-lines ch nlevel))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
820
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
821
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
822
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
823 ;;; Additional Utilities
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
824
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
825 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
826 (defun mh-thread-update-scan-line-map (msg notation offset)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
827 "In threaded view update `mh-thread-scan-line-map'.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
828 MSG is the message being notated with NOTATION at OFFSET."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
829 (let* ((msg (or msg (mh-get-msg-num nil)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
830 (cur-scan-line (and mh-thread-scan-line-map
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
831 (gethash msg mh-thread-scan-line-map)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
832 (old-scan-lines (loop for map in mh-thread-scan-line-map-stack
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
833 collect (and map (gethash msg map)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
834 (when cur-scan-line
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
835 (setf (aref (car cur-scan-line) offset) notation))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
836 (dolist (line old-scan-lines)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
837 (when line (setf (aref (car line) offset) notation)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
838
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
839 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
840 (defun mh-thread-find-msg-subject (msg)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
841 "Find canonicalized subject of MSG.
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
842 This function can only be used the folder is threaded."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
843 (ignore-errors
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
844 (mh-message-subject
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
845 (mh-container-message (gethash (gethash msg mh-thread-index-id-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
846 mh-thread-id-table)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
847
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
848 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
849 (defun mh-thread-add-spaces (count)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
850 "Add COUNT spaces to each scan line in `mh-thread-scan-line-map'."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
851 (let ((spaces (format (format "%%%ss" count) "")))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
852 (while (not (eobp))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
853 (let* ((msg-num (mh-get-msg-num nil))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
854 (old-line (nth 3 (gethash msg-num mh-thread-scan-line-map))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
855 (when (numberp msg-num)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
856 (setf (gethash msg-num mh-thread-scan-line-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
857 (mh-thread-parse-scan-line (format "%s%s" spaces old-line)))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
858 (forward-line 1))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
859
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
860 ;;;###mh-autoload
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
861 (defun mh-thread-forget-message (index)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
862 "Forget the message INDEX from the threading tables."
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
863 (let* ((id (gethash index mh-thread-index-id-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
864 (id-index (gethash id mh-thread-id-index-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
865 (duplicates (gethash id mh-thread-duplicates)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
866 (remhash index mh-thread-index-id-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
867 (remhash index mh-thread-scan-line-map)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
868 (cond ((and (eql index id-index) (null duplicates))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
869 (remhash id mh-thread-id-index-map))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
870 ((eql index id-index)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
871 (setf (gethash id mh-thread-id-index-map) (car duplicates))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
872 (setf (gethash (car duplicates) mh-thread-index-id-map) id)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
873 (setf (gethash id mh-thread-duplicates) (cdr duplicates)))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
874 (t
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
875 (setf (gethash id mh-thread-duplicates)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
876 (remove index duplicates))))))
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
877
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
878 (provide 'mh-thread)
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
879
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
880 ;; Local Variables:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
881 ;; indent-tabs-mode: nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
882 ;; sentence-end-double-space: nil
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
883 ;; End:
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
884
68470
4bd450a8dbe2 Add arch tagline
Miles Bader <miles@gnu.org>
parents: 68465
diff changeset
885 ;; arch-tag: b10e62f5-f028-4e04-873e-89d0e069b3d5
68465
37d03b3298bf The Great Cleanup
Bill Wohler <wohler@newt.com>
parents:
diff changeset
886 ;;; mh-thread.el ends here