Synch up with elmo-lunafy.
[elisp/wanderlust.git] / wl / wl-xmas.el
1 ;;; wl-xmas.el -- Wanderlust modules for XEmacsen.
2
3 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
4 ;; Copyright (C) 2000 Katsumi Yamaoka <yamaoka@jpl.org>
5
6 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
7 ;;      Katsumi Yamaoka <yamaoka@jpl.org>
8 ;; Keywords: mail, net news
9
10 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
11
12 ;; This program is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16 ;;
17 ;; This program is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21 ;;
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
26 ;;
27
28 ;;; Commentary:
29 ;;
30
31 ;;; Code:
32 ;;
33
34 (eval-when-compile
35   (require 'wl-folder)
36   (require 'wl-summary)
37   (require 'wl-draft)
38   (require 'wl-message)
39   (require 'wl-highlight)
40   (defvar-maybe wl-draft-mode-map (make-sparse-keymap))
41   (defalias-maybe 'toolbar-make-button-list 'ignore))
42
43 (add-hook 'wl-folder-mode-hook 'wl-setup-folder)
44 (add-hook 'wl-folder-mode-hook 'wl-folder-init-icons)
45
46 (add-hook 'wl-init-hook 'wl-biff-init-icons)
47 (add-hook 'wl-init-hook 'wl-plugged-init-icons)
48
49 (add-hook 'wl-summary-mode-hook 'wl-setup-summary)
50
51 (defvar wl-use-toolbar (if (featurep 'toolbar) 'default-toolbar nil))
52 (defvar wl-plugged-glyph nil)
53 (defvar wl-unplugged-glyph nil)
54 (defvar wl-biff-mail-glyph nil)
55 (defvar wl-biff-nomail-glyph nil)
56
57 (defvar wl-folder-toolbar
58   '([wl-folder-jump-to-current-entity
59      wl-folder-jump-to-current-entity t "Enter Current Folder"]
60     [wl-folder-next-entity
61      wl-folder-next-entity t "Next Folder"]
62     [wl-folder-prev-entity
63      wl-folder-prev-entity t "Previous Folder"]
64     [wl-folder-check-current-entity
65      wl-folder-check-current-entity t "Check Current Folder"]
66 ;;; [wl-draft
67 ;;;  wl-draft t "Write a New Message"]
68     [wl-folder-sync-current-entity
69      wl-folder-sync-current-entity t "Sync Current Folder"]
70     [wl-draft
71      wl-draft t "Write a New Message"]
72     [wl-folder-empty-trash
73      wl-folder-empty-trash t "Empty Trash"]
74     [wl-exit
75      wl-exit t "Quit Wanderlust"]
76     )
77   "The Folder buffer toolbar.")
78
79 (defvar wl-summary-toolbar
80   '([wl-summary-read
81      wl-summary-read t "Read Messages"]
82     [wl-summary-next
83      wl-summary-next t "Next Message"]
84     [wl-summary-prev
85      wl-summary-prev t "Previous Message"]
86     [wl-summary-jump-to-current-message
87      wl-summary-jump-to-current-message t "Jump to Current Message"]
88     [wl-summary-sync-force-update
89      wl-summary-sync-force-update t "Sync Current Folder"]
90     [wl-summary-delete
91      wl-summary-delete t "Delete Current Message"]
92     [wl-summary-mark-as-important
93      wl-summary-mark-as-important t "Mark Current Message as Important"]
94     [wl-draft
95      wl-draft t "Write a New Message"]
96     [wl-summary-reply
97      wl-summary-reply t "Reply to Current Message" ]
98     [wl-summary-reply-with-citation
99      wl-summary-reply-with-citation t "Reply to Current Message with Citation"]
100     [wl-summary-forward
101      wl-summary-forward t "Forward Current Message"]
102     [wl-summary-exit
103      wl-summary-exit t "Exit Current Summary"]
104     )
105   "The Summary buffer toolbar.")
106
107 (defvar wl-message-toolbar
108   '([wl-message-read
109      wl-message-read t "Read Contents"]
110     [wl-message-next-content
111      wl-message-next-content t "Next Content"]
112     [wl-message-prev-content
113      wl-message-prev-content t "Previous Content"]
114     [wl-message-quit
115      wl-message-quit t "Back to Summary"]
116     [wl-message-play-content
117      wl-message-play-content t "Play Content"]
118     [wl-message-extract-content
119      wl-message-extract-content t "Extract Content"]
120     )
121   "The Message buffer toolbar.")
122
123 (defalias 'wl-draft-insert-signature 'insert-signature);; for draft toolbar.
124
125 (defvar wl-draft-toolbar
126   '([wl-draft-send-from-toolbar
127      wl-draft-send-from-toolbar t "Send Current Draft"]
128     [wl-draft-yank-original
129      wl-draft-yank-original t "Yank Displaying Message"]
130     [wl-draft-insert-signature
131      wl-draft-insert-signature t "Insert Signature"]
132     [wl-draft-kill
133      wl-draft-kill t "Kill Current Draft"]
134     )
135   "The Draft buffer toolbar.")
136
137 (defun wl-xmas-setup-toolbar (bar)
138   (let ((dir wl-icon-dir)
139         icon up down disabled name)
140     (when dir
141       (while bar
142         (setq icon (aref (car bar) 0)
143               name (symbol-name icon)
144               bar (cdr bar))
145         (unless (boundp icon)
146           (setq up (expand-file-name (concat name "-up.xpm") dir)
147                 down (expand-file-name (concat name "-down.xpm") dir)
148                 disabled (expand-file-name (concat name "-disabled.xpm") dir))
149           (if (file-exists-p up)
150               (set icon (toolbar-make-button-list
151                          up (and (file-exists-p down) down)
152                          (and (file-exists-p disabled) disabled)))
153             (setq bar nil
154                   dir nil)))))
155     dir))
156
157 (defun wl-xmas-make-icon-glyph (icon-string icon-file
158                                             &optional locale tag-set)
159   (let ((glyph (make-glyph (vector 'string :data icon-string))))
160     (when wl-highlight-folder-with-icon
161       (set-glyph-image glyph
162                        (vector 'xpm :file (expand-file-name
163                                            icon-file wl-icon-dir))
164                        locale tag-set 'prepend))
165     glyph))
166
167 (eval-when-compile
168   (defsubst wl-xmas-setup-folder-toolbar ()
169     (and wl-use-toolbar
170          (wl-xmas-setup-toolbar wl-folder-toolbar)
171          (set-specifier (symbol-value wl-use-toolbar)
172                         (cons (current-buffer) wl-folder-toolbar))))
173
174   (defsubst wl-xmas-setup-summary-toolbar ()
175     (and wl-use-toolbar
176          (wl-xmas-setup-toolbar wl-summary-toolbar)
177          (set-specifier (symbol-value wl-use-toolbar)
178                         (cons (current-buffer) wl-summary-toolbar))))
179
180   (defsubst wl-xmas-setup-message-toolbar ()
181     (and wl-use-toolbar
182          (wl-xmas-setup-toolbar wl-message-toolbar)
183          (set-specifier (symbol-value wl-use-toolbar)
184                         (cons (current-buffer) wl-message-toolbar))))
185
186   (defsubst wl-xmas-setup-draft-toolbar ()
187     (and wl-use-toolbar
188          (wl-xmas-setup-toolbar wl-draft-toolbar)
189          (set-specifier (symbol-value wl-use-toolbar)
190                         (cons (current-buffer) wl-draft-toolbar)))))
191
192 (defvar wl-folder-toggle-icon-list
193   '((wl-folder-opened-glyph       . wl-opened-group-folder-icon)
194     (wl-folder-closed-glyph       . wl-closed-group-folder-icon)))
195
196 (eval-when-compile
197   (defsubst wl-xmas-highlight-folder-group-line (glyph text-face numbers)
198     (let ((start (match-beginning 1))
199           (end (match-end 1)))
200       (let (extent)
201         (while (and (setq extent (extent-at start nil nil extent 'at))
202                     (not (and (eq start (extent-start-position extent))
203                               (eq end (extent-end-position extent))
204                               (extent-end-glyph extent)))))
205         (unless extent
206           (setq extent (make-extent start end)))
207         (set-extent-properties extent `(end-open t start-closed t invisible t))
208         (set-extent-end-glyph
209          extent
210          (or (get glyph 'glyph)
211              (put glyph 'glyph
212                   (wl-xmas-make-icon-glyph
213                    (buffer-substring-no-properties start end)
214                    (symbol-value
215                     (cdr (assq glyph wl-folder-toggle-icon-list))))))))
216       (let ((inhibit-read-only t))
217         (when wl-use-highlight-mouse-line
218           (put-text-property start (point-at-eol) 'mouse-face 'highlight))
219         (setq start end
220               end (point-at-eol))
221         (if (and wl-highlight-folder-by-numbers
222                  numbers (nth 0 numbers) (nth 1 numbers)
223                  (re-search-forward "[0-9-]+/[0-9-]+/[0-9-]+" end t))
224             (let* ((unsync (nth 0 numbers))
225                    (unread (nth 1 numbers))
226                    (face (cond ((and unsync (zerop unsync))
227                                 (if (and unread (zerop unread))
228                                     'wl-highlight-folder-zero-face
229                                   'wl-highlight-folder-unread-face))
230                                ((and unsync
231                                      (>= unsync
232                                          wl-folder-many-unsync-threshold))
233                                 'wl-highlight-folder-many-face)
234                                (t
235                                 'wl-highlight-folder-few-face))))
236               (if (numberp wl-highlight-folder-by-numbers)
237                   (progn
238                     (put-text-property start (match-beginning 0)
239                                        'face text-face)
240                     (put-text-property (match-beginning 0) (point) 'face face))
241                 (put-text-property start end 'face face)))
242           (put-text-property start end 'face text-face))))))
243
244 (defun wl-highlight-folder-current-line (&optional numbers)
245   (interactive)
246   (save-excursion
247     (beginning-of-line)
248     (let (fld-name)
249       (cond
250        (;; opened folder group
251         (looking-at wl-highlight-folder-opened-regexp)
252         (wl-xmas-highlight-folder-group-line 'wl-folder-opened-glyph
253                                              'wl-highlight-folder-opened-face
254                                              numbers))
255        (;; closed folder group
256         (looking-at wl-highlight-folder-closed-regexp)
257         (wl-xmas-highlight-folder-group-line 'wl-folder-closed-glyph
258                                              'wl-highlight-folder-closed-face
259                                              numbers))
260        (;; basic folder
261         (and (setq fld-name (wl-folder-get-folder-name-by-id
262                              (get-text-property (point) 'wl-folder-entity-id)))
263              (looking-at "[ \t]+\\([^ \t]+\\)"))
264         (let ((start (match-beginning 1)))
265           (let (extent)
266             (while (and (setq extent (extent-at start nil nil extent 'at))
267                         (not (and (eq start (extent-start-position extent))
268                                   (eq start (extent-end-position extent))
269                                   (extent-begin-glyph extent)))))
270             (unless extent
271               (setq extent (make-extent start start)))
272             (let (type)
273               (set-extent-begin-glyph
274                extent
275                (cond
276                 ((string= fld-name wl-trash-folder);; trash folder
277                  (let ((num (nth 2 numbers)));; number of messages
278                    (get (if (or (not num) (zerop num))
279                             'wl-folder-trash-empty-glyph
280                           'wl-folder-trash-glyph)
281                         'glyph)))
282                 ((string= fld-name wl-draft-folder);; draft folder
283                  (get 'wl-folder-draft-glyph 'glyph))
284                 ((string= fld-name wl-queue-folder);; queue folder
285                  (get 'wl-folder-queue-glyph 'glyph))
286                 (;; and one of many other folders
287                  (setq type (elmo-folder-type fld-name))
288                  (get (intern (format "wl-folder-%s-glyph" type)) 'glyph))))))
289           (let ((end (point-at-eol)))
290             (when wl-use-highlight-mouse-line
291               (put-text-property start end 'mouse-face 'highlight))
292             (let ((text-face
293                    (if (looking-at (format "^[ \t]*\\(%s\\|%s\\)"
294                                            wl-folder-unsubscribe-mark
295                                            wl-folder-removed-mark))
296                        'wl-highlight-folder-killed-face
297                      'wl-highlight-folder-unknown-face)))
298               (if (and wl-highlight-folder-by-numbers
299                        numbers (nth 0 numbers) (nth 1 numbers)
300                        (re-search-forward "[0-9-]+/[0-9-]+/[0-9-]+" end t))
301                   (let* ((unsync (nth 0 numbers))
302                          (unread (nth 1 numbers))
303                          (face (cond
304                                 ((and unsync (zerop unsync))
305                                  (if (and unread (zerop unread))
306                                      'wl-highlight-folder-zero-face
307                                    'wl-highlight-folder-unread-face))
308                                 ((and unsync
309                                       (>= unsync
310                                           wl-folder-many-unsync-threshold))
311                                  'wl-highlight-folder-many-face)
312                                 (t
313                                  'wl-highlight-folder-few-face))))
314                     (if (numberp wl-highlight-folder-by-numbers)
315                         (progn
316                           (put-text-property start (match-beginning 0)
317                                              'face text-face)
318                           (put-text-property (match-beginning 0)
319                                              (match-end 0)
320                                              'face face))
321                       ;; Remove previous face.
322                       (put-text-property start (match-end 0) 'face nil)
323                       (put-text-property start (match-end 0) 'face face)))
324                 (put-text-property start end 'face text-face))))))))))
325
326 (defun wl-highlight-plugged-current-line ()
327   (interactive)
328   (save-excursion
329     (let ((inhibit-read-only t)
330           extent switch)
331       (beginning-of-line)
332       (when (looking-at "[ \t]*\\(\\[\\([^]]+\\)\\]\\)")
333         (setq switch (elmo-match-buffer 2))
334         (when (and (setq extent (extent-at (match-end 1) nil nil nil 'at))
335                    (extent-end-glyph extent))
336           (delete-extent extent))
337         (setq extent (make-extent (match-beginning 1) (match-end 1)))
338         (set-extent-property extent 'end-open t)
339         (set-extent-property extent 'start-closed t)
340         (set-extent-property extent 'invisible t)
341         (set-extent-end-glyph extent (if (string= switch wl-plugged-plug-on)
342                                          wl-plugged-glyph
343                                        wl-unplugged-glyph))))))
344
345 (defun wl-plugged-set-folder-icon (folder string)
346   (let ((string (copy-sequence string))
347         (len (length string))
348         type)
349     (if (string= folder wl-queue-folder)
350         (put-text-property 0 len 'begin-glyph
351                            (get 'wl-folder-queue-glyph 'glyph)
352                            string)
353       (if (setq type (elmo-folder-type folder))
354           (put-text-property 0 len
355                              'begin-glyph
356                              (get (intern (format "wl-folder-%s-glyph" type))
357                                   'glyph)
358                              string)))
359     string))
360
361 (defvar wl-folder-internal-icon-list
362   ;; alist of (glyph . icon-file)
363   '((wl-folder-nntp-glyph         . wl-nntp-folder-icon)
364     (wl-folder-imap4-glyph        . wl-imap-folder-icon)
365     (wl-folder-pop3-glyph         . wl-pop-folder-icon)
366     (wl-folder-localdir-glyph     . wl-localdir-folder-icon)
367     (wl-folder-localnews-glyph    . wl-localnews-folder-icon)
368     (wl-folder-internal-glyph     . wl-internal-folder-icon)
369     (wl-folder-multi-glyph        . wl-multi-folder-icon)
370     (wl-folder-filter-glyph       . wl-filter-folder-icon)
371     (wl-folder-archive-glyph      . wl-archive-folder-icon)
372     (wl-folder-pipe-glyph         . wl-pipe-folder-icon)
373     (wl-folder-maildir-glyph      . wl-maildir-folder-icon)
374     (wl-folder-nmz-glyph          . wl-nmz-folder-icon)
375     (wl-folder-shimbun-glyph      . wl-shimbun-folder-icon)
376     (wl-folder-trash-empty-glyph  . wl-empty-trash-folder-icon)
377     (wl-folder-draft-glyph        . wl-draft-folder-icon)
378     (wl-folder-queue-glyph        . wl-queue-folder-icon)
379     (wl-folder-trash-glyph        . wl-trash-folder-icon)))
380
381 (defun wl-folder-init-icons ()
382   (dolist (icon wl-folder-internal-icon-list)
383     (unless (get (car icon) 'glyph)
384       (put (car icon) 'glyph
385            (wl-xmas-make-icon-glyph "" (symbol-value (cdr icon)))))))
386
387 (defun wl-plugged-init-icons ()
388   (unless wl-plugged-glyph
389     (setq wl-plugged-glyph (wl-xmas-make-icon-glyph
390                             wl-plug-state-indicator-on wl-plugged-icon)
391           wl-unplugged-glyph (wl-xmas-make-icon-glyph
392                               wl-plug-state-indicator-off wl-unplugged-icon))
393     (let ((extent (make-extent nil nil)))
394       (let ((keymap (make-sparse-keymap)))
395         (define-key keymap 'button2
396           (make-modeline-command-wrapper 'wl-toggle-plugged))
397         (set-extent-keymap extent keymap)
398         (set-extent-property extent 'help-echo
399                              "button2 toggles plugged status"))
400       (setq wl-modeline-plug-state-on (cons extent wl-plugged-glyph)
401             wl-modeline-plug-state-off (cons extent wl-unplugged-glyph)))))
402
403 (defun wl-biff-init-icons ()
404   (unless wl-biff-mail-glyph
405     (setq wl-biff-mail-glyph (wl-xmas-make-icon-glyph
406                               wl-biff-state-indicator-on
407                               wl-biff-mail-icon)
408           wl-biff-nomail-glyph (wl-xmas-make-icon-glyph
409                                 wl-biff-state-indicator-off
410                                 wl-biff-nomail-icon))
411     (let ((extent (make-extent nil nil)))
412       (let ((keymap (make-sparse-keymap)))
413         (define-key keymap 'button2
414           (make-modeline-command-wrapper 'wl-biff-check-folders))
415         (set-extent-keymap extent keymap)
416         (set-extent-property extent 'help-echo "button2 checks new mails"))
417       (setq wl-modeline-biff-state-on (cons extent wl-biff-mail-glyph)
418             wl-modeline-biff-state-off (cons extent wl-biff-nomail-glyph)))))
419
420 (defun wl-make-date-string ()
421   (let ((s (current-time-string)))
422     (string-match "\\`\\([A-Z][a-z][a-z]\\) +[A-Z][a-z][a-z] +[0-9][0-9]? *[0-9][0-9]?:[0-9][0-9]:[0-9][0-9] *[0-9]?[0-9]?[0-9][0-9]"
423                   s)
424     (concat (wl-match-string 1 s) ", "
425             (timezone-make-date-arpa-standard s (current-time-zone)))))
426
427 (defun wl-setup-folder ()
428   (and (featurep 'scrollbar)
429        (set-specifier scrollbar-height (cons (current-buffer) 0)))
430   (wl-xmas-setup-folder-toolbar))
431
432 (defvar dragdrop-drop-functions)
433
434 (defun wl-setup-summary ()
435   (make-local-variable 'dragdrop-drop-functions)
436   (setq dragdrop-drop-functions '((wl-dnd-default-drop-message t t)))
437   (and (featurep 'scrollbar)
438        (set-specifier scrollbar-height (cons (current-buffer) 0)))
439   (wl-xmas-setup-summary-toolbar))
440
441 (defun wl-message-overload-functions ()
442   (wl-xmas-setup-message-toolbar)
443   (local-set-key "l" 'wl-message-toggle-disp-summary)
444   (local-set-key 'button2 'wl-message-refer-article-or-url)
445   (local-set-key 'button4 'wl-message-wheel-down)
446   (local-set-key 'button5 'wl-message-wheel-up)
447   (local-set-key [(shift button4)] 'wl-message-wheel-down)
448   (local-set-key [(shift button5)] 'wl-message-wheel-up)
449   (set-keymap-parent wl-message-button-map (current-local-map))
450   (define-key wl-message-button-map 'button2
451     'wl-message-button-dispatcher))
452
453 (defun wl-message-wheel-up (event)
454   (interactive "e")
455   (let ((cur-buf (current-buffer))
456         proceed)
457     (save-selected-window
458       (select-window (event-window event))
459       (set-buffer cur-buf)
460       (setq proceed (wl-message-next-page)))
461     (when proceed
462       (if (memq 'shift (event-modifiers event))
463           (wl-summary-down t)
464         (wl-summary-next t)))))
465
466 (defun wl-message-wheel-down (event)
467   (interactive "e")
468   (let ((cur-buf (current-buffer))
469         proceed)
470     (save-selected-window
471       (select-window (event-window event))
472       (set-buffer cur-buf)
473       (setq proceed (wl-message-prev-page)))
474     (when proceed
475       (if (memq 'shift (event-modifiers event))
476           (wl-summary-up t)
477         (wl-summary-prev t)))))
478
479 (defun wl-draft-overload-menubar ()
480   (when (featurep 'menubar)
481     (add-menu-item '("Mail") "Send, Keep Editing"
482                    'wl-draft-send t "Send Mail")
483     (add-menu-item '("Mail") "Send Message"
484                    'wl-draft-send-and-exit t "Send and Exit")
485     (delete-menu-item '("Mail" "Send Mail"))
486     (delete-menu-item '("Mail" "Send and Exit"))))
487
488 (defun wl-draft-mode-setup ()
489   (require 'derived)
490   (define-derived-mode wl-draft-mode mail-mode "Draft"
491     "draft mode for Wanderlust derived from mail mode.
492 See info under Wanderlust for full documentation.
493
494 Special commands:
495 \\{wl-draft-mode-map}"))
496
497 (defun wl-draft-key-setup ()
498   (define-key wl-draft-mode-map "\C-c\C-y" 'wl-draft-yank-original)
499   (define-key wl-draft-mode-map "\C-c\C-s" 'wl-draft-send)
500   (define-key wl-draft-mode-map "\C-c\C-a" 'wl-draft-insert-x-face-field)
501   (define-key wl-draft-mode-map "\C-c\C-c" 'wl-draft-send-and-exit)
502   (define-key wl-draft-mode-map "\C-c\C-z" 'wl-draft-save-and-exit)
503   (define-key wl-draft-mode-map "\C-c\C-k" 'wl-draft-kill)
504   (define-key wl-draft-mode-map "\C-l" 'wl-draft-highlight-and-recenter)
505   (define-key wl-draft-mode-map "\C-i" 'wl-complete-field-body-or-tab)
506   (define-key wl-draft-mode-map "\C-c\C-r" 'wl-draft-caesar-region)
507   (define-key wl-draft-mode-map "\M-t" 'wl-toggle-plugged)
508   (define-key wl-draft-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer)
509   (define-key wl-draft-mode-map "\C-c\C-e" 'wl-draft-config-exec)
510   (define-key wl-draft-mode-map "\C-c\C-j" 'wl-template-select)
511   (define-key wl-draft-mode-map "\C-c\C-p" 'wl-draft-preview-message)
512   (define-key wl-draft-mode-map "\C-x\C-s" 'wl-draft-save)
513   (define-key wl-draft-mode-map "\C-xk"    'wl-draft-mimic-kill-buffer))
514
515 (defun wl-draft-overload-functions ()
516   (wl-mode-line-buffer-identification)
517   ;; (local-set-key "\C-c\C-s" 'wl-draft-send);; override
518   (wl-xmas-setup-draft-toolbar)
519   (wl-draft-overload-menubar))
520
521 (defalias 'wl-defface 'defface)
522
523 (defun wl-read-event-char ()
524   "Get the next event."
525   (let ((event (next-command-event)))
526     (sit-for 0)
527     ;; We junk all non-key events.  Is this naughty?
528     (while (not (or (key-press-event-p event)
529                     (button-press-event-p event)))
530       (dispatch-event event)
531       (setq event (next-command-event)))
532     (cons (and (key-press-event-p event)
533                (event-to-character event))
534           event)))
535
536 (require 'product)
537 (product-provide (provide 'wl-xmas) (require 'wl-version))
538
539 ;;; wl-xmas.el ends here