forked from wanderlust/wanderlust
/
wl-conversation.el
91 lines (78 loc) · 3.78 KB
/
wl-conversation.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(defvar wl-all-folder-alist '(("" . "+all"))
"Alist of (regex . folder-name). Regex is matched against the current folder. First match is the name of folder containing all mail.")
(defun wl-summary-get-all-folders ()
(if wl-all-folder-alist
(if (not wl-summary-buffer-folder-name)
(remove-duplicates (mapcar 'cdr wl-all-folder-alist))
(list (wl-get-assoc-list-value wl-all-folder-alist
wl-summary-buffer-folder-name)))
nil))
(defvar wl-summary-prev-folder-name nil)
(defvar wl-summary-prev-message-id nil)
(defvar wl-summary-prev-sticky nil)
(defun wl-current-thread-location ()
"Return a pair consisting of the message-id of the current
message and of the root of its thread (both surrounded by <...>)"
(save-excursion
(wl-summary-set-message-buffer-or-redisplay)
(set-buffer (wl-message-get-original-buffer))
(let ((message-id (std11-field-body "Message-Id")))
;; The thread root is the first UID in References, if any, or
;; else is the current message
(cons message-id
(car (split-string (or (std11-field-body "References") message-id)
"[ \f\t\n\r\v,]+"))))
))
(defun wl-make-all-folder-filter (filter)
(let ((all-folders (wl-summary-get-all-folders)))
(if (> (length all-folders) 1)
(let ((folders (mapcar (lambda (folder)
(concat "/" filter "/" folder)) all-folders)))
(concat "*" (mapconcat
(lambda (folder)
(concat "\""
(replace-regexp-in-string "\"" "\\\"" folder nil t)
"\""))
folders ",")))
(concat "/" filter "/" (car all-folders)))))
(defun wl-thread-root-folder (thread-root)
(let* ((thread-root-no-brackets (substring thread-root 1 -1))
(filter (concat "message-id:\"" thread-root-no-brackets
"\"|references:\"" thread-root-no-brackets
"\"")))
(wl-make-all-folder-filter filter)))
(defun wl-summary-visit-conversation (&optional close)
(interactive "P")
(if close
(if wl-summary-prev-folder-name
(let ((scan-type (if wl-summary-prev-sticky 'no-sync 'update)))
(wl-summary-goto-folder-subr wl-summary-prev-folder-name
scan-type nil nil t)
(wl-summary-jump-to-msg-by-message-id wl-summary-prev-message-id))
(message "No previous folder to visit."))
(let* ((thread-location (wl-current-thread-location))
(cur-message-id (car thread-location))
(prev-folder-name wl-summary-buffer-folder-name)
(sticky (wl-summary-sticky-p)))
(wl-open-conversation-view (cdr thread-location))
(wl-summary-jump-to-msg-by-message-id cur-message-id)
(setq wl-summary-prev-folder-name prev-folder-name
wl-summary-prev-message-id cur-message-id
wl-summary-prev-sticky sticky)
(make-local-variable 'wl-summary-prev-folder-name)
(make-local-variable 'wl-summary-prev-message-id)
(make-local-variable 'wl-summary-prev-sticky)
)))
(defun wl-open-conversation-view (root)
(wl-summary-goto-folder-subr (wl-thread-root-folder root) 'update nil nil t))
(defun wl-open-message-view (mid)
(let ((filter (concat "message-id:\"" mid "\"")))
(wl-summary-goto-folder-subr (wl-make-all-folder-filter filter) 'update nil nil t)))
(defun wl-folder-virtual-all ()
"Goto virtual folder searching across all messages."
(interactive)
(wl-folder-goto-folder-subr
(wl-make-all-folder-filter
(wl-read-search-condition wl-fldmgr-make-filter-default))))
(define-key wl-summary-mode-map "X" 'wl-summary-visit-conversation)
(define-key wl-folder-mode-map "A" 'wl-folder-virtual-all)