* wl-summary.el (wl-summary-create-line): Fix.
[elisp/wanderlust.git] / wl / wl-summary.el
1 ;;; wl-summary.el --- Summary mode for Wanderlust.
2
3 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
4 ;; Copyright (C) 1998,1999,2000 Masahiro MURATA <muse@ba2.so-net.ne.jp>
5 ;; Copyright (C) 1999,2000      TSUMURA Tomoaki <tsumura@kuis.kyoto-u.ac.jp>
6 ;; Copyright (C) 1999,2000      Kenichi OKADA <okada@opaopa.org>
7
8 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
9 ;;      Masahiro MURATA <muse@ba2.so-net.ne.jp>
10 ;;      TSUMURA Tomoaki <tsumura@kuis.kyoto-u.ac.jp>
11 ;;      Kenichi OKADA <okada@opaopa.org>
12 ;; Keywords: mail, net news
13
14 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
15
16 ;; This program is free software; you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation; either version 2, or (at your option)
19 ;; any later version.
20 ;;
21 ;; This program is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 ;; GNU General Public License for more details.
25 ;;
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
28 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
29 ;; Boston, MA 02111-1307, USA.
30 ;;
31
32 ;;; Commentary:
33 ;;
34
35 ;;; Code:
36 ;;
37
38 (require 'elmo)
39 (require 'elmo-multi)
40 (require 'wl-message)
41 (require 'wl-vars)
42 (require 'wl-highlight)
43 (require 'wl-refile)
44 (require 'wl-util)
45 (condition-case nil (require 'timezone) (error nil))
46 (condition-case nil (require 'easymenu) (error nil))
47 (require 'elmo-date)
48 (condition-case nil (require 'ps-print) (error nil))
49
50 (eval-when-compile
51   (require 'cl)
52   (condition-case () (require 'timer) (error nil))
53   (defalias-maybe 'ps-print-buffer-with-faces 'ignore)
54   (defalias-maybe 'elmo-database-msgid-put 'ignore)
55   (defalias-maybe 'elmo-database-close 'ignore)
56   (defalias-maybe 'elmo-database-msgid-get 'ignore)
57   (defalias-maybe 'run-with-idle-timer 'ignore)
58   (defalias-maybe 'ps-print-preprint 'ignore))
59
60 (defvar dragdrop-drop-functions)
61 (defvar scrollbar-height)
62 (defvar mail-reply-buffer)
63
64 (defvar wl-summary-buffer-name "Summary")
65 (defvar wl-summary-mode-map nil)
66 (defvar wl-current-summary-buffer nil)
67
68 (defvar wl-summary-buffer-elmo-folder nil)
69
70 (defmacro wl-summary-buffer-folder-name ()
71   (` (and wl-summary-buffer-elmo-folder
72           (elmo-folder-name-internal wl-summary-buffer-elmo-folder))))
73
74 (defmacro wl-summary-buffer-msgdb ()
75   (` (and wl-summary-buffer-elmo-folder
76           (elmo-folder-msgdb wl-summary-buffer-elmo-folder))))
77
78 (defvar wl-summary-buffer-folder-indicator nil)
79 (defvar wl-summary-buffer-disp-msg    nil)
80 (defvar wl-summary-buffer-disp-folder nil)
81 (defvar wl-summary-buffer-refile-list nil)
82 (defvar wl-summary-buffer-delete-list nil)
83 (defvar wl-summary-buffer-last-displayed-msg nil)
84 (defvar wl-summary-buffer-current-msg nil)
85 (defvar wl-summary-buffer-unread-status " (0 new/0 unread)")
86 (defvar wl-summary-buffer-unread-count 0)
87 (defvar wl-summary-buffer-new-count    0)
88 (defvar wl-summary-buffer-mime-charset  nil)
89 (defvar wl-summary-buffer-weekday-name-lang  nil)
90 (defvar wl-summary-buffer-thread-indent-set-alist  nil)
91 (defvar wl-summary-buffer-view 'thread)
92 (defvar wl-summary-buffer-message-modified nil)
93 (defvar wl-summary-buffer-mark-modified nil)
94 (defvar wl-summary-buffer-thread-modified nil)
95 (defvar wl-summary-buffer-number-column nil)
96 (defvar wl-summary-buffer-persistent nil)
97 (defvar wl-summary-buffer-thread-nodes nil)
98 (defvar wl-summary-buffer-target-mark-list nil)
99 (defvar wl-summary-buffer-copy-list nil)
100 (defvar wl-summary-buffer-prev-refile-destination nil)
101 (defvar wl-summary-buffer-prev-copy-destination nil)
102 (defvar wl-summary-buffer-saved-message nil)
103 (defvar wl-summary-buffer-prev-folder-function nil)
104 (defvar wl-summary-buffer-next-folder-function nil)
105 (defvar wl-summary-buffer-exit-function nil)
106 (defvar wl-summary-buffer-next-message-function nil)
107 (defvar wl-summary-buffer-number-list nil)
108 (defvar wl-summary-buffer-msgdb nil)
109 (defvar wl-summary-buffer-folder-name nil)
110 (defvar wl-summary-buffer-line-formatter nil)
111
112 (defvar wl-thread-indent-level-internal nil)
113 (defvar wl-thread-have-younger-brother-str-internal nil)
114 (defvar wl-thread-youngest-child-str-internal nil)
115 (defvar wl-thread-vertical-str-internal nil)
116 (defvar wl-thread-horizontal-str-internal nil)
117 (defvar wl-thread-space-str-internal nil)
118 (defvar wl-summary-last-visited-folder nil)
119 (defvar wl-read-folder-hist nil)
120 (defvar wl-summary-scored nil)
121 (defvar wl-crosspost-alist-modified nil)
122 (defvar wl-summary-alike-hashtb nil)
123 (defvar wl-summary-search-buf-name " *wl-search-subject*")
124 (defvar wl-summary-delayed-update nil)
125 (defvar wl-summary-search-buf-folder-name nil)
126
127 (defvar wl-summary-get-petname-function 'wl-address-get-petname-1)
128
129 (defconst wl-summary-message-regexp "^ *-?[0-9]+"
130   "Regexp for the message.")
131
132 (defvar wl-summary-shell-command-last "")
133
134 (defvar wl-ps-preprint-hook nil)
135 (defvar wl-ps-print-hook nil)
136
137 (make-variable-buffer-local 'wl-summary-buffer-elmo-folder)
138 (make-variable-buffer-local 'wl-summary-search-buf-folder-name)
139 (make-variable-buffer-local 'wl-summary-buffer-disp-msg)
140 (make-variable-buffer-local 'wl-summary-buffer-disp-folder)
141 (make-variable-buffer-local 'wl-summary-buffer-refile-list)
142 (make-variable-buffer-local 'wl-summary-buffer-copy-list)
143 (make-variable-buffer-local 'wl-summary-buffer-target-mark-list)
144 (make-variable-buffer-local 'wl-summary-buffer-delete-list)
145 (make-variable-buffer-local 'wl-summary-buffer-folder-indicator)
146 (make-variable-buffer-local 'wl-summary-buffer-last-displayed-msg)
147 (make-variable-buffer-local 'wl-summary-buffer-unread-status)
148 (make-variable-buffer-local 'wl-summary-buffer-unread-count)
149 (make-variable-buffer-local 'wl-summary-buffer-new-count)
150 (make-variable-buffer-local 'wl-summary-buffer-mime-charset)
151 (make-variable-buffer-local 'wl-summary-buffer-weekday-name-lang)
152 (make-variable-buffer-local 'wl-summary-buffer-thread-indent-set)
153 (make-variable-buffer-local 'wl-summary-buffer-view)
154 (make-variable-buffer-local 'wl-summary-buffer-message-modified)
155 (make-variable-buffer-local 'wl-summary-buffer-mark-modified)
156 (make-variable-buffer-local 'wl-summary-buffer-thread-modified)
157 (make-variable-buffer-local 'wl-summary-buffer-number-column)
158 (make-variable-buffer-local 'wl-summary-buffer-persistent)
159 (make-variable-buffer-local 'wl-summary-buffer-thread-nodes)
160 (make-variable-buffer-local 'wl-summary-buffer-prev-refile-destination)
161 (make-variable-buffer-local 'wl-summary-buffer-saved-message)
162 (make-variable-buffer-local 'wl-summary-scored)
163 (make-variable-buffer-local 'wl-summary-default-score)
164 (make-variable-buffer-local 'wl-summary-move-direction-downward)
165 (make-variable-buffer-local 'wl-summary-important-above)
166 (make-variable-buffer-local 'wl-summary-target-above)
167 (make-variable-buffer-local 'wl-summary-mark-below)
168 (make-variable-buffer-local 'wl-summary-expunge-below)
169 (make-variable-buffer-local 'wl-thread-indent-level-internal)
170 (make-variable-buffer-local 'wl-thread-have-younger-brother-str-internal)
171 (make-variable-buffer-local 'wl-thread-youngest-child-str-internal)
172 (make-variable-buffer-local 'wl-thread-vertical-str-internal)
173 (make-variable-buffer-local 'wl-thread-horizontal-str-internal)
174 (make-variable-buffer-local 'wl-thread-space-str-internal)
175 (make-variable-buffer-local 'wl-summary-buffer-prev-folder-function)
176 (make-variable-buffer-local 'wl-summary-buffer-next-folder-function)
177 (make-variable-buffer-local 'wl-summary-buffer-exit-function)
178 (make-variable-buffer-local 'wl-summary-buffer-next-message-function)
179 (make-variable-buffer-local 'wl-summary-buffer-number-list)
180 (make-variable-buffer-local 'wl-summary-buffer-msgdb)
181 (make-variable-buffer-local 'wl-summary-buffer-folder-name)
182 (make-variable-buffer-local 'wl-summary-buffer-line-formatter)
183
184 ;; internal functions (dummy)
185 (unless (fboundp 'wl-summary-append-message-func-internal)
186   (defun wl-summary-append-message-func-internal (entity msgdb update
187                                                          &optional force-insert)))
188
189 (defmacro wl-summary-sticky-buffer-name (name)
190   (` (concat wl-summary-buffer-name ":" (, name))))
191
192 (defun wl-summary-default-subject (subject-string)
193   (if (string-match "^[ \t]*\\[[^:]+[,: ][0-9]+\\][ \t]*" subject-string)
194       (substring subject-string (match-end 0))
195     subject-string))
196
197 (eval-when-compile (defvar-maybe entity nil)) ; silence byte compiler.
198 (defun wl-summary-default-from (from)
199   (let (retval tos ng)
200     (unless
201         (and (eq major-mode 'wl-summary-mode)
202              (stringp wl-summary-showto-folder-regexp)
203              (string-match wl-summary-showto-folder-regexp
204                            (wl-summary-buffer-folder-name))
205              (wl-address-user-mail-address-p from)
206              (cond
207               ((and (setq tos (elmo-msgdb-overview-entity-get-to entity))
208                     (not (string= "" tos)))
209                (setq retval
210                      (concat "To:"
211                              (mapconcat
212                               (function
213                                (lambda (to)
214                                  (eword-decode-string
215                                   (if wl-use-petname
216                                       (or
217                                        (funcall wl-summary-get-petname-function to)
218                                        (car
219                                         (std11-extract-address-components to))
220                                        to)
221                                     to))))
222                               (wl-parse-addresses tos)
223                               ","))))
224               ((setq ng (elmo-msgdb-overview-entity-get-extra-field
225                          entity "newsgroups"))
226                (setq retval (concat "Ng:" ng)))))
227       (if wl-use-petname
228           (setq retval (or (funcall wl-summary-get-petname-function from)
229                            (car (std11-extract-address-components from))
230                            from))
231         (setq retval from)))
232     retval))
233
234 (defun wl-summary-simple-from (string)
235   (if wl-use-petname
236       (or (funcall wl-summary-get-petname-function string)
237           (car (std11-extract-address-components string))
238           string)
239     string))
240
241 (defvar wl-summary-mode-menu-spec
242   '("Summary"
243     ["Read" wl-summary-read t]
244     ["Prev page" wl-summary-prev-page t]
245     ["Next page" wl-summary-next-page t]
246     ["Top"       wl-summary-display-top t]
247     ["Bottom"    wl-summary-display-bottom t]
248     ["Prev"      wl-summary-prev t]
249     ["Next"      wl-summary-next t]
250     ["Up"        wl-summary-up t]
251     ["Down"      wl-summary-down t]
252     ["Parent message" wl-summary-jump-to-parent-message t]
253     "----"
254     ["Sync"            wl-summary-sync t]
255     ["Execute"         wl-summary-exec t]
256     ["Go to other folder" wl-summary-goto-folder t]
257     ["Pick" wl-summary-pick t]
258     ["Mark as read all" wl-summary-mark-as-read-all t]
259     ["Unmark all"      wl-summary-unmark-all t]
260     ["Toggle display message" wl-summary-toggle-disp-msg t]
261     ["Display folder" wl-summary-toggle-disp-folder t]
262     ["Toggle threading" wl-summary-toggle-thread t]
263     ["Stick" wl-summary-stick t]
264     ("Sort"
265      ["By Number" wl-summary-sort-by-number t]
266      ["By Date" wl-summary-sort-by-date t]
267      ["By From" wl-summary-sort-by-from t]
268      ["By Subject" wl-summary-sort-by-subject t])
269     "----"
270     ("Message Operation"
271      ["Mark as read"    wl-summary-mark-as-read t]
272      ["Mark as important" wl-summary-mark-as-important t]
273      ["Mark as unread"   wl-summary-mark-as-unread t]
274      ["Set delete mark" wl-summary-delete t]
275      ["Set refile mark" wl-summary-refile t]
276      ["Set copy mark"   wl-summary-copy t]
277      ["Prefetch"        wl-summary-prefetch t]
278      ["Set target mark" wl-summary-target-mark t]
279      ["Unmark"          wl-summary-unmark t]
280      ["Save"            wl-summary-save t]
281      ["Cancel posted news" wl-summary-cancel-message t]
282      ["Supersedes message" wl-summary-supersedes-message t]
283      ["Resend bounced mail" wl-summary-resend-bounced-mail t]
284      ["Resend message" wl-summary-resend-message t]
285      ["Enter the message" wl-summary-jump-to-current-message t]
286      ["Pipe message" wl-summary-pipe-message t]
287      ["Print message" wl-summary-print-message t])
288     ("Thread Operation"
289      ["Open or Close" wl-thread-open-close (eq wl-summary-buffer-view 'thread)]
290      ["Open all"     wl-thread-open-all (eq wl-summary-buffer-view 'thread)]
291      ["Close all"    wl-thread-close-all (eq wl-summary-buffer-view 'thread)]
292      ["Mark as read" wl-thread-mark-as-read (eq wl-summary-buffer-view 'thread)]
293      ["Mark as important"       wl-thread-mark-as-important (eq wl-summary-buffer-view 'thread)]
294      ["Mark as unread"          wl-thread-mark-as-unread (eq wl-summary-buffer-view 'thread)]
295      ["Set delete mark"  wl-thread-delete (eq wl-summary-buffer-view 'thread)]
296      ["Set refile mark"  wl-thread-refile (eq wl-summary-buffer-view 'thread)]
297      ["Set copy mark"    wl-thread-copy (eq wl-summary-buffer-view 'thread)]
298      ["Prefetch"     wl-thread-prefetch (eq wl-summary-buffer-view 'thread)]
299      ["Set target mark"        wl-thread-target-mark (eq wl-summary-buffer-view 'thread)]
300      ["Unmark"      wl-thread-unmark (eq wl-summary-buffer-view 'thread)]
301      ["Save"            wl-thread-save (eq wl-summary-buffer-view 'thread)]
302      ["Execute"      wl-thread-exec (eq wl-summary-buffer-view 'thread)])
303     ("Region Operation"
304      ["Mark as read" wl-summary-mark-as-read-region t]
305      ["Mark as important" wl-summary-mark-as-important-region t]
306      ["Mark as unread" wl-summary-mark-as-unread-region t]
307      ["Set delete mark" wl-summary-delete-region t]
308      ["Set refile mark" wl-summary-refile-region t]
309      ["Set copy mark" wl-summary-copy-region t]
310      ["Prefetch" wl-summary-prefetch-region t]
311      ["Set target mark" wl-summary-target-mark-region t]
312      ["Unmark" wl-summary-unmark-region t]
313      ["Save" wl-summary-save-region t]
314      ["Execute" wl-summary-exec-region t])
315     ("Mark Operation"
316      ["Mark as read" wl-summary-target-mark-mark-as-read t]
317      ["Mark as important" wl-summary-target-mark-mark-as-important t]
318      ["Mark as unread" wl-summary-target-mark-mark-as-unread t]
319      ["Set delete mark" wl-summary-target-mark-delete t]
320      ["Set refile mark" wl-summary-target-mark-refile t]
321      ["Set copy mark" wl-summary-target-mark-copy t]
322      ["Prefetch" wl-summary-target-mark-prefetch t]
323      ["Save" wl-summary-target-mark-save t]
324      ["Reply with citation" wl-summary-target-mark-reply-with-citation t]
325      ["Forward" wl-summary-target-mark-forward t]
326      ["uudecode" wl-summary-target-mark-uudecode t])
327     ("Score Operation"
328      ["Switch current score file" wl-score-change-score-file t]
329      ["Edit current score file" wl-score-edit-current-scores t]
330      ["Edit score file" wl-score-edit-file t]
331      ["Set mark below" wl-score-set-mark-below t]
332      ["Set expunge below" wl-score-set-expunge-below t]
333      ["Rescore buffer" wl-summary-rescore t]
334      ["Increase score" wl-summary-increase-score t]
335      ["Lower score" wl-summary-lower-score t])
336     "----"
337     ("Writing Messages"
338      ["Write a message" wl-summary-write t]
339      ["Write for current folder" wl-summary-write-current-folder t]
340      ["Reply" wl-summary-reply t]
341      ["Reply with citation" wl-summary-reply-with-citation t]
342      ["Forward" wl-summary-forward t])
343     "----"
344     ["Toggle Plug Status" wl-toggle-plugged t]
345     ["Change Plug Status" wl-plugged-change t]
346     "----"
347     ["Exit Current Folder" wl-summary-exit t]))
348
349 (if wl-on-xemacs
350     (defun wl-summary-setup-mouse ()
351       (define-key wl-summary-mode-map 'button4 'wl-summary-prev)
352       (define-key wl-summary-mode-map 'button5 'wl-summary-next)
353       (define-key wl-summary-mode-map [(shift button4)]
354         'wl-summary-up)
355       (define-key wl-summary-mode-map [(shift button5)]
356         'wl-summary-down)
357       (define-key wl-summary-mode-map 'button2 'wl-summary-click))
358   (defun wl-summary-setup-mouse ()
359     (define-key wl-summary-mode-map [mouse-4] 'wl-summary-prev)
360     (define-key wl-summary-mode-map [mouse-5] 'wl-summary-next)
361     (define-key wl-summary-mode-map [S-mouse-4] 'wl-summary-up)
362     (define-key wl-summary-mode-map [S-mouse-5] 'wl-summary-down)
363     (define-key wl-summary-mode-map [mouse-2] 'wl-summary-click)))
364
365 (if wl-summary-mode-map
366     ()
367   (setq wl-summary-mode-map (make-sparse-keymap))
368   (define-key wl-summary-mode-map " "    'wl-summary-read)
369   (define-key wl-summary-mode-map "."    'wl-summary-redisplay)
370   (define-key wl-summary-mode-map "<"    'wl-summary-display-top)
371   (define-key wl-summary-mode-map ">"    'wl-summary-display-bottom)
372   (define-key wl-summary-mode-map "\177" 'wl-summary-prev-page)
373   (define-key wl-summary-mode-map [backspace] 'wl-summary-prev-page)
374   (define-key wl-summary-mode-map "\r"   'wl-summary-next-line-content)
375   (define-key wl-summary-mode-map "\C-m" 'wl-summary-next-line-content)
376   (define-key wl-summary-mode-map "/"    'wl-thread-open-close)
377   (define-key wl-summary-mode-map "["    'wl-thread-open-all)
378   (define-key wl-summary-mode-map "]"    'wl-thread-close-all)
379   (define-key wl-summary-mode-map "-"    'wl-summary-prev-line-content)
380   (define-key wl-summary-mode-map "\e\r" 'wl-summary-prev-line-content)
381   (define-key wl-summary-mode-map "g"    'wl-summary-goto-folder)
382   (define-key wl-summary-mode-map "G"    'wl-summary-goto-folder-sticky)
383   (define-key wl-summary-mode-map "c"    'wl-summary-mark-as-read-all)
384 ;  (define-key wl-summary-mode-map "D"    'wl-summary-drop-unsync)
385
386   (define-key wl-summary-mode-map "a"    'wl-summary-reply)
387   (define-key wl-summary-mode-map "A"    'wl-summary-reply-with-citation)
388   (define-key wl-summary-mode-map "C"    'wl-summary-cancel-message)
389   (define-key wl-summary-mode-map "E"    'wl-summary-reedit)
390   (define-key wl-summary-mode-map "\eE"  'wl-summary-resend-bounced-mail)
391   (define-key wl-summary-mode-map "f"    'wl-summary-forward)
392   (define-key wl-summary-mode-map "$"    'wl-summary-mark-as-important)
393   (define-key wl-summary-mode-map "@"    'wl-summary-edit-addresses)
394
395   (define-key wl-summary-mode-map "y"    'wl-summary-save)
396   (define-key wl-summary-mode-map "n"    'wl-summary-next)
397   (define-key wl-summary-mode-map "p"    'wl-summary-prev)
398   (define-key wl-summary-mode-map "N"    'wl-summary-down)
399   (define-key wl-summary-mode-map "P"    'wl-summary-up)
400 ;;;(define-key wl-summary-mode-map "w"    'wl-draft)
401   (define-key wl-summary-mode-map "w"    'wl-summary-write)
402   (define-key wl-summary-mode-map "W"    'wl-summary-write-current-folder)
403 ;;;(define-key wl-summary-mode-map "e"     'wl-draft-open-file)
404   (define-key wl-summary-mode-map "e"     'wl-summary-save)
405   (define-key wl-summary-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer)
406   (define-key wl-summary-mode-map "\C-c\C-a" 'wl-addrmgr)
407   (define-key wl-summary-mode-map "\C-c\C-p" 'wl-summary-previous-buffer)
408   (define-key wl-summary-mode-map "\C-c\C-n" 'wl-summary-next-buffer)
409   (define-key wl-summary-mode-map "H"    'wl-summary-redisplay-all-header)
410   (define-key wl-summary-mode-map "M"    'wl-summary-redisplay-no-mime)
411   (define-key wl-summary-mode-map "B"    'wl-summary-burst)
412   (define-key wl-summary-mode-map "Z"    'wl-status-update)
413   (define-key wl-summary-mode-map "#"    'wl-summary-print-message)
414   (define-key wl-summary-mode-map "|"    'wl-summary-pipe-message)
415   (define-key wl-summary-mode-map "z"    'wl-summary-suspend)
416   (define-key wl-summary-mode-map "q"    'wl-summary-exit)
417   (define-key wl-summary-mode-map "Q"    'wl-summary-force-exit)
418
419   (define-key wl-summary-mode-map "j"    'wl-summary-jump-to-current-message)
420   (define-key wl-summary-mode-map "J"    'wl-thread-jump-to-msg)
421   (define-key wl-summary-mode-map "I"    'wl-summary-incorporate)
422   (define-key wl-summary-mode-map "\M-j" 'wl-summary-jump-to-msg-by-message-id)
423   (define-key wl-summary-mode-map "^"    'wl-summary-jump-to-parent-message)
424   (define-key wl-summary-mode-map "!"    'wl-summary-mark-as-unread)
425
426   (define-key wl-summary-mode-map "s"    'wl-summary-sync)
427   (define-key wl-summary-mode-map "S"    'wl-summary-sort)
428   (define-key wl-summary-mode-map "\M-s"    'wl-summary-stick)
429   (define-key wl-summary-mode-map "T"    'wl-summary-toggle-thread)
430
431   (define-key wl-summary-mode-map "l"    'wl-summary-toggle-disp-folder)
432   (define-key wl-summary-mode-map "v"    'wl-summary-toggle-disp-msg)
433   (define-key wl-summary-mode-map "V"    'wl-summary-virtual)
434
435   (define-key wl-summary-mode-map "\C-i"  'wl-summary-goto-last-displayed-msg)
436   (define-key wl-summary-mode-map "?"    'wl-summary-pick)
437   (define-key wl-summary-mode-map "\ee"  'wl-summary-expire)
438
439   ;; copy & paste.
440   (define-key wl-summary-mode-map "\ew"  'wl-summary-save-current-message)
441   (define-key wl-summary-mode-map "\C-y"  'wl-summary-yank-saved-message)
442
443   ;; line commands
444   (define-key wl-summary-mode-map "R"    'wl-summary-mark-as-read)
445   (define-key wl-summary-mode-map "i"    'wl-summary-prefetch)
446   (define-key wl-summary-mode-map "x"    'wl-summary-exec)
447   (define-key wl-summary-mode-map "*"    'wl-summary-target-mark)
448   (define-key wl-summary-mode-map "o"    'wl-summary-refile)
449   (define-key wl-summary-mode-map "O"    'wl-summary-copy)
450   (define-key wl-summary-mode-map "\M-o" 'wl-summary-refile-prev-destination)
451 ;  (define-key wl-summary-mode-map "\M-O" 'wl-summary-copy-prev-destination)
452   (define-key wl-summary-mode-map "\C-o" 'wl-summary-auto-refile)
453   (define-key wl-summary-mode-map "d"    'wl-summary-delete)
454   (define-key wl-summary-mode-map "u"    'wl-summary-unmark)
455   (define-key wl-summary-mode-map "U"    'wl-summary-unmark-all)
456
457   ;; thread commands
458   (define-key wl-summary-mode-map "t"   (make-sparse-keymap))
459   (define-key wl-summary-mode-map "tR" 'wl-thread-mark-as-read)
460   (define-key wl-summary-mode-map "ti" 'wl-thread-prefetch)
461   (define-key wl-summary-mode-map "tx" 'wl-thread-exec)
462   (define-key wl-summary-mode-map "t*" 'wl-thread-target-mark)
463   (define-key wl-summary-mode-map "to" 'wl-thread-refile)
464   (define-key wl-summary-mode-map "tO" 'wl-thread-copy)
465   (define-key wl-summary-mode-map "td" 'wl-thread-delete)
466   (define-key wl-summary-mode-map "tu" 'wl-thread-unmark)
467   (define-key wl-summary-mode-map "t!" 'wl-thread-mark-as-unread)
468   (define-key wl-summary-mode-map "t$" 'wl-thread-mark-as-important)
469   (define-key wl-summary-mode-map "ty" 'wl-thread-save)
470   (define-key wl-summary-mode-map "ts" 'wl-thread-set-parent)
471
472   ;; target-mark commands
473   (define-key wl-summary-mode-map "m"     (make-sparse-keymap))
474   (define-key wl-summary-mode-map "mi"   'wl-summary-target-mark-prefetch)
475   (define-key wl-summary-mode-map "mR"   'wl-summary-target-mark-mark-as-read)
476   (define-key wl-summary-mode-map "mo"   'wl-summary-target-mark-refile)
477   (define-key wl-summary-mode-map "mO"   'wl-summary-target-mark-copy)
478   (define-key wl-summary-mode-map "md"   'wl-summary-target-mark-delete)
479   (define-key wl-summary-mode-map "my"   'wl-summary-target-mark-save)
480   (define-key wl-summary-mode-map "m!"   'wl-summary-target-mark-mark-as-unread)
481   (define-key wl-summary-mode-map "m$"   'wl-summary-target-mark-mark-as-important)
482   (define-key wl-summary-mode-map "mu"   'wl-summary-delete-all-temp-marks)
483   (define-key wl-summary-mode-map "mU"   'wl-summary-target-mark-uudecode)
484   (define-key wl-summary-mode-map "ma"   'wl-summary-target-mark-all)
485   (define-key wl-summary-mode-map "mt"   'wl-summary-target-mark-thread)
486   (define-key wl-summary-mode-map "mA"   'wl-summary-target-mark-reply-with-citation)
487   (define-key wl-summary-mode-map "mf"   'wl-summary-target-mark-forward)
488   (define-key wl-summary-mode-map "m?"   'wl-summary-target-mark-pick)
489   (define-key wl-summary-mode-map "m#"   'wl-summary-target-mark-print)
490   (define-key wl-summary-mode-map "m|"   'wl-summary-target-mark-pipe)
491
492   ;; region commands
493   (define-key wl-summary-mode-map "r"    (make-sparse-keymap))
494   (define-key wl-summary-mode-map "rR"   'wl-summary-mark-as-read-region)
495   (define-key wl-summary-mode-map "ri"   'wl-summary-prefetch-region)
496   (define-key wl-summary-mode-map "rx"   'wl-summary-exec-region)
497   (define-key wl-summary-mode-map "mr"   'wl-summary-target-mark-region)
498   (define-key wl-summary-mode-map "r*"   'wl-summary-target-mark-region)
499   (define-key wl-summary-mode-map "ro"   'wl-summary-refile-region)
500   (define-key wl-summary-mode-map "rO"   'wl-summary-copy-region)
501   (define-key wl-summary-mode-map "rd"   'wl-summary-delete-region)
502   (define-key wl-summary-mode-map "ru"   'wl-summary-unmark-region)
503   (define-key wl-summary-mode-map "r!"   'wl-summary-mark-as-unread-region)
504   (define-key wl-summary-mode-map "r$"   'wl-summary-mark-as-important-region)
505   (define-key wl-summary-mode-map "ry"   'wl-summary-save-region)
506
507   ;; score commands
508   (define-key wl-summary-mode-map "K"    'wl-summary-increase-score)
509   (define-key wl-summary-mode-map "L"    'wl-summary-lower-score)
510   (define-key wl-summary-mode-map "h"    (make-sparse-keymap))
511   (define-key wl-summary-mode-map "hR"   'wl-summary-rescore)
512   (define-key wl-summary-mode-map "hc"   'wl-score-change-score-file)
513   (define-key wl-summary-mode-map "he"   'wl-score-edit-current-scores)
514   (define-key wl-summary-mode-map "hf"   'wl-score-edit-file)
515   (define-key wl-summary-mode-map "hF"   'wl-score-flush-cache)
516   (define-key wl-summary-mode-map "hm"   'wl-score-set-mark-below)
517   (define-key wl-summary-mode-map "hx"   'wl-score-set-expunge-below)
518
519   (define-key wl-summary-mode-map "\M-t" 'wl-toggle-plugged)
520   (define-key wl-summary-mode-map "\C-t" 'wl-plugged-change)
521   ;;
522   (define-key wl-summary-mode-map "\C-x\C-s" 'wl-summary-save-status)
523   (wl-summary-setup-mouse)
524   (easy-menu-define
525    wl-summary-mode-menu
526    wl-summary-mode-map
527    "Menu used in Summary mode."
528    wl-summary-mode-menu-spec))
529
530 (defun wl-status-update ()
531   (interactive)
532   (wl-address-init))
533
534 (defun wl-summary-display-top ()
535   (interactive)
536   (goto-char (point-min))
537   (if wl-summary-buffer-disp-msg
538       (wl-summary-redisplay)))
539
540 (defun wl-summary-display-bottom ()
541   (interactive)
542   (goto-char (point-max))
543   (forward-line -1)
544   (if wl-summary-buffer-disp-msg
545       (wl-summary-redisplay)))
546
547 (defun wl-summary-count-unread ()
548   (let ((pair
549          (elmo-msgdb-count-marks (wl-summary-buffer-msgdb)
550                                  wl-summary-new-mark
551                                  (list wl-summary-unread-uncached-mark
552                                        wl-summary-unread-cached-mark))))
553     (if (eq major-mode 'wl-summary-mode)
554         (setq wl-summary-buffer-new-count (car pair)
555               wl-summary-buffer-unread-count (cdr pair)))
556     pair))
557
558 (defun wl-summary-message-string (&optional use-cache)
559   "Return full body string of current message.
560 If optional USE-CACHE is non-nil, use cache if exists."
561   (let ((number (wl-summary-message-number))
562         (folder wl-summary-buffer-elmo-folder))
563     (if (null number)
564         (message "No message.")
565       (elmo-set-work-buf
566        (elmo-message-fetch folder
567                            number
568                            (elmo-make-fetch-strategy
569                             'entire
570                             use-cache ; use cache
571                             nil ; save cache (should `t'?)
572                             (and
573                              use-cache
574                              (elmo-file-cache-get-path
575                               (elmo-message-field folder number 'message-id))))
576                            nil
577                            (current-buffer)
578                            'unread)
579        (buffer-string)))))
580
581 (defun wl-summary-reedit (&optional arg)
582   "Re-edit current message.
583 If ARG is non-nil, Supersedes message"
584   (interactive "P")
585   (if arg
586       (wl-summary-supersedes-message)
587     (if (string= (wl-summary-buffer-folder-name) wl-draft-folder)
588         (if (wl-summary-message-number)
589             (progn
590               (wl-draft-reedit (wl-summary-message-number))
591               (if (wl-message-news-p)
592                   (mail-position-on-field "Newsgroups")
593                 (mail-position-on-field "To"))
594               (delete-other-windows)))
595       (wl-draft-edit-string (wl-summary-message-string)))))
596
597 (defun wl-summary-resend-bounced-mail ()
598   "Re-mail the current message.
599 This only makes sense if the current message is a bounce message which
600 contains some mail you have written but has been bounced back to
601 you."
602   (interactive)
603   (save-excursion
604     (wl-summary-set-message-buffer-or-redisplay)
605     (set-buffer (wl-message-get-original-buffer))
606     (goto-char (point-min))
607     (let ((case-fold-search nil))
608       (cond
609        ((and
610          (re-search-forward
611           (concat "^\\($\\|[Cc]ontent-[Tt]ype:[ \t]+multipart/\\(report\\|mixed\\)\\)") nil t)
612          (not (bolp))
613          (re-search-forward "boundary=\"\\([^\"]+\\)\"" nil t))
614         (let ((boundary (buffer-substring (match-beginning 1) (match-end 1)))
615               start)
616           (cond
617            ((and (setq start (re-search-forward
618                               (concat "^--" boundary "\n"
619                                       "\\([Cc]ontent-[Dd]escription:.*\n\\)?"
620                                       "[Cc]ontent-[Tt]ype:[ \t]+"
621                                       "\\(message/rfc822\\|text/rfc822-headers\\)\n"
622                                       "\\(.+\n\\)*\n") nil t))
623                  (re-search-forward
624                   (concat "\n\\(--" boundary "\\)--\n") nil t))
625             (wl-draft-edit-string (buffer-substring start (match-beginning 1))))
626            (t
627             (message "Seems no message/rfc822 part.")))))
628        ((let ((case-fold-search t))
629           (re-search-forward wl-rejected-letter-start nil t))
630         (skip-chars-forward " \t\n")
631         (wl-draft-edit-string (buffer-substring (point) (point-max))))
632        (t
633         (message "Does not appear to be a rejected letter."))))))
634
635 (defun wl-summary-resend-message (address)
636   "Resend the current message to ADDRESS."
637   (interactive "sResend message to: ")
638   (if (or (null address) (string-match "^[ \t]*$" address))
639       (message "No address specified.")
640     (message "Resending message to %s..." address)
641     (save-excursion
642       (let ((original (wl-summary-get-original-buffer)))
643         ;; We first set up a normal mail buffer.
644         (set-buffer (get-buffer-create " *wl-draft-resend*"))
645         (buffer-disable-undo (current-buffer))
646         (erase-buffer)
647         (setq wl-sent-message-via nil)
648         ;; Insert our usual headers.
649         (wl-draft-insert-from-field)
650         (wl-draft-insert-date-field)
651         (insert "to: " address "\n")
652         (goto-char (point-min))
653         ;; Rename them all to "Resent-*".
654         (while (re-search-forward "^[A-Za-z]" nil t)
655           (forward-char -1)
656           (insert "Resent-"))
657         (widen)
658         (forward-line)
659         (delete-region (point) (point-max))
660         (let ((beg  (point)))
661           ;; Insert the message to be resent.
662           (insert-buffer-substring original)
663           (goto-char (point-min))
664           (search-forward "\n\n")
665           (forward-char -1)
666           (save-restriction
667             (narrow-to-region beg (point))
668             (wl-draft-delete-fields wl-ignored-resent-headers)
669             (goto-char (point-max)))
670           (insert mail-header-separator)
671           ;; Rename all old ("Previous-")Resent headers.
672           (while (re-search-backward "^\\(Previous-\\)*Resent-" beg t)
673             (beginning-of-line)
674             (insert "Previous-"))
675           ;; Quote any "From " lines at the beginning.
676           (goto-char beg)
677           (when (looking-at "From ")
678             (replace-match "X-From-Line: ")))
679         ;; Send it.
680         (wl-draft-dispatch-message)
681         (kill-buffer (current-buffer)))
682       (message "Resending message to %s...done" address))))
683
684 (defun wl-summary-buffer-set-folder (folder)
685   (if (stringp folder)
686       (setq folder (wl-folder-get-elmo-folder folder)))
687   (setq wl-summary-buffer-elmo-folder folder)
688   (setq wl-summary-buffer-folder-indicator
689         (if (memq 'modeline wl-use-folder-petname)
690             (wl-folder-get-petname (elmo-folder-name-internal folder))
691           (elmo-folder-name-internal folder)))
692   (make-local-variable 'wl-message-buffer)
693   (setq wl-summary-buffer-mime-charset (or (wl-get-assoc-list-value
694                                             wl-folder-mime-charset-alist
695                                             (elmo-folder-name-internal folder))
696                                            wl-mime-charset))
697   (setq wl-summary-buffer-weekday-name-lang
698         (or (wl-get-assoc-list-value
699              wl-folder-weekday-name-lang-alist
700              (elmo-folder-name-internal folder))
701             wl-summary-weekday-name-lang))
702   (setq wl-summary-buffer-thread-indent-set
703         (wl-get-assoc-list-value
704          wl-folder-thread-indent-set-alist
705          (elmo-folder-name-internal folder)))
706   (setq wl-summary-buffer-number-column
707         (or (wl-get-assoc-list-value wl-summary-number-column-alist
708                                      (wl-summary-buffer-folder-name))
709             wl-summary-default-number-column))
710   (wl-line-formatter-setup
711    wl-summary-buffer-line-formatter
712    (or (wl-get-assoc-list-value
713         wl-folder-summary-line-format-alist
714         (elmo-folder-name-internal folder))
715        wl-summary-line-format)
716    wl-summary-line-format-spec-alist)
717   (setq wl-summary-buffer-persistent
718         (wl-folder-persistent-p (elmo-folder-name-internal folder)))
719   (elmo-folder-set-persistent-internal folder wl-summary-buffer-persistent)
720   ;; process duplicates.
721   (elmo-folder-set-process-duplicates-internal
722    folder (cdr (elmo-string-matched-assoc
723                 (elmo-folder-name-internal folder)
724                 wl-folder-process-duplicates-alist)))
725   (setq
726    wl-thread-indent-level-internal
727    (or (nth 0 wl-summary-buffer-thread-indent-set)
728        wl-thread-indent-level)
729    wl-thread-have-younger-brother-str-internal
730    (or (nth 1 wl-summary-buffer-thread-indent-set)
731        wl-thread-have-younger-brother-str)
732    wl-thread-youngest-child-str-internal
733    (or (nth 2 wl-summary-buffer-thread-indent-set)
734        wl-thread-youngest-child-str)
735    wl-thread-vertical-str-internal
736    (or (nth 3 wl-summary-buffer-thread-indent-set)
737        wl-thread-vertical-str)
738    wl-thread-horizontal-str-internal
739    (or (nth 4 wl-summary-buffer-thread-indent-set)
740        wl-thread-horizontal-str)
741    wl-thread-space-str-internal
742    (or (nth 5 wl-summary-buffer-thread-indent-set)
743        wl-thread-space-str))
744   (setq wl-thread-indent-regexp
745         (concat
746          (regexp-quote wl-thread-have-younger-brother-str-internal) "\\|"
747          (regexp-quote wl-thread-youngest-child-str-internal) "\\|"
748          (regexp-quote wl-thread-vertical-str-internal) "\\|"
749          (regexp-quote wl-thread-horizontal-str-internal) "\\|"
750          (regexp-quote wl-thread-space-str-internal)))
751   (run-hooks 'wl-summary-buffer-set-folder-hook))
752
753 (defun wl-summary-mode ()
754   "Major mode for reading threaded messages.
755 See Info under Wanderlust for full documentation.
756
757 Special commands:
758 \\{wl-summary-mode-map}
759
760 Entering Folder mode calls the value of `wl-summary-mode-hook'."
761   (interactive)
762   (unless (interactive-p) (kill-all-local-variables))
763   (setq major-mode 'wl-summary-mode)
764   (setq mode-name "Summary")
765   (use-local-map wl-summary-mode-map)
766 ;;;(setq default-directory (or wl-tmp-dir (expand-file-name "~/")))
767   (setq buffer-read-only t)
768   (setq truncate-lines t)
769 ;;;(make-local-variable 'tab-width)
770 ;;;(setq tab-width 1)
771   (buffer-disable-undo (current-buffer))
772   (wl-mode-line-buffer-identification '("Wanderlust: "
773                                         wl-summary-buffer-folder-indicator
774                                         wl-summary-buffer-unread-status))
775   (easy-menu-add wl-summary-mode-menu)
776   (when wl-summary-lazy-highlight
777     (make-local-variable 'window-scroll-functions)
778     (add-hook 'window-scroll-functions 'wl-highlight-summary-window))
779   ;; This hook may contain the function `wl-setup-summary' for reasons
780   ;; of system internal to accord facilities for the Emacs variants.
781   (run-hooks 'wl-summary-mode-hook))
782
783 (defun wl-summary-overview-entity-compare-by-date (x y)
784   "Compare entity X and Y by date."
785   (condition-case nil
786       (string<
787        (timezone-make-date-sortable
788         (elmo-msgdb-overview-entity-get-date x))
789        (timezone-make-date-sortable
790         (elmo-msgdb-overview-entity-get-date y)))
791     (error))) ;; ignore error.
792
793 (defun wl-summary-overview-entity-compare-by-number (x y)
794    "Compare entity X and Y by number."
795   (<
796    (elmo-msgdb-overview-entity-get-number x)
797    (elmo-msgdb-overview-entity-get-number y)))
798
799 (defun wl-summary-overview-entity-compare-by-from (x y)
800   "Compare entity X and Y by from."
801   (string<
802    (wl-address-header-extract-address
803     (or (elmo-msgdb-overview-entity-get-from-no-decode x)
804         wl-summary-no-from-message))
805    (wl-address-header-extract-address
806     (or (elmo-msgdb-overview-entity-get-from-no-decode y)
807         wl-summary-no-from-message))))
808
809 (defun wl-summary-overview-entity-compare-by-subject (x y)
810   "Compare entity X and Y by subject."
811   (string< (elmo-msgdb-overview-entity-get-subject-no-decode x)
812            (elmo-msgdb-overview-entity-get-subject-no-decode y)))
813
814 (defun wl-summary-sort-by-date ()
815   (interactive)
816   (wl-summary-rescan "date"))
817 (defun wl-summary-sort-by-number ()
818   (interactive)
819   (wl-summary-rescan "number"))
820 (defun wl-summary-sort-by-subject ()
821   (interactive)
822   (wl-summary-rescan "subject"))
823 (defun wl-summary-sort-by-from ()
824   (interactive)
825   (wl-summary-rescan "from"))
826
827 (defun wl-summary-rescan (&optional sort-by)
828   "Rescan current folder without updating."
829   (interactive)
830   (let* ((cur-buf (current-buffer))
831          (msgdb (wl-summary-buffer-msgdb))
832          (overview (elmo-msgdb-get-overview msgdb))
833          (number-alist (elmo-msgdb-get-number-alist msgdb))
834          (elmo-mime-charset wl-summary-buffer-mime-charset)
835          i percent num
836          gc-message entity
837          curp
838          (inhibit-read-only t)
839          (buffer-read-only nil)
840          expunged)
841     (fset 'wl-summary-append-message-func-internal
842           (wl-summary-get-append-message-func))
843     (erase-buffer)
844     (message "Re-scanning...")
845     (setq i 0)
846     (setq num (length overview))
847     (when sort-by
848       (message "Sorting by %s..." sort-by)
849       (setq overview
850             (sort overview
851                   (intern (format "wl-summary-overview-entity-compare-by-%s"
852                                   sort-by))))
853       (message "Sorting by %s...done" sort-by)
854       (elmo-msgdb-set-overview (wl-summary-buffer-msgdb)
855                                overview))
856     (setq curp overview)
857     (set-buffer cur-buf)
858     (setq wl-thread-entity-hashtb (elmo-make-hash (* (length overview) 2)))
859     (setq wl-thread-entity-list nil)
860     (setq wl-thread-entities nil)
861     (setq wl-summary-buffer-number-list nil)
862     (setq wl-summary-buffer-target-mark-list nil)
863     (setq wl-summary-buffer-refile-list nil)
864     (setq wl-summary-buffer-delete-list nil)
865     (setq wl-summary-delayed-update nil)
866     (elmo-kill-buffer wl-summary-search-buf-name)
867     (message "Constructing summary structure...")
868     (while curp
869       (setq entity (car curp))
870       (wl-summary-append-message-func-internal entity msgdb nil)
871       (setq curp (cdr curp))
872       (when (> num elmo-display-progress-threshold)
873         (setq i (+ i 1))
874         (if (or (zerop (% i 5)) (= i num))
875             (elmo-display-progress
876              'wl-summary-rescan "Constructing summary structure..."
877              (/ (* i 100) num)))))
878     (when wl-summary-delayed-update
879       (while wl-summary-delayed-update
880         (message "Parent (%d) of message %d is no entity"
881                  (caar wl-summary-delayed-update)
882                  (elmo-msgdb-overview-entity-get-number
883                   (cdar wl-summary-delayed-update)))
884         (wl-summary-append-message-func-internal
885          (cdar wl-summary-delayed-update) msgdb nil t)
886         (setq wl-summary-delayed-update (cdr wl-summary-delayed-update))))
887     (message "Constructing summary structure...done")
888     (set-buffer cur-buf)
889     (if (eq wl-summary-buffer-view 'thread)
890         (progn
891           (message "Inserting thread...")
892           (wl-thread-insert-top)
893           (message "Inserting thread...done"))
894       (wl-summary-make-number-list))
895     (when wl-use-scoring
896       (setq wl-summary-scored nil)
897       (wl-summary-score-headers nil msgdb
898                                 (wl-summary-rescore-msgs number-alist)
899                                 t)
900       (when (and wl-summary-scored
901                  (setq expunged (wl-summary-score-update-all-lines)))
902         (message "%d message(s) are expunged by scoring." (length expunged))))
903     (wl-summary-set-message-modified)
904     (wl-summary-count-unread)
905     (wl-summary-update-modeline)
906     (goto-char (point-max))
907     (forward-line -1)
908     (set-buffer-modified-p nil)))
909
910 (defun wl-summary-next-folder-or-exit (&optional next-entity upward)
911   (if (and next-entity
912            wl-auto-select-next)
913       (let (retval)
914         (wl-summary-toggle-disp-msg 'off)
915         (unwind-protect
916             (setq retval
917                   (wl-summary-goto-folder-subr next-entity
918                                                'force-update
919                                                nil
920                                                nil ; not sticky
921                                                t   ; interactive!
922                                                ))
923           (wl-folder-set-current-entity-id (wl-folder-get-entity-id next-entity))
924           (if (and (eq retval 'more-next)
925                    (memq wl-auto-select-next '(unread skip-no-unread))
926                    (memq this-command wl-summary-next-no-unread-command))
927               (if upward
928                   (wl-summary-up
929                    t (eq wl-auto-select-next 'skip-no-unread))
930                 (goto-char (point-max))
931                 (forward-line -1)
932                 (wl-summary-down
933                  t (eq wl-auto-select-next 'skip-no-unread))))))
934     (wl-summary-exit)))
935
936 (defun wl-summary-entity-info-msg (entity finfo)
937   (or (and entity
938            (concat
939             (elmo-replace-in-string
940              (if (memq 'ask-folder wl-use-folder-petname)
941                  (wl-folder-get-petname entity)
942                entity)
943              "%" "%%")
944             (if (null (car finfo))
945                 " (? new/? unread)"
946               (format
947                " (%d new/%d unread)"
948                (nth 0 finfo)
949                (+ (nth 0 finfo)
950                   (nth 1 finfo))))))
951       "folder mode"))
952
953 (defun wl-summary-set-message-modified ()
954   (elmo-folder-set-message-modified-internal
955    wl-summary-buffer-elmo-folder t)
956   (setq wl-summary-buffer-message-modified t))
957 (defun wl-summary-message-modified-p ()
958   wl-summary-buffer-message-modified)
959 (defun wl-summary-set-mark-modified ()
960   (elmo-folder-set-mark-modified-internal
961    wl-summary-buffer-elmo-folder t)
962   (setq wl-summary-buffer-mark-modified t))
963 (defun wl-summary-mark-modified-p ()
964   wl-summary-buffer-mark-modified)
965 (defun wl-summary-set-thread-modified ()
966   (setq wl-summary-buffer-thread-modified t))
967 (defun wl-summary-thread-modified-p ()
968   wl-summary-buffer-thread-modified)
969
970 (defsubst wl-summary-cleanup-temp-marks (&optional sticky)
971   (if (or wl-summary-buffer-refile-list
972           wl-summary-buffer-copy-list
973           wl-summary-buffer-delete-list)
974       (if (y-or-n-p "Marks remain to be executed.  Execute them? ")
975           (progn
976             (wl-summary-exec)
977             (if (or wl-summary-buffer-refile-list
978                     wl-summary-buffer-copy-list
979                     wl-summary-buffer-delete-list)
980                 (error "Some execution was failed")))
981         ;; delete temp-marks
982         (message "")
983         (wl-summary-delete-all-refile-marks)
984         (wl-summary-delete-all-copy-marks)
985         (wl-summary-delete-all-delete-marks)))
986   (if wl-summary-buffer-target-mark-list
987       (progn
988         (wl-summary-delete-all-target-marks)
989         (setq wl-summary-buffer-target-mark-list nil)))
990   (wl-summary-delete-all-temp-marks-on-buffer sticky)
991   (setq wl-summary-scored nil))
992
993 ;; a subroutine for wl-summary-exit/wl-save-status
994 ;; Note that folder is not commited here.
995 (defun wl-summary-save-view ()
996   ;; already in summary buffer.
997   (when wl-summary-buffer-persistent
998     ;; save the current summary buffer view.
999     (if (and wl-summary-cache-use
1000              (or (wl-summary-message-modified-p)
1001                  (wl-summary-mark-modified-p)
1002                  (wl-summary-thread-modified-p)))
1003         (wl-summary-save-view-cache))))
1004
1005 (defun wl-summary-save-status ()
1006   "Save summary view and msgdb."
1007   (interactive)
1008   (if (interactive-p) (message "Saving summary status..."))
1009   (wl-summary-save-view)
1010   (elmo-folder-commit wl-summary-buffer-elmo-folder)
1011   (elmo-folder-check wl-summary-buffer-elmo-folder)
1012   (if wl-use-scoring (wl-score-save))
1013   (if (interactive-p) (message "Saving summary status...done.")))
1014
1015 (defun wl-summary-force-exit ()
1016   "Exit current summary.  Buffer is deleted even the buffer is sticky."
1017   (interactive)
1018   (wl-summary-exit 'force-exit))
1019
1020 (defun wl-summary-exit (&optional force-exit)
1021   "Exit current summary.  if FORCE-EXIT, exits even the summary is sticky."
1022   (interactive "P")
1023   (let ((summary-buf (current-buffer))
1024         (sticky (wl-summary-sticky-p))
1025         summary-win
1026         message-buf message-win
1027         folder-buf folder-win)
1028     (run-hooks 'wl-summary-exit-pre-hook)
1029     (if wl-summary-buffer-exit-function
1030         (funcall wl-summary-buffer-exit-function)
1031       (if (or force-exit (not sticky))
1032           (wl-summary-cleanup-temp-marks sticky))
1033       (unwind-protect
1034           ;; save summary status
1035           (progn
1036             (wl-summary-save-view)
1037             (if (or force-exit (not sticky))
1038                 (elmo-folder-close wl-summary-buffer-elmo-folder)
1039               (elmo-folder-commit wl-summary-buffer-elmo-folder)
1040               (elmo-folder-check wl-summary-buffer-elmo-folder))
1041             (if wl-use-scoring (wl-score-save)))
1042         ;; for sticky summary
1043         (wl-delete-all-overlays)
1044         (setq wl-summary-buffer-disp-msg nil)
1045         (elmo-kill-buffer wl-summary-search-buf-name)
1046         ;; delete message window if displayed.
1047         (if (and wl-message-buffer (get-buffer-window wl-message-buffer))
1048             (delete-window (get-buffer-window wl-message-buffer)))
1049         (if (and wl-summary-use-frame
1050                  (> (length (visible-frame-list)) 1))
1051             (delete-frame))
1052         (if (setq folder-buf (get-buffer wl-folder-buffer-name))
1053             (if wl-summary-use-frame
1054                 (let (select-frame)
1055                   (save-selected-window
1056                     (dolist (frame (visible-frame-list))
1057                       (select-frame frame)
1058                       (if (get-buffer-window folder-buf)
1059                           (setq select-frame frame))))
1060                   (if select-frame
1061                       (select-frame select-frame)
1062                     (switch-to-buffer folder-buf)))
1063               (if (setq folder-win (get-buffer-window folder-buf))
1064                   ;; folder win is already displayed.
1065                   (select-window folder-win)
1066                 ;; folder win is not displayed.
1067                 (switch-to-buffer folder-buf)))
1068           ;; currently no folder buffer
1069           (wl-folder))
1070         (and wl-folder-move-cur-folder
1071              wl-folder-buffer-cur-point
1072              (goto-char wl-folder-buffer-cur-point))
1073         (setq wl-folder-buffer-cur-path nil)
1074         (setq wl-folder-buffer-cur-entity-id nil)
1075         (wl-delete-all-overlays)
1076         (if wl-summary-exit-next-move
1077             (wl-folder-next-unsync t)
1078           (beginning-of-line))
1079         (if (setq summary-win (get-buffer-window summary-buf))
1080             (delete-window summary-win))
1081         (if (or force-exit
1082                 (not sticky))
1083             (progn
1084               (set-buffer summary-buf)
1085               (kill-buffer summary-buf)))
1086         (run-hooks 'wl-summary-exit-hook)))))
1087
1088 (defun wl-summary-suspend ()
1089   (interactive)
1090   (wl-summary-exit)
1091   (wl-folder-suspend))
1092
1093 (defun wl-summary-sync-force-update (&optional unset-cursor no-check)
1094   (interactive)
1095   (wl-summary-sync-update unset-cursor nil no-check))
1096
1097 (defsubst wl-summary-sync-all-init ()
1098   (wl-summary-cleanup-temp-marks)
1099   (erase-buffer)
1100   (wl-summary-set-message-modified)
1101   (wl-summary-set-mark-modified)
1102   (setq wl-thread-entity-hashtb (elmo-make-hash
1103                                  (* (length (elmo-msgdb-get-number-alist
1104                                              (wl-summary-buffer-msgdb))) 2)))
1105   (setq wl-thread-entity-list nil)
1106   (setq wl-thread-entities nil)
1107   (setq wl-summary-buffer-number-list nil)
1108   (setq wl-summary-buffer-target-mark-list nil)
1109   (setq wl-summary-buffer-refile-list nil)
1110   (setq wl-summary-buffer-copy-list nil)
1111   (setq wl-summary-buffer-delete-list nil))
1112
1113 (defun wl-summary-sync (&optional unset-cursor force-range)
1114   (interactive)
1115   (let* ((folder wl-summary-buffer-elmo-folder)
1116          (inhibit-read-only t)
1117          (buffer-read-only nil)
1118          (msgdb-dir (elmo-folder-msgdb-path folder))
1119          (range (or force-range (wl-summary-input-range
1120                                  (elmo-folder-name-internal folder)))))
1121     (cond ((string= range "rescan")
1122            (let ((msg (wl-summary-message-number)))
1123              (wl-summary-rescan)
1124              (and msg (wl-summary-jump-to-msg msg))))
1125           ((string= range "rescan-noscore")
1126            (let ((msg (wl-summary-message-number))
1127                  wl-use-scoring)
1128              (wl-summary-rescan)
1129              (and msg (wl-summary-jump-to-msg msg))))
1130           ((string= range "cache-status")
1131            (let ((msg (wl-summary-message-number)))
1132              (wl-summary-resume-cache-status)
1133              (and msg (wl-summary-jump-to-msg msg))))
1134           ((or (string-match "last:" range)
1135                (string-match "first:" range))
1136            (wl-summary-goto-folder-subr (concat "/" range "/"
1137                                                 (elmo-folder-name-internal
1138                                                  folder))
1139             'force-update nil nil t))
1140           (t
1141            (wl-summary-sync-update unset-cursor
1142                                    (cond ((string= range "all") 'all)
1143                                          ((string= range "all-visible")
1144                                           'visible-only)))))))
1145
1146 (defvar wl-summary-edit-addresses-candidate-fields
1147   ;; First element becomes default.
1148   '("from" "to" "cc"))
1149
1150 (defun wl-summary-edit-addresses-collect-candidate-fields (mime-charset)
1151   (let ((fields wl-summary-edit-addresses-candidate-fields)
1152         body candidates components)
1153     (while fields
1154       (setq body
1155             (mapconcat 'identity (elmo-multiple-field-body (car fields))
1156                        ","))
1157       (setq body (wl-parse-addresses body))
1158       (if body (setq candidates (append candidates body)))
1159       (setq fields (cdr fields)))
1160     (setq candidates (elmo-uniq-list candidates))
1161     (elmo-set-work-buf
1162      (elmo-set-buffer-multibyte default-enable-multibyte-characters)
1163      (mapcar (function
1164               (lambda (x)
1165                 (setq components (std11-extract-address-components x))
1166                 (cons (nth 1 components)
1167                       (and (car components)
1168                            (eword-decode-string
1169                             (decode-mime-charset-string
1170                              (car components)
1171                              mime-charset))))))
1172              candidates))))
1173
1174 (defun wl-summary-edit-addresses-subr (the-email name-in-addr)
1175   ;; returns nil if there's no change.
1176   (if (elmo-get-hash-val (downcase the-email) wl-address-petname-hash)
1177       (let (char)
1178         (message "'%s' already exists. (e)dit/(d)elete/(c)ancel?"
1179                  the-email)
1180         (while (not (or (eq (setq char (read-char)) ?\r)
1181                         (eq char ?\n)
1182                         (eq char ? )
1183                         (eq char ?e)
1184                         (eq char ?c)
1185                         (eq char ?d)))
1186           (message
1187            "Please answer `e' or `d' or `c'. (e)dit/(d)elete/(c)ancel?"))
1188         (cond
1189          ((or (eq char ?e)
1190               (eq char ?\n)
1191               (eq char ?\r)
1192               (eq char ? ))
1193           ;; Change Addresses
1194           (wl-address-add-or-change
1195            the-email
1196            (wl-address-header-extract-realname
1197             (cdr (assoc
1198                   (let ((completion-ignore-case t) comp)
1199                     (setq comp
1200                           (try-completion the-email wl-address-completion-list))
1201                     (if (equal comp t) the-email comp))
1202                   wl-address-completion-list))))
1203           "edited")
1204          ((eq char ?d)
1205           ;; Delete Addresses
1206           (if (y-or-n-p (format "Delete '%s'? "
1207                                 the-email))
1208               (progn
1209                 (wl-address-delete the-email)
1210                 "deleted")
1211             (message "")
1212             nil))
1213          (t (message "")
1214             nil)))
1215     ;; Add Petname
1216     (wl-address-add-or-change the-email name-in-addr)
1217     "added"))
1218
1219 (defun wl-summary-edit-addresses (&optional addr-str)
1220   "Edit address book interactively.
1221 Optional argument ADDR-STR is used as a target address if specified."
1222   (interactive (if current-prefix-arg
1223                    (list (read-from-minibuffer "Target address: "))))
1224   (if (null (wl-summary-message-number))
1225       (message "No message.")
1226     (save-excursion
1227       (let* ((charset wl-summary-buffer-mime-charset)
1228              (candidates
1229               (with-current-buffer (wl-summary-get-original-buffer)
1230                 (wl-summary-edit-addresses-collect-candidate-fields
1231                  charset)))
1232              address pair result)
1233         (if addr-str
1234             (setq address addr-str)
1235           (when candidates
1236             (setq address (car (car candidates)))
1237             (setq address
1238                   (completing-read
1239                    (format "Target address (%s): " address)
1240                    (mapcar
1241                     (function (lambda (x) (cons (car x) (car x))))
1242                     candidates)
1243                    nil nil nil nil address))))
1244         (when address
1245           (setq pair (assoc address candidates))
1246           (unless pair
1247             (setq pair (cons address nil)))
1248           (when (setq result (wl-summary-edit-addresses-subr (car pair) (cdr pair)))
1249             ;; update alias
1250             (wl-status-update)
1251             (setq address (assoc (car pair) wl-address-list))
1252             (if address
1253                 (message "%s, %s, <%s> is %s."
1254                          (nth 2 address)
1255                          (nth 1 address)
1256                          (nth 0 address)
1257                          result)))
1258 ;;; i'd like to update summary-buffer, but...
1259 ;;;     (wl-summary-rescan)
1260           (run-hooks 'wl-summary-edit-addresses-hook))))))
1261
1262 (defun wl-summary-incorporate (&optional arg)
1263   "Check and prefetch all uncached messages.
1264 If ARG is non-nil, checking is omitted."
1265   (interactive "P")
1266   (unless arg
1267     (save-excursion
1268       (wl-summary-sync-force-update)))
1269   (wl-summary-prefetch-region (point-min) (point-max)
1270                               wl-summary-incorporate-marks))
1271
1272 (defun wl-summary-prefetch-msg (number &optional arg)
1273   "Returns status-mark. if skipped, returns nil."
1274   ;; prefetching procedure.
1275   (save-excursion
1276     (let* ((msgdb (wl-summary-buffer-msgdb))
1277            (number-alist (elmo-msgdb-get-number-alist msgdb))
1278            (message-id (cdr (assq number number-alist)))
1279            (ov (elmo-msgdb-overview-get-entity message-id msgdb))
1280            (entity ov)
1281            (size (elmo-msgdb-overview-entity-get-size ov))
1282            (inhibit-read-only t)
1283            (buffer-read-only nil)
1284            (file-cached (elmo-file-cache-exists-p message-id))
1285            (force-read (and size
1286                             (or (null wl-prefetch-threshold)
1287                                 (< size wl-prefetch-threshold))))
1288            mark new-mark)
1289       (unwind-protect
1290           (progn
1291             (when (and (or arg (not file-cached))
1292                        size (not force-read) wl-prefetch-confirm)
1293               (setq force-read
1294                     (save-restriction
1295                       (widen)
1296                       (y-or-n-p
1297                        (format
1298                         "Message from %s has %d bytes.  Prefetch it? "
1299                         (concat
1300                          "[ "
1301                          (save-match-data
1302                            (wl-set-string-width
1303                             17
1304                             (funcall wl-summary-from-function
1305                              (eword-decode-string
1306                               (elmo-delete-char
1307                                ?\"
1308                                (or
1309                                 (elmo-msgdb-overview-entity-get-from ov)
1310                                 "??")))))) " ]")
1311                         size))))
1312               (message ""))             ; flush.
1313             (setq mark (elmo-msgdb-get-mark msgdb number))
1314             (if force-read
1315                 (save-excursion
1316                   (save-match-data
1317                     ;; online
1318                     (if (or arg (not file-cached))
1319                         (elmo-message-encache
1320                          wl-summary-buffer-elmo-folder
1321                          number))
1322                     (setq new-mark
1323                           (cond
1324                            ((string= mark
1325                                      wl-summary-unread-uncached-mark)
1326                             wl-summary-unread-cached-mark)
1327                            ((string= mark wl-summary-new-mark)
1328                             (setq wl-summary-buffer-new-count
1329                                   (- wl-summary-buffer-new-count 1))
1330                             (setq wl-summary-buffer-unread-count
1331                                   (+ wl-summary-buffer-unread-count 1))
1332                             wl-summary-unread-cached-mark)
1333                            ((string= mark wl-summary-read-uncached-mark)
1334                             nil)
1335                            (t mark)))
1336                     (elmo-msgdb-set-mark msgdb number new-mark)
1337                     (or new-mark (setq new-mark " "))
1338                     (wl-summary-set-mark-modified)
1339                     (wl-summary-update-modeline)
1340                     (wl-folder-update-unread
1341                      (wl-summary-buffer-folder-name)
1342                      (+ wl-summary-buffer-unread-count
1343                         wl-summary-buffer-new-count)))
1344                   new-mark)))))))
1345
1346 ;;(defvar wl-summary-message-uncached-marks
1347 ;;  (list wl-summary-new-mark
1348 ;;      wl-summary-unread-uncached-mark
1349 ;;      wl-summary-read-uncached-mark))
1350
1351 (defun wl-summary-prefetch-region (beg end &optional prefetch-marks)
1352   (interactive "r")
1353   (let ((count 0)
1354         targets
1355         mark length
1356         entity msg
1357         start-pos pos)
1358     (save-excursion
1359       (setq start-pos (point))
1360       (save-restriction
1361         (narrow-to-region beg end)
1362         ;; collect prefetch targets.
1363         (message "Collecting marks...")
1364         (goto-char (point-min))
1365         (while (not (eobp))
1366           (beginning-of-line)
1367           (when (looking-at "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)")
1368             (setq mark (wl-match-buffer 2))
1369             (setq msg (string-to-int (wl-match-buffer 1)))
1370             (if (or (and (null prefetch-marks)
1371                          msg
1372                          (null (elmo-file-cache-exists-p
1373                                 (cdr (assq msg
1374                                            (elmo-msgdb-get-number-alist
1375                                             (wl-summary-buffer-msgdb)))))))
1376                     (member mark prefetch-marks))
1377                 (setq targets (nconc targets (list msg))))
1378             (setq entity (wl-thread-get-entity msg))
1379             (if (or (not (eq wl-summary-buffer-view 'thread))
1380                     (wl-thread-entity-get-opened entity))
1381                 (); opened. no hidden children.
1382               ;; hidden children!!
1383               (setq targets (nconc
1384                              targets
1385                              (wl-thread-get-children-msgs-uncached
1386                               msg prefetch-marks)))))
1387           (forward-line 1))
1388         (setq length (length targets))
1389         (message "Prefetching...")
1390         (while targets
1391           (setq mark (if (not (wl-thread-entity-parent-invisible-p
1392                                (wl-thread-get-entity (car targets))))
1393                          (progn
1394                            (wl-summary-jump-to-msg (car targets))
1395                            (wl-summary-prefetch))
1396                        (wl-summary-prefetch-msg (car targets))))
1397           (if (if prefetch-marks
1398                   (string= mark wl-summary-unread-cached-mark)
1399                 (or (string= mark wl-summary-unread-cached-mark)
1400                     (string= mark " ")))
1401               (message "Prefetching... %d/%d message(s)"
1402                        (setq count (+ 1 count)) length))
1403           ;; redisplay!
1404           (save-excursion
1405             (setq pos (point))
1406             (goto-char start-pos)
1407             (if (pos-visible-in-window-p pos)
1408                 (save-restriction
1409                   (widen)
1410                   (sit-for 0))))
1411           (setq targets (cdr targets)))
1412         (message "Prefetched %d/%d message(s)" count length)
1413         (cons count length)))))
1414
1415 (defun wl-summary-prefetch (&optional arg)
1416   "Prefetch current message."
1417   (interactive "P")
1418   (save-excursion
1419     (save-match-data
1420       (beginning-of-line)
1421       (when (looking-at "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)")
1422         (goto-char (match-beginning 2))
1423         (let ((inhibit-read-only t)
1424               (buffer-read-only nil)
1425               (beg (match-beginning 2))
1426               (end (match-end 2))
1427               mark)
1428           (setq mark (wl-summary-prefetch-msg
1429                       (string-to-int (wl-match-buffer 1)) arg))
1430           (when mark
1431             (delete-region beg end)
1432             (insert mark)
1433             (if wl-summary-highlight
1434                 (wl-highlight-summary-current-line)))
1435           (set-buffer-modified-p nil)
1436           mark)))))
1437
1438 (defun wl-summary-delete-marks-on-buffer (marks)
1439   (while marks
1440     (wl-summary-unmark (pop marks))))
1441
1442 (defun wl-summary-delete-copy-marks-on-buffer (copies)
1443   (wl-summary-delete-marks-on-buffer copies))
1444
1445 (defun wl-summary-delete-all-refile-marks ()
1446   (let ((marks wl-summary-buffer-refile-list))
1447     (while marks
1448       (wl-summary-unmark (car (pop marks))))))
1449
1450 (defun wl-summary-delete-all-copy-marks ()
1451   (let ((marks wl-summary-buffer-copy-list))
1452     (while marks
1453       (wl-summary-unmark (car (pop marks))))))
1454
1455 (defun wl-summary-delete-all-delete-marks ()
1456   (wl-summary-delete-marks-on-buffer wl-summary-buffer-delete-list))
1457
1458 (defun wl-summary-delete-all-target-marks ()
1459   (wl-summary-delete-marks-on-buffer wl-summary-buffer-target-mark-list))
1460
1461 (defun wl-summary-delete-all-temp-marks-on-buffer (&optional sticky)
1462   ;; for summary view cache saving.
1463   (interactive)
1464   (save-excursion
1465     (goto-char (point-min))
1466     (let ((inhibit-read-only t)
1467           (buffer-read-only nil)
1468           (case-fold-search nil)
1469           (regexp (concat wl-summary-message-regexp "\\([^ 0-9]\\)" )))
1470       (while (re-search-forward regexp nil t)
1471         (delete-region (match-beginning 1) (match-end 1))
1472         (insert " ")
1473         (if (and sticky wl-summary-highlight)
1474             (wl-highlight-summary-current-line))))))
1475
1476 ;; Does not work correctly...
1477 (defun wl-summary-mark-as-read-region (beg end)
1478   (interactive "r")
1479   (save-excursion
1480     (save-restriction
1481       (narrow-to-region beg end)
1482 ;;; use narrowing.
1483 ;;;   (save-excursion (goto-char end)
1484 ;;;                   (end-of-line) (point)))
1485       (goto-char (point-min))
1486       (if (eq wl-summary-buffer-view 'thread)
1487           (progn
1488             (while (not (eobp))
1489               (let* ((number (wl-summary-message-number))
1490                      (entity (wl-thread-get-entity number))
1491                      children)
1492                 (if (wl-thread-entity-get-opened entity)
1493                     ;; opened...mark line.
1494                     ;; Crossposts are not processed
1495                     (wl-summary-mark-as-read t)
1496                   ;; closed
1497                   (wl-summary-mark-as-read t) ; mark itself.
1498                   (setq children (wl-thread-get-children-msgs number))
1499                   (while children
1500                     (wl-summary-mark-as-read t nil nil (car children))
1501                     (setq children (cdr children))))
1502                 (forward-line 1))))
1503         (while (not (eobp))
1504           (wl-summary-mark-as-read t)
1505           (forward-line 1)))))
1506   (wl-summary-count-unread)
1507   (wl-summary-update-modeline))
1508
1509 (defun wl-summary-mark-as-unread-region (beg end)
1510   (interactive "r")
1511   (save-excursion
1512     (save-restriction
1513       (narrow-to-region beg end)
1514 ;;; use narrowing.
1515 ;;;      (save-excursion (goto-char end)
1516 ;;;                   (end-of-line) (point)))
1517       (goto-char (point-min))
1518       (if (eq wl-summary-buffer-view 'thread)
1519           (progn
1520             (while (not (eobp))
1521               (let* ((number (wl-summary-message-number))
1522                      (entity (wl-thread-get-entity number))
1523                      children)
1524                 (if (wl-thread-entity-get-opened entity)
1525                     ;; opened...mark line.
1526                     ;; Crossposts are not processed
1527                     (wl-summary-mark-as-unread)
1528                   ;; closed
1529                   (wl-summary-mark-as-unread) ; mark itself.
1530                   (setq children
1531                         (delq number (wl-thread-get-children-msgs number)))
1532                   (while children
1533                     (wl-summary-mark-as-unread (car children))
1534                     (setq children (cdr children))))
1535                 (forward-line 1))))
1536         (while (not (eobp))
1537           (wl-summary-mark-as-unread)
1538           (forward-line 1)))))
1539   (wl-summary-count-unread)
1540   (wl-summary-update-modeline))
1541
1542 (defun wl-summary-mark-as-important-region (beg end)
1543   (interactive "r")
1544   (save-excursion
1545     (save-restriction
1546       (narrow-to-region beg end);(save-excursion (goto-char end)
1547                                         ;    (end-of-line) (point)))
1548       (goto-char (point-min))
1549       (if (eq wl-summary-buffer-view 'thread)
1550           (progn
1551             (while (not (eobp))
1552               (let* ((number (wl-summary-message-number))
1553                      (entity (wl-thread-get-entity number))
1554                      children)
1555                 (if (wl-thread-entity-get-opened entity)
1556                     ;; opened...mark line.
1557                     ;; Crossposts are not processed
1558                     (wl-summary-mark-as-important)
1559                   ;; closed
1560                   (wl-summary-mark-as-important) ; mark itself.
1561                   (setq children
1562                         (delq number (wl-thread-get-children-msgs number)))
1563                   (while children
1564                     (wl-thread-msg-mark-as-important (car children))
1565                     (setq children (cdr children))))
1566                 (forward-line 1))))
1567         (while (not (eobp))
1568           (wl-summary-mark-as-important)
1569           (forward-line 1)))))
1570   (wl-summary-count-unread)
1571   (wl-summary-update-modeline))
1572
1573 (defun wl-summary-mark-as-read-all ()
1574   (interactive)
1575   (if (or (not (interactive-p))
1576           (y-or-n-p "Mark all messages as read? "))
1577       (let* ((folder wl-summary-buffer-elmo-folder)
1578              (cur-buf (current-buffer))
1579              (msgdb (wl-summary-buffer-msgdb))
1580              (inhibit-read-only t)
1581              (buffer-read-only nil)
1582              (case-fold-search nil)
1583              msg mark)
1584         (message "Setting all msgs as read...")
1585         (elmo-folder-mark-as-read folder
1586                                   (elmo-folder-list-unreads
1587                                    folder
1588                                    (list wl-summary-unread-cached-mark
1589                                          wl-summary-unread-uncached-mark
1590                                          wl-summary-new-mark)))
1591         (save-excursion
1592           (goto-char (point-min))
1593           (while (re-search-forward "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9 ]\\)"
1594                                     nil t)
1595             (setq msg (string-to-int (wl-match-buffer 1)))
1596             (setq mark (wl-match-buffer 2))
1597             (when (and (not (string= mark wl-summary-important-mark))
1598                        (not (string= mark wl-summary-read-uncached-mark)))
1599               (delete-region (match-beginning 2) (match-end 2))
1600               (if (or (not (elmo-message-use-cache-p folder msg))
1601                       (string= mark wl-summary-unread-cached-mark))
1602                   (progn
1603                     (insert " ")
1604                     (elmo-msgdb-set-mark msgdb msg nil))
1605                 ;; New mark and unread-uncached mark
1606                 (insert wl-summary-read-uncached-mark)
1607                 (elmo-msgdb-set-mark
1608                  msgdb msg wl-summary-read-uncached-mark))
1609               (if wl-summary-highlight
1610                   (wl-highlight-summary-current-line nil nil t)))))
1611         (elmo-folder-replace-marks
1612          folder
1613          (list (cons wl-summary-unread-cached-mark
1614                      nil)
1615                (cons wl-summary-unread-uncached-mark
1616                      wl-summary-read-uncached-mark)
1617                (cons wl-summary-new-mark
1618                      wl-summary-read-uncached-mark)))
1619         (wl-summary-set-mark-modified)
1620         (wl-folder-update-unread (wl-summary-buffer-folder-name) 0)
1621         (setq wl-summary-buffer-unread-count 0)
1622         (setq wl-summary-buffer-new-count    0)
1623         (wl-summary-update-modeline)
1624         (message "Setting all msgs as read...done")
1625         (set-buffer-modified-p nil))))
1626
1627 (defun wl-summary-delete-cache ()
1628   "Delete cache of current message."
1629   (interactive)
1630   (save-excursion
1631     (let* ((inhibit-read-only t)
1632            (buffer-read-only nil)
1633            (folder wl-summary-buffer-elmo-folder)
1634            (msgdb (wl-summary-buffer-msgdb))
1635            (number-alist (elmo-msgdb-get-number-alist msgdb))
1636            (case-fold-search nil)
1637            mark number unread new-mark)
1638       (beginning-of-line)
1639       (when (looking-at "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)")
1640         (progn
1641           (setq mark (wl-match-buffer 2))
1642           (cond
1643            ((or (string= mark wl-summary-new-mark)
1644                 (string= mark wl-summary-unread-uncached-mark)
1645                 (string= mark wl-summary-important-mark))
1646             ;; noop
1647             )
1648            ((string= mark wl-summary-unread-cached-mark)
1649             (setq new-mark wl-summary-unread-uncached-mark))
1650            (t
1651             (setq new-mark wl-summary-read-uncached-mark)))
1652           (when new-mark
1653             (setq number (string-to-int (wl-match-buffer 1)))
1654             (delete-region (match-beginning 2) (match-end 2))
1655             (goto-char (match-beginning 2))
1656             (insert new-mark)
1657             (elmo-file-cache-delete
1658              (elmo-file-cache-get-path
1659               (elmo-message-field wl-summary-buffer-elmo-folder
1660                                   number
1661                                   'message-id)))
1662             (elmo-msgdb-set-mark msgdb number new-mark)
1663             (wl-summary-set-mark-modified)
1664             (if wl-summary-highlight
1665                 (wl-highlight-summary-current-line nil nil t))
1666             (set-buffer-modified-p nil)))))))
1667
1668 (defun wl-summary-resume-cache-status ()
1669   "Resume the cache status of all messages in the current folder."
1670   (interactive)
1671   (let* ((folder wl-summary-buffer-elmo-folder)
1672          (cur-buf (current-buffer))
1673          (msgdb (wl-summary-buffer-msgdb))
1674          (number-alist (elmo-msgdb-get-number-alist msgdb))
1675          (inhibit-read-only t)
1676          (buffer-read-only nil)
1677          (case-fold-search nil)
1678          msg mark msgid set-mark)
1679     (message "Resuming cache status...")
1680     (save-excursion
1681       (goto-char (point-min))
1682       (while (re-search-forward "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)" nil t)
1683         (setq msg (string-to-int
1684                    (wl-match-buffer 1)))
1685         (setq mark (wl-match-buffer 2))
1686         (setq msgid (elmo-msgdb-get-field msgdb msg 'message-id))
1687         (setq set-mark nil)
1688         (if (elmo-file-cache-exists-p msgid)
1689             (if (or
1690                  (string= mark wl-summary-unread-uncached-mark) ; U -> !
1691                  (string= mark wl-summary-new-mark)             ; N -> !
1692                  )
1693                 (setq set-mark wl-summary-unread-cached-mark)
1694               (if (string= mark wl-summary-read-uncached-mark)  ; u -> ' '
1695                   (setq set-mark " ")))
1696           (if (string= mark " ")
1697               (setq set-mark wl-summary-read-uncached-mark)     ;' ' -> u
1698             (if (string= mark wl-summary-unread-cached-mark)
1699                 (setq set-mark wl-summary-unread-uncached-mark) ; !  -> U
1700               )))
1701         (when set-mark
1702           (delete-region (match-beginning 2) (match-end 2))
1703           (insert set-mark)
1704           (elmo-msgdb-set-mark msgdb msg
1705                                (if (string= set-mark " ") nil set-mark))
1706           (if wl-summary-highlight
1707               (wl-highlight-summary-current-line))))
1708       (wl-summary-set-mark-modified)
1709       (wl-summary-count-unread)
1710       (wl-summary-update-modeline)
1711       (message "Resuming cache status...done")
1712       (set-buffer-modified-p nil))))
1713
1714 (defun wl-summary-delete-messages-on-buffer (msgs &optional deleting-info)
1715   (interactive)
1716   (save-excursion
1717     (let ((inhibit-read-only t)
1718           (buffer-read-only nil)
1719           (msgs2 msgs)
1720           (len (length msgs))
1721           (i 0)
1722           update-list)
1723       (elmo-kill-buffer wl-summary-search-buf-name)
1724       (while msgs
1725         (if (eq wl-summary-buffer-view 'thread)
1726             (progn
1727               ;; don't use wl-append(nconc), because list is broken. ...why?
1728               (setq update-list
1729                     (append update-list
1730                             (wl-thread-delete-message (car msgs))))
1731               (setq update-list (delq (car msgs) update-list)))
1732           (goto-char (point-min))
1733           (if (re-search-forward (format "^ *%d[^0-9]\\([^0-9]\\).*$"
1734                                          (car msgs)) nil t)
1735               (progn
1736                 (delete-region (match-beginning 0) (match-end 0))
1737                 (delete-char 1) ; delete '\n'
1738                 (setq wl-summary-buffer-number-list
1739                       (delq (car msgs) wl-summary-buffer-number-list)))))
1740         (when (and deleting-info
1741                    (> len elmo-display-progress-threshold))
1742           (setq i (1+ i))
1743           (if (or (zerop (% i 5)) (= i len))
1744               (elmo-display-progress
1745                'wl-summary-delete-messages-on-buffer deleting-info
1746                (/ (* i 100) len))))
1747         (setq msgs (cdr msgs)))
1748       (when (eq wl-summary-buffer-view 'thread)
1749         (wl-thread-update-line-msgs (elmo-uniq-list update-list)
1750                                     (unless deleting-info 'no-msg))
1751         (wl-thread-cleanup-symbols msgs2))
1752       (wl-summary-count-unread)
1753       (wl-summary-update-modeline)
1754       (wl-folder-update-unread
1755        (wl-summary-buffer-folder-name)
1756        (+ wl-summary-buffer-unread-count wl-summary-buffer-new-count)))))
1757
1758 (defun wl-summary-replace-status-marks (before after)
1759   "Replace the status marks on buffer."
1760   (interactive)
1761   (save-excursion
1762     (goto-char (point-min))
1763     (let ((inhibit-read-only t)
1764           (buffer-read-only nil)
1765           (regexp (concat wl-summary-message-regexp ".\\(\\%s\\)")))
1766       (while (re-search-forward
1767               (format regexp (regexp-quote before)) nil t)
1768         (delete-region (match-beginning 1) (match-end 1))
1769         (insert after)
1770         (if wl-summary-highlight
1771             (wl-highlight-summary-current-line))))))
1772
1773 (defun wl-summary-get-delete-folder (folder)
1774   (if (string= folder wl-trash-folder)
1775       'null
1776     (let* ((type (or (wl-get-assoc-list-value wl-delete-folder-alist folder)
1777                      'trash)))
1778       (cond ((stringp type)
1779              type)
1780             ((or (equal type 'remove) (equal type 'null))
1781              'null)
1782             (t;; (equal type 'trash)
1783              (let ((trash-folder (wl-folder-get-elmo-folder wl-trash-folder)))
1784                (unless (elmo-folder-exists-p trash-folder)
1785                  (if (y-or-n-p
1786                       (format "Trash Folder %s does not exist, create it? "
1787                               wl-trash-folder))
1788                      (elmo-folder-create trash-folder)
1789                    (error "Trash Folder is not created"))))
1790                wl-trash-folder)))))
1791
1792 (defun wl-summary-get-append-message-func ()
1793   (if (eq wl-summary-buffer-view 'thread)
1794       'wl-summary-insert-thread-entity
1795     'wl-summary-insert-sequential))
1796
1797 (defun wl-summary-sort ()
1798   (interactive)
1799   (let ((sort-by (let ((input-range-list '("number" "date" "subject" "from"))
1800                        (default "date")
1801                        in)
1802                    (setq in
1803                          (completing-read
1804                           (format "Sort by (%s): " default)
1805                           (mapcar
1806                            (function (lambda (x) (cons x x)))
1807                            input-range-list)))
1808                    (if (string= in "")
1809                        default
1810                      in))))
1811     (if (not (member sort-by '("number" "date" "subject" "from")))
1812         (error "Sort by %s is not implemented"  sort-by))
1813     (wl-summary-rescan sort-by)))
1814
1815 (defun wl-summary-sync-marks ()
1816   "Update marks in summary."
1817   (interactive)
1818   (let ((last-progress 0)
1819         (i 0)
1820         unread-marks importants unreads
1821         importants-in-db unreads-in-db diff diffs
1822         mes progress)
1823     ;; synchronize marks.
1824     (when (not (eq (elmo-folder-type-internal
1825                     wl-summary-buffer-elmo-folder)
1826                    'internal))
1827       (message "Updating marks...")
1828       (setq unread-marks (list wl-summary-unread-cached-mark
1829                                wl-summary-unread-uncached-mark
1830                                wl-summary-new-mark)
1831             importants-in-db (elmo-folder-list-messages-mark-match
1832                               wl-summary-buffer-elmo-folder
1833                               (regexp-quote wl-summary-important-mark))
1834             unreads-in-db (elmo-folder-list-messages-mark-match
1835                            wl-summary-buffer-elmo-folder
1836                            (wl-regexp-opt unread-marks))
1837             importants (elmo-folder-list-importants
1838                         wl-summary-buffer-elmo-folder
1839                         wl-summary-important-mark)
1840             unreads (elmo-folder-list-unreads
1841                      wl-summary-buffer-elmo-folder
1842                      unread-marks))
1843       (setq diff (elmo-list-diff importants importants-in-db))
1844       (setq diffs (cadr diff)) ; important-deletes
1845       (setq mes (format "Updated (-%d" (length diffs)))
1846       (while diffs
1847         (wl-summary-mark-as-important (car diffs)
1848                                       wl-summary-important-mark
1849                                       'no-server)
1850         (setq diffs (cdr diffs)))
1851       (setq diffs (car diff)) ; important-appends
1852       (setq mes (concat mes (format "/+%d) important," (length diffs))))
1853       (while diffs
1854         (wl-summary-mark-as-important (car diffs) " " 'no-server)
1855         (setq diffs (cdr diffs)))
1856       (setq diff (elmo-list-diff unreads unreads-in-db))
1857       (setq diffs (cadr diff))
1858       (setq mes (concat mes (format "(-%d" (length diffs))))
1859       (while diffs
1860         (wl-summary-mark-as-read t 'no-server nil (car diffs))
1861         (setq diffs (cdr diffs)))
1862       (setq diffs (car diff)) ; unread-appends
1863       (setq mes (concat mes (format "/+%d) unread mark(s)." (length diffs))))
1864       (while diffs
1865         (wl-summary-mark-as-unread (car diffs) 'no-server 'no-modeline)
1866         (setq diffs (cdr diffs)))
1867       (if (interactive-p) (message mes)))))
1868
1869 (defun wl-summary-sync-update (&optional unset-cursor sync-all no-check)
1870   "Update the summary view to the newest folder status."
1871   (interactive)
1872   (let* ((folder wl-summary-buffer-elmo-folder)
1873          (case-fold-search nil)
1874          (elmo-mime-charset wl-summary-buffer-mime-charset)
1875          (inhibit-read-only t)
1876          (buffer-read-only nil)
1877          gc-message
1878          overview number-alist
1879          curp num i new-msgdb
1880          append-list delete-list crossed
1881          update-thread update-top-list
1882          expunged mes sync-result)
1883     (unwind-protect
1884         (progn
1885           (unless wl-summary-buffer-elmo-folder
1886             (error "(Internal error) Folder is not set:%s" (buffer-name
1887                                                             (current-buffer))))
1888           (fset 'wl-summary-append-message-func-internal
1889                 (wl-summary-get-append-message-func))
1890           ;; Flush pending append operations (disconnected operation).
1891           ;;(setq seen-list
1892           ;;(wl-summary-flush-pending-append-operations seen-list))
1893           (goto-char (point-max))
1894           (wl-folder-confirm-existence folder (elmo-folder-plugged-p folder))
1895           (setq sync-result (elmo-folder-synchronize
1896                              folder
1897                              wl-summary-new-mark
1898                              wl-summary-unread-uncached-mark
1899                              wl-summary-unread-cached-mark
1900                              wl-summary-read-uncached-mark
1901                              wl-summary-important-mark
1902                              sync-all no-check))
1903           (setq new-msgdb (nth 0 sync-result))
1904           (setq delete-list (nth 1 sync-result))
1905           (setq crossed (nth 2 sync-result))
1906           (if sync-result
1907               (progn
1908                 ;; Setup sync-all
1909                 (if sync-all (wl-summary-sync-all-init))
1910 ;    (if (and has-nntp
1911 ;            (elmo-nntp-max-number-precedes-list-active-p))
1912         ;; XXX this does not work correctly in rare case.
1913 ;       (setq delete-list
1914 ;             (wl-summary-delete-canceled-msgs-from-list
1915 ;              delete-list
1916 ;              (wl-summary-buffer-msgdb))))
1917                 (when delete-list
1918                   (wl-summary-delete-messages-on-buffer delete-list "Deleting...")
1919                   (message "Deleting...done"))
1920                 (when new-msgdb
1921                   (wl-summary-replace-status-marks
1922                    wl-summary-new-mark
1923                    wl-summary-unread-uncached-mark))
1924                 (setq append-list (elmo-msgdb-get-overview new-msgdb))
1925                 (setq curp append-list)
1926                 (setq num (length curp))
1927                 (when append-list
1928                   (setq i 0)
1929
1930                   ;; set these value for append-message-func
1931                   (setq overview (elmo-msgdb-get-overview
1932                                   (elmo-folder-msgdb folder)))
1933                   (setq number-alist (elmo-msgdb-get-number-alist
1934                                       (elmo-folder-msgdb folder)))
1935
1936                   (setq wl-summary-delayed-update nil)
1937                   (elmo-kill-buffer wl-summary-search-buf-name)
1938                   (while curp
1939                     (setq entity (car curp))
1940                     (when (setq update-thread
1941                                 (wl-summary-append-message-func-internal
1942                                  entity (elmo-folder-msgdb folder)
1943                                  (not sync-all)))
1944                       (wl-append update-top-list update-thread))
1945                     (if elmo-use-database
1946                         (elmo-database-msgid-put
1947                          (car entity) (elmo-folder-name-internal folder)
1948                          (elmo-msgdb-overview-entity-get-number entity)))
1949                     (setq curp (cdr curp))
1950                     (when (> num elmo-display-progress-threshold)
1951                       (setq i (+ i 1))
1952                       (if (or (zerop (% i 5)) (= i num))
1953                           (elmo-display-progress
1954                            'wl-summary-sync-update "Updating thread..."
1955                            (/ (* i 100) num)))))
1956                   (when wl-summary-delayed-update
1957                     (while wl-summary-delayed-update
1958                       (message "Parent (%d) of message %d is no entity"
1959                                (caar wl-summary-delayed-update)
1960                                (elmo-msgdb-overview-entity-get-number
1961                                 (cdar wl-summary-delayed-update)))
1962                       (when (setq update-thread
1963                                   (wl-summary-append-message-func-internal
1964                                    (cdar wl-summary-delayed-update)
1965                                    (elmo-folder-msgdb folder)
1966                                    (not sync-all) t))
1967                         (wl-append update-top-list update-thread))
1968                       (setq wl-summary-delayed-update
1969                             (cdr wl-summary-delayed-update))))
1970                   (when (and (eq wl-summary-buffer-view 'thread)
1971                              update-top-list)
1972                     (wl-thread-update-indent-string-thread
1973                      (elmo-uniq-list update-top-list)))
1974                   (message "Updating thread...done"))
1975                 (unless (eq wl-summary-buffer-view 'thread)
1976                   (wl-summary-make-number-list))
1977                 (wl-summary-set-message-modified)
1978                 (wl-summary-set-mark-modified)
1979                 (when (and sync-all (eq wl-summary-buffer-view 'thread))
1980                   (elmo-kill-buffer wl-summary-search-buf-name)
1981                   (message "Inserting thread...")
1982                   (setq wl-thread-entity-cur 0)
1983                   (wl-thread-insert-top)
1984                   (message "Inserting thread...done"))
1985                 (if elmo-use-database
1986                     (elmo-database-close))
1987                 (run-hooks 'wl-summary-sync-updated-hook)
1988                 (setq mes
1989                       (if (and (eq (length delete-list) 0)
1990                                (eq num 0))
1991                           (format
1992                            "No updates for \"%s\"" (elmo-folder-name-internal
1993                                                     folder))
1994                         (format "Updated (-%d/+%d) message(s)"
1995                                 (length delete-list) num))))
1996             (setq mes "Quit updating.")))
1997       ;; synchronize marks.
1998       (if (and wl-summary-auto-sync-marks sync-result)
1999           (wl-summary-sync-marks))
2000       ;; scoring
2001       (when wl-use-scoring
2002         (setq wl-summary-scored nil)
2003         (wl-summary-score-headers nil (wl-summary-buffer-msgdb)
2004                                   (and sync-all
2005                                        (wl-summary-rescore-msgs number-alist))
2006                                   sync-all)
2007         (when (and wl-summary-scored
2008                    (setq expunged (wl-summary-score-update-all-lines)))
2009           (setq mes (concat mes
2010                             (format " (%d expunged)"
2011                                     (length expunged))))))
2012       (if (and crossed (> crossed 0))
2013           (setq mes
2014                 (if mes
2015                     (concat mes
2016                             (format " (%d crosspost)" crossed))
2017                   (format "%d crosspost message(s)" crossed)))
2018         (and mes (setq mes (concat mes "."))))
2019       ;; Update Folder mode
2020       (wl-folder-set-folder-updated
2021        (elmo-folder-name-internal folder)
2022        (list 0
2023              (let ((pair (wl-summary-count-unread)))
2024                (+ (car pair) (cdr pair)))
2025              (elmo-folder-messages folder)))
2026       (wl-summary-update-modeline)
2027       ;;
2028       (unless unset-cursor
2029         (goto-char (point-min))
2030         (if (not (wl-summary-cursor-down t))
2031             (progn
2032               (goto-char (point-max))
2033               (forward-line -1))
2034           (if (and wl-summary-highlight
2035                    (not (get-text-property (point) 'face)))
2036               (save-excursion
2037                 (forward-line (- 0
2038                                  (or
2039                                   wl-summary-partial-highlight-above-lines
2040                                   wl-summary-highlight-partial-threshold)))
2041                 (wl-highlight-summary (point) (point-max))))))
2042       (setq wl-summary-buffer-msgdb (elmo-folder-msgdb folder))
2043       (wl-delete-all-overlays)
2044       (set-buffer-modified-p nil)
2045       (if mes (message "%s" mes)))))
2046
2047 (defun wl-summary-set-score-mark (mark)
2048   (save-excursion
2049     (beginning-of-line)
2050     (let ((inhibit-read-only t)
2051           (buffer-read-only nil)
2052           msg-num
2053           cur-mark)
2054       (when (looking-at "^ *\\(-?[0-9]+\\)\\([^0-9]\\)")
2055         (setq msg-num  (string-to-int (wl-match-buffer 1)))
2056         (setq cur-mark (wl-match-buffer 2))
2057         (when (member cur-mark (list " "
2058                                      wl-summary-score-below-mark
2059                                      wl-summary-score-over-mark))
2060           (goto-char (match-end 1))
2061           (delete-region (match-beginning 2) (match-end 2))
2062           (insert mark)
2063           (if wl-summary-highlight
2064               (wl-highlight-summary-current-line nil nil t))
2065           (set-buffer-modified-p nil))))))
2066
2067 (defun wl-summary-get-score-mark (msg-num)
2068   (let ((score (cdr (assq msg-num wl-summary-scored))))
2069     (if score
2070         (cond ((< score wl-summary-default-score)
2071                "-")
2072               ((> score wl-summary-default-score)
2073                "+")))))
2074
2075 (defun wl-summary-update-modeline ()
2076   (setq wl-summary-buffer-unread-status
2077         (format " {%s}(%d new/%d unread)"
2078                 (if (eq wl-summary-buffer-view 'thread)
2079                     "T" "S")
2080                 wl-summary-buffer-new-count
2081                 (+ wl-summary-buffer-new-count
2082                    wl-summary-buffer-unread-count))))
2083
2084 (defsubst wl-summary-jump-to-msg (&optional number)
2085   (interactive)
2086   (let ((num (or number
2087                  (string-to-int
2088                   (read-from-minibuffer "Jump to Message(No.): ")))))
2089     (setq num (int-to-string num))
2090     (beginning-of-line)
2091     (if (or (re-search-forward (concat "^[ \t]*" num "[^0-9]") nil t)
2092             (re-search-backward (concat "^[ \t]*" num "[^0-9]") nil t))
2093         (progn (beginning-of-line) t)
2094       nil)))
2095
2096 (defun wl-summary-highlight-msgs (msgs)
2097   (save-excursion
2098     (let ((len (length msgs))
2099           i)
2100       (message "Hilighting...")
2101       (setq i 0)
2102       (while msgs
2103         (if (wl-summary-jump-to-msg (car msgs))
2104             (wl-highlight-summary-current-line))
2105         (setq msgs (cdr msgs))
2106         (when (> len elmo-display-progress-threshold)
2107           (setq i (+ i 1))
2108           (if (or (zerop (% i 5)) (= i len))
2109               (elmo-display-progress
2110                'wl-summary-highlight-msgs "Highlighting..."
2111                (/ (* i 100) len)))))
2112       (message "Highlighting...done"))))
2113
2114 (defun wl-summary-message-number ()
2115   (save-excursion
2116     (beginning-of-line)
2117     (if (looking-at "^ *\\(-?[0-9]+\\)")
2118         (string-to-int (wl-match-buffer 1))
2119       nil)))
2120
2121 (defun wl-summary-move (src dsts-msgs)
2122   (let* ((dsts (car dsts-msgs))         ; (+foo +bar)
2123 ;;;      (msgs (cdr dsts-msgs))         ; (1 2 3)
2124 ;;;      (msgdb (wl-summary-buffer-msgdb))
2125 ;;;      result)
2126          )
2127     (while dsts
2128       (setq dsts (cdr dsts)))))
2129
2130 (defun wl-summary-delete-all-msgs ()
2131   (interactive)
2132   (let ((cur-buf (current-buffer))
2133         (dels (elmo-folder-list-messages wl-summary-buffer-elmo-folder)))
2134     (set-buffer cur-buf)
2135     (if (null dels)
2136         (message "No message to delete.")
2137       (if (y-or-n-p (format "%s has %d message(s).  Delete all? "
2138                             (wl-summary-buffer-folder-name)
2139                             (length dels)))
2140           (progn
2141             (message "Deleting...")
2142             (elmo-folder-delete-messages
2143              wl-summary-buffer-elmo-folder dels)
2144             (elmo-msgdb-delete-msgs (wl-summary-buffer-msgdb)
2145                                     dels)
2146 ;;;         (elmo-msgdb-save (wl-summary-buffer-folder-name) nil)
2147             (wl-summary-set-message-modified)
2148             (wl-summary-set-mark-modified)
2149             (wl-folder-set-folder-updated (wl-summary-buffer-folder-name)
2150                                           (list 0 0 0))
2151 ;;; for thread.
2152 ;;;         (setq wl-thread-top-entity '(nil t nil nil))
2153             (setq wl-summary-buffer-unread-count 0)
2154             (setq wl-summary-buffer-new-count    0)
2155             (wl-summary-update-modeline)
2156             (set-buffer cur-buf)
2157             (let ((inhibit-read-only t)
2158                   (buffer-read-only nil))
2159               (erase-buffer))
2160 ;;;         (if wl-summary-cache-use (wl-summary-save-view-cache))
2161             (message "Deleting...done")
2162             t)
2163         nil))))
2164
2165 (defun wl-summary-toggle-thread (&optional arg)
2166   "Toggle thread status (T)hread and (S)equential.
2167 If ARG, without confirm."
2168   (interactive "P")
2169   (when (or arg
2170             (y-or-n-p (format "Toggle threading? (y=%s): "
2171                               (if (eq wl-summary-buffer-view 'thread)
2172                                   "\"off\"" "\"on\""))))
2173     (if (eq wl-summary-buffer-view 'thread)
2174         (setq wl-summary-buffer-view 'sequence)
2175       (setq wl-summary-buffer-view 'thread))
2176     (wl-summary-update-modeline)
2177     (force-mode-line-update)
2178     (wl-summary-rescan)))
2179
2180 (defun wl-summary-load-file-object (filename)
2181   "Load lisp object from dir."
2182   (save-excursion
2183     (let ((tmp-buffer (get-buffer-create " *wl-summary-load-file-object*"))
2184           insert-file-contents-pre-hook   ; To avoid autoconv-xmas...
2185           insert-file-contents-post-hook
2186           ret-val)
2187       (if (not (file-readable-p filename))
2188           ()
2189         (set-buffer tmp-buffer)
2190         (as-binary-input-file (insert-file-contents filename))
2191         (setq ret-val
2192               (condition-case nil
2193                   (read (current-buffer))
2194                 (error (error "Reading failed")))))
2195       (kill-buffer tmp-buffer)
2196       ret-val)))
2197
2198 (defun wl-summary-goto-folder (&optional arg)
2199   (interactive "P")
2200   (wl-summary-goto-folder-subr nil nil nil nil t nil arg))
2201
2202 (defun wl-summary-goto-folder-sticky ()
2203   (interactive)
2204   (wl-summary-goto-folder-subr nil nil nil t t))
2205
2206 (defun wl-summary-goto-last-visited-folder ()
2207   (interactive)
2208   (let ((entity
2209          (wl-folder-search-entity-by-name wl-summary-last-visited-folder
2210                                           wl-folder-entity
2211                                           'folder)))
2212     (if entity (wl-folder-set-current-entity-id
2213                 (wl-folder-get-entity-id entity))))
2214   (wl-summary-goto-folder-subr wl-summary-last-visited-folder nil nil nil t))
2215
2216 (defun wl-summary-sticky-p (&optional folder)
2217   (if folder
2218       (get-buffer (wl-summary-sticky-buffer-name
2219                    (elmo-folder-name-internal folder)))
2220     (not (string= wl-summary-buffer-name (buffer-name)))))
2221
2222 (defun wl-summary-always-sticky-folder-p (folder)
2223   (or (eq t wl-summary-always-sticky-folder-list)
2224       (wl-string-match-member
2225        (elmo-folder-name-internal folder)
2226        wl-summary-always-sticky-folder-list)))
2227
2228 (defun wl-summary-stick (&optional force)
2229   "Make current summary buffer sticky."
2230   (interactive "P")
2231   (if (wl-summary-sticky-p)
2232       (message "Current summary buffer is already sticky.")
2233     (when (or force (y-or-n-p "Stick current summary buffer? "))
2234       (wl-summary-toggle-disp-msg 'off)
2235       (wl-summary-switch-to-clone-buffer
2236        (wl-summary-sticky-buffer-name
2237         (wl-summary-buffer-folder-name)))
2238 ;;; ???hang up
2239 ;;;   (rename-buffer (wl-summary-sticky-buffer-name
2240 ;;;                   (wl-summary-buffer-folder-name))))
2241       (message "Folder `%s' is now sticky." (wl-summary-buffer-folder-name)))))
2242
2243 (defun wl-summary-switch-to-clone-buffer (buffer-name)
2244   (let ((cur-buf (current-buffer))
2245         (msg (wl-summary-message-number))
2246         (buf (get-buffer-create buffer-name))
2247         (folder wl-summary-buffer-elmo-folder)
2248         (copy-variables
2249          (append '(wl-summary-buffer-view
2250                    wl-summary-buffer-refile-list
2251                    wl-summary-buffer-delete-list
2252                    wl-summary-buffer-copy-list
2253                    wl-summary-buffer-target-mark-list
2254                    wl-summary-buffer-elmo-folder
2255                    wl-summary-buffer-number-column
2256                    wl-summary-buffer-message-modified
2257                    wl-summary-buffer-mark-modified
2258                    wl-summary-buffer-thread-modified
2259                    wl-summary-buffer-number-list
2260                    wl-summary-buffer-msgdb
2261                    wl-summary-buffer-folder-name
2262                    wl-summary-buffer-line-formatter)
2263                  (and (eq wl-summary-buffer-view 'thread)
2264                       '(wl-thread-entity-hashtb
2265                         wl-thread-entities
2266                         wl-thread-entity-list))
2267                  (and wl-use-scoring
2268                       '(wl-summary-scored
2269                         wl-summary-default-score
2270                         wl-summary-important-above
2271                         wl-summary-target-above
2272                         wl-summary-mark-below
2273                         wl-summary-expunge-below))
2274                  (and (featurep 'wl-score)
2275                       '(wl-current-score-file
2276                         wl-score-alist)))))
2277     (set-buffer buf)
2278     (wl-summary-mode)
2279     (wl-summary-buffer-set-folder folder)
2280     (let ((buffer-read-only nil))
2281       (insert-buffer cur-buf))
2282     (set-buffer-modified-p nil)
2283     (while copy-variables
2284       (set (car copy-variables)
2285            (save-excursion
2286              (set-buffer cur-buf)
2287              (symbol-value (car copy-variables))))
2288       (setq copy-variables (cdr copy-variables)))
2289     (switch-to-buffer buf)
2290     (kill-buffer cur-buf)
2291     (wl-summary-count-unread)
2292     (wl-summary-update-modeline)
2293     (if msg
2294         (if (eq wl-summary-buffer-view 'thread)
2295             (wl-thread-jump-to-msg msg)
2296           (wl-summary-jump-to-msg msg))
2297       (goto-char (point-max))
2298       (beginning-of-line))))
2299
2300 (defun wl-summary-get-buffer (folder)
2301   (or (and folder
2302            (get-buffer (wl-summary-sticky-buffer-name folder)))
2303       (get-buffer wl-summary-buffer-name)))
2304
2305 (defun wl-summary-get-buffer-create (name &optional force-sticky)
2306   (if force-sticky
2307       (get-buffer-create
2308        (wl-summary-sticky-buffer-name name))
2309     (or (get-buffer (wl-summary-sticky-buffer-name name))
2310         (get-buffer-create wl-summary-buffer-name))))
2311
2312 (defun wl-summary-make-number-list ()
2313   (setq wl-summary-buffer-number-list
2314         (mapcar
2315          (lambda (x) (elmo-msgdb-overview-entity-get-number x))
2316          (elmo-msgdb-get-overview (wl-summary-buffer-msgdb)))))
2317
2318 (defun wl-summary-auto-select-msg-p (unread-msg)
2319   (and unread-msg
2320        (not (string=
2321              (elmo-msgdb-get-mark
2322               (wl-summary-buffer-msgdb)
2323               unread-msg)
2324              wl-summary-important-mark))))
2325
2326 (defsubst wl-summary-open-folder (folder)
2327   ;; Select folder
2328   (let ((elmo-mime-charset wl-summary-buffer-mime-charset))
2329     (unwind-protect
2330         (elmo-folder-open folder 'load-msgdb)
2331       ;; For compatibility
2332       (setq wl-summary-buffer-msgdb (elmo-folder-msgdb folder))
2333       (setq wl-summary-buffer-folder-name (elmo-folder-name-internal
2334                                            folder)))))
2335
2336 (defun wl-summary-goto-folder-subr (&optional name scan-type other-window
2337                                               sticky interactive scoring
2338                                               force-exit)
2339   "Display target folder on summary."
2340   (interactive)
2341   (let* ((keep-cursor (memq this-command
2342                             wl-summary-keep-cursor-command))
2343          (name (or name (wl-summary-read-folder wl-default-folder)))
2344          (cur-fld wl-summary-buffer-elmo-folder)
2345          folder buf mes hilit reuse-buf
2346          retval entity)
2347     (if (string= name "")
2348         (setq name wl-default-folder))
2349     (setq folder (wl-folder-get-elmo-folder name))
2350     (when (and (not (string=
2351                      (and cur-fld (elmo-folder-name-internal cur-fld))
2352                      (elmo-folder-name-internal folder))) ; folder is moved.
2353                (eq major-mode 'wl-summary-mode)) ; called in summary.
2354       (setq wl-summary-last-visited-folder (wl-summary-buffer-folder-name))
2355       (run-hooks 'wl-summary-exit-pre-hook)
2356       (if (or force-exit (not (wl-summary-sticky-p)))
2357           (wl-summary-cleanup-temp-marks (wl-summary-sticky-p)))
2358       (wl-summary-save-view)
2359       (elmo-folder-commit wl-summary-buffer-elmo-folder)
2360       (if (and (wl-summary-sticky-p) force-exit)
2361           (kill-buffer (current-buffer))))
2362     (setq buf (wl-summary-get-buffer-create (elmo-folder-name-internal folder)
2363                                             sticky))
2364     (setq reuse-buf
2365           (save-excursion
2366             (set-buffer buf)
2367             (string= (elmo-folder-name-internal folder)
2368                      (wl-summary-buffer-folder-name))))
2369     (unwind-protect
2370         (if reuse-buf
2371             (if interactive
2372                 (switch-to-buffer buf)
2373               (set-buffer buf))
2374           (if other-window
2375               (delete-other-windows))
2376           (set-buffer buf)
2377           (unless (eq major-mode 'wl-summary-mode)
2378             (wl-summary-mode))
2379           (wl-summary-buffer-set-folder folder)
2380           (setq wl-summary-buffer-disp-msg nil)
2381           (setq wl-summary-buffer-last-displayed-msg nil)
2382           (setq wl-summary-buffer-current-msg nil)
2383           (let ((case-fold-search nil)
2384                 (inhibit-read-only t)
2385                 (buffer-read-only nil))
2386             (erase-buffer)
2387             ;; Resume summary view
2388             (if wl-summary-cache-use
2389                 (let* ((dir (elmo-folder-msgdb-path folder))
2390                        (cache (expand-file-name wl-summary-cache-file dir))
2391                        (view (expand-file-name wl-summary-view-file dir)))
2392                   (when (file-exists-p cache)
2393                     (insert-file-contents-as-binary cache)
2394                     (elmo-set-buffer-multibyte
2395                      default-enable-multibyte-characters)
2396                     (decode-mime-charset-region
2397                      (point-min)(point-max)
2398                      wl-summary-buffer-mime-charset))
2399                   (when (file-exists-p view)
2400                     (setq wl-summary-buffer-view
2401                           (wl-summary-load-file-object view)))
2402                   (wl-thread-resume-entity folder)
2403                   (wl-summary-open-folder folder))
2404               (setq wl-summary-buffer-view
2405                     (wl-summary-load-file-object
2406                      (expand-file-name wl-summary-view-file
2407                                        (elmo-folder-msgdb-path folder))))
2408               (wl-summary-open-folder folder)
2409               (wl-summary-rescan))
2410             (wl-summary-count-unread)
2411             (wl-summary-update-modeline)))
2412       (unless (eq wl-summary-buffer-view 'thread)
2413         (wl-summary-make-number-list))
2414       (wl-summary-toggle-disp-msg (if wl-summary-buffer-disp-msg 'on 'off))
2415       (unless (and reuse-buf keep-cursor)
2416         ;(setq hilit wl-summary-highlight)
2417         (unwind-protect
2418             (let ((wl-summary-highlight (if reuse-buf wl-summary-highlight))
2419                   (wl-use-scoring
2420                    (if (or scoring interactive) wl-use-scoring)))
2421               (if (and (not scan-type)
2422                        interactive
2423                        (not wl-ask-range))
2424                   (setq scan-type (wl-summary-get-sync-range folder)))
2425               (cond
2426                ((eq scan-type nil)
2427                 (wl-summary-sync 'unset-cursor))
2428                ((eq scan-type 'all)
2429                 (wl-summary-sync 'unset-cursor "all"))
2430                ((eq scan-type 'no-sync))
2431                ((or (eq scan-type 'force-update)
2432                     (eq scan-type 'update))
2433                 (setq mes (wl-summary-sync-force-update
2434                            'unset-cursor 'no-check)))))
2435           (if interactive
2436               (switch-to-buffer buf)
2437             (set-buffer buf))
2438           ;; stick always-sticky-folder
2439           (when (wl-summary-always-sticky-folder-p folder)
2440             (or (wl-summary-sticky-p) (wl-summary-stick t)))
2441           (run-hooks 'wl-summary-prepared-pre-hook)
2442           (set-buffer-modified-p nil)
2443           (goto-char (point-min))
2444           (if (wl-summary-cursor-down t)
2445               (let ((unreadp (wl-summary-next-message
2446                               (wl-summary-message-number)
2447                               'down t)))
2448                 (cond ((and wl-auto-select-first
2449                             (wl-summary-auto-select-msg-p unreadp))
2450                        ;; wl-auto-select-first is non-nil and
2451                        ;; unreadp is non-nil but not important
2452                        (setq retval 'disp-msg))
2453                       ((and wl-auto-prefetch-first
2454                             (wl-summary-auto-select-msg-p unreadp))
2455                        ;; wl-auto-select-first is non-nil and
2456                        ;; unreadp is non-nil but not important
2457                        (setq retval 'prefetch-msg))
2458                       ((not (wl-summary-auto-select-msg-p unreadp))
2459                        ;; unreadp is nil or important
2460                        (setq retval 'more-next))))
2461             (goto-char (point-max))
2462             (if (elmo-folder-plugged-p folder)
2463                 (forward-line -1)
2464               (wl-summary-prev))
2465             (setq retval 'more-next))
2466           ;(setq wl-summary-highlight hilit)
2467           (if (and wl-summary-highlight
2468                    (not wl-summary-lazy-highlight)
2469                    (not reuse-buf))
2470               (if (and wl-summary-highlight-partial-threshold
2471                        (> (count-lines (point-min) (point-max))
2472                           wl-summary-highlight-partial-threshold))
2473                   (save-excursion
2474                     (forward-line (-
2475                                    0
2476                                    (or
2477                                     wl-summary-partial-highlight-above-lines
2478                                     wl-summary-highlight-partial-threshold)))
2479                     (wl-highlight-summary (point) (point-max)))
2480                 (wl-highlight-summary (point-min) (point-max))))
2481           (if (eq retval 'disp-msg)
2482               (wl-summary-redisplay))
2483           (if (eq retval 'prefetch-msg)
2484               (wl-message-buffer-prefetch
2485                folder
2486                (wl-summary-message-number)
2487                wl-message-buffer-prefetch-depth
2488                (current-buffer)
2489                wl-summary-buffer-mime-charset))
2490           (if mes (message "%s" mes))
2491           (if (and interactive wl-summary-recenter)
2492               (recenter (/ (- (window-height) 2) 2))))))
2493     ;; set current entity-id
2494     (if (and (not folder)
2495              (setq entity
2496                    (wl-folder-search-entity-by-name (elmo-folder-name-internal
2497                                                      folder)
2498                                                     wl-folder-entity
2499                                                     'folder)))
2500         ;; entity-id is unknown.
2501         (wl-folder-set-current-entity-id
2502          (wl-folder-get-entity-id entity)))
2503     (unwind-protect
2504         (run-hooks 'wl-summary-prepared-hook)
2505       (set-buffer-modified-p nil))
2506     retval))
2507
2508 (defun wl-summary-goto-previous-message-beginning ()
2509   (end-of-line)
2510   (re-search-backward wl-summary-message-regexp nil t)
2511   (beginning-of-line))
2512
2513 (defun wl-summary-goto-top-of-current-thread ()
2514   (wl-summary-jump-to-msg
2515    (wl-thread-entity-get-number
2516     (wl-thread-entity-get-top-entity (wl-thread-get-entity
2517                                       (wl-summary-message-number))))))
2518
2519 (defun wl-summary-goto-bottom-of-sub-thread (&optional depth)
2520   (interactive)
2521   (let ((depth (or depth
2522                    (wl-thread-get-depth-of-current-line))))
2523     (forward-line 1)
2524     (while (and (not (eobp))
2525                 (>= (wl-thread-get-depth-of-current-line)
2526                     depth))
2527       (forward-line 1))
2528     (beginning-of-line)))
2529
2530 (defun wl-summary-insert-line (line)
2531   "Insert LINE in the Summary."
2532   (if wl-use-highlight-mouse-line
2533       ;; remove 'mouse-face of current line.
2534       (put-text-property
2535        (save-excursion (beginning-of-line)(point))
2536        (save-excursion (end-of-line)(point))
2537        'mouse-face nil))
2538   (insert line "\n")
2539   (if wl-use-highlight-mouse-line
2540       ;; remove 'mouse-face of current line.
2541       (put-text-property
2542        (save-excursion (beginning-of-line)(point))
2543        (save-excursion (end-of-line)(point))
2544        'mouse-face nil))
2545   (ignore-errors
2546     (run-hooks 'wl-summary-line-inserted-hook)))
2547
2548 (defun wl-summary-insert-sequential (entity msgdb &rest args)
2549   (let ((inhibit-read-only t)
2550         buffer-read-only)
2551     (goto-char (point-max))
2552     (wl-summary-insert-line
2553      (wl-summary-create-line entity nil nil))))
2554
2555 (defun wl-summary-default-subject-filter (subject)
2556   (let ((case-fold-search t))
2557     (setq subject (elmo-replace-in-string subject "[ \t]*\\(re\\|was\\)[:>]" ""))
2558     (setq subject (elmo-replace-in-string subject "[ \t]" ""))
2559     (elmo-replace-in-string subject "^\\[.*\\]" "")))
2560
2561 (defun wl-summary-subject-equal (subject1 subject2)
2562   (string= (funcall wl-summary-subject-filter-function subject1)
2563            (funcall wl-summary-subject-filter-function subject2)))
2564
2565 (defmacro wl-summary-put-alike (alike)
2566   (` (elmo-set-hash-val (format "#%d" (wl-count-lines))
2567                         (, alike)
2568                         wl-summary-alike-hashtb)))
2569
2570 (defmacro wl-summary-get-alike ()
2571   (` (elmo-get-hash-val (format "#%d" (wl-count-lines))
2572                         wl-summary-alike-hashtb)))
2573
2574 (defun wl-summary-insert-headers (overview func mime-decode)
2575   (let (ov this last alike)
2576     (buffer-disable-undo (current-buffer))
2577     (make-local-variable 'wl-summary-alike-hashtb)
2578     (setq wl-summary-alike-hashtb (elmo-make-hash (* (length overview) 2)))
2579     (when mime-decode
2580       (elmo-set-buffer-multibyte default-enable-multibyte-characters))
2581     (while (setq ov (pop overview))
2582       (setq this (funcall func ov))
2583       (and this (setq this (std11-unfold-string this)))
2584       (if (equal last this)
2585           (wl-append alike (list ov))
2586         (when last
2587           (wl-summary-put-alike alike)
2588           (insert last ?\n))
2589         (setq alike (list ov)
2590               last this)))
2591     (when last
2592       (wl-summary-put-alike alike)
2593       (insert last ?\n))
2594     (when mime-decode
2595       (decode-mime-charset-region (point-min) (point-max)
2596                                   elmo-mime-charset)
2597       (when (eq mime-decode 'mime)
2598         (eword-decode-region (point-min) (point-max))))
2599     (run-hooks 'wl-summary-insert-headers-hook)))
2600
2601 (defun wl-summary-search-by-subject (entity overview)
2602   (let ((summary-buf (current-buffer))
2603         (buf (get-buffer-create wl-summary-search-buf-name))
2604         (folder-name (wl-summary-buffer-folder-name))
2605         match founds found-entity)
2606     (with-current-buffer buf
2607       (let ((case-fold-search t))
2608         (when (or (not (string= wl-summary-search-buf-folder-name folder-name))
2609                   (zerop (buffer-size)))
2610           (setq wl-summary-search-buf-folder-name folder-name)
2611           (wl-summary-insert-headers
2612            overview
2613            (function
2614             (lambda (x)
2615               (funcall wl-summary-subject-filter-function
2616                (elmo-msgdb-overview-entity-get-subject-no-decode x))))
2617            t))
2618         (setq match (funcall wl-summary-subject-filter-function
2619                              (elmo-msgdb-overview-entity-get-subject entity)))
2620         (if (string= match "")
2621             (setq match "\n"))
2622         (goto-char (point-min))
2623         (while (and (not founds)
2624                     (not (= (point) (point-max)))
2625                     (search-forward match nil t))
2626           ;; check exactly match
2627           (when (and (eolp)
2628                      (= (point-at-bol)
2629                         (match-beginning 0)))
2630             (setq found-entity (wl-summary-get-alike))
2631             (if (and found-entity
2632                      ;; Is founded entity myself or children?
2633                      (not (string=
2634                            (elmo-msgdb-overview-entity-get-id entity)
2635                            (elmo-msgdb-overview-entity-get-id
2636                             (car found-entity))))
2637                      (with-current-buffer summary-buf
2638                        (not (wl-thread-descendant-p
2639                              (elmo-msgdb-overview-entity-get-number entity)
2640                              (elmo-msgdb-overview-entity-get-number
2641                               (car found-entity))))))
2642                 ;; return matching entity
2643                 (setq founds found-entity))))
2644         (if founds
2645             (car founds))))))
2646
2647 (defun wl-summary-insert-thread-entity (entity msgdb update
2648                                                &optional force-insert)
2649   (let* ((overview (elmo-msgdb-get-overview msgdb))
2650          this-id
2651          parent-entity
2652          parent-number
2653          (case-fold-search t)
2654          cur number overview2 cur-entity linked retval delayed-entity
2655          update-list entity-stack)
2656     (while entity
2657       (setq this-id (elmo-msgdb-overview-entity-get-id entity)
2658             parent-entity
2659             (elmo-msgdb-get-parent-entity entity msgdb)
2660             parent-number (elmo-msgdb-overview-entity-get-number
2661                            parent-entity))
2662       (setq number (elmo-msgdb-overview-entity-get-number entity))
2663       ;; If thread loop detected, set parent as nil.
2664       (setq cur entity)
2665       (while cur
2666         (if (eq number (elmo-msgdb-overview-entity-get-number
2667                         (setq cur
2668                               (elmo-msgdb-get-parent-entity cur msgdb))))
2669             (setq parent-number nil
2670                   cur nil)))
2671       (if (and parent-number
2672                (not (wl-thread-get-entity parent-number))
2673                (not force-insert))
2674           ;; parent exists in overview, but not in wl-thread-entities
2675           (progn
2676             (wl-append wl-summary-delayed-update
2677                        (list (cons parent-number entity)))
2678             (setq entity nil)) ;; exit loop
2679         ;; Search parent by subject.
2680         (when (and (null parent-number)
2681                    wl-summary-search-parent-by-subject-regexp
2682                    (string-match
2683                     wl-summary-search-parent-by-subject-regexp
2684                     (elmo-msgdb-overview-entity-get-subject entity)))
2685           (let ((found (wl-summary-search-by-subject entity overview)))
2686             (when (and found
2687                        (not (member found wl-summary-delayed-update)))
2688               (setq parent-entity found)
2689               (setq parent-number
2690                     (elmo-msgdb-overview-entity-get-number parent-entity))
2691               (setq linked t))))
2692         ;; If subject is change, divide thread.
2693         (if (and parent-number
2694                  wl-summary-divide-thread-when-subject-changed
2695                  (not (wl-summary-subject-equal
2696                        (or (elmo-msgdb-overview-entity-get-subject
2697                             entity) "")
2698                        (or (elmo-msgdb-overview-entity-get-subject
2699                             parent-entity) ""))))
2700             (setq parent-number nil))
2701         (setq retval
2702               (wl-thread-insert-message entity
2703                                         number parent-number update linked))
2704         (and retval
2705              (wl-append update-list (list retval)))
2706         (setq entity nil) ; exit loop
2707         (while (setq delayed-entity (assq number wl-summary-delayed-update))
2708           (setq wl-summary-delayed-update
2709                 (delq delayed-entity wl-summary-delayed-update))
2710           ;; update delayed message
2711           (wl-append entity-stack (list (cdr delayed-entity)))))
2712       (if (and (not entity)
2713                entity-stack)
2714           (setq entity (pop entity-stack))))
2715     update-list))
2716
2717 (defun wl-summary-update-thread (entity
2718                                  thr-entity
2719                                  parent-entity)
2720   (let* ((this-id (elmo-msgdb-overview-entity-get-id entity))
2721          (overview-entity entity)
2722          (parent-id (elmo-msgdb-overview-entity-get-id parent-entity))
2723          (parent-number (elmo-msgdb-overview-entity-get-number parent-entity))
2724          summary-line msg subject-differ)
2725     (cond
2726      ((or (not parent-id)
2727           (string= this-id parent-id))
2728       (goto-char (point-max))
2729       (beginning-of-line))
2730      ;; parent already exists in buffer.
2731      ((wl-summary-jump-to-msg parent-number)
2732       (wl-thread-goto-bottom-of-sub-thread)))
2733     (let ((inhibit-read-only t)
2734           (buffer-read-only nil))
2735       (wl-summary-insert-line
2736        (wl-summary-create-line
2737         entity
2738         parent-entity
2739         nil
2740         (wl-thread-maybe-get-children-num msg)
2741         (wl-thread-make-indent-string thr-entity)
2742         (wl-thread-entity-get-linked thr-entity))))))
2743
2744 (defun wl-summary-mark-as-unread (&optional number
2745                                             no-server-update
2746                                             no-modeline-update)
2747   (interactive)
2748   (save-excursion
2749     (let* (eol
2750           (inhibit-read-only t)
2751           (buffer-read-only nil)
2752           (folder wl-summary-buffer-elmo-folder)
2753           (msgdb (wl-summary-buffer-msgdb))
2754 ;;;       (number-alist (elmo-msgdb-get-number-alist msgdb))
2755           new-mark visible mark)
2756       (if number
2757           (progn
2758             (setq visible (wl-summary-jump-to-msg number))
2759             (unless (setq mark (elmo-msgdb-get-mark msgdb number))
2760               (setq mark " ")))
2761         ;; interactive
2762         (setq visible t))
2763       (when visible
2764         (if (null (wl-summary-message-number))
2765             (message "No message.")
2766           (end-of-line)
2767           (setq eol (point))
2768           (wl-summary-goto-previous-message-beginning)))
2769       (if (or (and (not visible)
2770                    ;; already exists in msgdb.
2771                    (assq number (elmo-msgdb-get-number-alist msgdb)))
2772               (re-search-forward
2773                (format (concat "^ *\\("
2774                                (if number (int-to-string number)
2775                                  "-?[0-9]+")
2776                                "\\)[^0-9]\\(%s\\|%s\\)")
2777                        wl-summary-read-uncached-mark
2778                        " ") eol t))
2779           (progn
2780             (setq number (or number (string-to-int (wl-match-buffer 1))))
2781             (setq mark (or mark (elmo-match-buffer 2)))
2782             (save-match-data
2783               (setq new-mark (if (string= mark
2784                                           wl-summary-read-uncached-mark)
2785                                  wl-summary-unread-uncached-mark
2786                                (if (elmo-message-use-cache-p folder number)
2787                                    wl-summary-unread-mark
2788                                  wl-summary-unread-uncached-mark))))
2789             ;; server side mark
2790             (unless no-server-update
2791               (save-match-data
2792                 (unless (elmo-folder-unmark-read folder (list number))
2793                   (error "Setting mark failed"))))
2794             (when visible
2795               (delete-region (match-beginning 2) (match-end 2))
2796               (insert new-mark))
2797             (elmo-msgdb-set-mark msgdb number new-mark)
2798             (unless no-modeline-update
2799               (setq wl-summary-buffer-unread-count
2800                     (+ 1 wl-summary-buffer-unread-count))
2801               (wl-summary-update-modeline)
2802               (wl-folder-update-unread
2803                (wl-summary-buffer-folder-name)
2804                (+ wl-summary-buffer-unread-count
2805                   wl-summary-buffer-new-count)))
2806             (wl-summary-set-mark-modified)
2807             (if (and visible wl-summary-highlight)
2808                 (wl-highlight-summary-current-line))))))
2809   (set-buffer-modified-p nil))
2810
2811 (defun wl-summary-delete (&optional number)
2812   "Mark Delete mark 'D'.
2813 If optional argument NUMBER is specified, mark message specified by NUMBER."
2814   (interactive)
2815   (let* ((buffer-num (wl-summary-message-number))
2816          (msg-num (or number buffer-num))
2817          mark)
2818     (catch 'done
2819       (when (null msg-num)
2820         (if (interactive-p)
2821             (message "No message."))
2822         (throw 'done nil))
2823       (when (setq mark (wl-summary-get-mark msg-num))
2824         (when (wl-summary-reserve-temp-mark-p mark)
2825           (if (interactive-p)
2826               (error "Already marked as `%s'" mark))
2827           (throw 'done nil))
2828         (wl-summary-unmark msg-num))
2829       (if (or (interactive-p)
2830               (eq number buffer-num))
2831           (wl-summary-mark-line "D"))
2832       (setq wl-summary-buffer-delete-list
2833             (cons msg-num wl-summary-buffer-delete-list))
2834       (if (interactive-p)
2835           (if (eq wl-summary-move-direction-downward nil)
2836               (wl-summary-prev)
2837             (wl-summary-next)))
2838       msg-num)))
2839
2840 (defun wl-summary-remove-destination ()
2841   (save-excursion
2842     (let ((inhibit-read-only t)
2843           (buffer-read-only nil)
2844           (buf (current-buffer))
2845           sol eol rs re)
2846       (beginning-of-line)
2847       (setq sol (point))
2848       (end-of-line)
2849       (setq eol (point))
2850       (setq rs (next-single-property-change sol 'wl-summary-destination
2851                                             buf eol))
2852       (setq re (next-single-property-change rs 'wl-summary-destination
2853                                             buf eol))
2854       (put-text-property rs re 'wl-summary-destination nil)
2855       (put-text-property rs re 'invisible nil)
2856       (goto-char re)
2857       (delete-char (- eol re)))))
2858
2859 (defun wl-summary-check-mark (msg mark)
2860   (let ((check-func (cond ((string= mark "o")
2861                            'wl-summary-msg-marked-as-refiled)
2862                           ((string= mark "O")
2863                            'wl-summary-msg-marked-as-copied)
2864                           ((string= mark "D")
2865                            'wl-summary-msg-marked-as-deleted)
2866                           ((string= mark "*")
2867                            'wl-summary-msg-marked-as-target))))
2868     (if check-func
2869         (funcall check-func msg))))
2870
2871 (defun wl-summary-mark-collect (mark &optional begin end)
2872   (save-excursion
2873     (save-restriction
2874       (let (msglist)
2875         (narrow-to-region (or begin (point-min))
2876                           (or end (point-max)))
2877         (goto-char (point-min))
2878         ;; for thread...
2879         (if (eq wl-summary-buffer-view 'thread)
2880             (progn
2881               (while (not (eobp))
2882                 (let* ((number (wl-summary-message-number))
2883                        (entity (wl-thread-get-entity number))
2884                        result)
2885                   ;; opened...only myself is checked.
2886                   (if (wl-summary-check-mark number mark)
2887                       (wl-append msglist (list number)))
2888                   (unless (wl-thread-entity-get-opened entity)
2889                     ;; closed...children is also checked.
2890                     (if (setq result (wl-thread-get-children-msgs-with-mark
2891                                       number
2892                                       mark))
2893                         (wl-append msglist result)))
2894                   (forward-line 1)))
2895               (elmo-uniq-list msglist))
2896           (let* ((case-fold-search nil)
2897                  (re (format (concat wl-summary-message-regexp "%s")
2898                              (regexp-quote mark))))
2899             (while (re-search-forward re nil t)
2900               (setq msglist (cons (wl-summary-message-number) msglist)))
2901             (nreverse msglist)))))))
2902
2903 (defun wl-summary-exec ()
2904   (interactive)
2905   (wl-summary-exec-subr (mapcar 'car wl-summary-buffer-refile-list)
2906                         (reverse wl-summary-buffer-delete-list)
2907                         (mapcar 'car wl-summary-buffer-copy-list)))
2908
2909 (defun wl-summary-exec-region (beg end)
2910   (interactive "r")
2911   (message "Collecting marks ...")
2912   (save-excursion
2913     (goto-char beg)
2914     (beginning-of-line)
2915     (setq beg (point))
2916     (goto-char (1- end))
2917     (forward-line)
2918     (setq end (point))
2919     (wl-summary-exec-subr (wl-summary-mark-collect "o" beg end)
2920                           (wl-summary-mark-collect "D" beg end)
2921                           (wl-summary-mark-collect "O" beg end))))
2922
2923 (defun wl-summary-exec-subr (moves dels copies)
2924   (if (not (or moves dels copies))
2925       (message "No marks")
2926     (save-excursion
2927       (let ((del-fld (wl-summary-get-delete-folder
2928                       (wl-summary-buffer-folder-name)))
2929             (start (point))
2930             (unread-marks (list wl-summary-unread-cached-mark
2931                                 wl-summary-unread-uncached-mark
2932                                 wl-summary-new-mark))
2933             (refiles (append moves dels))
2934             (refile-failures 0)
2935             (copy-failures 0)
2936             (copy-len (length copies))
2937             refile-len
2938             dst-msgs                    ; loop counter
2939             result)
2940         (message "Executing ...")
2941         (while dels
2942           (when (not (assq (car dels) wl-summary-buffer-refile-list))
2943             (wl-append wl-summary-buffer-refile-list
2944                        (list (cons (car dels) del-fld)))
2945             (setq wl-summary-buffer-delete-list
2946                   (delete (car dels) wl-summary-buffer-delete-list)))
2947           (setq dels (cdr dels)))
2948         ;; begin refile...
2949         (setq refile-len (length refiles))
2950         (setq dst-msgs
2951               (wl-inverse-alist refiles wl-summary-buffer-refile-list))
2952         (goto-char start)               ; avoid moving cursor to
2953                                         ; the bottom line.
2954         (when (> refile-len elmo-display-progress-threshold)
2955           (elmo-progress-set 'elmo-folder-move-messages
2956                              refile-len "Moving messages..."))
2957         (while dst-msgs
2958           (setq result nil)
2959           (condition-case nil
2960               (setq result (elmo-folder-move-messages
2961                             wl-summary-buffer-elmo-folder
2962                             (cdr (car dst-msgs))
2963                             (if (eq 'null (car (car dst-msgs)))
2964                                 'null
2965                               (wl-folder-get-elmo-folder
2966                                (car (car dst-msgs))))
2967                             (wl-summary-buffer-msgdb)
2968                             (not (null (cdr dst-msgs)))
2969                             nil ; no-delete
2970                             nil ; same-number
2971                             unread-marks
2972                             t))
2973             (error nil))
2974           (if result                    ; succeeded.
2975               (progn
2976                 ;; update buffer.
2977                 (wl-summary-delete-messages-on-buffer (cdr (car dst-msgs)))
2978                 ;; update refile-alist.
2979                 (setq wl-summary-buffer-refile-list
2980                       (wl-delete-associations (cdr (car dst-msgs))
2981                                               wl-summary-buffer-refile-list)))
2982             (setq refile-failures
2983                   (+ refile-failures (length (cdr (car dst-msgs))))))
2984           (setq dst-msgs (cdr dst-msgs)))
2985         (elmo-progress-clear 'elmo-folder-move-messages)
2986         ;; end refile
2987         ;; begin cOpy...
2988         (setq dst-msgs (wl-inverse-alist copies wl-summary-buffer-copy-list))
2989         (when (> copy-len elmo-display-progress-threshold)
2990           (elmo-progress-set 'elmo-folder-move-messages
2991                              copy-len "Copying messages..."))
2992         (while dst-msgs
2993           (setq result nil)
2994           (condition-case nil
2995               (setq result (elmo-folder-move-messages
2996                             wl-summary-buffer-elmo-folder
2997                             (cdr (car dst-msgs))
2998                             (wl-folder-get-elmo-folder
2999                              (car (car dst-msgs)))
3000                             (wl-summary-buffer-msgdb)
3001                             (not (null (cdr dst-msgs)))
3002                             t ; t is no-delete (copy)
3003                             nil ; same number
3004                             unread-marks
3005                             t))
3006             (error nil))
3007           (if result                    ; succeeded.
3008               (progn
3009                 ;; update buffer.
3010                 (wl-summary-delete-copy-marks-on-buffer (cdr (car dst-msgs)))
3011                 ;; update copy-alist
3012                 (setq wl-summary-buffer-copy-list
3013                       (wl-delete-associations (cdr (car dst-msgs))
3014                                               wl-summary-buffer-copy-list)))
3015             (setq copy-failures
3016                   (+ copy-failures (length (cdr (car dst-msgs))))))
3017           (setq dst-msgs (cdr dst-msgs)))
3018         ;; Hide progress bar.
3019         (elmo-progress-clear 'elmo-folder-move-messages)
3020         ;; end cOpy
3021         (wl-summary-folder-info-update)
3022         (wl-summary-set-message-modified)
3023         (wl-summary-set-mark-modified)
3024         (run-hooks 'wl-summary-exec-hook)
3025         (unless (and wl-message-buffer
3026                      (eq (wl-summary-message-number)
3027                          (with-current-buffer wl-message-buffer
3028                            wl-message-buffer-cur-number)))
3029           (wl-summary-toggle-disp-msg 'off))
3030         (set-buffer-modified-p nil)
3031         (message (concat "Executing ... done"
3032                          (if (> refile-failures 0)
3033                              (format " (%d refiling failed)" refile-failures)
3034                            "")
3035                          (if (> copy-failures 0)
3036                              (format " (%d copying failed)" copy-failures)
3037                            "")
3038                          "."))))))
3039
3040 (defun wl-summary-read-folder (default &optional purpose ignore-error
3041                                 no-create init)
3042   (let ((fld (completing-read
3043               (format "Folder name %s(%s): " (or purpose "")
3044                       default)
3045               (or wl-folder-completion-function
3046                   (if (memq 'read-folder wl-use-folder-petname)
3047                       (wl-folder-get-entity-with-petname)
3048                     wl-folder-entity-hashtb))
3049               nil nil (or init wl-default-spec)
3050               'wl-read-folder-hist)))
3051     (if (or (string= fld wl-default-spec)
3052             (string= fld ""))
3053         (setq fld default))
3054     (setq fld (elmo-string (wl-folder-get-realname fld)))
3055     (if (string-match "\n" fld)
3056         (error "Not supported folder name: %s" fld))
3057     (unless no-create
3058       (if ignore-error
3059           (condition-case nil
3060               (wl-folder-confirm-existence
3061                (wl-folder-get-elmo-folder
3062                 fld))
3063             (error))
3064         (wl-folder-confirm-existence (wl-folder-get-elmo-folder
3065                                       fld))))
3066     fld))
3067
3068 (defun wl-summary-print-destination (msg-num folder)
3069   "Print refile destination on line."
3070   (wl-summary-remove-destination)
3071   (let ((inhibit-read-only t)
3072         (folder (copy-sequence folder))
3073         (buffer-read-only nil)
3074         len rs re c)
3075     (setq len (string-width folder))
3076     (if (< len 1) ()
3077       (end-of-line)
3078       (setq re (point))
3079       (setq c 0)
3080       (while (< c len)
3081         (forward-char -1)
3082         (setq c (+ c (char-width (following-char)))))
3083       (and (> c len) (setq folder (concat " " folder)))
3084       (setq rs (point))
3085       (put-text-property rs re 'invisible t)
3086       (put-text-property rs re 'wl-summary-destination t)
3087       (goto-char re)
3088       (wl-highlight-refile-destination-string folder)
3089       (insert folder)
3090       (set-buffer-modified-p nil))))
3091
3092 (defsubst wl-summary-get-mark (number)
3093   "Return a temporal mark of message specified by NUMBER."
3094   (or (and (memq number wl-summary-buffer-delete-list) "D")
3095       (and (assq number wl-summary-buffer-copy-list) "O")
3096       (and (assq number wl-summary-buffer-refile-list) "o")
3097       (and (memq number wl-summary-buffer-target-mark-list) "*")))
3098
3099 (defsubst wl-summary-reserve-temp-mark-p (mark)
3100   "Return t if temporal MARK should be reserved."
3101   (member mark wl-summary-reserve-mark-list))
3102
3103 (defun wl-summary-refile (&optional dst number)
3104   "Put refile mark on current line message.
3105 If optional argument DST is specified, put mark without asking
3106 destination folder.
3107 If optional argument NUMBER is specified, mark message specified by NUMBER.
3108
3109 If folder is read-only, message should be copied.
3110 See `wl-refile-policy-alist' for more details."
3111   (interactive)
3112   (let ((policy (wl-get-assoc-list-value wl-refile-policy-alist
3113                                          (wl-summary-buffer-folder-name))))
3114     (cond ((eq policy 'copy)
3115            (if (interactive-p)
3116                (call-interactively 'wl-summary-copy)
3117              (wl-summary-copy dst number)))
3118           (t
3119            (wl-summary-refile-subr 'refile (interactive-p) dst number)))))
3120
3121 (defun wl-summary-copy (&optional dst number)
3122   "Put copy mark on current line message.
3123 If optional argument DST is specified, put mark without asking
3124 destination folder.
3125 If optional argument NUMBER is specified, mark message specified by NUMBER."
3126   (interactive)
3127   (wl-summary-refile-subr 'copy (interactive-p) dst number))
3128
3129 (defun wl-summary-refile-subr (copy-or-refile interactive &optional dst number)
3130   (let* ((buffer-num (wl-summary-message-number))
3131          (msg-num (or number buffer-num))
3132          (msgid (and msg-num
3133                      (elmo-message-field wl-summary-buffer-elmo-folder
3134                                          msg-num 'message-id)))
3135          (entity (and msg-num
3136                       (elmo-msgdb-overview-get-entity
3137                        msg-num (wl-summary-buffer-msgdb))))
3138          (variable
3139           (intern (format "wl-summary-buffer-%s-list" copy-or-refile)))
3140          folder mark already tmp-folder)
3141     (catch 'done
3142       (when (null entity)
3143         ;; msgdb is empty?
3144         (if interactive
3145             (message "Cannot refile."))
3146         (throw 'done nil))
3147       (when (null msg-num)
3148         (if interactive
3149             (message "No message."))
3150         (throw 'done nil))
3151       (when (setq mark (wl-summary-get-mark msg-num))
3152         (when (wl-summary-reserve-temp-mark-p mark)
3153           (if interactive
3154               (error "Already marked as `%s'" mark))
3155           (throw 'done nil)))
3156       (setq folder (and msg-num
3157                         (or dst (wl-summary-read-folder
3158                                  (or (wl-refile-guess entity) wl-trash-folder)
3159                                  (format "for %s" copy-or-refile)))))
3160       ;; Cache folder hack by okada@opaopa.org
3161       (if (and (eq (elmo-folder-type-internal
3162                     (wl-folder-get-elmo-folder
3163                      (wl-folder-get-realname folder))) 'cache)
3164                (not (string= folder
3165                              (setq tmp-folder
3166                                    (concat "'cache/"
3167                                            (elmo-cache-get-path-subr
3168                                             (elmo-msgid-to-cache msgid)))))))
3169           (progn
3170             (setq folder tmp-folder)
3171             (message "Force refile to %s." folder)))
3172       (if (string= folder (wl-summary-buffer-folder-name))
3173           (error "Same folder"))
3174       (if (or (not (elmo-folder-writable-p (wl-folder-get-elmo-folder folder)))
3175               (string= folder wl-queue-folder)
3176               (string= folder wl-draft-folder))
3177           (error "Don't %s messages to %s" copy-or-refile folder))
3178       ;; learn for refile.
3179       (if (eq copy-or-refile 'refile)
3180           (wl-refile-learn entity folder))
3181       (wl-summary-unmark msg-num)
3182       (set variable (append
3183                      (symbol-value variable)
3184                      (list (cons msg-num folder))))
3185       (when (or interactive
3186                 (eq number buffer-num))
3187         (wl-summary-mark-line (if (eq copy-or-refile 'refile)
3188                                   "o" "O"))
3189         ;; print refile destination
3190         (wl-summary-print-destination msg-num folder))
3191       (if interactive
3192           (if (eq wl-summary-move-direction-downward nil)
3193               (wl-summary-prev)
3194             (wl-summary-next)))
3195       (run-hooks (intern (format "wl-summary-%s-hook" copy-or-refile)))
3196       (setq wl-summary-buffer-prev-refile-destination folder)
3197       msg-num)))
3198
3199 (defun wl-summary-refile-prev-destination ()
3200   "Refile message to previously refiled destination."
3201   (interactive)
3202   (wl-summary-refile wl-summary-buffer-prev-refile-destination
3203                      (wl-summary-message-number))
3204   (if (eq wl-summary-move-direction-downward nil)
3205       (wl-summary-prev)
3206     (wl-summary-next)))
3207
3208 (defun wl-summary-copy-prev-destination ()
3209   "Refile message to previously refiled destination."
3210   (interactive)
3211   (wl-summary-copy wl-summary-buffer-prev-copy-destination
3212                    (wl-summary-message-number))
3213   (if (eq wl-summary-move-direction-downward nil)
3214       (wl-summary-prev)
3215     (wl-summary-next)))
3216
3217 (defsubst wl-summary-no-auto-refile-message-p (msg)
3218   (member (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) msg)
3219           wl-summary-auto-refile-skip-marks))
3220
3221 (defun wl-summary-auto-refile (&optional open-all)
3222   "Set refile mark automatically according to 'wl-refile-guess-by-rule'."
3223   (interactive "P")
3224   (message "Marking...")
3225   (save-excursion
3226     (if (and (eq wl-summary-buffer-view 'thread)
3227              open-all)
3228         (wl-thread-open-all))
3229     (let* ((spec (wl-summary-buffer-folder-name))
3230            checked-dsts
3231            (count 0)
3232            number dst thr-entity)
3233       (goto-line 1)
3234       (while (not (eobp))
3235         (setq number (wl-summary-message-number))
3236         (dolist (number (cons number
3237                               (and (eq wl-summary-buffer-view 'thread)
3238                                    ;; process invisible children.
3239                                    (not (wl-thread-entity-get-opened
3240                                          (setq thr-entity
3241                                                (wl-thread-get-entity number))))
3242                                    (wl-thread-entity-get-descendant
3243                                     thr-entity))))
3244           (when (and (not (wl-summary-no-auto-refile-message-p
3245                            number))
3246                      (setq dst
3247                            (wl-folder-get-realname
3248                             (wl-refile-guess-by-rule
3249                              (elmo-msgdb-overview-get-entity
3250                               number (wl-summary-buffer-msgdb)))))
3251                      (not (equal dst spec))
3252                      (let ((pair (assoc dst checked-dsts))
3253                            ret)
3254                        (if pair
3255                            (cdr pair)
3256                          (setq ret
3257                                (condition-case nil
3258                                    (progn
3259                                      (wl-folder-confirm-existence
3260                                       (wl-folder-get-elmo-folder dst))
3261                                      t)
3262                                  (error)))
3263                          (setq checked-dsts (cons (cons dst ret) checked-dsts))
3264                          ret)))
3265             (if (wl-summary-refile dst number)
3266                 (incf count))
3267             (message "Marking...%d message(s)." count)))
3268         (forward-line))
3269       (if (eq count 0)
3270           (message "No message was marked.")
3271         (message "Marked %d message(s)." count)))))
3272
3273 (defun wl-summary-unmark (&optional number)
3274   "Unmark marks (temporary, refile, copy, delete)of current line.
3275 If optional argument NUMBER is specified, unmark message specified by NUMBER."
3276   (interactive)
3277   (save-excursion
3278     (beginning-of-line)
3279     (let ((inhibit-read-only t)
3280           (buffer-read-only nil)
3281           visible
3282           msg-num
3283           cur-mark
3284           score-mark)
3285       (if number
3286           (setq visible (wl-summary-jump-to-msg number))
3287         (setq visible t))
3288       ;; Delete mark on buffer.
3289       (when (and visible
3290                  (looking-at "^ *\\(-?[0-9]+\\)\\([^0-9]\\)"))
3291         (goto-char (match-end 2))
3292         (or number
3293             (setq number (string-to-int (wl-match-buffer 1))))
3294         (setq cur-mark (wl-match-buffer 2))
3295         (if (string= cur-mark " ")
3296             ()
3297           (delete-region (match-beginning 2) (match-end 2))
3298           (if (setq score-mark (wl-summary-get-score-mark number))
3299               (insert score-mark)
3300             (insert " ")))
3301         (if (or (string= cur-mark "o")
3302                 (string= cur-mark "O"))
3303             (wl-summary-remove-destination))
3304         (if wl-summary-highlight
3305             (wl-highlight-summary-current-line nil nil score-mark))
3306         (set-buffer-modified-p nil))
3307       ;; Remove from temporary mark structure.
3308       (and number
3309            (wl-summary-delete-mark number)))))
3310
3311 (defun wl-summary-msg-marked-as-target (msg)
3312   (if (memq msg wl-summary-buffer-target-mark-list)
3313       t))
3314
3315 (defun wl-summary-msg-marked-as-copied (msg)
3316   (assq msg wl-summary-buffer-copy-list))
3317
3318 (defun wl-summary-msg-marked-as-deleted (msg)
3319   (if (memq msg wl-summary-buffer-delete-list)
3320       t))
3321
3322 (defun wl-summary-msg-marked-as-refiled (msg)
3323   (assq msg wl-summary-buffer-refile-list))
3324
3325 (defun wl-summary-target-mark (&optional number)
3326   "Put target mark '*' on current message.
3327 If optional argument NUMBER is specified, mark message specified by NUMBER."
3328   (interactive)
3329   (let* ((buffer-num (wl-summary-message-number))
3330          (msg-num (or number buffer-num))
3331          mark)
3332     (catch 'done
3333       (when (null msg-num)
3334         (if (interactive-p)
3335             (message "No message."))
3336         (throw 'done nil))
3337       (when (setq mark (wl-summary-get-mark msg-num))
3338         (when (wl-summary-reserve-temp-mark-p mark)
3339           (if (interactive-p)
3340               (error "Already marked as `%s'" mark))
3341           (throw 'done nil))
3342         (wl-summary-unmark msg-num))
3343       (if (or (interactive-p)
3344               (eq number buffer-num))
3345           (wl-summary-mark-line "*"))
3346       (setq wl-summary-buffer-target-mark-list
3347             (cons msg-num wl-summary-buffer-target-mark-list))
3348       (if (interactive-p)
3349           (if (eq wl-summary-move-direction-downward nil)
3350               (wl-summary-prev)
3351             (wl-summary-next)))
3352       msg-num)))
3353
3354
3355 (defun wl-summary-refile-region (beg end)
3356   "Put copy mark on messages in the region specified by BEG and END."
3357   (interactive "r")
3358   (wl-summary-refile-region-subr "refile" beg end))
3359
3360 (defun wl-summary-copy-region (beg end)
3361   "Put copy mark on messages in the region specified by BEG and END."
3362   (interactive "r")
3363   (wl-summary-refile-region-subr "copy" beg end))
3364
3365 (defun wl-summary-refile-region-subr (copy-or-refile beg end)
3366   (save-excursion
3367     (save-restriction
3368       (goto-char beg)
3369       ;; guess by first msg
3370       (let* ((msgid (cdr (assq (wl-summary-message-number)
3371                                (elmo-msgdb-get-number-alist
3372                                 (wl-summary-buffer-msgdb)))))
3373              (function (intern (format "wl-summary-%s" copy-or-refile)))
3374              (entity (assoc msgid (elmo-msgdb-get-overview
3375                                    (wl-summary-buffer-msgdb))))
3376              folder)
3377         (if entity
3378             (setq folder (wl-summary-read-folder (wl-refile-guess entity)
3379                                                  (format "for %s"
3380                                                          copy-or-refile))))
3381         (narrow-to-region beg end)
3382         (if (eq wl-summary-buffer-view 'thread)
3383             (progn
3384               (while (not (eobp))
3385                 (let* ((number (wl-summary-message-number))
3386                        (entity (wl-thread-get-entity number))
3387                        children)
3388                   (if (wl-thread-entity-get-opened entity)
3389                       ;; opened...refile line.
3390                       (funcall function folder number)
3391                     ;; closed
3392                     (setq children (wl-thread-get-children-msgs number))
3393                     (while children
3394                       (funcall function folder (pop children))))
3395                   (forward-line 1))))
3396           (while (not (eobp))
3397             (funcall function folder (wl-summary-message-number))
3398             (forward-line 1)))))))
3399
3400 (defun wl-summary-unmark-region (beg end)
3401   (interactive "r")
3402   (save-excursion
3403     (save-restriction
3404       (narrow-to-region beg end)
3405       (goto-char (point-min))
3406       (if (eq wl-summary-buffer-view 'thread)
3407           (progn
3408             (while (not (eobp))
3409               (let* ((number (wl-summary-message-number))
3410                      (entity (wl-thread-get-entity number)))
3411                 (if (wl-thread-entity-get-opened entity)
3412                     ;; opened...unmark line.
3413                     (wl-summary-unmark)
3414                   ;; closed
3415                   (wl-summary-delete-marks-on-buffer
3416                    (wl-thread-get-children-msgs number))))
3417               (forward-line 1)))
3418         (while (not (eobp))
3419           (wl-summary-unmark)
3420           (forward-line 1))))))
3421
3422 (defun wl-summary-mark-region-subr (function beg end)
3423   (save-excursion
3424     (save-restriction
3425       (narrow-to-region beg end)
3426       (goto-char (point-min))
3427       (if (eq wl-summary-buffer-view 'thread)
3428           (progn
3429             (while (not (eobp))
3430               (let* ((number (wl-summary-message-number))
3431                      (entity (wl-thread-get-entity number))
3432                      (wl-summary-move-direction-downward t)
3433                      children)
3434                 (if (wl-thread-entity-get-opened entity)
3435                     ;; opened...delete line.
3436                     (funcall function number)
3437                   ;; closed
3438                   (setq children (wl-thread-get-children-msgs number))
3439                   (while children
3440                     (funcall function (pop children))))
3441                 (forward-line 1))))
3442         (while (not (eobp))
3443           (funcall function (wl-summary-message-number))
3444           (forward-line 1))))))
3445
3446 (defun wl-summary-delete-region (beg end)
3447   (interactive "r")
3448   (wl-summary-mark-region-subr 'wl-summary-delete beg end))
3449
3450 (defun wl-summary-target-mark-region (beg end)
3451   (interactive "r")
3452   (wl-summary-mark-region-subr 'wl-summary-target-mark beg end))
3453
3454 (defun wl-summary-target-mark-all ()
3455   (interactive)
3456   (wl-summary-target-mark-region (point-min) (point-max))
3457   (setq wl-summary-buffer-target-mark-list
3458         (mapcar 'car
3459                 (elmo-msgdb-get-number-alist (wl-summary-buffer-msgdb)))))
3460
3461 (defun wl-summary-delete-all-mark (mark)
3462   (goto-char (point-min))
3463   (let ((case-fold-search nil))
3464     (while (re-search-forward (format "^ *-?[0-9]+%s"
3465                                       (regexp-quote mark)) nil t)
3466       (wl-summary-unmark))
3467     (cond ((string= mark "*")
3468            (setq wl-summary-buffer-target-mark-list nil))
3469           ((string= mark "D")
3470            (setq wl-summary-buffer-delete-list nil))
3471           ((string= mark "O")
3472            (setq wl-summary-buffer-copy-list nil))
3473           ((string= mark "o")
3474            (setq wl-summary-buffer-refile-list nil)))))
3475
3476 (defun wl-summary-unmark-all ()
3477   "Unmark all according to what you input."
3478   (interactive)
3479   (let ((unmarks (string-to-char-list (read-from-minibuffer "Unmark: ")))
3480         cur-mark)
3481     (save-excursion
3482       (while unmarks
3483         (setq cur-mark (char-to-string (car unmarks)))
3484         (wl-summary-delete-all-mark cur-mark)
3485         (setq unmarks (cdr unmarks))))))
3486
3487 (defun wl-summary-target-mark-thread ()
3488   (interactive)
3489   (wl-thread-call-region-func 'wl-summary-target-mark-region t))
3490
3491 (defun wl-summary-target-mark-msgs (msgs)
3492   "Return the number of marked messages."
3493   (let ((i 0) num)
3494     (while msgs
3495       (if (eq wl-summary-buffer-view 'thread)
3496           (wl-thread-jump-to-msg (car msgs))
3497         (wl-summary-jump-to-msg (car msgs)))
3498       (setq num (wl-summary-message-number))
3499       (when (eq num (car msgs))
3500         (wl-summary-target-mark num)
3501         (setq i (1+ i)))
3502       (setq msgs (cdr msgs)))
3503     i))
3504
3505 (defun wl-summary-pick (&optional from-list delete-marks)
3506   (interactive)
3507   (save-excursion
3508     (let* ((condition (car (elmo-parse-search-condition
3509                             (elmo-read-search-condition
3510                              wl-summary-pick-field-default))))
3511            (result (elmo-folder-search wl-summary-buffer-elmo-folder
3512                                        condition
3513                                        from-list))
3514            num)
3515       (if delete-marks
3516           (let ((mlist wl-summary-buffer-target-mark-list))
3517             (while mlist
3518               (when (wl-summary-jump-to-msg (car mlist))
3519                 (wl-summary-unmark))
3520               (setq mlist (cdr mlist)))
3521             (setq wl-summary-buffer-target-mark-list nil)))
3522       (if (and result
3523                (setq num (wl-summary-target-mark-msgs result))
3524                (> num 0))
3525           (if (= num (length result))
3526               (message "%d message(s) are picked." num)
3527             (message "%d(%d) message(s) are picked." num
3528                      (- (length result) num)))
3529         (message "No message was picked.")))))
3530
3531 (defun wl-summary-unvirtual ()
3532   "Exit from current virtual folder."
3533   (interactive)
3534   (if (eq 'filter
3535           (elmo-folder-type-internal wl-summary-buffer-elmo-folder))
3536       (wl-summary-goto-folder-subr
3537        (elmo-folder-name-internal
3538         (elmo-filter-folder-target-internal
3539          wl-summary-buffer-elmo-folder))
3540        'update nil nil t)
3541     (error "This folder is not filtered")))
3542
3543 (defun wl-summary-virtual (&optional arg)
3544   "Goto virtual folder.
3545 If ARG, exit virtual folder."
3546   (interactive "P")
3547   (if arg
3548       (wl-summary-unvirtual)
3549     (wl-summary-goto-folder-subr (concat "/"
3550                                          (elmo-read-search-condition
3551                                           wl-summary-pick-field-default)
3552                                          "/"
3553                                          (wl-summary-buffer-folder-name))
3554                                  'update nil nil t)))
3555
3556 (defun wl-summary-delete-all-temp-marks (&optional no-msg)
3557   "Erase all temp marks from buffer."
3558   (interactive)
3559   (when (or wl-summary-buffer-target-mark-list
3560             wl-summary-buffer-delete-list
3561             wl-summary-buffer-refile-list
3562             wl-summary-buffer-copy-list)
3563     (save-excursion
3564       (goto-char (point-min))
3565       (unless no-msg
3566         (message "Unmarking..."))
3567       (while (not (eobp))
3568         (wl-summary-unmark)
3569         (forward-line))
3570       (unless no-msg
3571         (message "Unmarking...done"))
3572       (setq wl-summary-buffer-target-mark-list nil)
3573       (setq wl-summary-buffer-delete-list nil)
3574       (setq wl-summary-buffer-refile-list nil)
3575       (setq wl-summary-buffer-copy-list nil))))
3576
3577 (defun wl-summary-delete-mark (number)
3578   "Delete temporary mark of the message specified by NUMBER."
3579   (cond
3580    ((memq number wl-summary-buffer-target-mark-list)
3581     (setq wl-summary-buffer-target-mark-list
3582           (delq number wl-summary-buffer-target-mark-list)))
3583    ((memq number wl-summary-buffer-delete-list)
3584     (setq wl-summary-buffer-delete-list
3585           (delq number wl-summary-buffer-delete-list)))
3586    (t
3587     (let (pair)
3588       (cond
3589        ((setq pair (assq number wl-summary-buffer-copy-list))
3590         (setq wl-summary-buffer-copy-list
3591               (delq pair wl-summary-buffer-copy-list)))
3592        ((setq pair (assq number wl-summary-buffer-refile-list))
3593         (setq wl-summary-buffer-refile-list
3594               (delq pair wl-summary-buffer-refile-list))))))))
3595
3596 (defun wl-summary-mark-line (mark)
3597   "Put MARK on current line.  Return message number."
3598   (save-excursion
3599     (beginning-of-line)
3600     (let ((inhibit-read-only t)
3601           (buffer-read-only nil)
3602           msg-num
3603           cur-mark)
3604       (when (looking-at "^ *\\(-?[0-9]+\\)\\([^0-9]\\)")
3605         (setq msg-num  (string-to-int (wl-match-buffer 1)))
3606         (setq cur-mark (wl-match-buffer 2))
3607         (goto-char (match-end 1))
3608         (delete-region (match-beginning 2) (match-end 2))
3609 ;;;     (wl-summary-delete-mark msg-num)
3610         (insert mark)
3611         (if wl-summary-highlight
3612             (wl-highlight-summary-current-line nil nil t))
3613         (set-buffer-modified-p nil)
3614         msg-num))))
3615
3616 (defun wl-summary-target-mark-delete ()
3617   (interactive)
3618   (save-excursion
3619     (goto-char (point-min))
3620     (let ((regexp (concat wl-summary-message-regexp "\\(\\*\\)"))
3621           number mlist)
3622       (while (re-search-forward regexp nil t)
3623         (let (wl-summary-buffer-disp-msg)
3624           (when (setq number (wl-summary-message-number))
3625             (wl-summary-delete number)
3626             (setq wl-summary-buffer-target-mark-list
3627                   (delq number wl-summary-buffer-target-mark-list)))))
3628       (setq mlist wl-summary-buffer-target-mark-list)
3629       (while mlist
3630         (wl-append wl-summary-buffer-delete-list (list (car mlist)))
3631         (setq wl-summary-buffer-target-mark-list
3632               (delq (car mlist) wl-summary-buffer-target-mark-list))
3633         (setq mlist (cdr mlist))))))
3634
3635 (defun wl-summary-target-mark-prefetch (&optional ignore-cache)
3636   (interactive "P")
3637   (save-excursion
3638     (let* ((mlist (nreverse wl-summary-buffer-target-mark-list))
3639            (inhibit-read-only t)
3640            (buffer-read-only nil)
3641            (count 0)
3642            (length (length mlist))
3643            (pos (point))
3644            skipped
3645            new-mark)
3646       (while mlist
3647         (setq new-mark (wl-summary-prefetch-msg (car mlist) ignore-cache))
3648         (if new-mark
3649             (progn
3650               (message "Prefetching... %d/%d message(s)"
3651                        (setq count (+ 1 count)) length)
3652               (when (wl-summary-jump-to-msg (car mlist))
3653                 (wl-summary-unmark)
3654                 (when new-mark
3655                   (when (looking-at "^ *-?[0-9]+[^0-9]\\([^0-9]\\)")
3656                     (delete-region (match-beginning 1) (match-end 1)))
3657                   (goto-char (match-beginning 1))
3658                   (insert new-mark)
3659                   (if wl-summary-highlight
3660                       (wl-highlight-summary-current-line))
3661                   (save-excursion
3662                     (goto-char pos)
3663                     (sit-for 0)))))
3664           (setq skipped (cons (car mlist) skipped)))
3665         (setq mlist (cdr mlist)))
3666       (setq wl-summary-buffer-target-mark-list skipped)
3667       (message "Prefetching... %d/%d message(s)." count length)
3668       (set-buffer-modified-p nil))))
3669
3670 (defun wl-summary-target-mark-refile-subr (copy-or-refile)
3671   (let ((variable
3672          (intern (format "wl-summary-buffer-%s-list" copy-or-refile)))
3673         (function
3674          (intern (format "wl-summary-%s" copy-or-refile)))
3675         regexp number msgid entity folder mlist)
3676     (save-excursion
3677       (goto-char (point-min))
3678       (setq regexp (concat wl-summary-message-regexp "\\(\\*\\)"))
3679       ;; guess by first mark
3680       (when (re-search-forward regexp nil t)
3681         (setq msgid (cdr (assq (setq number (wl-summary-message-number))
3682                                (elmo-msgdb-get-number-alist
3683                                 (wl-summary-buffer-msgdb))))
3684               entity (assoc msgid
3685                             (elmo-msgdb-get-overview
3686                              (wl-summary-buffer-msgdb))))
3687         (if (null entity)
3688             (error "Cannot %s" copy-or-refile))
3689         (funcall function
3690                  (setq folder (wl-summary-read-folder
3691                                (wl-refile-guess entity)
3692                                (format "for %s" copy-or-refile)))
3693                  number)
3694         (if number
3695             (setq wl-summary-buffer-target-mark-list
3696                   (delq number wl-summary-buffer-target-mark-list)))
3697         (while (re-search-forward regexp nil t)
3698           (let (wl-summary-buffer-disp-msg)
3699             (when (setq number (wl-summary-message-number))
3700               (funcall function folder number)
3701               (setq wl-summary-buffer-target-mark-list
3702                     (delq number wl-summary-buffer-target-mark-list)))))
3703         ;; process invisible messages.
3704         (setq mlist wl-summary-buffer-target-mark-list)
3705         (while mlist
3706           (set variable
3707                (append (symbol-value variable)
3708                        (list (cons (car mlist) folder))))
3709           (setq wl-summary-buffer-target-mark-list
3710                 (delq (car mlist) wl-summary-buffer-target-mark-list))
3711           (setq mlist (cdr mlist)))))))
3712
3713 (defun wl-summary-next-buffer ()
3714   "Switch to next summary buffer."
3715   (interactive)
3716   (let ((buffers (sort (wl-collect-summary)
3717                        (lambda (buffer1 buffer2)
3718                          (string-lessp (buffer-name buffer1)
3719                                        (buffer-name buffer2))))))
3720     (switch-to-buffer
3721      (or (cadr (memq (current-buffer) buffers))
3722          (car buffers)))))
3723
3724 (defun wl-summary-previous-buffer ()
3725   "Switch to previous summary buffer."
3726   (interactive)
3727   (let ((buffers (sort (wl-collect-summary)
3728                        (lambda (buffer1 buffer2)
3729                          (not (string-lessp (buffer-name buffer1)
3730                                             (buffer-name buffer2)))))))
3731     (switch-to-buffer
3732      (or (cadr (memq (current-buffer) buffers))
3733          (car buffers)))))
3734
3735 (defun wl-summary-target-mark-copy ()
3736   (interactive)
3737   (wl-summary-target-mark-refile-subr "copy"))
3738
3739 (defun wl-summary-target-mark-refile ()
3740   (interactive)
3741   (wl-summary-target-mark-refile-subr "refile"))
3742
3743 (defun wl-summary-target-mark-mark-as-read ()
3744   (interactive)
3745   (save-excursion
3746     (goto-char (point-min))
3747     (let ((regexp (concat wl-summary-message-regexp "\\(\\*\\)"))
3748           (inhibit-read-only t)
3749           (buffer-read-only nil)
3750           number mlist)
3751       (while (re-search-forward regexp nil t)
3752         (let (wl-summary-buffer-disp-msg)
3753           ;; delete target-mark from buffer.
3754           (delete-region (match-beginning 1) (match-end 1))
3755           (insert " ")
3756           (setq number (wl-summary-mark-as-read t))
3757           (if wl-summary-highlight
3758               (wl-highlight-summary-current-line))
3759           (if number
3760               (setq wl-summary-buffer-target-mark-list
3761                     (delq number wl-summary-buffer-target-mark-list)))))
3762       (setq mlist wl-summary-buffer-target-mark-list)
3763       (while mlist
3764         (wl-summary-mark-as-read t nil nil (car mlist))
3765         (setq wl-summary-buffer-target-mark-list
3766               (delq (car mlist) wl-summary-buffer-target-mark-list))
3767         (setq mlist (cdr mlist)))
3768       (wl-summary-count-unread)
3769       (wl-summary-update-modeline))))
3770
3771 (defun wl-summary-target-mark-mark-as-unread ()
3772   (interactive)
3773   (save-excursion
3774     (goto-char (point-min))
3775     (let ((regexp (concat wl-summary-message-regexp "\\(\\*\\)"))
3776           (inhibit-read-only t)
3777           (buffer-read-only nil)
3778           number mlist)
3779       (while (re-search-forward regexp nil t)
3780         (let (wl-summary-buffer-disp-msg)
3781           ;; delete target-mark from buffer.
3782           (delete-region (match-beginning 1) (match-end 1))
3783           (insert " ")
3784           (setq number (wl-summary-mark-as-unread))
3785           (if wl-summary-highlight
3786               (wl-highlight-summary-current-line))
3787           (if number
3788               (setq wl-summary-buffer-target-mark-list
3789                     (delq number wl-summary-buffer-target-mark-list)))))
3790       (setq mlist wl-summary-buffer-target-mark-list)
3791       (while mlist
3792         (wl-summary-mark-as-unread (car mlist))
3793 ;;;     (wl-thread-msg-mark-as-unread (car mlist))
3794         (setq wl-summary-buffer-target-mark-list
3795               (delq (car mlist) wl-summary-buffer-target-mark-list))
3796         (setq mlist (cdr mlist)))
3797       (wl-summary-count-unread)
3798       (wl-summary-update-modeline))))
3799
3800 (defun wl-summary-target-mark-mark-as-important ()
3801   (interactive)
3802   (save-excursion
3803     (goto-char (point-min))
3804     (let ((regexp (concat wl-summary-message-regexp "\\(\\*\\)"))
3805           (inhibit-read-only t)
3806           (buffer-read-only nil)
3807           number mlist)
3808       (while (re-search-forward regexp nil t)
3809         (let (wl-summary-buffer-disp-msg)
3810           ;; delete target-mark from buffer.
3811           (delete-region (match-beginning 1) (match-end 1))
3812           (insert " ")
3813           (setq number (wl-summary-mark-as-important))
3814           (if wl-summary-highlight
3815               (wl-highlight-summary-current-line))
3816           (if number
3817               (setq wl-summary-buffer-target-mark-list
3818                     (delq number wl-summary-buffer-target-mark-list)))))
3819       (setq mlist wl-summary-buffer-target-mark-list)
3820       (while mlist
3821         (wl-summary-mark-as-important (car mlist))
3822         (wl-thread-msg-mark-as-important (car mlist))
3823         (setq wl-summary-buffer-target-mark-list
3824               (delq (car mlist) wl-summary-buffer-target-mark-list))
3825         (setq mlist (cdr mlist)))
3826       (wl-summary-count-unread)
3827       (wl-summary-update-modeline))))
3828
3829 (defun wl-summary-target-mark-save ()
3830   (interactive)
3831   (save-excursion
3832     (goto-char (point-min))
3833     (let ((wl-save-dir
3834            (wl-read-directory-name "Save to directory: "
3835                                    wl-temporary-file-directory))
3836           (regexp (concat wl-summary-message-regexp "\\(\\*\\)"))
3837           number mlist)
3838       (if (null (file-exists-p wl-save-dir))
3839           (make-directory wl-save-dir))
3840       (while (re-search-forward regexp nil t)
3841         (let (wl-summary-buffer-disp-msg)
3842           (setq number (wl-summary-save t wl-save-dir))
3843           (wl-summary-unmark)
3844           (if number
3845               (setq wl-summary-buffer-target-mark-list
3846                     (delq number wl-summary-buffer-target-mark-list))))))))
3847
3848 (defun wl-summary-target-mark-pick ()
3849   (interactive)
3850   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
3851
3852 (defun wl-summary-mark-as-read (&optional notcrosses
3853                                           leave-server-side-mark-untouched
3854                                           displayed
3855                                           number
3856                                           cached)
3857   (interactive)
3858   (save-excursion
3859     (let* (eol
3860            (inhibit-read-only t)
3861            (buffer-read-only nil)
3862            (folder wl-summary-buffer-elmo-folder)
3863            (msgdb (wl-summary-buffer-msgdb))
3864 ;;;        (number-alist (elmo-msgdb-get-number-alist msgdb))
3865            (case-fold-search nil)
3866            mark stat visible uncached new-mark marked)
3867       (if number
3868           (progn
3869             (setq visible (wl-summary-jump-to-msg number))
3870             (setq mark (elmo-msgdb-get-mark msgdb number)))
3871         ;; interactive
3872         (setq visible t))
3873       (beginning-of-line)
3874       (if (or (not visible)
3875               (looking-at
3876                (format "^ *\\(-?[0-9]+\\)[^0-9]\\(%s\\|%s\\|%s\\|%s\\).*$"
3877                        (regexp-quote wl-summary-read-uncached-mark)
3878                        (regexp-quote wl-summary-unread-uncached-mark)
3879                        (regexp-quote wl-summary-unread-cached-mark)
3880                        (regexp-quote wl-summary-new-mark))))
3881           (progn
3882             (setq mark (or mark (wl-match-buffer 2)))
3883             (when mark
3884               (cond
3885                ((string= mark wl-summary-new-mark) ; N
3886                 (setq stat 'new)
3887                 (setq uncached t))
3888                ((string= mark wl-summary-unread-uncached-mark) ; U
3889                 (setq stat 'unread)
3890                 (setq uncached t))
3891                ((string= mark wl-summary-unread-cached-mark)  ; !
3892                 (setq stat 'unread))
3893                (t
3894                 ;; no need to mark server.
3895                 (setq leave-server-side-mark-untouched t))))
3896             (setq number (or number (string-to-int (wl-match-buffer 1))))
3897             ;; set server side mark...
3898             (setq new-mark (if (and uncached
3899                                     (if (elmo-message-use-cache-p folder number)
3900                                         (not (elmo-folder-local-p folder)))
3901                                     (not cached))
3902                                wl-summary-read-uncached-mark
3903                              nil))
3904             (if (not leave-server-side-mark-untouched)
3905                 (save-match-data
3906                   (setq marked (elmo-folder-mark-as-read
3907                                 folder
3908                                 (list number)))))
3909             (if (or leave-server-side-mark-untouched
3910                     marked)
3911                 (progn
3912                   (cond ((eq stat 'unread)
3913                          (setq wl-summary-buffer-unread-count
3914                                (1- wl-summary-buffer-unread-count)))
3915                         ((eq stat 'new)
3916                          (setq wl-summary-buffer-new-count
3917                                (1- wl-summary-buffer-new-count))))
3918                   (wl-summary-update-modeline)
3919                   (wl-folder-update-unread
3920                    (wl-summary-buffer-folder-name)
3921                    (+ wl-summary-buffer-unread-count
3922                       wl-summary-buffer-new-count))
3923                   (when (or stat cached)
3924                     (when visible
3925                       (goto-char (match-end 2))
3926                       (delete-region (match-beginning 2) (match-end 2))
3927                       (insert (or new-mark " ")))
3928                     (elmo-msgdb-set-mark msgdb number new-mark)
3929                     (wl-summary-set-mark-modified))
3930                   (if (and visible wl-summary-highlight)
3931                       (wl-highlight-summary-current-line nil nil t)))
3932               (if mark (message "Warning: Changing mark failed.")))))
3933       (set-buffer-modified-p nil)
3934       (if stat
3935           (run-hooks 'wl-summary-unread-message-hook))
3936       number ;return value
3937       )))
3938
3939 (defun wl-summary-mark-as-important (&optional number
3940                                                mark
3941                                                no-server-update)
3942   (interactive)
3943   (if (eq (elmo-folder-type-internal wl-summary-buffer-elmo-folder)
3944           'internal)
3945       (error "Cannot process mark in this folder"))
3946   (save-excursion
3947     (let* (eol
3948           (inhibit-read-only t)
3949           (buffer-read-only nil)
3950           (folder wl-summary-buffer-elmo-folder)
3951           (msgdb (wl-summary-buffer-msgdb))
3952           (number-alist (elmo-msgdb-get-number-alist msgdb))
3953           message-id visible)
3954       (if number
3955           (progn
3956             (setq visible (wl-summary-jump-to-msg number))
3957             (setq mark (or mark (elmo-msgdb-get-mark msgdb number))))
3958         (setq visible t))
3959       (when visible
3960         (if (null (setq number (wl-summary-message-number)))
3961             (progn
3962               (message "No message.")
3963               (setq visible nil))
3964           (end-of-line)
3965           (setq eol (point))
3966           (wl-summary-goto-previous-message-beginning)))
3967       (if (or (and (not visible)
3968                    (assq number (elmo-msgdb-get-number-alist msgdb)))
3969               (re-search-forward "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)" eol t))
3970           (progn
3971             (setq number (or number (string-to-int (wl-match-buffer 1))))
3972             (setq mark (or mark (wl-match-buffer 2)))
3973             (setq message-id (elmo-message-field
3974                               wl-summary-buffer-elmo-folder
3975                               number
3976                               'message-id))
3977             (if (string= mark wl-summary-important-mark)
3978                 (progn
3979                   ;; server side mark
3980                   (save-match-data
3981                     (unless no-server-update
3982                       (elmo-folder-unmark-important folder (list number))
3983                       (elmo-msgdb-global-mark-delete message-id))
3984                     ;; Remove cache if local folder.
3985                     (if (and (elmo-folder-local-p folder)
3986                              (not (eq 'mark
3987                                       (elmo-folder-type-internal folder))))
3988                         (elmo-file-cache-delete
3989                          (elmo-file-cache-get-path message-id))))
3990                   (when visible
3991                     (delete-region (match-beginning 2) (match-end 2))
3992                     (insert " "))
3993                   (elmo-msgdb-set-mark msgdb number nil))
3994               ;; server side mark
3995               (save-match-data
3996                 (unless no-server-update
3997                   (elmo-folder-mark-as-important folder (list number))))
3998               (when visible
3999                 (delete-region (match-beginning 2) (match-end 2))
4000                 (insert wl-summary-important-mark))
4001               (elmo-msgdb-set-mark msgdb number
4002                                    wl-summary-important-mark)
4003               (if (eq (elmo-file-cache-exists-p message-id) 'entire)
4004                   (elmo-folder-mark-as-read folder (list number))
4005                 ;; Force cache message.
4006                 (elmo-message-encache folder number 'read))
4007               (unless no-server-update
4008                 (elmo-msgdb-global-mark-set message-id
4009                                             wl-summary-important-mark)))
4010             (wl-summary-set-mark-modified)))
4011       (if (and visible wl-summary-highlight)
4012           (wl-highlight-summary-current-line nil nil t))))
4013   (set-buffer-modified-p nil)
4014   number)
4015
4016 ;;; Summary line.
4017 (defvar wl-summary-line-formatter nil)
4018
4019 (defvar wl-datevec)
4020 (defvar wl-thr-indent-string)
4021 (defvar wl-thr-children-number)
4022 (defvar wl-thr-linked)
4023 (defvar wl-message-entity)
4024 (defvar wl-parent-message-entity)
4025
4026 (defun wl-summary-line-year ()
4027   (aref wl-datevec 0))
4028 (defun wl-summary-line-month ()
4029   (format "%02d" (aref wl-datevec 1)))
4030 (defun wl-summary-line-day ()
4031   (format "%02d" (aref wl-datevec 2)))
4032 (defun wl-summary-line-day-of-week ()
4033   (elmo-date-get-week (aref wl-datevec 0)
4034                       (aref wl-datevec 1)
4035                       (aref wl-datevec 2)))
4036 (defun wl-summary-line-hour ()
4037   (format "%02d" (aref wl-datevec 3)))
4038 (defun wl-summary-line-minute ()
4039   (format "%02d" (aref wl-datevec 4)))
4040 (defun wl-summary-line-open-bracket ()
4041   (if wl-thr-linked "<" "["))
4042 (defun wl-summary-line-close-bracket ()
4043   (if wl-thr-linked ">" "]"))
4044 (defun wl-summary-line-children-number ()
4045   (if wl-thr-children-number
4046       (concat "+" (int-to-string wl-thr-children-number) ":")
4047     ""))
4048 (defun wl-summary-line-thread-indent ()
4049   (or wl-thr-indent-string ""))
4050
4051 (defun wl-summary-line-size ()
4052   (let ((size (elmo-msgdb-overview-entity-get-size wl-message-entity)))
4053     (if size
4054         (cond
4055          ((<= 1 (/ size 1048576))
4056           (format "%.0fM" (/ size 1048576.0)))
4057          ((<= 1 (/ size 1024))
4058           (format "%.0fK" (/ size 1024.0)))
4059          (t (format "%dB" size)))
4060       "")))
4061
4062 (defun wl-summary-line-subject ()
4063   (let (no-parent subject parent-raw-subject parent-subject)
4064     (if (string= wl-thr-indent-string "")
4065         (setq no-parent t)) ; no parent
4066     (setq subject
4067           (elmo-delete-char ?\n
4068                             (or (elmo-msgdb-overview-entity-get-subject
4069                                  wl-message-entity)
4070                                 wl-summary-no-subject-message)))
4071     (setq parent-raw-subject
4072           (elmo-msgdb-overview-entity-get-subject wl-parent-message-entity))
4073     (setq parent-subject
4074           (if parent-raw-subject
4075               (elmo-delete-char ?\n parent-raw-subject)))
4076     (setq subject
4077           (if (or no-parent
4078                   (null parent-subject)
4079                   (not (wl-summary-subject-equal
4080                         subject parent-subject)))
4081               (funcall wl-summary-subject-function subject)
4082             ""))
4083     (if (and (not wl-summary-width)
4084              wl-summary-subject-length-limit)
4085         (truncate-string subject 
4086                          wl-summary-subject-length-limit)
4087       subject)))
4088
4089 (defun wl-summary-line-from ()
4090   (elmo-delete-char ?\n
4091                     (funcall wl-summary-from-function
4092                              (elmo-msgdb-overview-entity-get-from
4093                               wl-message-entity))))
4094
4095 (defun wl-summary-line-children-and-from ()
4096   (concat
4097    (wl-summary-line-children-number) " "
4098    (wl-summary-line-from)))
4099
4100 (defun wl-summary-create-line (wl-message-entity
4101                                wl-parent-message-entity
4102                                temp-mark
4103                                &optional
4104                                wl-thr-children-number
4105                                wl-thr-indent-string
4106                                wl-thr-linked)
4107   "Create a summary line."
4108   (let ((wl-mime-charset wl-summary-buffer-mime-charset)
4109         (elmo-mime-charset wl-summary-buffer-mime-charset)
4110         (elmo-lang wl-summary-buffer-weekday-name-lang)
4111         (wl-datevec (timezone-fix-time
4112                      (elmo-msgdb-overview-entity-get-date 
4113                       wl-message-entity)
4114                      nil
4115                      wl-summary-fix-timezone))
4116         line mark)
4117     (if (and wl-thr-indent-string
4118              wl-summary-indent-length-limit
4119              (< wl-summary-indent-length-limit
4120                 (string-width wl-thr-indent-string)))
4121         (setq wl-thr-indent-string (wl-set-string-width
4122                                     wl-summary-indent-length-limit
4123                                     wl-thr-indent-string)))
4124     (setq line 
4125           (concat
4126            (format
4127             (concat "%"
4128                     (number-to-string wl-summary-buffer-number-column)
4129                     "s%s%s")
4130             (number-to-string
4131              (elmo-msgdb-overview-entity-get-number wl-message-entity))
4132             (or temp-mark " ")
4133             (setq mark
4134                   (or (elmo-msgdb-get-mark
4135                        (wl-summary-buffer-msgdb)
4136                        (elmo-msgdb-overview-entity-get-number
4137                         wl-message-entity))
4138                       " ")))
4139            (funcall wl-summary-buffer-line-formatter)))
4140     (if wl-summary-width (setq line
4141                                (wl-set-string-width
4142                                 (- wl-summary-width 1) line)))
4143     (if wl-summary-highlight
4144         (wl-highlight-summary-line-string line
4145                                           mark
4146                                           temp-mark
4147                                           wl-thr-indent-string))
4148     line))
4149
4150 (defsubst wl-summary-proc-wday (wday-str year month mday)
4151   (save-match-data
4152     (if (string-match "\\([A-Z][a-z][a-z]\\).*" wday-str)
4153         (wl-match-string 1 wday-str)
4154       (elmo-date-get-week year month mday))))
4155
4156 (defvar wl-summary-move-spec-plugged-alist
4157   (` ((new . ((t . nil)
4158               (p . (, wl-summary-new-mark))
4159               (p . (, (wl-regexp-opt
4160                        (list wl-summary-unread-uncached-mark
4161                              wl-summary-unread-cached-mark))))
4162               (p . (, (regexp-quote wl-summary-important-mark)))))
4163       (unread . ((t . nil)
4164                  (p . (, (wl-regexp-opt
4165                           (list wl-summary-new-mark
4166                                 wl-summary-unread-uncached-mark
4167                                 wl-summary-unread-cached-mark))))
4168                  (p . (, (regexp-quote wl-summary-important-mark))))))))
4169
4170 (defvar wl-summary-move-spec-unplugged-alist
4171   (` ((new . ((t . nil)
4172               (p . (, wl-summary-unread-cached-mark))
4173               (p . (, (regexp-quote wl-summary-important-mark)))))
4174       (unread . ((t . nil)
4175                  (p . (, wl-summary-unread-cached-mark))
4176                  (p . (, (regexp-quote wl-summary-important-mark))))))))
4177
4178 (defsubst wl-summary-next-message (num direction hereto)
4179   (if wl-summary-buffer-next-message-function
4180       (funcall wl-summary-buffer-next-message-function num direction hereto)
4181     (let ((cur-spec (cdr (assq wl-summary-move-order
4182                                (if (elmo-folder-plugged-p
4183                                     wl-summary-buffer-elmo-folder)
4184                                    wl-summary-move-spec-plugged-alist
4185                                  wl-summary-move-spec-unplugged-alist))))
4186           (nums (memq num (if (eq direction 'up)
4187                               (reverse wl-summary-buffer-number-list)
4188                             wl-summary-buffer-number-list)))
4189           marked-list nums2)
4190       (unless hereto (setq nums (cdr nums)))
4191       (setq nums2 nums)
4192       (if cur-spec
4193           (catch 'done
4194             (while cur-spec
4195               (setq nums nums2)
4196               (cond ((eq (car (car cur-spec)) 'p)
4197                      (if (setq marked-list
4198                                (elmo-folder-list-messages-mark-match
4199                                 wl-summary-buffer-elmo-folder
4200                                 (cdr (car cur-spec))))
4201                          (while nums
4202                            (if (memq (car nums) marked-list)
4203                                (throw 'done (car nums)))
4204                            (setq nums (cdr nums)))))
4205                     ((eq (car (car cur-spec)) 't)
4206                      (if wl-summary-buffer-target-mark-list
4207                          (while nums
4208                            (if (memq (car nums)
4209                                      wl-summary-buffer-target-mark-list)
4210                                (throw 'done (car nums)))
4211                            (setq nums (cdr nums))))))
4212               (setq cur-spec (cdr cur-spec))))
4213         (car nums)))))
4214
4215 (defsubst wl-summary-cursor-move (direction hereto)
4216   (when (and (eq direction 'up)
4217              (eobp))
4218     (forward-line -1)
4219     (setq hereto t))
4220   (let (num)
4221     (when (setq num (wl-summary-next-message (wl-summary-message-number)
4222                                              direction hereto))
4223       (if (numberp num)
4224           (wl-thread-jump-to-msg num))
4225       t)))
4226 ;;
4227 ;; Goto unread or important
4228 ;; returns t if next message exists in this folder.
4229 (defun wl-summary-cursor-down (&optional hereto)
4230   (interactive "P")
4231   (wl-summary-cursor-move 'down hereto))
4232
4233 (defun wl-summary-cursor-up (&optional hereto)
4234   (interactive "P")
4235   (wl-summary-cursor-move 'up hereto))
4236
4237 (defun wl-summary-save-view-cache ()
4238   (save-excursion
4239     (let* ((dir (elmo-folder-msgdb-path wl-summary-buffer-elmo-folder))
4240            (cache (expand-file-name wl-summary-cache-file dir))
4241            (view (expand-file-name wl-summary-view-file dir))
4242            (save-view wl-summary-buffer-view)
4243            (mark-list (copy-sequence wl-summary-buffer-target-mark-list))
4244            (refile-list (copy-sequence wl-summary-buffer-refile-list))
4245            (copy-list (copy-sequence wl-summary-buffer-copy-list))
4246            (delete-list (copy-sequence wl-summary-buffer-delete-list))
4247            (tmp-buffer (get-buffer-create " *wl-summary-save-view-cache*"))
4248            (charset wl-summary-buffer-mime-charset))
4249       (if (file-directory-p dir)
4250           (); ok.
4251         (if (file-exists-p dir)
4252             (error "File %s already exists" dir)
4253           (elmo-make-directory dir)))
4254       (if (eq save-view 'thread)
4255           (wl-thread-save-entity dir))
4256       (unwind-protect
4257           (progn
4258             (when (file-writable-p cache)
4259               (copy-to-buffer tmp-buffer (point-min) (point-max))
4260               (with-current-buffer tmp-buffer
4261                 (widen)
4262                 (setq wl-summary-buffer-target-mark-list mark-list
4263                       wl-summary-buffer-refile-list refile-list
4264                       wl-summary-buffer-copy-list copy-list
4265                       wl-summary-buffer-delete-list delete-list)
4266                 (wl-summary-delete-all-temp-marks 'no-msg)
4267                 (encode-mime-charset-region
4268                  (point-min) (point-max) charset)
4269                 (write-region-as-binary (point-min)(point-max)
4270                                         cache nil 'no-msg)))
4271             (when (file-writable-p view) ; 'thread or 'sequence
4272               (save-excursion
4273                 (set-buffer tmp-buffer)
4274                 (erase-buffer)
4275                 (prin1 save-view tmp-buffer)
4276                 (princ "\n" tmp-buffer)
4277                 (write-region (point-min) (point-max) view nil 'no-msg))))
4278         ;; kill tmp buffer.
4279         (kill-buffer tmp-buffer)))))
4280
4281 (defsubst wl-summary-get-sync-range (folder)
4282   (intern (or (and
4283                (elmo-folder-plugged-p folder)
4284                (wl-get-assoc-list-value
4285                 wl-folder-sync-range-alist
4286                 (elmo-folder-name-internal folder)))
4287               wl-default-sync-range)))
4288
4289 ;; redefined for wl-summary-sync-update
4290 (defun wl-summary-input-range (folder)
4291   "returns update or all or rescan."
4292   ;; for the case when parts are expanded in the bottom of the folder
4293   (let ((input-range-list '("update" "all" "rescan" "first:" "last:"
4294                             "cache-status"
4295                             "no-sync" "rescan-noscore" "all-visible"))
4296         (default (or (wl-get-assoc-list-value
4297                       wl-folder-sync-range-alist
4298                       folder)
4299                      wl-default-sync-range))
4300         range)
4301     (setq range
4302           (completing-read (format "Range (%s): " default)
4303                            (mapcar
4304                             (function (lambda (x) (cons x x)))
4305                             input-range-list)))
4306     (if (string= range "")
4307         default
4308       range)))
4309
4310 (defun wl-summary-toggle-disp-folder (&optional arg)
4311   (interactive)
4312   (let ((cur-buf (current-buffer))
4313         (summary-win (get-buffer-window (current-buffer)))
4314         fld-buf fld-win)
4315     (cond
4316      ((eq arg 'on)
4317       (setq wl-summary-buffer-disp-folder t)
4318       ;; hide your folder window
4319       (if (setq fld-buf (get-buffer wl-folder-buffer-name))
4320           (if (setq fld-win (get-buffer-window fld-buf))
4321               (delete-window fld-win))))
4322      ((eq arg 'off)
4323       (setq wl-summary-buffer-disp-folder nil)
4324       ;; hide your wl-message window!
4325       (when (buffer-live-p wl-message-buffer)
4326         (wl-message-select-buffer wl-message-buffer)
4327         (delete-window))
4328       (select-window (get-buffer-window cur-buf))
4329       ;; display wl-folder window!!
4330       (if (setq fld-buf (get-buffer wl-folder-buffer-name))
4331           (if (setq fld-win (get-buffer-window fld-buf))
4332               ;; folder win is already displayed.
4333               (select-window fld-win)
4334             ;; folder win is not displayed.
4335             (switch-to-buffer fld-buf))
4336         ;; no folder buf
4337         (wl-folder))
4338       ;; temporarily delete summary-win.
4339       (if summary-win
4340           (delete-window summary-win))
4341       (split-window-horizontally wl-folder-window-width)
4342       (other-window 1)
4343       (switch-to-buffer cur-buf))
4344      (t
4345       (if (setq fld-buf (get-buffer wl-folder-buffer-name))
4346           (if (setq fld-win (get-buffer-window fld-buf))
4347               (setq wl-summary-buffer-disp-folder nil)
4348             (setq wl-summary-buffer-disp-folder t)))
4349       (if (not wl-summary-buffer-disp-folder)
4350           ;; hide message window
4351           (let ((mes-win (and wl-message-buffer
4352                               (get-buffer-window wl-message-buffer)))
4353                 (wl-stay-folder-window t))
4354             (if mes-win (delete-window mes-win))
4355             ;; hide your folder window
4356             (if (setq fld-buf (get-buffer wl-folder-buffer-name))
4357                 (if (setq fld-win (get-buffer-window fld-buf))
4358                     (progn
4359                       (delete-window (get-buffer-window cur-buf))
4360                       (select-window fld-win)
4361                       (switch-to-buffer cur-buf))))
4362             (run-hooks 'wl-summary-toggle-disp-folder-off-hook)
4363             ;; resume message window.
4364             (when mes-win
4365               (wl-message-select-buffer wl-message-buffer)
4366               (run-hooks 'wl-summary-toggle-disp-folder-message-resumed-hook)
4367               (select-window (get-buffer-window cur-buf))))
4368         ;; hide message window
4369         (let ((wl-stay-folder-window t)
4370               (mes-win (and wl-message-buffer
4371                             (get-buffer-window wl-message-buffer))))
4372           (if mes-win (delete-window mes-win))
4373           (select-window (get-buffer-window cur-buf))
4374           ;; display wl-folder window!!
4375           (if (setq fld-buf (get-buffer wl-folder-buffer-name))
4376               (if (setq fld-win (get-buffer-window fld-buf))
4377                   ;; folder win is already displayed.
4378                   (select-window fld-win)
4379                 ;; folder win is not displayed...occupy all.
4380                 (switch-to-buffer fld-buf))
4381             ;; no folder buf
4382             (wl-folder))
4383           (split-window-horizontally wl-folder-window-width)
4384           (other-window 1)
4385           (switch-to-buffer cur-buf)
4386           ;; resume message window.
4387           (run-hooks 'wl-summary-toggle-disp-folder-on-hook)
4388           (when mes-win
4389             (wl-message-select-buffer wl-message-buffer)
4390             (run-hooks 'wl-summary-toggle-disp-folder-message-resumed-hook)
4391             (select-window (get-buffer-window cur-buf))))))))
4392   (run-hooks 'wl-summary-toggle-disp-folder-hook))
4393
4394 (defun wl-summary-toggle-disp-msg (&optional arg)
4395   (interactive)
4396   (let ((cur-buf (current-buffer))
4397         fld-buf fld-win
4398         summary-win)
4399     (cond
4400      ((eq arg 'on)
4401       (setq wl-summary-buffer-disp-msg t)
4402       (save-excursion
4403         ;; hide your folder window
4404         (if (and (not wl-stay-folder-window)
4405                  (setq fld-buf (get-buffer wl-folder-buffer-name)))
4406             (if (setq fld-win (get-buffer-window fld-buf))
4407                 (unless (one-window-p fld-win)
4408                   (delete-window fld-win))))))
4409      ((eq arg 'off)
4410       (wl-delete-all-overlays)
4411       (setq wl-summary-buffer-disp-msg nil)
4412       (save-excursion
4413         (when (buffer-live-p wl-message-buffer)
4414           (wl-message-select-buffer wl-message-buffer)
4415           (delete-window)
4416           (and (get-buffer-window cur-buf)
4417                (select-window (get-buffer-window cur-buf))))
4418         (run-hooks 'wl-summary-toggle-disp-off-hook)))
4419      (t
4420       (if (and wl-message-buffer
4421                (get-buffer-window wl-message-buffer)) ; already displayed
4422           (setq wl-summary-buffer-disp-msg nil)
4423         (setq wl-summary-buffer-disp-msg t))
4424       (if wl-summary-buffer-disp-msg
4425           (progn
4426             (wl-summary-redisplay)
4427 ;;; hide your folder window
4428 ;;;         (setq fld-buf (get-buffer wl-folder-buffer-name))
4429 ;;;         (if (setq fld-win (get-buffer-window fld-buf))
4430 ;;;             (delete-window fld-win)))
4431             (run-hooks 'wl-summary-toggle-disp-on-hook))
4432         (wl-delete-all-overlays)
4433         (save-excursion
4434           (wl-message-select-buffer wl-message-buffer)
4435           (delete-window)
4436           (select-window (get-buffer-window cur-buf))
4437           (run-hooks 'wl-summary-toggle-disp-off-hook))
4438 ;;;     (switch-to-buffer cur-buf)
4439         )))))
4440
4441 (defun wl-summary-next-line-content ()
4442   "Show next line of the message."
4443   (interactive)
4444   (let ((cur-buf (current-buffer)))
4445     (wl-summary-toggle-disp-msg 'on)
4446     (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original)
4447       (set-buffer cur-buf)
4448       (wl-message-next-page 1))))
4449
4450 (defun wl-summary-prev-line-content ()
4451   (interactive)
4452   (let ((cur-buf (current-buffer)))
4453     (wl-summary-toggle-disp-msg 'on)
4454     (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original)
4455       (set-buffer cur-buf)
4456       (wl-message-prev-page 1))))
4457
4458 (defun wl-summary-next-page ()
4459   (interactive)
4460   (let ((cur-buf (current-buffer)))
4461     (wl-summary-toggle-disp-msg 'on)
4462     (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original)
4463       (set-buffer cur-buf)
4464       (wl-message-next-page))))
4465
4466 (defun wl-summary-prev-page ()
4467   (interactive)
4468   (let ((cur-buf (current-buffer)))
4469     (wl-summary-toggle-disp-msg 'on)
4470     (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original)
4471       (set-buffer cur-buf)
4472       (wl-message-prev-page))))
4473
4474 (defsubst wl-summary-no-mime-p (folder)
4475   (wl-string-match-member (elmo-folder-name-internal folder)
4476                           wl-summary-no-mime-folder-list))
4477
4478 (defun wl-summary-set-message-buffer-or-redisplay (&rest args)
4479   "Set message buffer.
4480 If message is not displayed yet, display it.
4481 Return t if message exists."
4482   (let ((folder wl-summary-buffer-elmo-folder)
4483         (number (wl-summary-message-number))
4484         cur-folder cur-number message-last-pos)
4485     (when (buffer-live-p wl-message-buffer)
4486       (save-window-excursion
4487         (wl-message-select-buffer wl-message-buffer)
4488         (setq cur-folder wl-message-buffer-cur-folder)
4489         (setq cur-number wl-message-buffer-cur-number)))
4490     (if (and (string= (elmo-folder-name-internal folder) (or cur-folder ""))
4491              (eq number (or cur-number 0)))
4492         (progn
4493           (set-buffer wl-message-buffer)
4494           t)
4495       (if (wl-summary-no-mime-p folder)
4496           (wl-summary-redisplay-no-mime-internal folder number)
4497         (wl-summary-redisplay-internal folder number))
4498       (when (buffer-live-p wl-message-buffer)
4499         (set-buffer wl-message-buffer))
4500       nil)))
4501
4502 (defun wl-summary-target-mark-forward (&optional arg)
4503   (interactive "P")
4504   (let ((mlist (nreverse wl-summary-buffer-target-mark-list))
4505         (summary-buf (current-buffer))
4506         (wl-draft-forward t)
4507         start-point
4508         draft-buf)
4509     (wl-summary-jump-to-msg (car mlist))
4510     (wl-summary-forward t)
4511     (setq start-point (point))
4512     (setq draft-buf (current-buffer))
4513     (setq mlist (cdr mlist))
4514     (save-window-excursion
4515       (when mlist
4516         (while mlist
4517           (set-buffer summary-buf)
4518           (wl-summary-jump-to-msg (car mlist))
4519           (wl-summary-redisplay)
4520           (set-buffer draft-buf)
4521           (goto-char (point-max))
4522           (wl-draft-insert-message)
4523           (setq mlist (cdr mlist)))
4524         (wl-draft-body-goto-top)
4525         (wl-draft-enclose-digest-region (point) (point-max)))
4526       (goto-char start-point)
4527       (save-excursion
4528         (set-buffer summary-buf)
4529         (wl-summary-delete-all-temp-marks)))
4530     (run-hooks 'wl-mail-setup-hook)))
4531
4532 (defun wl-summary-target-mark-reply-with-citation (&optional arg)
4533   (interactive "P")
4534   (let ((mlist (nreverse wl-summary-buffer-target-mark-list))
4535         (summary-buf (current-buffer))
4536         change-major-mode-hook
4537         start-point
4538         draft-buf)
4539     (wl-summary-jump-to-msg (car mlist))
4540     (wl-summary-reply arg t)
4541     (goto-char (point-max))
4542     (setq start-point (point-marker))
4543     (setq draft-buf (current-buffer))
4544     (save-window-excursion
4545       (while mlist
4546         (set-buffer summary-buf)
4547         (delete-other-windows)
4548         (wl-summary-jump-to-msg (car mlist))
4549         (wl-summary-redisplay)
4550         (set-buffer draft-buf)
4551         (goto-char (point-max))
4552         (wl-draft-yank-original)
4553         (setq mlist (cdr mlist)))
4554       (goto-char start-point)
4555       (save-excursion
4556         (set-buffer summary-buf)
4557         (wl-summary-delete-all-temp-marks)))
4558     (run-hooks 'wl-mail-setup-hook)))
4559
4560 (defun wl-summary-reply-with-citation (&optional arg)
4561   (interactive "P")
4562   (when (wl-summary-reply arg t)
4563     (goto-char (point-max))
4564     (wl-draft-yank-original)
4565     (run-hooks 'wl-mail-setup-hook)))
4566
4567 (defun wl-summary-jump-to-msg-by-message-id (&optional id)
4568   (interactive)
4569   (let* ((original (wl-summary-message-number))
4570          (msgid (elmo-string (or id (read-from-minibuffer "Message-ID: "))))
4571          (number-alist (elmo-msgdb-get-number-alist (wl-summary-buffer-msgdb)))
4572          msg otherfld schar
4573          (errmsg
4574           (format "No message with id \"%s\" in the folder." msgid)))
4575     (if (setq msg (car (rassoc msgid number-alist)))
4576 ;;;     (wl-summary-jump-to-msg-internal
4577 ;;;      (wl-summary-buffer-folder-name) msg 'no-sync)
4578         (progn
4579           (wl-thread-jump-to-msg msg)
4580           t)
4581       ;; for XEmacs!
4582       (if (and elmo-use-database
4583                (setq errmsg
4584                      (format
4585                       "No message with id \"%s\" in the database." msgid))
4586                (setq otherfld (elmo-database-msgid-get msgid)))
4587           (if (cdr (wl-summary-jump-to-msg-internal
4588                     (car otherfld) (nth 1 otherfld) 'no-sync))
4589               t ; succeed.
4590             ;; Back to original.
4591             (wl-summary-jump-to-msg-internal
4592              (wl-summary-buffer-folder-name) original 'no-sync))
4593         (cond ((eq wl-summary-search-via-nntp 'confirm)
4594                (require 'elmo-nntp)
4595                (message "Search message in nntp server \"%s\" <y/n/s(elect)>?"
4596                         elmo-nntp-default-server)
4597                (setq schar (read-char))
4598                (cond ((eq schar ?y)
4599                       (wl-summary-jump-to-msg-by-message-id-via-nntp msgid))
4600                      ((eq schar ?s)
4601                       (wl-summary-jump-to-msg-by-message-id-via-nntp
4602                        msgid
4603                        (read-from-minibuffer "NNTP Server: ")))
4604                      (t
4605                       (message errmsg)
4606                       nil)))
4607               (wl-summary-search-via-nntp
4608                (wl-summary-jump-to-msg-by-message-id-via-nntp msgid))
4609               (t
4610                (message errmsg)
4611                nil))))))
4612
4613 (defun wl-summary-jump-to-msg-by-message-id-via-nntp (&optional id server-spec)
4614   (interactive)
4615   (let* ((msgid (elmo-string (or id (read-from-minibuffer "Message-ID: "))))
4616          newsgroups folder ret
4617          user server port type spec)
4618     (if server-spec
4619         (if (string-match "^-" server-spec)
4620             (setq spec (wl-folder-get-elmo-folder server-spec)
4621                   user (elmo-net-folder-user-internal spec)
4622                   server (elmo-net-folder-server-internal spec)
4623                   port (elmo-net-folder-port-internal spec)
4624                   type (elmo-net-folder-stream-type-internal spec))
4625           (setq server server-spec)))
4626     (when (setq ret (elmo-nntp-get-newsgroup-by-msgid
4627                      msgid
4628                      (or server elmo-nntp-default-server)
4629                      (or user elmo-nntp-default-user)
4630                      (or port elmo-nntp-default-port)
4631                      (or type elmo-nntp-default-stream-type)))
4632       (setq newsgroups (elmo-nntp-parse-newsgroups ret))
4633       (setq folder (concat "-" (car newsgroups)
4634                            (elmo-nntp-folder-postfix user server port type)))
4635       (catch 'found
4636         (while newsgroups
4637           (if (wl-folder-entity-exists-p (car newsgroups)
4638                                          wl-folder-newsgroups-hashtb)
4639               (throw 'found
4640                      (setq folder (concat "-" (car newsgroups)
4641                                           (elmo-nntp-folder-postfix
4642                                            user server port type)))))
4643           (setq newsgroups (cdr newsgroups)))))
4644     (if ret
4645         (wl-summary-jump-to-msg-internal folder nil 'update msgid)
4646       (message "No message id \"%s\" in nntp server \"%s\"."
4647                msgid (or server elmo-nntp-default-server))
4648       nil)))
4649
4650 (defun wl-summary-jump-to-msg-internal (folder msg scan-type &optional msgid)
4651   (let (wl-auto-select-first entity)
4652     (if (or (string= folder (wl-summary-buffer-folder-name))
4653             (y-or-n-p
4654              (format
4655               "Message was found in the folder \"%s\". Jump to it? "
4656               folder)))
4657         (progn
4658           (unwind-protect
4659               (wl-summary-goto-folder-subr
4660                folder scan-type nil nil t)
4661             (if msgid
4662                 (setq msg
4663                       (car (rassoc msgid
4664                                    (elmo-msgdb-get-number-alist
4665                                     (wl-summary-buffer-msgdb))))))
4666             (setq entity (wl-folder-search-entity-by-name folder
4667                                                           wl-folder-entity
4668                                                           'folder))
4669             (if entity
4670                 (wl-folder-set-current-entity-id
4671                  (wl-folder-get-entity-id entity))))
4672           (if (null msg)
4673               (message "Message was not found currently in this folder.")
4674             (setq msg (and (wl-thread-jump-to-msg msg) msg)))
4675           (cons folder msg)))))
4676
4677 (defun wl-summary-jump-to-parent-message (arg)
4678   (interactive "P")
4679   (let ((cur-buf (current-buffer))
4680         (number (wl-summary-message-number))
4681         (regexp "\\(<[^<>]*>\\)[ \t]*$")
4682         (i -1) ;; xxx
4683         msg-id msg-num ref-list ref irt)
4684     (if (null number)
4685         (message "No message.")
4686       (when (eq wl-summary-buffer-view 'thread)
4687         (cond ((and arg (not (numberp arg)))
4688                (setq msg-num
4689                      (wl-thread-entity-get-number
4690                       (wl-thread-entity-get-top-entity
4691                        (wl-thread-get-entity number)))))
4692               ((and arg (numberp arg))
4693                (setq i 0)
4694                (setq msg-num number)
4695                (while (< i arg)
4696                  (setq msg-num
4697                        (wl-thread-entity-get-number
4698                         (wl-thread-entity-get-parent-entity
4699                          (wl-thread-get-entity msg-num))))
4700                  (setq i (1+ i))))
4701               (t (setq msg-num
4702                        (wl-thread-entity-get-number
4703                         (wl-thread-entity-get-parent-entity
4704                          (wl-thread-get-entity number)))))))
4705       (when (null msg-num)
4706         (wl-summary-set-message-buffer-or-redisplay)
4707         (set-buffer (wl-message-get-original-buffer))
4708         (message "Searching parent message...")
4709         (setq ref (std11-field-body "References")
4710               irt (std11-field-body "In-Reply-To"))
4711         (cond
4712          ((and arg (not (numberp arg)) ref (not (string= ref ""))
4713                (string-match regexp ref))
4714           ;; The first message of the thread.
4715           (setq msg-id (wl-match-string 1 ref)))
4716          ;; "In-Reply-To:" has only one msg-id.
4717          ((and (null arg) irt (not (string= irt ""))
4718                (string-match regexp irt))
4719           (setq msg-id (wl-match-string 1 irt)))
4720          ((and (or (null arg) (numberp arg)) ref (not (string= ref ""))
4721                (string-match regexp ref))
4722           ;; "^" searching parent, "C-u 2 ^" looking for grandparent.
4723           (while (string-match regexp ref)
4724             (setq ref-list
4725                   (append (list
4726                            (wl-match-string 1 ref))
4727                           ref-list))
4728             (setq ref (substring ref (match-end 0)))
4729             (setq i (1+ i)))
4730           (setq msg-id
4731                 (if (null arg) (nth 0 ref-list) ;; previous
4732                   (if (<= arg i) (nth (1- arg) ref-list)
4733                     (nth i ref-list)))))))
4734       (set-buffer cur-buf)
4735       (cond ((and (null msg-id) (null msg-num))
4736              (message "No parent message!")
4737              nil)
4738             ((and msg-id (wl-summary-jump-to-msg-by-message-id msg-id))
4739              (wl-summary-redisplay)
4740              (message "Searching parent message...done")
4741              t)
4742             ((and msg-num (wl-summary-jump-to-msg msg-num))
4743              (wl-summary-redisplay)
4744              (message "Searching parent message...done")
4745              t)
4746             (t ; failed.
4747              (message "Parent message was not found.")
4748              nil)))))
4749
4750 (defun wl-summary-reply (&optional arg without-setup-hook)
4751   "Reply to current message. Default is \"wide\" reply.
4752 Reply to author if invoked with ARG."
4753   (interactive "P")
4754   (let ((folder wl-summary-buffer-elmo-folder)
4755         (number (wl-summary-message-number))
4756         (summary-buf (current-buffer))
4757         mes-buf)
4758     (when number
4759       (save-excursion
4760         (wl-summary-redisplay-internal folder number))
4761       (setq mes-buf wl-message-buffer)
4762       (wl-message-select-buffer wl-message-buffer)
4763       (set-buffer mes-buf)
4764       (goto-char (point-min))
4765       (unless wl-draft-use-frame
4766         (split-window-vertically)
4767         (other-window 1))
4768       (when (setq mes-buf (wl-message-get-original-buffer))
4769         (wl-draft-reply mes-buf arg summary-buf)
4770         (unless without-setup-hook
4771           (run-hooks 'wl-mail-setup-hook)))
4772       t)))
4773
4774 (defun wl-summary-write ()
4775   "Write a new draft from Summary."
4776   (interactive)
4777   (wl-draft (list (cons 'To ""))
4778             nil nil nil nil (wl-summary-buffer-folder-name))
4779   (run-hooks 'wl-mail-setup-hook)
4780   (mail-position-on-field "To"))
4781
4782 (defvar wl-summary-write-current-folder-functions
4783   '(wl-folder-get-newsgroups
4784     wl-folder-guess-mailing-list-by-refile-rule
4785     wl-folder-guess-mailing-list-by-folder-name)
4786   "Newsgroups or Mailing List address guess functions list.
4787 Call from `wl-summary-write-current-folder'.
4788 When guess function return nil, challenge next guess-function.")
4789
4790 (defun wl-summary-write-current-folder (&optional folder)
4791   "Write message to current FOLDER's newsgroup or mailing-list.
4792 Use function list is `wl-summary-write-current-folder-functions'."
4793   (interactive)
4794   ;; default FOLDER is current buffer folder
4795   (setq folder (or folder (wl-summary-buffer-folder-name)))
4796   (let ((func-list wl-summary-write-current-folder-functions)
4797         guess-list guess-func)
4798     (while func-list
4799       (setq guess-list (funcall (car func-list) folder))
4800       (if (null guess-list)
4801           (setq func-list (cdr func-list))
4802         (setq guess-func (car func-list))
4803         (setq func-list nil)))
4804     (if (null guess-func)
4805         (wl-summary-write)
4806       (unless (or (stringp (nth 0 guess-list))
4807                   (stringp (nth 1 guess-list))
4808                   (stringp (nth 2 guess-list)))
4809         (error "Invalid value return guess function `%s'"
4810                (symbol-name guess-func)))
4811       (wl-draft (list (cons 'To (nth 0 guess-list))
4812                       (cons 'Cc (nth 1 guess-list))
4813                       (cons 'Newsgroups (nth 2 guess-list)))
4814                 nil nil nil nil folder)
4815       (run-hooks 'wl-mail-setup-hook)
4816       (mail-position-on-field "Subject"))))
4817
4818 (defun wl-summary-forward (&optional without-setup-hook)
4819   ""
4820   (interactive)
4821   (let ((folder wl-summary-buffer-elmo-folder)
4822         (number (wl-summary-message-number))
4823         (summary-buf (current-buffer))
4824         (wl-draft-forward t)
4825         mes-buf
4826         entity subject num)
4827     (if (null number)
4828         (message "No message.")
4829       (if (and (elmo-message-use-cache-p folder number)
4830                (eq (elmo-file-cache-status
4831                     (elmo-file-cache-get
4832                      (elmo-message-field folder number 'message-id)))
4833                    'section))
4834           ;; Reload.
4835           (wl-summary-redisplay-internal nil nil 'force-reload)
4836         (wl-summary-redisplay-internal folder number))
4837       (setq mes-buf wl-message-buffer)
4838       (wl-message-select-buffer mes-buf)
4839       (unless wl-draft-use-frame
4840         (split-window-vertically)
4841         (other-window 1))
4842       ;; get original subject.
4843       (if summary-buf
4844           (save-excursion
4845             (set-buffer summary-buf)
4846             (setq subject
4847                   (or (elmo-message-field folder number 'subject) ""))))
4848       (set-buffer mes-buf)
4849       (wl-draft-forward subject summary-buf)
4850       (unless without-setup-hook
4851         (run-hooks 'wl-mail-setup-hook)))))
4852
4853 (defun wl-summary-click (e)
4854   (interactive "e")
4855   (mouse-set-point e)
4856   (wl-summary-read))
4857
4858 (defun wl-summary-read ()
4859   "Proceed reading message in the summary buffer."
4860   (interactive)
4861   (let ((cur-buf (current-buffer)))
4862     (wl-summary-toggle-disp-msg 'on)
4863     (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original)
4864       (set-buffer cur-buf)
4865       (if (wl-message-next-page)
4866           (wl-summary-down t)))))
4867
4868 (defun wl-summary-prev (&optional interactive)
4869   ""
4870   (interactive)
4871   (if wl-summary-move-direction-toggle
4872       (setq wl-summary-move-direction-downward nil))
4873   (let ((skip-mark-regexp (mapconcat
4874                            'regexp-quote
4875                            wl-summary-skip-mark-list ""))
4876         goto-next regex-list regex next-entity finfo)
4877     (beginning-of-line)
4878     (if (elmo-folder-plugged-p wl-summary-buffer-elmo-folder)
4879         (setq regex (format "%s[^%s]"
4880                             wl-summary-message-regexp
4881                             skip-mark-regexp))
4882       (setq regex (format "%s[^%s]\\(%s\\|%s\\| \\)"
4883                           wl-summary-message-regexp
4884                           skip-mark-regexp
4885                           (regexp-quote wl-summary-unread-cached-mark)
4886                           (regexp-quote wl-summary-important-mark))))
4887     (unless (re-search-backward regex nil t)
4888       (setq goto-next t))
4889     (beginning-of-line)
4890     (if (not goto-next)
4891         (progn
4892           (if wl-summary-buffer-disp-msg
4893               (wl-summary-redisplay)))
4894       (if (or interactive (interactive-p))
4895           (if wl-summary-buffer-prev-folder-function
4896               (funcall wl-summary-buffer-prev-folder-function)
4897             (when wl-auto-select-next
4898               (setq next-entity (wl-summary-get-prev-folder))
4899               (if next-entity
4900                   (setq finfo (wl-folder-get-entity-info next-entity))))
4901             (wl-ask-folder
4902              '(lambda () (wl-summary-next-folder-or-exit next-entity))
4903              (format
4904               "No more messages. Type SPC to go to %s."
4905               (wl-summary-entity-info-msg next-entity finfo))))))))
4906
4907 (defun wl-summary-next (&optional interactive)
4908   ""
4909   (interactive)
4910   (if wl-summary-move-direction-toggle
4911       (setq wl-summary-move-direction-downward t))
4912   (let ((skip-mark-regexp (mapconcat
4913                            'regexp-quote
4914                            wl-summary-skip-mark-list ""))
4915         goto-next regex regex-list next-entity finfo)
4916     (end-of-line)
4917     (if (elmo-folder-plugged-p wl-summary-buffer-elmo-folder)
4918         (setq regex (format "%s[^%s]"
4919                             wl-summary-message-regexp
4920                             skip-mark-regexp))
4921       (setq regex (format "%s[^%s]\\(%s\\|%s\\| \\)"
4922                           wl-summary-message-regexp
4923                           skip-mark-regexp
4924                           (regexp-quote wl-summary-unread-cached-mark)
4925                           (regexp-quote wl-summary-important-mark))))
4926     (unless (re-search-forward regex nil t)
4927       (forward-line 1)
4928       (setq goto-next t))
4929     (beginning-of-line)
4930     (if (not goto-next)
4931         (if wl-summary-buffer-disp-msg
4932             (wl-summary-redisplay))
4933       (if (or interactive (interactive-p))
4934           (if wl-summary-buffer-next-folder-function
4935               (funcall wl-summary-buffer-next-folder-function)
4936             (when wl-auto-select-next
4937               (setq next-entity (wl-summary-get-next-folder))
4938               (if next-entity
4939                   (setq finfo (wl-folder-get-entity-info next-entity))))
4940             (wl-ask-folder
4941              '(lambda () (wl-summary-next-folder-or-exit next-entity))
4942              (format
4943               "No more messages. Type SPC to go to %s."
4944               (wl-summary-entity-info-msg next-entity finfo))))))))
4945
4946 (defun wl-summary-up (&optional interactive skip-no-unread)
4947   ""
4948   (interactive)
4949   (if wl-summary-move-direction-toggle
4950       (setq wl-summary-move-direction-downward nil))
4951   (if (wl-summary-cursor-up)
4952       (if wl-summary-buffer-disp-msg
4953           (wl-summary-redisplay))
4954     (if (or interactive
4955             (interactive-p))
4956         (if wl-summary-buffer-prev-folder-function
4957             (funcall wl-summary-buffer-prev-folder-function)
4958           (let (next-entity finfo)
4959             (when wl-auto-select-next
4960               (progn
4961                 (setq next-entity (wl-summary-get-prev-unread-folder))
4962                 (if next-entity
4963                     (setq finfo (wl-folder-get-entity-info next-entity)))))
4964             (if (and skip-no-unread
4965                      (eq wl-auto-select-next 'skip-no-unread))
4966                 (wl-summary-next-folder-or-exit next-entity t)
4967               (wl-ask-folder
4968                '(lambda () (wl-summary-next-folder-or-exit next-entity t))
4969                (format
4970                 "No more unread messages. Type SPC to go to %s."
4971                 (wl-summary-entity-info-msg next-entity finfo)))))))))
4972
4973 (defun wl-summary-get-prev-folder ()
4974   (let ((folder-buf (get-buffer wl-folder-buffer-name))
4975         last-entity cur-id)
4976     (when folder-buf
4977       (setq cur-id (save-excursion (set-buffer folder-buf)
4978                                    wl-folder-buffer-cur-entity-id))
4979       (wl-folder-get-prev-folder cur-id))))
4980
4981 (defun wl-summary-get-next-folder ()
4982   (let ((folder-buf (get-buffer wl-folder-buffer-name))
4983         cur-id)
4984     (when folder-buf
4985       (setq cur-id (save-excursion (set-buffer folder-buf)
4986                                    wl-folder-buffer-cur-entity-id))
4987       (wl-folder-get-next-folder cur-id))))
4988
4989 (defun wl-summary-get-next-unread-folder ()
4990   (let ((folder-buf (get-buffer wl-folder-buffer-name))
4991         cur-id)
4992     (when folder-buf
4993       (setq cur-id (save-excursion (set-buffer folder-buf)
4994                                    wl-folder-buffer-cur-entity-id))
4995       (wl-folder-get-next-folder cur-id 'unread))))
4996
4997 (defun wl-summary-get-prev-unread-folder ()
4998   (let ((folder-buf (get-buffer wl-folder-buffer-name))
4999         cur-id)
5000     (when folder-buf
5001       (setq cur-id (save-excursion (set-buffer folder-buf)
5002                                    wl-folder-buffer-cur-entity-id))
5003       (wl-folder-get-prev-folder cur-id 'unread))))
5004
5005 (defun wl-summary-down (&optional interactive skip-no-unread)
5006   (interactive)
5007   (if wl-summary-move-direction-toggle
5008       (setq wl-summary-move-direction-downward t))
5009   (if (wl-summary-cursor-down)
5010       (if wl-summary-buffer-disp-msg
5011           (wl-summary-redisplay))
5012     (if (or interactive
5013             (interactive-p))
5014         (if wl-summary-buffer-next-folder-function
5015             (funcall wl-summary-buffer-next-folder-function)
5016           (let (next-entity finfo)
5017             (when wl-auto-select-next
5018               (setq next-entity (wl-summary-get-next-unread-folder)))
5019             (if next-entity
5020                 (setq finfo (wl-folder-get-entity-info next-entity)))
5021             (if (and skip-no-unread
5022                      (eq wl-auto-select-next 'skip-no-unread))
5023                 (wl-summary-next-folder-or-exit next-entity)
5024               (wl-ask-folder
5025                '(lambda () (wl-summary-next-folder-or-exit next-entity))
5026                (format
5027                 "No more unread messages. Type SPC to go to %s."
5028                 (wl-summary-entity-info-msg next-entity finfo)))))))))
5029
5030 (defun wl-summary-goto-last-displayed-msg ()
5031   (interactive)
5032   (unless wl-summary-buffer-last-displayed-msg
5033     (setq wl-summary-buffer-last-displayed-msg
5034           wl-summary-buffer-current-msg))
5035   (if wl-summary-buffer-last-displayed-msg
5036       (progn
5037         (wl-summary-jump-to-msg wl-summary-buffer-last-displayed-msg)
5038         (if wl-summary-buffer-disp-msg
5039             (wl-summary-redisplay)))
5040     (message "No last message.")))
5041
5042 (defun wl-summary-redisplay (&optional arg)
5043   (interactive "P")
5044   (if (and (not arg)
5045            (wl-summary-no-mime-p wl-summary-buffer-elmo-folder))
5046       (wl-summary-redisplay-no-mime)
5047     (wl-summary-redisplay-internal nil nil arg)))
5048
5049 (defsubst wl-summary-redisplay-internal (&optional folder number force-reload)
5050   (interactive)
5051   (let* ((msgdb (wl-summary-buffer-msgdb))
5052          (folder (or folder wl-summary-buffer-elmo-folder))
5053          (num (or number (wl-summary-message-number)))
5054          (wl-mime-charset      wl-summary-buffer-mime-charset)
5055          (default-mime-charset wl-summary-buffer-mime-charset)
5056          fld-buf fld-win thr-entity)
5057     (if (and wl-thread-open-reading-thread
5058              (eq wl-summary-buffer-view 'thread)
5059              (not (wl-thread-entity-get-opened
5060                    (setq thr-entity (wl-thread-get-entity
5061                                      num))))
5062              (wl-thread-entity-get-children thr-entity))
5063         (wl-thread-force-open))
5064     (if num
5065         (progn
5066           (setq wl-summary-buffer-disp-msg t)
5067           (setq wl-summary-buffer-last-displayed-msg
5068                 wl-summary-buffer-current-msg)
5069           ;; hide folder window
5070           (if (and (not wl-stay-folder-window)
5071                    (setq fld-buf (get-buffer wl-folder-buffer-name)))
5072               (if (setq fld-win (get-buffer-window fld-buf))
5073                   (delete-window fld-win)))
5074           (setq wl-current-summary-buffer (current-buffer))
5075           (wl-summary-mark-as-read
5076            nil
5077            ;; not fetched, then change server-mark.
5078            (if (wl-message-redisplay folder num 'mime
5079                                      (or force-reload
5080                                          (string= (elmo-folder-name-internal
5081                                                    folder)
5082                                                   wl-draft-folder)))
5083                nil
5084              ;; plugged, then leave server-mark.
5085              (if (and
5086                   (not
5087                    (elmo-folder-local-p
5088                     wl-summary-buffer-elmo-folder))
5089                   (elmo-folder-plugged-p
5090                    wl-summary-buffer-elmo-folder))
5091                  'leave))
5092            t ; displayed
5093            nil
5094            'cached ; cached by reading.
5095            )
5096           (setq wl-summary-buffer-current-msg num)
5097           (when wl-summary-recenter
5098             (recenter (/ (- (window-height) 2) 2))
5099             (if (not wl-summary-indent-length-limit)
5100                 (wl-horizontal-recenter)))
5101           (wl-highlight-summary-displaying)
5102           (wl-message-buffer-prefetch-next folder num
5103                                            wl-message-buffer-prefetch-depth
5104                                            (current-buffer)
5105                                            wl-summary-buffer-mime-charset)
5106           (run-hooks 'wl-summary-redisplay-hook))
5107       (message "No message to display."))))
5108
5109 (defun wl-summary-redisplay-no-mime (&optional ask-coding)
5110   "Display message without MIME decoding.
5111 If ASK-CODING is non-nil, coding-system for the message is asked."
5112   (interactive "P")
5113   (let ((elmo-mime-display-as-is-coding-system
5114          (if ask-coding
5115              (or (read-coding-system "Coding system: ")
5116                  elmo-mime-display-as-is-coding-system)
5117            elmo-mime-display-as-is-coding-system)))
5118     (wl-summary-redisplay-no-mime-internal)))
5119
5120 (defun wl-summary-redisplay-no-mime-internal (&optional folder number)
5121   (let* ((fld (or folder wl-summary-buffer-elmo-folder))
5122          (num (or number (wl-summary-message-number)))
5123          wl-break-pages)
5124     (if num
5125         (progn
5126           (setq wl-summary-buffer-disp-msg t)
5127           (setq wl-summary-buffer-last-displayed-msg
5128                 wl-summary-buffer-current-msg)
5129           (setq wl-current-summary-buffer (current-buffer))
5130           (wl-message-redisplay fld num 'as-is
5131                                 (string= (elmo-folder-name-internal fld)
5132                                          wl-draft-folder))
5133           (wl-summary-mark-as-read nil nil t)
5134           (setq wl-summary-buffer-current-msg num)
5135           (when wl-summary-recenter
5136             (recenter (/ (- (window-height) 2) 2))
5137             (if (not wl-summary-indent-length-limit)
5138                 (wl-horizontal-recenter)))
5139           (wl-highlight-summary-displaying)
5140           (run-hooks 'wl-summary-redisplay-hook))
5141       (message "No message to display.")
5142       (wl-ask-folder 'wl-summary-exit
5143                      "No more messages. Type SPC to go to folder mode."))))
5144
5145 (defun wl-summary-redisplay-all-header (&optional folder number)
5146   (interactive)
5147   (let* ((fld (or folder wl-summary-buffer-elmo-folder))
5148          (num (or number (wl-summary-message-number)))
5149          (wl-mime-charset      wl-summary-buffer-mime-charset)
5150          (default-mime-charset wl-summary-buffer-mime-charset))
5151     (if num
5152         (progn
5153           (setq wl-summary-buffer-disp-msg t)
5154           (setq wl-summary-buffer-last-displayed-msg
5155                 wl-summary-buffer-current-msg)
5156           (setq wl-current-summary-buffer (current-buffer))
5157           (if (wl-message-redisplay fld num 'all-header
5158                                     (string= (elmo-folder-name-internal fld)
5159                                              wl-draft-folder))
5160               (wl-summary-mark-as-read nil nil t))
5161           (setq wl-summary-buffer-current-msg num)
5162           (when wl-summary-recenter
5163             (recenter (/ (- (window-height) 2) 2))
5164             (if (not wl-summary-indent-length-limit)
5165                 (wl-horizontal-recenter)))
5166           (wl-highlight-summary-displaying)
5167           (run-hooks 'wl-summary-redisplay-hook))
5168       (message "No message to display."))))
5169
5170 (defun wl-summary-jump-to-current-message ()
5171   "Jump into Message buffer."
5172   (interactive)
5173   (let (message-buf message-win)
5174     (if (setq message-buf wl-message-buffer)
5175         (if (setq message-win (get-buffer-window message-buf))
5176             (select-window message-win)
5177           (wl-message-select-buffer wl-message-buffer))
5178       (wl-summary-redisplay)
5179       (wl-message-select-buffer wl-message-buffer))))
5180
5181 (defun wl-summary-cancel-message ()
5182   "Cancel an article on news."
5183   (interactive)
5184   (if (null (wl-summary-message-number))
5185       (message "No message.")
5186     (let ((summary-buf (current-buffer))
5187           message-buf)
5188       (wl-summary-set-message-buffer-or-redisplay)
5189       (if (setq message-buf (wl-message-get-original-buffer))
5190           (set-buffer message-buf))
5191       (unless (wl-message-news-p)
5192         (set-buffer summary-buf)
5193         (if (and (eq (elmo-folder-type-internal wl-summary-buffer-elmo-folder)
5194                      'nntp)
5195                  (y-or-n-p "Cannot get Newsgroups. Fetch again? "))
5196             (progn
5197               (wl-summary-redisplay t)
5198               (wl-summary-supersedes-message))
5199           (error "This is not a news article; supersedes is impossible")))
5200       (when (yes-or-no-p "Do you really want to cancel this article? ")
5201         (let (from newsgroups message-id distribution buf)
5202           (save-excursion
5203             (setq from (std11-field-body "from")
5204                   newsgroups (std11-field-body "newsgroups")
5205                   message-id (std11-field-body "message-id")
5206                   distribution (std11-field-body "distribution"))
5207             ;; Make sure that this article was written by the user.
5208             (unless (wl-address-user-mail-address-p
5209                      (wl-address-header-extract-address
5210                       (car (wl-parse-addresses from))))
5211               (error "This article is not yours"))
5212             ;; Make control message.
5213             (setq buf (set-buffer (get-buffer-create " *message cancel*")))
5214             (setq wl-draft-buffer-cur-summary-buffer summary-buf)
5215             (buffer-disable-undo (current-buffer))
5216             (erase-buffer)
5217             (insert "Newsgroups: " newsgroups "\n"
5218                     "From: " (wl-address-header-extract-address
5219                               wl-from) "\n"
5220                               "Subject: cmsg cancel " message-id "\n"
5221                               "Control: cancel " message-id "\n"
5222                               (if distribution
5223                                   (concat "Distribution: " distribution "\n")
5224                                 "")
5225                               mail-header-separator "\n"
5226                               wl-summary-cancel-message)
5227             (message "Canceling your message...")
5228             (wl-draft-raw-send t t) ; kill when done, force-pre-hooks.
5229             (message "Canceling your message...done")))))))
5230
5231 (defun wl-summary-supersedes-message ()
5232   "Supersede current message."
5233   (interactive)
5234   (let ((summary-buf (current-buffer))
5235         message-buf from)
5236     (wl-summary-set-message-buffer-or-redisplay)
5237     (if (setq message-buf (wl-message-get-original-buffer))
5238         (set-buffer message-buf))
5239     (unless (wl-message-news-p)
5240       (set-buffer summary-buf)
5241       (if (and (eq (elmo-folder-type-internal wl-summary-buffer-elmo-folder)
5242                    'nntp)
5243                (y-or-n-p "Cannot get Newsgroups. Fetch again? "))
5244           (progn
5245             (wl-summary-redisplay t)
5246             (wl-summary-supersedes-message))
5247         (error "This is not a news article; supersedes is impossible")))
5248     (save-excursion
5249       (setq from (std11-field-body "from"))
5250       ;; Make sure that this article was written by the user.
5251       (unless (wl-address-user-mail-address-p
5252                (wl-address-header-extract-address
5253                 (car (wl-parse-addresses from))))
5254         (error "This article is not yours"))
5255       (let* ((message-id (std11-field-body "message-id"))
5256              (followup-to (std11-field-body "followup-to"))
5257              (mail-default-headers
5258               (concat mail-default-headers
5259                       "Supersedes: " message-id "\n"
5260                       (and followup-to
5261                            (concat "Followup-To: " followup-to "\n")))))
5262         (if message-buf (set-buffer message-buf))
5263         (wl-draft-edit-string (buffer-substring (point-min) (point-max)))))))
5264
5265 (defun wl-summary-save (&optional arg wl-save-dir)
5266   "Save current message to disk."
5267   (interactive)
5268   (let ((filename)
5269         (num (wl-summary-message-number)))
5270     (if (null wl-save-dir)
5271         (setq wl-save-dir wl-temporary-file-directory))
5272     (if num
5273         (save-excursion
5274           (setq filename (expand-file-name
5275                           (int-to-string num)
5276                           wl-save-dir))
5277           (if (null (and arg
5278                          (null (file-exists-p filename))))
5279               (setq filename
5280                     (read-file-name "Save to file: " filename)))
5281
5282           (wl-summary-set-message-buffer-or-redisplay)
5283           (set-buffer (wl-message-get-original-buffer))
5284           (if (and (null arg) (file-exists-p filename))
5285               (if (y-or-n-p "File already exists.  override it? ")
5286                   (write-region (point-min) (point-max) filename))
5287             (write-region (point-min) (point-max) filename)))
5288       (message "No message to save."))
5289     num))
5290
5291 (defun wl-summary-save-region (beg end)
5292   (interactive "r")
5293   (save-excursion
5294     (save-restriction
5295       (narrow-to-region beg end)
5296       (goto-char (point-min))
5297       (let ((wl-save-dir
5298              (wl-read-directory-name "Save to directory: "
5299                                      wl-temporary-file-directory)))
5300         (if (null (file-exists-p wl-save-dir))
5301             (make-directory wl-save-dir))
5302         (if (eq wl-summary-buffer-view 'thread)
5303             (progn
5304               (while (not (eobp))
5305                 (let* ((number (wl-summary-message-number))
5306                        (entity (wl-thread-get-entity number)))
5307                   (if (wl-thread-entity-get-opened entity)
5308                       (wl-summary-save t wl-save-dir)
5309                     ;; closed
5310                     (wl-summary-save t wl-save-dir))
5311                   (forward-line 1))))
5312           (while (not (eobp))
5313             (wl-summary-save t wl-save-dir)
5314             (forward-line 1)))))))
5315
5316 ;; mew-summary-pipe-message()
5317 (defun wl-summary-pipe-message (prefix command)
5318   "Send this message via pipe."
5319   (interactive (list current-prefix-arg nil))
5320   (if (null (wl-summary-message-number))
5321       (message "No message.")
5322     (setq command (read-string "Shell command on message: "
5323                                wl-summary-shell-command-last))
5324     (if (y-or-n-p "Send this message to pipe? ")
5325         (wl-summary-pipe-message-subr prefix command))))
5326
5327 (defun wl-summary-target-mark-pipe (prefix command)
5328   "Send each marked messages via pipe."
5329   (interactive (list current-prefix-arg nil))
5330   (if (null wl-summary-buffer-target-mark-list)
5331       (message "No marked message.")
5332     (setq command (read-string "Shell command on each marked message: "
5333                                wl-summary-shell-command-last))
5334     (when (y-or-n-p "Send each marked message to pipe? ")
5335       (while (car wl-summary-buffer-target-mark-list)
5336         (let ((num (car wl-summary-buffer-target-mark-list)))
5337           (wl-thread-jump-to-msg num)
5338           (wl-summary-pipe-message-subr prefix command)
5339           (wl-summary-unmark num))))))
5340
5341 (defun wl-summary-pipe-message-subr (prefix command)
5342   (save-excursion
5343     (wl-summary-set-message-buffer-or-redisplay)
5344     (set-buffer (wl-message-get-original-buffer))
5345     (if (string= command "")
5346         (setq command wl-summary-shell-command-last))
5347     (goto-char (point-min)) ; perhaps this line won't be necessary
5348     (if prefix
5349         (search-forward "\n\n"))
5350     (shell-command-on-region (point) (point-max) command nil)
5351     (setq wl-summary-shell-command-last command)))
5352
5353 (defun wl-summary-print-message (&optional arg)
5354   (interactive "P")
5355   (if (null (wl-summary-message-number))
5356       (message "No message.")
5357     (save-excursion
5358       (wl-summary-set-message-buffer-or-redisplay)
5359       (if (or (not (interactive-p))
5360               (y-or-n-p "Print ok? "))
5361           (progn
5362             (let ((buffer (generate-new-buffer " *print*")))
5363               (copy-to-buffer buffer (point-min) (point-max))
5364               (set-buffer buffer)
5365               (funcall wl-print-buffer-function)
5366               (kill-buffer buffer)))
5367         (message "")))))
5368
5369 (defun wl-summary-print-message-with-ps-print (&optional filename)
5370   "Print message via ps-print."
5371   (interactive)
5372   (if (null (wl-summary-message-number))
5373       (message "No message.")
5374     (setq filename (ps-print-preprint current-prefix-arg))
5375     (if (or (not (interactive-p))
5376             (y-or-n-p "Print ok? "))
5377         (let ((summary-buffer (current-buffer))
5378               wl-break-pages)
5379           (save-excursion
5380             (wl-summary-set-message-buffer-or-redisplay)
5381             ;; (wl-summary-redisplay-internal)
5382             (let* ((buffer (generate-new-buffer " *print*"))
5383                    (entity (progn
5384                              (set-buffer summary-buffer)
5385                              (assoc (cdr (assq
5386                                           (wl-summary-message-number)
5387                                           (elmo-msgdb-get-number-alist
5388                                            (wl-summary-buffer-msgdb))))
5389                                     (elmo-msgdb-get-overview
5390                                      (wl-summary-buffer-msgdb)))))
5391                    (wl-ps-subject
5392                     (and entity
5393                          (or (elmo-msgdb-overview-entity-get-subject entity)
5394                              "")))
5395                    (wl-ps-from
5396                     (and entity
5397                          (or (elmo-msgdb-overview-entity-get-from entity) "")))
5398                    (wl-ps-date
5399                     (and entity
5400                          (or (elmo-msgdb-overview-entity-get-date entity) ""))))
5401               (run-hooks 'wl-ps-preprint-hook)
5402               (set-buffer wl-message-buffer)
5403               (copy-to-buffer buffer (point-min) (point-max))
5404               (set-buffer buffer)
5405               (unwind-protect
5406                   (let ((ps-left-header
5407                          (list (concat "(" wl-ps-subject ")")
5408                                (concat "(" wl-ps-from ")")))
5409                         (ps-right-header
5410                          (list "/pagenumberstring load"
5411                                (concat "(" wl-ps-date ")"))))
5412                     (run-hooks 'wl-ps-print-hook)
5413                     (funcall wl-ps-print-buffer-function filename))
5414                 (kill-buffer buffer)))))
5415       (message ""))))
5416
5417 (if (featurep 'ps-print) ; ps-print is available.
5418     (fset 'wl-summary-print-message 'wl-summary-print-message-with-ps-print))
5419
5420 (defun wl-summary-target-mark-print ()
5421   (interactive)
5422   (if (null wl-summary-buffer-target-mark-list)
5423       (message "No marked message.")
5424     (when (y-or-n-p "Print all marked messages. OK? ")
5425       (while (car wl-summary-buffer-target-mark-list)
5426         (let ((num (car wl-summary-buffer-target-mark-list)))
5427           (wl-thread-jump-to-msg num)
5428           (wl-summary-print-message)
5429           (wl-summary-unmark num))))))
5430
5431 (defun wl-summary-folder-info-update ()
5432   (let ((folder (elmo-string (wl-summary-buffer-folder-name)))
5433         (num-db (elmo-msgdb-get-number-alist
5434                  (wl-summary-buffer-msgdb))))
5435     (wl-folder-set-folder-updated folder
5436                                   (list 0
5437                                         (+ wl-summary-buffer-unread-count
5438                                            wl-summary-buffer-new-count)
5439                                         (length num-db)))))
5440
5441 (defun wl-summary-get-original-buffer ()
5442   "Get original buffer for the current summary."
5443   (save-excursion
5444     (wl-summary-set-message-buffer-or-redisplay)
5445     (wl-message-get-original-buffer)))
5446
5447 (defun wl-summary-pack-number (&optional arg)
5448   (interactive "P")
5449   (elmo-folder-pack-numbers wl-summary-buffer-elmo-folder)
5450   (let (wl-use-scoring)
5451     (wl-summary-rescan)))
5452
5453 (defun wl-summary-target-mark-uudecode ()
5454   (interactive)
5455   (let ((mlist (reverse wl-summary-buffer-target-mark-list))
5456         (summary-buf (current-buffer))
5457         (tmp-buf (get-buffer-create "*WL UUENCODE*"))
5458         orig-buf i k filename rc errmsg)
5459     (setq i 1)
5460     (setq k (length mlist))
5461     (set-buffer tmp-buf)
5462     (erase-buffer)
5463     (save-window-excursion
5464       (while mlist
5465         (set-buffer summary-buf)
5466         (wl-summary-jump-to-msg (car mlist))
5467         (wl-summary-redisplay)
5468         (set-buffer (setq orig-buf (wl-summary-get-original-buffer)))
5469         (goto-char (point-min))
5470         (cond ((= i 1) ; first
5471                (if (setq filename (wl-message-uu-substring
5472                                    orig-buf tmp-buf t
5473                                    (= i k)))
5474                    nil
5475                  (error "Can't find begin line")))
5476               ((< i k)
5477                (wl-message-uu-substring orig-buf tmp-buf))
5478               (t ; last
5479                (wl-message-uu-substring orig-buf tmp-buf nil t)))
5480         (setq i (1+ i))
5481         (setq mlist (cdr mlist)))
5482       (set-buffer tmp-buf)
5483       (message "Exec %s..." wl-prog-uudecode)
5484       (unwind-protect
5485           (let ((decode-dir wl-temporary-file-directory))
5486             (if (not wl-prog-uudecode-no-stdout-option)
5487                 (setq filename (read-file-name "Save to file: "
5488                                                (expand-file-name
5489                                                 (elmo-safe-filename filename)
5490                                                 wl-temporary-file-directory)))
5491               (setq decode-dir
5492                     (wl-read-directory-name "Save to directory: "
5493                                             wl-temporary-file-directory))
5494               (setq filename (expand-file-name filename decode-dir)))
5495             (if (file-exists-p filename)
5496                 (or (yes-or-no-p (format "File %s exists. Save anyway? "
5497                                          filename))
5498                     (error "")))
5499             (elmo-bind-directory
5500              decode-dir
5501              (setq rc
5502                    (as-binary-process
5503                     (apply 'call-process-region (point-min) (point-max)
5504                            wl-prog-uudecode t (current-buffer) nil
5505                            wl-prog-uudecode-arg))))
5506             (when (not (= 0 rc))
5507               (setq errmsg (buffer-substring (point-min)(point-max)))
5508               (error "Uudecode error: %s" errmsg))
5509             (if (not wl-prog-uudecode-no-stdout-option)
5510                 (let (file-name-handler-alist) ;; void jka-compr
5511                   (as-binary-output-file
5512                    (write-region (point-min) (point-max)
5513                                  filename nil 'no-msg))))
5514             (save-excursion
5515               (set-buffer summary-buf)
5516               (wl-summary-delete-all-temp-marks))
5517             (if (file-exists-p filename)
5518                 (message "Saved as %s" filename)))
5519         (kill-buffer tmp-buf)))))
5520
5521 ;; Someday
5522 ;; (defun wl-summary-drop-unsync ()
5523 ;;   "Drop all unsync messages."
5524 ;;   (interactive)
5525 ;;   (if (elmo-folder-pipe-p (wl-summary-buffer-folder-name))
5526 ;;       (error "You cannot drop unsync messages in this folder"))
5527 ;;   (if (or (not (interactive-p))
5528 ;;        (y-or-n-p "Drop all unsync messages? "))
5529 ;;       (let* ((folder-list (elmo-folder-get-primitive-folder-list
5530 ;;                         (wl-summary-buffer-folder-name)))
5531 ;;           (is-multi (elmo-multi-p (wl-summary-buffer-folder-name)))
5532 ;;           (sum 0)
5533 ;;           (multi-num 0)
5534 ;;           pair)
5535 ;;      (message "Dropping...")
5536 ;;      (while folder-list
5537 ;;        (setq pair (elmo-folder-message-numbers (car folder-list)))
5538 ;;        (when is-multi ;; dirty hack...
5539 ;;          (incf multi-num)
5540 ;;          (setcar pair (+ (* multi-num elmo-multi-divide-number)
5541 ;;                          (car pair))))
5542 ;;        (elmo-msgdb-set-number-alist
5543 ;;         (wl-summary-buffer-msgdb)
5544 ;;         (nconc
5545 ;;          (elmo-msgdb-get-number-alist (wl-summary-buffer-msgdb))
5546 ;;          (list (cons (car pair) nil))))
5547 ;;        (setq sum (+ sum (cdr pair)))
5548 ;;        (setq folder-list (cdr folder-list)))
5549 ;;      (wl-summary-set-message-modified)
5550 ;;      (wl-folder-set-folder-updated (wl-summary-buffer-folder-name)
5551 ;;                                    (list 0
5552 ;;                                          (+ wl-summary-buffer-unread-count
5553 ;;                                             wl-summary-buffer-new-count)
5554 ;;                                          sum))
5555 ;;      (message "Dropping...done"))))
5556
5557 (defun wl-summary-default-get-next-msg (msg)
5558   (or (wl-summary-next-message msg
5559                                (if wl-summary-move-direction-downward 'down
5560                                  'up)
5561                                nil)
5562       (cadr (memq msg (if wl-summary-move-direction-downward
5563                           wl-summary-buffer-number-list
5564                         (reverse wl-summary-buffer-number-list))))))
5565
5566 (defun wl-summary-save-current-message ()
5567   "Save current message for `wl-summary-yank-saved-message'."
5568   (interactive)
5569   (let ((number (wl-summary-message-number)))
5570     (setq wl-summary-buffer-saved-message number)
5571     (and number (message "No: %s is saved." number))))
5572
5573 (defun wl-summary-yank-saved-message ()
5574   "Set current message as a parent of the saved message."
5575   (interactive)
5576   (if wl-summary-buffer-saved-message
5577       (let ((number (wl-summary-message-number)))
5578         (if (eq wl-summary-buffer-saved-message number)
5579             (message "Cannot set itself as a parent.")
5580           (save-excursion
5581             (wl-thread-jump-to-msg wl-summary-buffer-saved-message)
5582             (wl-thread-set-parent number)
5583             (wl-summary-set-thread-modified))
5584           (setq  wl-summary-buffer-saved-message nil)))
5585     (message "There's no saved message.")))
5586
5587 (require 'product)
5588 (product-provide (provide 'wl-summary) (require 'wl-version))
5589
5590 ;;; wl-summary.el ends here