* wl.el (wl-save-status, wl-init): Remove last period in
[elisp/wanderlust.git] / wl / wl-highlight.el
1 ;;; wl-highlight.el -- Hilight modules for Wanderlust.
2
3 ;; Copyright 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
4
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Keywords: mail, net news
7
8 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24 ;;
25
26 ;;; Commentary:
27 ;;
28
29 ;;; Code:
30 ;;
31
32 (if (and (featurep 'xemacs)
33          (featurep 'dragdrop))
34     (require 'wl-dnd))
35 (require 'wl-vars)
36 (require 'product)
37 (product-provide (provide 'wl-highlight) (require 'wl-version))
38
39 (eval-when-compile
40   (cond (wl-on-xemacs
41          (require 'wl-xmas))
42         (wl-on-emacs21
43          (require 'wl-e21))
44         (wl-on-nemacs
45          (require 'wl-nemacs))
46         (t
47          (require 'wl-mule)))
48   (defun-maybe extent-begin-glyph (a))
49   (defun-maybe delete-extent (a))
50   (defun-maybe make-extent (a b))
51   (defun-maybe set-extent-begin-glyph (a b))
52   (defun-maybe set-extent-end-glyph (a b))
53   (defun-maybe extent-at (a b c d e))
54   (defun-maybe wl-dnd-set-drop-target (a b))
55   (defun-maybe wl-dnd-set-drag-starter (a b)))
56
57 (put 'wl-defface 'lisp-indent-function 'defun)
58
59 (defgroup wl-faces nil
60   "Wanderlust, Faces."
61   :prefix "wl-highlight-"
62   :group 'wl-highlight
63   :group 'wl)
64
65 (defgroup wl-summary-faces nil
66   "Wanderlust, Faces of summary buffer."
67   :prefix "wl-highlight-"
68   :group 'wl-highlight
69   :group 'wl-summary)
70
71 (defgroup wl-folder-faces nil
72   "Wanderlust, Faces of folder buffer."
73   :prefix "wl-highlight-"
74   :group 'wl-highlight
75   :group 'wl-folder)
76
77 (defgroup wl-message-faces nil
78   "Wanderlust, Faces of message buffer."
79   :prefix "wl-highlight-"
80   :group 'wl-highlight)
81
82 ;; for message header and signature
83
84 (wl-defface wl-highlight-message-headers
85   '(
86     (((type tty)
87       (background dark))
88      (:foreground "cyan"))
89     (((class color)
90       (background dark))
91      (:foreground "gray" :bold t))
92     (((class color)
93       (background light))
94      (:foreground "gray50" :bold t)))
95   "Face used for displaying header names."
96   :group 'wl-message-faces
97   :group 'wl-faces)
98
99 (wl-defface wl-highlight-message-header-contents
100   '(
101     (((type tty)
102       (background dark))
103      (:foreground "green"))
104     (((class color)
105       (background dark))
106      (:foreground "LightSkyBlue" :bold t))
107     (((class color)
108       (background light))
109      (:foreground "purple" :bold t)))
110   "Face used for displaying header content."
111   :group 'wl-message-faces
112   :group 'wl-faces)
113
114 (wl-defface wl-highlight-message-important-header-contents
115   '(
116     (((type tty)
117       (background dark))
118      (:foreground "yellow"))
119     (((class color)
120       (background dark))
121      (:foreground "yellow" :bold t))
122     (((class color)
123       (background light))
124      (:foreground "brown" :bold t)))
125   "Face used for displaying contents of special headers."
126   :group 'wl-message-faces
127   :group 'wl-faces)
128
129 (wl-defface wl-highlight-message-important-header-contents2
130   '(
131     (((type tty)
132       (background dark))
133      (:foreground "red"))
134     (((class color)
135       (background dark))
136      (:foreground "orange" :bold t))
137     (((class color)
138       (background light))
139      (:foreground "DarkSlateBlue" :bold t)))
140   "Face used for displaying contents of special headers."
141   :group 'wl-message-faces
142   :group 'wl-faces)
143
144 (wl-defface wl-highlight-message-citation-header
145   '(
146     (((type tty)
147       (background dark))
148      (:foreground "cyan"))
149     (((class color)
150       (background dark))
151      (:foreground "SkyBlue"))
152     (((class color)
153       (background light))
154      (:foreground "DarkGreen")))
155   "Face used for displaying header of quoted texts."
156   :group 'wl-message-faces
157   :group 'wl-faces)
158
159 (wl-defface wl-highlight-message-unimportant-header-contents
160   '(
161     (((type tty)
162       (background dark))
163      (:foreground "green"))
164     (((class color)
165       (background dark))
166      (:foreground "GreenYellow" :bold t))
167     (((class color)
168       (background light))
169      (:foreground "DarkGreen" :bold t)))
170   "Face used for displaying contents of unimportant headers."
171   :group 'wl-message-faces
172   :group 'wl-faces)
173
174 (wl-defface wl-highlight-message-signature
175   '((((class color)
176       (background dark))
177      (:foreground "khaki"))
178     (((class color)
179       (background light))
180      (:foreground "DarkSlateBlue")))
181   "Face used for displaying signature."
182   :group 'wl-message-faces
183   :group 'wl-faces)
184
185 ;; for draft
186
187 (wl-defface wl-highlight-header-separator-face
188   '(
189     (((type tty)
190       (background dark))
191      (:foreground "black" :background "yellow"))
192     (((class color))
193      (:foreground "Black" :background "DarkKhaki")))
194   "Face used for displaying header separator."
195   :group 'wl-draft
196   :group 'wl-faces)
197
198 ;; important messages
199
200 (wl-defface wl-highlight-summary-important-face
201   '(
202     (((type tty)
203       (background dark))
204      (:foreground "magenta"))
205     (((class color)
206       (background dark))
207      (:foreground "orange"))
208     (((class color)
209       (background light))
210      (:foreground "purple")))
211   "Face used for displaying important messages."
212   :group 'wl-summary-faces
213   :group 'wl-faces)
214
215 (wl-defface wl-highlight-summary-new-face
216   '(
217     (((type tty)
218       (background dark))
219      (:foreground "red"))
220     (((class color)
221       (background dark))
222      (:foreground "tomato"))
223     (((class color)
224       (background light))
225      (:foreground "tomato")))
226   "Face used for displaying new messages."
227   :group 'wl-summary-faces
228   :group 'wl-faces)
229
230 (wl-defface wl-highlight-summary-displaying-face
231   '((t
232      (:underline t :bold t)))
233   "Face used for displaying message."
234   :group 'wl-summary-faces
235   :group 'wl-faces)
236
237 (wl-defface wl-highlight-thread-indent-face
238   '((t
239      (:foreground "gray40")))
240   "Face used for displaying indented thread."
241   :group 'wl-summary-faces
242   :group 'wl-faces)
243
244 ;; unimportant messages
245
246 (wl-defface wl-highlight-summary-unread-face
247   '(
248     (((type tty)
249       (background dark))
250      (:foreground "cyan"))
251     (((class color)
252       (background dark))
253      (:foreground "LightSkyBlue"))
254     (((class color)
255       (background light))
256      (:foreground "RoyalBlue")))
257   "Face used for displaying unread messages."
258   :group 'wl-summary-faces
259   :group 'wl-faces)
260
261 (wl-defface wl-highlight-summary-deleted-face
262   '(
263     (((type tty)
264       (background dark))
265      (:foreground "blue"))
266     (((class color)
267       (background dark))
268      (:foreground "gray"))
269     (((class color)
270       (background light))
271      (:foreground "DarkKhaki")))
272   "Face used for displaying messages mark as deleted."
273   :group 'wl-summary-faces
274   :group 'wl-faces)
275
276 (wl-defface wl-highlight-summary-refiled-face
277   '(
278     (((type tty)
279       (background dark))
280      (:foreground "blue"))
281     (((class color)
282       (background dark))
283      (:foreground "blue"))
284     (((class color)
285       (background light))
286      (:foreground "firebrick")))
287   "Face used for displaying messages mark as refiled."
288   :group 'wl-summary-faces
289   :group 'wl-faces)
290
291 (wl-defface wl-highlight-summary-copied-face
292   '(
293     (((type tty)
294       (background dark))
295      (:foreground "blue"))
296     (((class color)
297       (background dark))
298      (:foreground "cyan"))
299     (((class color)
300       (background light))
301      (:foreground "blue")))
302   "Face used for displaying messages mark as copied."
303   :group 'wl-summary-faces
304   :group 'wl-faces)
305
306 ;; obsolete.
307 (wl-defface wl-highlight-summary-temp-face
308   '(
309     (((type tty)
310       (background dark))
311      (:foreground "gold"))
312     (((class color))
313      (:foreground "HotPink1")))
314   "Face used for displaying messages mark as temp."
315   :group 'wl-summary-faces
316   :group 'wl-faces)
317
318 (wl-defface wl-highlight-summary-target-face
319   '(
320     (((type tty)
321       (background dark))
322      (:foreground "gold"))
323     (((class color))
324      (:foreground "HotPink1")))
325   "Face used for displaying messages mark as target."
326   :group 'wl-summary-faces
327   :group 'wl-faces)
328
329 (wl-defface wl-highlight-summary-low-read-face
330   '(
331     (((type tty)
332       (background dark))
333      (:foreground "yellow" :italic t))
334     (((class color)
335       (background dark))
336      (:foreground "PaleGreen" :italic t))
337     (((class color)
338       (background light))
339      (:foreground "Green3" :italic t)))
340   "Face used for displaying low interest read messages."
341   :group 'wl-summary-faces
342   :group 'wl-faces)
343
344 (wl-defface wl-highlight-summary-high-read-face
345   '(
346     (((type tty))
347      (:bold t))
348     (((class color)
349       (background dark))
350      (:foreground "PaleGreen" :bold t))
351     (((class color)
352       (background light))
353      (:foreground "SeaGreen" :bold t)))
354   "Face used for displaying high interest read messages."
355   :group 'wl-summary-faces
356   :group 'wl-faces)
357
358 (wl-defface wl-highlight-summary-low-unread-face
359   '(
360     (((type tty)
361       (background dark))
362      (:foreground "cyan" :italic t))
363     (((class color)
364       (background dark))
365      (:foreground "LightSkyBlue" :italic t))
366     (((class color)
367       (background light))
368      (:foreground "RoyalBlue" :italic t)))
369   "Face used for displaying low interest unread messages."
370   :group 'wl-summary-faces
371   :group 'wl-faces)
372
373 (wl-defface wl-highlight-summary-high-unread-face
374   '(
375     (((type tty))
376      (:foreground "red" :bold t))
377     (((class color)
378       (background dark))
379      (:foreground "tomato" :bold t))
380     (((class color)
381       (background light))
382      (:foreground "tomato" :bold t)))
383   "Face used for displaying high interest unread messages."
384   :group 'wl-summary-faces
385   :group 'wl-faces)
386
387 ;; ordinary messages
388
389 (wl-defface wl-highlight-summary-thread-top-face
390   '(
391     (((type tty)
392       (background dark))
393      (:foreground "green"))
394     (((class color)
395       (background dark))
396      (:foreground "GreenYellow"))
397     (((class color)
398       (background light))
399      (:foreground "green4")))
400   "Face used for displaying top thread message."
401   :group 'wl-summary-faces
402   :group 'wl-faces)
403
404 (wl-defface wl-highlight-summary-normal-face
405   '(
406     (((type tty)
407       (background dark))
408      (:foreground "yellow"))
409     (((class color)
410       (background dark))
411      (:foreground "PaleGreen"))
412     (((class color)
413       (background light))
414      (:foreground "SeaGreen")))
415   "Face used for displaying normal message."
416   :group 'wl-summary-faces
417   :group 'wl-faces)
418
419 ;; folder
420
421 (wl-defface wl-highlight-folder-unknown-face
422   '(
423     (((type tty)
424       (background dark))
425      (:foreground "cyan"))
426     (((class color)
427       (background dark))
428      (:foreground "pink"))
429     (((class color)
430       (background light))
431      (:foreground "RoyalBlue")))
432   "Face used for displaying unread folder."
433   :group 'wl-folder-faces
434   :group 'wl-faces)
435
436 (wl-defface wl-highlight-folder-killed-face
437   '(
438     (((type tty)
439       (background dark))
440      (:foreground "gray"))
441     (((class color))
442      (:foreground "gray50")))
443   "Face used for displaying killed folder."
444   :group 'wl-folder-faces
445   :group 'wl-faces)
446
447 (wl-defface wl-highlight-folder-zero-face
448   '(
449     (((type tty)
450       (background dark))
451      (:foreground "green"))
452     (((class color)
453       (background dark))
454      (:foreground "SkyBlue"))
455     (((class color)
456       (background light))
457      (:foreground "BlueViolet")))
458   "Face used for displaying folder needs no sync."
459   :group 'wl-folder-faces
460   :group 'wl-faces)
461
462 (wl-defface wl-highlight-folder-few-face
463   '(
464     (((type tty)
465       (background dark))
466      (:foreground "yellow"))
467     (((class color)
468       (background dark))
469      (:foreground "orange"))
470     (((class color)
471       (background light))
472      (:foreground "OrangeRed3")))
473   "Face used for displaying folder contains few unsync messages."
474   :group 'wl-folder-faces
475   :group 'wl-faces)
476
477 (wl-defface wl-highlight-folder-many-face
478   '(
479     (((type tty)
480       (background dark))
481      (:foreground "red"))
482     (((class color)
483       (background dark))
484      (:foreground "HotPink1"))
485     (((class color)
486       (background light))
487      (:foreground "tomato")))
488   "Face used for displaying folder contains many unsync messages."
489   :group 'wl-folder-faces
490   :group 'wl-faces)
491
492 (wl-defface wl-highlight-folder-unread-face
493   '(
494     (((type tty)
495       (background dark))
496      (:foreground "magenta"))
497     (((class color)
498       (background dark))
499      (:foreground "gold"))
500     (((class color)
501       (background light))
502      (:foreground "MediumVioletRed")))
503   "Face used for displaying unread folder."
504   :group 'wl-folder-faces
505   :group 'wl-faces)
506
507 (wl-defface wl-highlight-folder-opened-face
508   '(
509     (((type tty)
510       (background dark))
511      (:foreground "blue"))
512     (((class color)
513       (background dark))
514      (:foreground "PaleGreen"))
515     (((class color)
516       (background light))
517      (:foreground "ForestGreen")))
518   "Face used for displaying opened group folder."
519   :group 'wl-folder-faces
520   :group 'wl-faces)
521
522 (wl-defface wl-highlight-folder-closed-face
523   '(
524     (((type tty)
525       (background dark))
526      (:foreground "cyan"))
527     (((class color)
528       (background dark))
529      (:foreground "GreenYellow"))
530     (((class color)
531       (background light))
532      (:foreground "DarkOliveGreen4")))
533   "Face used for displaying closed group folder."
534   :group 'wl-folder-faces
535   :group 'wl-faces)
536
537 (wl-defface wl-highlight-folder-path-face
538   '((t
539      (:bold t :underline t)))
540   "Face used for displaying path."
541   :group 'wl-folder-faces
542   :group 'wl-faces)
543
544 (wl-defface wl-highlight-demo-face
545   '(
546     (((type tty)
547       (background dark))
548      (:foreground "green"))
549     (((class color)
550       (background dark))
551      (:foreground "GreenYellow"))
552     (((class color)
553       (background light))
554      (:foreground "blue2")))
555   "Face used for displaying demo."
556   :group 'wl-faces)
557
558 (wl-defface wl-highlight-logo-face
559   '(
560     (((type tty)
561       (background dark))
562      (:foreground "cyan"))
563     (((class color)
564       (background dark))
565      (:foreground "SkyBlue"))
566     (((class color)
567       (background light))
568      (:foreground "SteelBlue")))
569   "Face used for displaying demo."
570   :group 'wl-faces)
571
572 (wl-defface wl-highlight-refile-destination-face
573   '((((class color)
574       (background dark))
575      (:foreground "pink"))
576     (((class color)
577       (background light))
578      (:foreground "red")))
579   "Face used for displaying refile destination."
580   :group 'wl-summary-faces
581   :group 'wl-faces)
582
583 ;; cited face
584
585 (wl-defface wl-highlight-message-cited-text-1
586   '(
587     (((type tty)
588       (background dark))
589      (:foreground "magenta"))
590     (((class color)
591       (background dark))
592      (:foreground "HotPink1"))
593     (((class color)
594       (background light))
595      (:foreground "ForestGreen")))
596   "Face used for displaying quoted text from other messages."
597   :group 'wl-message-faces
598   :group 'wl-faces)
599
600 (wl-defface wl-highlight-message-cited-text-2
601   '(
602     (((type tty)
603       (background dark))
604      (:foreground "blue"))
605     (((class color))
606      (:foreground "violet")))
607   "Face used for displaying quoted text from other messages."
608   :group 'wl-message-faces
609   :group 'wl-faces)
610
611 (wl-defface wl-highlight-message-cited-text-3
612   '(
613     (((type tty)
614       (background dark))
615      (:foreground "cyan"))
616     (((class color))
617      (:foreground "orchid3")))
618   "Face used for displaying quoted text from other messages."
619   :group 'wl-message-faces
620   :group 'wl-faces)
621
622 (wl-defface wl-highlight-message-cited-text-4
623   '(
624     (((type tty)
625       (background dark))
626      (:foreground "green"))
627     (((class color))
628      (:foreground "purple1")))
629   "Face used for displaying quoted text from other messages."
630   :group 'wl-message-faces
631   :group 'wl-faces)
632
633 (wl-defface wl-highlight-message-cited-text-5
634   '(
635     (((type tty)
636       (background dark))
637      (:foreground "yellow"))
638     (((class color))
639      (:foreground "MediumPurple1")))
640   "Face used for displaying quoted text from other messages."
641   :group 'wl-message-faces
642   :group 'wl-faces)
643
644 (wl-defface wl-highlight-message-cited-text-6
645   '(
646     (((type tty)
647       (background dark))
648      (:foreground "red"))
649     (((class color))
650      (:foreground "PaleVioletRed")))
651   "Face used for displaying quoted text from other messages."
652   :group 'wl-message-faces
653   :group 'wl-faces)
654
655 (wl-defface wl-highlight-message-cited-text-7
656   '(
657     (((type tty)
658       (background dark))
659      (:foreground "magenta"))
660     (((class color))
661      (:foreground "LightPink")))
662   "Face used for displaying quoted text from other messages."
663   :group 'wl-message-faces
664   :group 'wl-faces)
665
666 (wl-defface wl-highlight-message-cited-text-8
667   '(
668     (((type tty)
669       (background dark))
670      (:foreground "blue"))
671     (((class color))
672      (:foreground "salmon")))
673   "Face used for displaying quoted text from other messages."
674   :group 'wl-message-faces
675   :group 'wl-faces)
676
677 (wl-defface wl-highlight-message-cited-text-9
678   '(
679     (((type tty)
680       (background dark))
681      (:foreground "cyan"))
682     (((class color))
683      (:foreground "SandyBrown")))
684   "Face used for displaying quoted text from other messages."
685   :group 'wl-message-faces
686   :group 'wl-faces)
687
688 (wl-defface wl-highlight-message-cited-text-10
689   '(
690     (((type tty)
691       (background dark))
692      (:foreground "green"))
693     (((class color))
694      (:foreground "wheat")))
695   "Face used for displaying quoted text from other messages."
696   :group 'wl-message-faces
697   :group 'wl-faces)
698
699 (defvar wl-highlight-folder-opened-regexp " *\\(\\[\\-\\]\\)")
700 (defvar wl-highlight-folder-closed-regexp " *\\(\\[\\+\\]\\)")
701 (defvar wl-highlight-folder-leaf-regexp "[ ]*\\([-%\\+]\\)\\(.*\\):.*$")
702
703 (defvar wl-highlight-summary-unread-regexp " *[0-9]+[^0-9]\\(!\\|U\\)")
704 (defvar wl-highlight-summary-important-regexp " *[0-9]+[^0-9]\\$")
705 (defvar wl-highlight-summary-new-regexp " *[0-9]+[^0-9]N")
706 (defvar wl-highlight-summary-deleted-regexp " *[0-9]+D")
707 (defvar wl-highlight-summary-refiled-regexp " *[0-9]+o")
708 (defvar wl-highlight-summary-copied-regexp " *[0-9]+O")
709 (defvar wl-highlight-summary-target-regexp " *[0-9]+\\*")
710 ;(defvar wl-highlight-summary-thread-top-regexp " *[0-9]+[^0-9][^0-9]../..\(.*\)..:.. \\[")
711
712 (defvar wl-highlight-citation-face-list
713   '(wl-highlight-message-cited-text-1
714     wl-highlight-message-cited-text-2
715     wl-highlight-message-cited-text-3
716     wl-highlight-message-cited-text-4
717     wl-highlight-message-cited-text-5
718     wl-highlight-message-cited-text-6
719     wl-highlight-message-cited-text-7
720     wl-highlight-message-cited-text-8
721     wl-highlight-message-cited-text-9
722     wl-highlight-message-cited-text-10))
723
724 (defmacro defun-hilit (name &rest everything-else)
725   "Define a function for highlight. Nemacs implementation is set as empty."
726   (if wl-on-nemacs
727       (` (defun (, name) nil nil))
728     (` (defun (, name) (,@ everything-else)))))
729
730 (defmacro defun-hilit2 (name &rest everything-else)
731   "Define a function for highlight w/o nemacs."
732   (if wl-on-nemacs
733       () ; noop
734     (` (defun (, name) (,@ everything-else)))))
735
736 (defmacro wl-delete-all-overlays ()
737   "Delete all momentary overlays."
738   (if wl-on-nemacs
739       nil
740     '(let ((overlays (overlays-in (point-min) (point-max)))
741            overlay)
742        (while (setq overlay (car overlays))
743          (if (overlay-get overlay 'wl-momentary-overlay)
744              (delete-overlay overlay))
745          (setq overlays (cdr overlays))))))
746
747 (defun-hilit wl-highlight-summary-displaying ()
748   (interactive)
749   (wl-delete-all-overlays)
750   (let (bol eol ov)
751     (save-excursion
752       (beginning-of-line)
753       (setq bol (point))
754       (save-excursion (end-of-line) (setq eol (point)))
755       (setq ov (make-overlay bol eol))
756       (overlay-put ov 'face 'wl-highlight-summary-displaying-face)
757       (overlay-put ov 'evaporate t)
758       (overlay-put ov 'wl-momentary-overlay t))))
759
760 (defun-hilit2 wl-highlight-folder-group-line (numbers)
761   (end-of-line)
762   (let ((eol (point))
763         bol)
764     (beginning-of-line)
765     (setq bol (point))
766     (let ((text-face (cond ((looking-at wl-highlight-folder-opened-regexp)
767                             'wl-highlight-folder-opened-face)
768                            ((looking-at wl-highlight-folder-closed-regexp)
769                             'wl-highlight-folder-closed-face))))
770       (if (and wl-highlight-folder-by-numbers
771                (re-search-forward "[0-9-]+/[0-9-]+/[0-9-]+" eol t))
772           (let* ((unsync (nth 0 numbers))
773                  (unread (nth 1 numbers))
774                  (face (cond ((and unsync (zerop unsync))
775                               (if (and unread (> unread 0))
776                                   'wl-highlight-folder-unread-face
777                                 'wl-highlight-folder-zero-face))
778                              ((and unsync
779                                    (>= unsync wl-folder-many-unsync-threshold))
780                               'wl-highlight-folder-many-face)
781                              (t
782                               'wl-highlight-folder-few-face))))
783             (if (numberp wl-highlight-folder-by-numbers)
784                 (progn
785                   (put-text-property bol (match-beginning 0) 'face text-face)
786                   (put-text-property (match-beginning 0) (match-end 0)
787                                      'face face))
788               ;; Remove previous face.
789               (put-text-property bol (match-end 0) 'face nil)
790               (put-text-property bol (match-end 0) 'face face)))
791         (put-text-property bol eol 'face text-face)))))
792
793 (defun-hilit2 wl-highlight-summary-line-string (line mark temp-mark indent)
794   (let (fsymbol)
795     (cond ((and (string= temp-mark "+")
796                 (member mark (list wl-summary-unread-cached-mark
797                                    wl-summary-unread-uncached-mark
798                                    wl-summary-new-mark)))
799            (setq fsymbol 'wl-highlight-summary-high-unread-face))
800           ((and (string= temp-mark "-")
801                 (member mark (list wl-summary-unread-cached-mark
802                                    wl-summary-unread-uncached-mark
803                                    wl-summary-new-mark)))
804            (setq fsymbol 'wl-highlight-summary-low-unread-face))
805           ((string= temp-mark "o")
806            (setq fsymbol 'wl-highlight-summary-refiled-face))
807           ((string= temp-mark "O")
808            (setq fsymbol 'wl-highlight-summary-copied-face))
809           ((string= temp-mark "D")
810            (setq fsymbol 'wl-highlight-summary-deleted-face))
811           ((string= temp-mark "*")
812            (setq fsymbol 'wl-highlight-summary-temp-face))
813           ((string= mark wl-summary-new-mark)
814            (setq fsymbol 'wl-highlight-summary-new-face))
815           ((member mark (list wl-summary-unread-cached-mark
816                               wl-summary-unread-uncached-mark))
817            (setq fsymbol 'wl-highlight-summary-unread-face))
818           ((or (string= mark wl-summary-important-mark))
819            (setq fsymbol 'wl-highlight-summary-important-face))
820           ((string= temp-mark "-")
821            (setq fsymbol 'wl-highlight-summary-low-read-face))
822           ((string= temp-mark "+")
823            (setq fsymbol 'wl-highlight-summary-high-read-face))
824           (t (if (= 0 (length indent))
825                  (setq fsymbol 'wl-highlight-summary-thread-top-face)
826                (setq fsymbol 'wl-highlight-summary-normal-face))))
827     (put-text-property 0 (length line) 'face fsymbol line))
828   (if wl-use-highlight-mouse-line
829       (put-text-property 0 (length line) 'mouse-face 'highlight line)))
830
831 (defun-hilit2 wl-highlight-summary-current-line (&optional smark regexp temp-too)
832   (interactive)
833   (save-excursion
834     (let ((inhibit-read-only t)
835           (case-fold-search nil) temp-mark status-mark
836           (sregexp (concat
837                     "^"
838                     wl-summary-buffer-number-regexp
839                     "\\(.\\)\\(.\\)../..\(.*\)..:.. \\("
840                     wl-highlight-thread-indent-string-regexp
841                     "\\)[[<]"))
842           fregexp fsymbol bol eol matched thread-top looked-at)
843       (beginning-of-line)
844       (setq bol (point))
845       (save-excursion (end-of-line) (setq eol (point)))
846       (if smark
847           (setq status-mark smark)
848         (setq looked-at (looking-at sregexp))
849         (setq status-mark (buffer-substring (match-beginning 2)
850                                             (match-end 2))))
851       (when temp-too
852         (unless looked-at
853           (setq looked-at (looking-at sregexp)))
854         (when looked-at
855           (setq temp-mark (buffer-substring (match-beginning 1)
856                                             (match-end 1)))
857           (cond
858            ((string= temp-mark "*")
859             (setq fsymbol 'wl-highlight-summary-temp-face))
860            ((string= temp-mark "D")
861             (setq fsymbol 'wl-highlight-summary-deleted-face))
862            ((string= temp-mark "O")
863             (setq fsymbol 'wl-highlight-summary-copied-face))
864            ((string= temp-mark "o")
865             (setq fsymbol 'wl-highlight-summary-refiled-face)))))
866       (if (not fsymbol)
867           (cond
868            ((and (string= temp-mark "+")
869                  (member status-mark (list wl-summary-unread-cached-mark
870                                            wl-summary-unread-uncached-mark
871                                            wl-summary-new-mark)))
872             (setq fsymbol 'wl-highlight-summary-high-unread-face))
873            ((and (string= temp-mark "-")
874                  (member status-mark (list wl-summary-unread-cached-mark
875                                            wl-summary-unread-uncached-mark
876                                            wl-summary-new-mark)))
877             (setq fsymbol 'wl-highlight-summary-low-unread-face))
878            ((string= status-mark wl-summary-new-mark)
879             (setq fsymbol 'wl-highlight-summary-new-face))
880            ((member status-mark (list wl-summary-unread-cached-mark
881                                       wl-summary-unread-uncached-mark))
882             (setq fsymbol 'wl-highlight-summary-unread-face))
883            ((string= status-mark wl-summary-important-mark)
884             (setq fsymbol 'wl-highlight-summary-important-face))
885            ;; score mark
886            ((string= temp-mark "-")
887             (setq fsymbol 'wl-highlight-summary-low-read-face))
888            ((string= temp-mark "+")
889             (setq fsymbol 'wl-highlight-summary-high-read-face))
890            ;;
891            (t (if (and looked-at
892                        (string= (buffer-substring
893                                  (match-beginning 3)
894                                  (match-end 3)) ""))
895                   (setq fsymbol 'wl-highlight-summary-thread-top-face)
896                 (setq fsymbol 'wl-highlight-summary-normal-face)))))
897       (put-text-property bol eol 'face fsymbol)
898       (if wl-use-highlight-mouse-line
899           (put-text-property bol;(1- (match-end 0))
900                              eol 'mouse-face 'highlight))
901 ;      (put-text-property (match-beginning 3) (match-end 3)
902 ;                        'face 'wl-highlight-thread-indent-face)
903       ;; Dnd stuff.
904       (if wl-use-dnd
905           (wl-dnd-set-drag-starter bol eol)))))
906
907 (defun-hilit2 wl-highlight-folder (start end)
908   "Highlight folder between start and end.
909 Faces used:
910   wl-highlight-folder-unknown-face      unread messages
911   wl-highlight-folder-zero-face         folder needs no sync
912   wl-highlight-folder-few-face          folder contains few unsync messages
913   wl-highlight-folder-many-face         folder contains many unsync messages
914   wl-highlight-folder-opened-face       opened group folder
915   wl-highlight-folder-closed-face       closed group folder
916
917 Variables used:
918   wl-highlight-folder-opened-regexp     matches opened group folder
919   wl-highlight-folder-closed-regexp     matches closed group folder
920 "
921   (interactive "r")
922   (if (< end start)
923       (let ((s start)) (setq start end end s)))
924   (let* ((lines (count-lines start end))
925          (real-end end)
926          gc-message)
927     (save-excursion
928       (save-restriction
929         (widen)
930         (narrow-to-region start end)
931         (save-restriction
932           (goto-char start)
933           (while (not (eobp))
934             (wl-highlight-folder-current-line)
935             (forward-line 1)))))))
936
937 (defun-hilit2 wl-highlight-folder-path (folder-path)
938   "Highlight current folder path...overlay"
939   (save-excursion
940     (wl-delete-all-overlays)
941     (let ((fp folder-path) ov)
942       (goto-char (point-min))
943       (while (and fp
944                   (not (eobp)))
945         (beginning-of-line)
946         (or (looking-at "^[ ]*\\[[\\+-]\\]\\(.+\\):.*\n")
947             (looking-at "^[ ]*\\([^ \\[].+\\):.*\n"))
948         (when (equal
949                (get-text-property (point) 'wl-folder-entity-id)
950                (car fp))
951           (setq fp (cdr fp))
952           (setq ov (make-overlay
953                     (match-beginning 1)
954                     (match-end 1)))
955           (setq wl-folder-buffer-cur-point (point))
956           (overlay-put ov 'face 'wl-highlight-folder-path-face)
957           (overlay-put ov 'evaporate t)
958           (overlay-put ov 'wl-momentary-overlay t))
959         (forward-line 1)))))
960
961 (defun-hilit2 wl-highlight-refile-destination-string (string)
962   (put-text-property 0 (length string) 'face
963                      'wl-highlight-refile-destination-face
964                      string))
965
966 (defun-hilit wl-highlight-summary-all ()
967   "For evaluation"
968   (interactive)
969   (wl-highlight-summary (point-min)(point-max)))
970
971 (defun-hilit2 wl-highlight-summary (start end)
972   "Highlight summary between start and end.
973 Faces used:
974   wl-highlight-summary-unread-face      unread messages
975   wl-highlight-summary-important-face   important messages
976   wl-highlight-summary-deleted-face     messages mark as deleted
977   wl-highlight-summary-refiled-face     messages mark as refiled
978   wl-highlight-summary-copied-face      messages mark as copied
979   wl-highlight-summary-new-face         new messages
980
981 Variables used:
982   wl-highlight-summary-unread-regexp    matches unread messages
983   wl-highlight-summary-important-regexp matches important messages
984   wl-highlight-summary-deleted-regexp   matches messages mark as deleted
985   wl-highlight-summary-refiled-regexp   matches messages mark as refiled
986   wl-highlight-summary-copied-regexp    matches messages mark as copied
987   wl-highlight-summary-new-regexp       matches new messages
988
989 If HACK-SIG is true,then we search backward from END for something that
990 looks like the beginning of a signature block, and don't consider that a
991 part of the message (this is because signatures are often incorrectly
992 interpreted as cited text.)"
993   (if (< end start)
994       (let ((s start)) (setq start end end s)))
995   (let* ((lines (count-lines start end))
996          (too-big (and wl-highlight-max-summary-lines
997                        (> lines wl-highlight-max-summary-lines)))
998          (real-end end)
999          gc-message
1000          e p hend i percent)
1001     (save-excursion
1002       (save-restriction
1003         (widen)
1004         (narrow-to-region start end)
1005         (if (not too-big)
1006             (save-restriction
1007               (goto-char start)
1008               (setq i 0)
1009               (while (not (eobp))
1010                 (wl-highlight-summary-current-line nil nil wl-summary-scored)
1011                 (when (> lines elmo-display-progress-threshold)
1012                   (setq i (+ i 1))
1013                   (setq percent (/ (* i 100) lines))
1014                   (if (or (eq (% percent 5) 0) (= i lines))
1015                       (elmo-display-progress
1016                        'wl-highlight-summary "Highlighting..."
1017                        percent)))
1018                 (forward-line 1))
1019               (message "Highlighting...done")))))))
1020
1021 (defun wl-highlight-headers ()
1022   (let ((beg (point-min))
1023         (end (or (save-excursion (re-search-forward "^$" nil t)
1024                                  (point))
1025                  (point-max))))
1026     (wl-highlight-message beg end nil)
1027     (wl-highlight-message-add-buttons-to-header beg end)
1028     (and wl-highlight-x-face-func
1029          (funcall wl-highlight-x-face-func beg end))
1030     (run-hooks 'wl-highlight-headers-hook)))
1031
1032 (defun wl-highlight-message-add-buttons-to-header (start end)
1033   (save-excursion
1034     (save-restriction
1035       (narrow-to-region start end)
1036       (let ((case-fold-search t)
1037             (alist wl-highlight-message-header-button-alist)
1038             entry)
1039         (while alist
1040           (setq entry (car alist)
1041                 alist (cdr alist))
1042           (goto-char (point-min))
1043           (while (re-search-forward (car entry) nil t)
1044             (setq start (match-beginning 0)
1045                   end (if (re-search-forward "^[^ \t]" nil t)
1046                           (match-beginning 0)
1047                         (point-max)))
1048             (goto-char start)
1049             (while (re-search-forward (nth 1 entry) end t)
1050               (goto-char (match-end 0))
1051               (wl-message-add-button
1052                (match-beginning (nth 2 entry))
1053                (match-end (nth 2 entry))
1054                (nth 3 entry) (match-string (nth 4 entry))))
1055             (goto-char end)))))))
1056
1057 (defun wl-highlight-body-all ()
1058   (wl-highlight-message (point-min) (point-max) t t))
1059
1060 (defun-hilit wl-highlight-body ()
1061   (let ((beg (or (save-excursion (goto-char (point-min))
1062                                  (re-search-forward "^$" nil t))
1063                  (point-min)))
1064         (end (point-max)))
1065     (wl-highlight-message beg end t)))
1066
1067 (defun-hilit2 wl-highlight-body-region (beg end)
1068   (wl-highlight-message beg end t t))
1069
1070 (defun wl-highlight-signature-search-simple (beg end)
1071   "Search signature area in the body message between beg and end.
1072 Returns start point of signature."
1073   (save-excursion
1074     (goto-char end)
1075     (if (re-search-backward "\n--+ *\n" beg t)
1076         (if (eq (char-after (point)) ?\n)
1077             (1+ (point))
1078           (point))
1079       end)))
1080
1081 (defun wl-highlight-signature-search (beg end)
1082   "Search signature area in the body message between beg and end.
1083 Returns start point of signature."
1084   (save-excursion
1085     (goto-char end)
1086     (or
1087      ;; look for legal signature separator (check at first for fasten)
1088      (re-search-backward "\n-- \n" beg t)
1089
1090      ;; look for dual separator
1091      (save-excursion
1092        (and
1093         (re-search-backward "^[^A-Za-z0-9> \t\n]+ *$" beg t)
1094         (> (- (match-end 0) (match-beginning 0)) 10);; "10" is a magic number.
1095         (re-search-backward
1096          (concat "^"
1097                  (regexp-quote (buffer-substring (match-beginning 0) (match-end 0)))
1098                  "$") beg t)))
1099
1100      ;; look for user specified signature-separator
1101      (if (stringp wl-highlight-signature-separator)
1102          (re-search-backward wl-highlight-signature-separator nil t);; case one string
1103        (let ((sep wl-highlight-signature-separator))            ;; case list
1104          (while (and sep
1105                      (not (re-search-backward (car sep) beg t)))
1106            (setq sep (cdr sep)))
1107          (point)))      ;; if no separator found, returns end.
1108      )))
1109
1110 (defun-hilit2 wl-highlight-message (start end hack-sig &optional body-only)
1111   "Highlight message headers between start and end.
1112 Faces used:
1113   wl-highlight-message-headers                    the part before the colon
1114   wl-highlight-message-header-contents            the part after the colon
1115   wl-highlight-message-important-header-contents  contents of \"special\"
1116                                                   headers
1117   wl-highlight-message-important-header-contents2 contents of \"special\"
1118                                                   headers
1119   wl-highlight-message-unimportant-header-contents contents of unimportant
1120                                                    headers
1121   wl-highlight-message-cited-text                  quoted text from other
1122                                                    messages
1123   wl-highlight-message-citation-header             header of quoted texts
1124   wl-highlight-message-signature                   signature
1125
1126 Variables used:
1127   wl-highlight-important-header-regexp   what makes a \"special\" header
1128   wl-highlight-important-header2-regexp  what makes a \"special\" header
1129   wl-highlight-unimportant-header-regexp what makes a \"special\" header
1130   wl-highlight-citation-prefix-regexp    matches lines of quoted text
1131   wl-highlight-citation-header-regexp    matches headers for quoted text
1132
1133 If HACK-SIG is true,then we search backward from END for something that
1134 looks like the beginning of a signature block, and don't consider that a
1135 part of the message (this is because signatures are often incorrectly
1136 interpreted as cited text.)"
1137   (if (< end start)
1138       (let ((s start)) (setq start end end s)))
1139   (let* ((too-big (and wl-highlight-max-message-size
1140                        (> (- end start)
1141                           wl-highlight-max-message-size)))
1142          (real-end end)
1143          current  beg
1144          e p hend)
1145     (save-excursion
1146       (save-restriction
1147         (widen)
1148         ;; take off signature
1149         (if (and hack-sig (not too-big))
1150             (setq end (funcall wl-highlight-signature-search-func
1151                                (- end wl-max-signature-size) end)))
1152         (if hack-sig
1153             (put-text-property end (point-max)
1154                                'face 'wl-highlight-message-signature))
1155         (narrow-to-region start end)
1156
1157         (save-restriction
1158           ;; narrow down to just the headers...
1159           (goto-char start)
1160           ;; If this search fails then the narrowing performed above
1161           ;; is sufficient
1162           (if (re-search-forward (format
1163                                   "^$\\|%s"
1164                                   (regexp-quote mail-header-separator)) nil t)
1165               (narrow-to-region (point-min) (point)))
1166           (goto-char start)
1167           (while (and (not body-only)
1168                       (not (eobp)))
1169             (cond
1170              ((looking-at "^\\([^ \t\n:]+[ \t]*:\\) *\\(.*\\(\n[ \t].*\\)*\n\\)")
1171               (setq hend (match-end 0))
1172               (put-text-property (match-beginning 1) (match-end 1)
1173                                  'face 'wl-highlight-message-headers)
1174               (setq p (match-end 1))
1175               (cond
1176                ((catch 'match
1177                   (let ((regexp-alist wl-highlight-message-header-alist))
1178                     (while regexp-alist
1179                       (when (save-match-data
1180                               (looking-at (caar regexp-alist)))
1181                         (put-text-property
1182                          (match-beginning 2) (match-end 2)
1183                          'face
1184                          (cdar regexp-alist))
1185                         (throw 'match t))
1186                       (setq regexp-alist (cdr regexp-alist)))
1187                     (throw 'match nil))))
1188                (t
1189                 (put-text-property
1190                  (match-beginning 2) (match-end 2)
1191                  'face 'wl-highlight-message-header-contents)))
1192               (goto-char hend))
1193              ((looking-at mail-header-separator)
1194               (put-text-property (match-beginning 0) (match-end 0)
1195                                  'face 'wl-highlight-header-separator-face)
1196               (goto-char (match-end 0)))
1197              ;; ignore non-header field name lines
1198              (t (forward-line 1)))))
1199         ;; now do the body, unless it's too big....
1200         (if too-big
1201             nil
1202           (let (prefix prefix-face-alist pair end)
1203           (while (not (eobp))
1204             (cond
1205              ((null wl-highlight-force-citation-header-regexp)
1206               nil)
1207              ((looking-at wl-highlight-force-citation-header-regexp)
1208               (setq current 'wl-highlight-message-citation-header)
1209               (setq end (match-end 0)))
1210              ((null wl-highlight-citation-prefix-regexp)
1211               nil)
1212              ((looking-at wl-highlight-citation-prefix-regexp)
1213               (setq prefix (buffer-substring (point)
1214                                              (match-end 0)))
1215               (setq pair (assoc prefix prefix-face-alist))
1216               (unless pair
1217                 (setq prefix-face-alist
1218                       (append prefix-face-alist
1219                               (list
1220                                (setq pair
1221                                      (cons
1222                                       prefix
1223                                       (nth
1224                                        (% (length prefix-face-alist)
1225                                           (length
1226                                            wl-highlight-citation-face-list))
1227                                        wl-highlight-citation-face-list)))))))
1228               (unless wl-highlight-highlight-citation-too
1229                 (goto-char (match-end 0)))
1230               (setq current (cdr pair)))
1231              ((null wl-highlight-citation-header-regexp)
1232               nil)
1233              ((looking-at wl-highlight-citation-header-regexp)
1234               (setq current 'wl-highlight-message-citation-header)
1235               (setq end (match-end 0)))
1236              (t (setq current nil)))
1237             (cond (current
1238                    (setq p (point))
1239                    (forward-line 1) ; this is to put the \n in the face too
1240                    (let ();(inhibit-read-only t))
1241                      (put-text-property p (or end (point))
1242                                         'face current)
1243                      (setq end nil))
1244                    (forward-char -1)))
1245             (forward-line 1)))
1246           (run-hooks 'wl-highlight-message-hook))))))
1247
1248
1249 ;; highlight-mouse-line for folder mode
1250
1251 (defun wl-highlight-folder-mouse-line ()
1252   (interactive)
1253   (let* ((end (save-excursion (end-of-line) (point)))
1254          (beg (progn
1255                 (re-search-forward "[^ ]" end t)
1256                 (1- (point))))
1257          (inhibit-read-only t))
1258     (put-text-property beg end 'mouse-face 'highlight)))
1259
1260 ;;; wl-highlight.el ends here