Merged beta branch.
[elisp/wanderlust.git] / wl / wl-e21.el
1 ;;; wl-e21.el -- Wanderlust modules for Emacs 21.
2
3 ;; Copyright 2000 Yuuichi Teranishi <teranisi@gohome.org>
4
5 ;; Author: Katsumi Yamaoka <yamaoka@jpl.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 ;; This module uses `before-string' overlay property to show icon
29 ;; images instead of `insert-image', so don't delete such overlays
30 ;; sloppily.  Here is a sample code to show icons in the buffer.
31 ;;
32 ;;(let* ((load-path (cons wl-icon-dir load-path))
33 ;;       (image (find-image `((:type xpm :file ,wl-nntp-folder-icon
34 ;;                                 :ascent center))))
35 ;;       (icon (copy-sequence wl-nntp-folder-icon))
36 ;;       (folder "-fj.wanderlust:0/0/0")
37 ;;       overlay)
38 ;;  (put-text-property 0 (length icon) 'display image icon)
39 ;;  (pop-to-buffer (get-buffer-create "*wl-e21-demo*"))
40 ;;  (erase-buffer)
41 ;;  (insert "   ")
42 ;;  (setq overlay (make-overlay (point) (progn (insert folder) (point))))
43 ;;  (overlay-put overlay 'before-string icon)
44 ;;  (overlay-put overlay 'wl-e21-icon t)
45 ;;  (overlay-put overlay 'evaporate t)
46 ;;  (insert "\n"))
47
48 ;;; Code:
49 ;;
50
51 (eval-when-compile
52   (require 'wl-folder)
53   (require 'wl-summary)
54   (require 'wl-draft)
55   (require 'wl-message)
56   (require 'wl-highlight)
57   (defvar-maybe wl-folder-mode-map (make-sparse-keymap))
58   (defvar-maybe wl-draft-mode-map (make-sparse-keymap)))
59
60 (add-hook 'wl-folder-mode-hook 'wl-setup-folder)
61 (add-hook 'wl-folder-mode-hook 'wl-folder-init-icons)
62
63 (add-hook 'wl-make-plugged-hook 'wl-biff-init-icons)
64 (add-hook 'wl-make-plugged-hook 'wl-plugged-init-icons)
65
66 (add-hook 'wl-summary-mode-hook 'wl-setup-summary)
67
68 (defvar wl-use-toolbar (image-type-available-p 'xpm))
69 (defvar wl-plugged-image nil)
70 (defvar wl-unplugged-image nil)
71 (defvar wl-biff-mail-image nil)
72 (defvar wl-biff-nomail-image nil)
73
74 (defvar wl-folder-toolbar
75   '([wl-folder-jump-to-current-entity
76      wl-folder-jump-to-current-entity t "Enter Current Folder"]
77     [wl-folder-next-entity
78      wl-folder-next-entity t "Next Folder"]
79     [wl-folder-prev-entity
80      wl-folder-prev-entity t "Previous Folder"]
81     [wl-folder-check-current-entity
82      wl-folder-check-current-entity t "Check Current Folder"]
83     ;;[wl-draft
84     ;; wl-draft t "Write a New Message"]
85     [wl-folder-sync-current-entity
86      wl-folder-sync-current-entity t "Sync Current Folder"]
87     [wl-draft
88      wl-draft t "Write a New Message"]
89     [wl-folder-empty-trash
90      wl-folder-empty-trash t "Empty Trash"]
91     [wl-exit
92      wl-exit t "Quit Wanderlust"]
93     )
94   "The Folder buffer toolbar.")
95
96 (defvar wl-summary-toolbar
97   '([wl-summary-read
98      wl-summary-read t "Read Messages"]
99     [wl-summary-next
100      wl-summary-next t "Next Message"]
101     [wl-summary-prev
102      wl-summary-prev t "Previous Message"]
103     [wl-summary-jump-to-current-message
104      wl-summary-jump-to-current-message t "Jump to Current Message"]
105     [wl-summary-sync-force-update
106      wl-summary-sync-force-update t "Sync Current Folder"]
107     [wl-summary-delete
108      wl-summary-delete t "Delete Current Message"]
109     [wl-summary-mark-as-important
110      wl-summary-mark-as-important t "Mark Current Message as Important"]
111     [wl-draft
112      wl-draft t "Write a New Message"]
113     [wl-summary-reply
114      wl-summary-reply t "Reply to Current Message" ]
115     [wl-summary-reply-with-citation
116      wl-summary-reply-with-citation t "Reply to Current Message with Citation"]
117     [wl-summary-forward
118      wl-summary-forward t "Forward Current Message"]
119     [wl-summary-exit
120      wl-summary-exit t "Exit Current Summary"]
121     )
122   "The Summary buffer toolbar.")
123
124 (defvar wl-message-toolbar
125   '([wl-message-read
126      wl-message-read t "Read Contents"]
127     [wl-message-next-content
128      wl-message-next-content t "Next Content"]
129     [wl-message-prev-content
130      wl-message-prev-content t "Previous Content"]
131     [wl-message-quit
132      wl-message-quit t "Back to Summary"]
133     [wl-message-play-content
134      wl-message-play-content t "Play Content"]
135     [wl-message-extract-content
136      wl-message-extract-content t "Extract Content"]
137     )
138   "The Message buffer toolbar.")
139
140 (defalias 'wl-draft-insert-signature 'insert-signature);; for draft toolbar.
141
142 (defvar wl-draft-toolbar
143   '([wl-draft-send-from-toolbar
144      wl-draft-send-from-toolbar t "Send Current Draft"]
145     [wl-draft-yank-original
146      wl-draft-yank-original t "Yank Displaying Message"]
147     [wl-draft-insert-signature
148      wl-draft-insert-signature t "Insert Signature"]
149     [wl-draft-kill
150      wl-draft-kill t "Kill Current Draft"]
151     )
152   "The Draft buffer toolbar.")
153
154 (defun wl-e21-setup-toolbar (bar)
155   (let ((load-path (cons wl-icon-dir load-path))
156         (props '(:type xpm :ascent center
157                        :color-symbols (("backgroundToolBarColor" . "None"))
158                        :file))
159         (success t)
160         icon up down disabled name success)
161     (while bar
162       (setq icon (aref (pop bar) 0))
163       (unless (boundp icon)
164         (setq name (symbol-name icon)
165               up (find-image `((,@props ,(concat name "-up.xpm")))))
166         (if up
167             (progn
168               (setq down (find-image `((,@props ,(concat name "-down.xpm"))))
169                     disabled (find-image `((,@props
170                                             ,(concat name "-disabled.xpm")))))
171               (set icon (vector down up disabled disabled)))
172           (setq bar nil
173                 success nil))))
174     success))
175
176 (defvar wl-e21-toolbar-configurations
177   '((auto-resize-tool-bar        . t)
178     (auto-raise-tool-bar-buttons . t)
179     (tool-bar-button-margin      . 0)
180     (tool-bar-button-relief      . 2)))
181
182 (defun wl-e21-make-toolbar-buttons (keymap defs)
183   (let ((configs wl-e21-toolbar-configurations)
184         config)
185     (while (setq config (pop configs))
186       (set (make-local-variable (car config)) (cdr config))))
187   ;; Invalidate the default bindings.
188   (let ((keys (cdr (key-binding [tool-bar] t)))
189         item)
190     (while (setq item (pop keys))
191       (when (setq item (car-safe item))
192         (define-key keymap (vector 'tool-bar item) 'undefined))))
193   (let ((n (length defs))
194         def)
195     (while (>= n 0)
196       (setq n (1- n)
197             def (nth n defs))
198       (define-key keymap (vector 'tool-bar (aref def 1))
199         (list 'menu-item (aref def 3) (aref def 1)
200               :enable (aref def 2)
201               :image (symbol-value (aref def 0)))))))
202
203 (defun wl-e21-setup-folder-toolbar ()
204   (and wl-use-toolbar
205        (display-graphic-p)
206        (wl-e21-setup-toolbar wl-folder-toolbar)
207        (wl-e21-make-toolbar-buttons wl-folder-mode-map wl-folder-toolbar)))
208
209 (defun wl-e21-setup-summary-toolbar ()
210   (and wl-use-toolbar
211        (display-graphic-p)
212        (wl-e21-setup-toolbar wl-summary-toolbar)
213        (wl-e21-make-toolbar-buttons wl-summary-mode-map wl-summary-toolbar)))
214
215 (eval-when-compile
216   (defsubst wl-e21-setup-message-toolbar ()
217     (and wl-use-toolbar
218          (display-graphic-p)
219          (wl-e21-setup-toolbar wl-message-toolbar)
220          (wl-e21-make-toolbar-buttons (current-local-map) wl-message-toolbar)))
221
222   (defsubst wl-e21-setup-draft-toolbar ()
223     (and wl-use-toolbar
224          (display-graphic-p)
225          (wl-e21-setup-toolbar wl-draft-toolbar)
226          (wl-e21-make-toolbar-buttons wl-draft-mode-map wl-draft-toolbar))))
227
228 (defvar wl-folder-toggle-icon-list
229   '((wl-folder-opened-image       . wl-opened-group-folder-icon)
230     (wl-folder-closed-image       . wl-closed-group-folder-icon)))
231
232 (eval-when-compile
233   (defsubst wl-e21-highlight-folder-group-line (start end icon numbers)
234     (when (display-graphic-p)
235       (let (overlay)
236         (let ((overlays (overlays-in start end)))
237           (while (and (setq overlay (pop overlays))
238                       (not (overlay-get overlay 'wl-e21-icon)))))
239         (unless overlay
240           (setq overlay (make-overlay start end))
241           (overlay-put overlay 'wl-e21-icon t)
242           (overlay-put overlay 'evaporate t))
243         (let ((image (get icon 'image)))
244           (unless image
245             (let ((name (copy-sequence
246                          (symbol-value
247                           (cdr (assq icon wl-folder-toggle-icon-list)))))
248                   (load-path (cons wl-icon-dir load-path)))
249               (when (setq image (find-image `((:type xpm :file ,name
250                                                      :ascent center))))
251                 (put-text-property 0 (length name) 'display image name)
252                 (setq image (put icon 'image name)))))
253           (overlay-put overlay 'before-string image)
254           (overlay-put overlay 'invisible (and image t))
255           (when (and wl-use-highlight-mouse-line (display-mouse-p))
256             (let ((inhibit-read-only t))
257               (put-text-property (if image
258                                      (max (1- start) (line-beginning-position))
259                                    start)
260                                  (line-end-position)
261                                  'mouse-face 'highlight)))))))
262
263   (defsubst wl-e21-highlight-folder-by-numbers (start end text-face numbers)
264     (when (display-color-p)
265       (let ((inhibit-read-only t))
266         (if (and wl-highlight-folder-by-numbers
267                  numbers (nth 0 numbers) (nth 1 numbers)
268                  (re-search-forward "[0-9-]+/[0-9-]+/[0-9-]+"
269                                     (line-end-position) t))
270             (let* ((unsync (nth 0 numbers))
271                    (unread (nth 1 numbers))
272                    (face (cond ((and unsync (zerop unsync))
273                                 (if (and unread (zerop unread))
274                                     'wl-highlight-folder-zero-face
275                                   'wl-highlight-folder-unread-face))
276                                ((and unsync
277                                      (>= unsync
278                                          wl-folder-many-unsync-threshold))
279                                 'wl-highlight-folder-many-face)
280                                (t
281                                 'wl-highlight-folder-few-face))))
282               (if (numberp wl-highlight-folder-by-numbers)
283                   (progn
284                     (put-text-property start (match-beginning 0)
285                                        'face text-face)
286                     (put-text-property (match-beginning 0) (match-end 0)
287                                        'face face))
288                 (put-text-property start (match-end 0) 'face face)))
289           (put-text-property start (line-end-position) 'face text-face))))))
290
291 (defun wl-highlight-folder-current-line (&optional numbers)
292   (interactive)
293   (save-excursion
294     (beginning-of-line)
295     (let (fld-name start end)
296       (cond
297        (;; opened folder group
298         (looking-at wl-highlight-folder-opened-regexp)
299         (setq start (match-beginning 1)
300               end (match-end 1))
301         (wl-e21-highlight-folder-group-line start end
302                                             'wl-folder-opened-image
303                                             numbers)
304         (wl-e21-highlight-folder-by-numbers start end
305                                             'wl-highlight-folder-opened-face
306                                             numbers))
307        (;; closed folder group
308         (looking-at wl-highlight-folder-closed-regexp)
309         (setq start (match-beginning 1)
310               end (match-end 1))
311         (wl-e21-highlight-folder-group-line start end
312                                             'wl-folder-closed-image
313                                             numbers)
314         (wl-e21-highlight-folder-by-numbers start end
315                                             'wl-highlight-folder-closed-face
316                                             numbers))
317        (;; basic folder
318         (and (setq fld-name (wl-folder-get-folder-name-by-id
319                              (get-text-property (point) 'wl-folder-entity-id)))
320              (looking-at "[\t ]+\\([^\t\n ]+\\)"))
321         (setq start (match-beginning 1)
322               end (match-end 1))
323         (let (image)
324           (when (display-graphic-p)
325             (let (overlay)
326               (let ((overlays (overlays-in start end)))
327                 (while (and (setq overlay (pop overlays))
328                             (not (overlay-get overlay 'wl-e21-icon)))))
329               (unless overlay
330                 (setq overlay (make-overlay start end))
331                 (overlay-put overlay 'wl-e21-icon t)
332                 (overlay-put overlay 'evaporate t))
333               (let (type)
334                 (setq image
335                       (cond ((string= fld-name wl-trash-folder);; trash folder
336                              (let ((num (nth 2 numbers)));; number of messages
337                                (get (if (or (not num) (zerop num))
338                                         'wl-folder-trash-empty-image
339                                       'wl-folder-trash-image)
340                                     'image)))
341                             ((string= fld-name wl-draft-folder);; draft folder
342                              (get 'wl-folder-draft-image 'image))
343                             ((string= fld-name wl-queue-folder);; queue folder
344                              (get 'wl-folder-queue-image 'image))
345                             (;; and one of many other folders
346                              (setq type (elmo-folder-get-type fld-name))
347                              (get (intern (format "wl-folder-%s-image" type))
348                                   'image)))))
349               (overlay-put overlay 'before-string image)))
350           (when (and wl-use-highlight-mouse-line (display-mouse-p))
351             (let ((inhibit-read-only t))
352               (put-text-property (if image
353                                      (max (1- start)
354                                           (line-beginning-position))
355                                    start)
356                                  (line-end-position)
357                                  'mouse-face 'highlight))))
358         (when (display-color-p)
359           (wl-e21-highlight-folder-by-numbers
360            start end
361            (if (looking-at (format "^[\t ]*\\(%s\\|%s\\)"
362                                    wl-folder-unsubscribe-mark
363                                    wl-folder-removed-mark))
364                'wl-highlight-folder-killed-face
365              'wl-highlight-folder-unknown-face)
366            numbers)))))))
367
368 (defun wl-highlight-plugged-current-line ()
369   (interactive)
370   (when (display-graphic-p)
371     (save-excursion
372       (beginning-of-line)
373       (when (looking-at "[\t ]*\\(\\[\\([^]]+\\)\\]\\)")
374         (let* ((start (match-beginning 1))
375                (end (match-end 1))
376                (status (match-string-no-properties 2))
377                (image (if (string-equal wl-plugged-plug-on status)
378                           wl-plugged-image
379                         wl-unplugged-image)))
380           (when image
381             (let (overlay)
382               (let ((overlays (overlays-in start end)))
383                 (while (and (setq overlay (pop overlays))
384                             (not (overlay-get overlay 'wl-e21-icon)))))
385               (unless overlay
386                 (setq overlay (make-overlay start end))
387                 (overlay-put overlay 'wl-e21-icon t)
388                 (overlay-put overlay 'evaporate t))
389               (put-text-property 0 (length status) 'display image status)
390               (overlay-put overlay 'before-string status)
391               (overlay-put overlay 'invisible t))))))))
392
393 (defun wl-plugged-set-folder-icon (folder string)
394   (if (display-graphic-p)
395       (let ((istring (concat " " string))
396             type)
397         (cond ((string= folder wl-queue-folder)
398                (put-text-property 0 1 'display
399                                   (get 'wl-folder-queue-image 'image) istring)
400                istring)
401               ((setq type (elmo-folder-get-type folder))
402                (put-text-property 0 1 'display
403                                   (get (intern (format "wl-folder-%s-image"
404                                                        type))
405                                        'image)
406                                   istring)
407                istring)
408               (t
409                string)))
410     string))
411
412 (defvar wl-folder-internal-icon-list
413   ;; alist of (image . icon-file)
414   '((wl-folder-nntp-image         . wl-nntp-folder-icon)
415     (wl-folder-imap4-image        . wl-imap-folder-icon)
416     (wl-folder-pop3-image         . wl-pop-folder-icon)
417     (wl-folder-localdir-image     . wl-localdir-folder-icon)
418     (wl-folder-localnews-image    . wl-localnews-folder-icon)
419     (wl-folder-internal-image     . wl-internal-folder-icon)
420     (wl-folder-multi-image        . wl-multi-folder-icon)
421     (wl-folder-filter-image       . wl-filter-folder-icon)
422     (wl-folder-archive-image      . wl-archive-folder-icon)
423     (wl-folder-pipe-image         . wl-pipe-folder-icon)
424     (wl-folder-maildir-image      . wl-maildir-folder-icon)
425     (wl-folder-trash-empty-image  . wl-empty-trash-folder-icon)
426     (wl-folder-draft-image        . wl-draft-folder-icon)
427     (wl-folder-queue-image        . wl-queue-folder-icon)
428     (wl-folder-trash-image        . wl-trash-folder-icon)))
429
430 (defun wl-folder-init-icons ()
431   (let ((load-path (cons wl-icon-dir load-path))
432         (icons wl-folder-internal-icon-list)
433         icon name image)
434     (while (setq icon (pop icons))
435       (unless (get (car icon) 'image)
436         (setq name (symbol-value (cdr icon))
437               image (find-image `((:type xpm :file ,name :ascent center))))
438         (when image
439           (let* ((str (copy-sequence name))
440                  (len (length str)))
441             (put-text-property 0 len 'display image str)
442             (put (car icon) 'image str)))))))
443
444 (defun wl-plugged-init-icons ()
445   (unless wl-plugged-image
446     (let ((load-path (cons wl-icon-dir load-path)))
447       (setq wl-plugged-image (find-image `((:type xpm
448                                                   :file ,wl-plugged-icon
449                                                   :ascent center)))
450             wl-unplugged-image (find-image `((:type xpm
451                                                     :file ,wl-unplugged-icon
452                                                     :ascent center)))))
453     (setq wl-modeline-plug-state-on (copy-sequence
454                                      wl-plug-state-indicator-on)
455           wl-modeline-plug-state-off (copy-sequence
456                                       wl-plug-state-indicator-off)))
457   (let ((props (when (display-mouse-p)
458                  (list 'local-map (purecopy (make-mode-line-mouse2-map
459                                              #'wl-toggle-plugged))
460                        'help-echo "mouse-2 toggles plugged status"))))
461     (add-text-properties 0 (length wl-modeline-plug-state-on)
462                          (nconc props (when (display-graphic-p)
463                                         (list 'display wl-plugged-image)))
464                          wl-modeline-plug-state-on)
465     (add-text-properties 0 (length wl-modeline-plug-state-off)
466                          (nconc props (when (display-graphic-p)
467                                         (list 'display wl-unplugged-image)))
468                          wl-modeline-plug-state-off)))
469
470 (defun wl-biff-init-icons ()
471   (unless wl-biff-mail-image
472     (let ((load-path (cons wl-icon-dir load-path)))
473       (setq wl-biff-mail-image (find-image
474                                 `((:type xpm :file ,wl-biff-mail-icon
475                                          :ascent center)))
476             wl-biff-nomail-image (find-image
477                                   `((:type xpm :file ,wl-biff-nomail-icon
478                                            :ascent center)))))
479     (setq wl-modeline-biff-state-on (copy-sequence
480                                      wl-biff-state-indicator-on)
481           wl-modeline-biff-state-off (copy-sequence
482                                       wl-biff-state-indicator-off)))
483   (let ((props (when (display-mouse-p)
484                  (list 'local-map (purecopy (make-mode-line-mouse2-map
485                                              (lambda nil
486                                                (call-interactively
487                                                 'wl-biff-check-folders))))
488                        'help-echo "mouse-2 checks new mails"))))
489     (add-text-properties 0 (length wl-modeline-biff-state-on)
490                          (nconc props (when (display-graphic-p)
491                                         (list 'display wl-biff-mail-image)))
492                          wl-modeline-biff-state-on)
493     (add-text-properties 0 (length wl-modeline-biff-state-off)
494                          (nconc props (when (display-graphic-p)
495                                         (list 'display wl-biff-nomail-image)))
496                          wl-modeline-biff-state-off)))
497
498 (defun wl-make-date-string ()
499   (format-time-string "%a, %d %b %Y %T %z"))
500
501 (defalias 'wl-setup-folder 'wl-e21-setup-folder-toolbar)
502
503 (defalias 'wl-setup-summary 'wl-e21-setup-summary-toolbar)
504
505 (defun wl-message-overload-functions ()
506   (wl-e21-setup-message-toolbar)
507   (let ((keymap (current-local-map)))
508     (define-key keymap "l" 'wl-message-toggle-disp-summary)
509     (define-key keymap [mouse-2] 'wl-message-refer-article-or-url)
510     (define-key keymap [mouse-4] 'wl-message-wheel-down)
511     (define-key keymap [mouse-5] 'wl-message-wheel-up)
512     (define-key keymap [S-mouse-4] 'wl-message-wheel-down)
513     (define-key keymap [S-mouse-5] 'wl-message-wheel-up)
514     (set-keymap-parent wl-message-button-map keymap))
515   (define-key wl-message-button-map [mouse-2] 'wl-message-button-dispatcher))
516
517 (defun wl-message-wheel-up (event)
518   (interactive "e")
519   (if (string-match wl-message-buf-name (buffer-name))
520       (wl-message-next-page)
521     (let ((cur-buf (current-buffer))
522           proceed)
523       (save-selected-window
524         (select-window (posn-window (event-start event)))
525         (set-buffer cur-buf)
526         (setq proceed (wl-message-next-page)))
527       (if proceed
528           (if (memq 'shift (event-modifiers event))
529               (wl-summary-down t)
530             (wl-summary-next t))))))
531
532 (defun wl-message-wheel-down (event)
533   (interactive "e")
534   (if (string-match wl-message-buf-name (buffer-name))
535       (wl-message-prev-page)
536     (let ((cur-buf (current-buffer))
537           proceed)
538       (save-selected-window
539         (select-window (posn-window (event-start event)))
540         (set-buffer cur-buf)
541         (setq proceed (wl-message-prev-page)))
542       (if proceed
543           (if (memq 'shift (event-modifiers event))
544               (wl-summary-up t)
545             (wl-summary-prev t))))))
546
547 (defun wl-draft-overload-menubar ()
548   (let ((keymap (current-local-map)))
549     (define-key keymap [menu-bar mail send]
550       '("Send Message" . wl-draft-send-and-exit))
551     (define-key keymap [menu-bar mail send-stay]
552       '("Send, Keep Editing" . wl-draft-send))
553     (define-key keymap [menu-bar mail cancel]
554       '("Kill Current Draft" . wl-draft-kill))
555     (define-key keymap [menu-bar mail yank]
556       '("Cite Message" . wl-draft-yank-original))
557     (define-key keymap [menu-bar mail signature]
558       '("Insert Signature" . insert-signature))
559     (define-key keymap [menu-bar headers fcc]
560       '("FCC" . wl-draft-fcc))))
561
562 (defun wl-draft-mode-setup ()
563   (require 'derived)
564   (define-derived-mode wl-draft-mode mail-mode "Draft"
565     "draft mode for Wanderlust derived from mail mode.
566 See info under Wanderlust for full documentation.
567
568 Special commands:
569 \\{wl-draft-mode-map}"))
570
571 (defun wl-draft-key-setup ()
572   (define-key wl-draft-mode-map "\C-c\C-y" 'wl-draft-yank-original)
573   (define-key wl-draft-mode-map "\C-c\C-s" 'wl-draft-send)
574   (define-key wl-draft-mode-map "\C-c\C-a" 'wl-draft-insert-x-face-field)
575   (define-key wl-draft-mode-map "\C-c\C-c" 'wl-draft-send-and-exit)
576   (define-key wl-draft-mode-map "\C-c\C-z" 'wl-draft-save-and-exit)
577   (define-key wl-draft-mode-map "\C-c\C-k" 'wl-draft-kill)
578   (define-key wl-draft-mode-map "\C-l" 'wl-draft-highlight-and-recenter)
579   (define-key wl-draft-mode-map "\C-i" 'wl-complete-field-body-or-tab)
580   (define-key wl-draft-mode-map "\C-c\C-r" 'wl-draft-caesar-region)
581   (define-key wl-draft-mode-map "\M-t" 'wl-toggle-plugged)
582   (define-key wl-draft-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer)
583   (define-key wl-draft-mode-map "\C-c\C-e" 'wl-draft-config-exec)
584   (define-key wl-draft-mode-map "\C-c\C-j" 'wl-template-select)
585   (define-key wl-draft-mode-map "\C-c\C-p" 'wl-draft-preview-message)
586   (define-key wl-draft-mode-map "\C-x\C-s" 'wl-draft-save)
587   (define-key wl-draft-mode-map "\C-xk"    'wl-draft-mimic-kill-buffer))
588
589 (defun wl-draft-overload-functions ()
590   (wl-mode-line-buffer-identification)
591   (local-set-key "\C-c\C-s" 'wl-draft-send);; override
592   (wl-e21-setup-draft-toolbar)
593   (wl-draft-overload-menubar))
594
595 (defalias 'wl-defface 'defface)
596
597 (require 'product)
598 (product-provide (provide 'wl-e21) (require 'wl-version))
599
600 ;;; wl-e21.el ends here